SBT : le maven de Scala

SBT : le maven de Scala

SBT (pour Simple Build Tool) est le Maven de Scala : c’est un outil open-source qui gère les builds de projets Scala et Java.

Article rédigé à partir de la documentation officielle : http://www.scala-sbt.org/0.13/docs/

Téléchargement de sbt : http://www.scala-sbt.org/download.html

Parmi ses fonctionnalités on peut noter :

  • la compilation des sources Java et Scala d’un projet
  • des descriptions de builds écrites en Scala
  • la gestion des dépendances via Ivy
  • le support de projets où Java et Scala sont mixés

Structure de fichiers

SBT repose (presque) sur la même structure de dossiers que maven :

src/
  main/
    resources/
       <fichiers à inclure dans le jar>
    scala/
       <les sources Scala>
    java/
       <les sources Java>
  test/
    resources
       <fichiers à inclure dans le jar de tests>
    scala/
       <les sources Scala pour les tests>
    java/
       <les sources Java pour les tests>

On peut juste noter comme différence l’ajout des dossiers recevant les sources Scala pour les tests et le programme principal.

Le fichier build.sbt

Ce fichier est placé à la racine du projet et contient les informations du build (équivalent au pom.xml)

Le produit des builds

Comme pour Maven, le produit des build est placé dans un répertoire nommé target à la racine du projet.


La commande sbt

La commande sbt lance un shell interactif dans lequel on peut exécuter des builds définis dans le fichier build.sbt

On peut par exemple lancer compile pour compiler le projet :

$ sbt
> compile
> exit

Pour quitter le shell, on peut taper exit ou bien faire ctrl + c.

Utilisation en mode batch

L’utilisation par défaut de Maven se fait en mode batch (mvn clean install). On peut utiliser sbt de la même manière :

sbt clean compile

Cependant utiliser sbt ainsi consommera plus de ressources que si vous l’utilisiez en mode de compilation incrémentale.

Build et tests en continu

Pour accélérer le cycle « édition-compilation-test », on peut spécifier à sbt de recompiler ou lancer un test automatiquement lorsque l’on sauvegarde un fichier.

Pour lancer une commande lorsqu’un ou plusieurs fichiers sources ont été modifiés, il faut préfixer la commande par un ~ (tilde) :

> ~testQuick

Pour arrêter le build en continu, appuyez sur entrée.

Commande principales

Voici les principales commandes utilisées avec sbt :

clean Supprime les fichiers générés (dans target/).
compile Compile les sources du programme principal (src/main/java et src/main/scala).
test Compile et lance tous les tests
console Démarre l’interpréteur Scala en rajoutant au classpath les sources compilées et leurs dépendances. Pour retourner au shell, taper :quit.
run <argument>* Lance la classe main du projet dans la même JVM que sbt.
package Créé un jar contenant les fichiers dans src/main/resources et les classes compilées de src/main/scala et src/main/java.
help <command> Affiche une aide pour la commande spécifiée.
reload Recharge la définition du build (build.sbt, project/*.scala, project/*.sbt).

Définition du build

La définition du build se fait dans le fichier build.sbt et dans les fichiers contenus sous project/*.scala et project/*.sbt.

Spécification de la version de sbt

Pour que le projet soit compilé par la même version de sbt sur différents postes de travail, il faut spécifier la version de sbt utilisée via la ligne suivant dans le fichier build.sbt :

sbt.version=0.13.15

Si la version spécifiée n’est pas disponible sur le poste de l’utilisateur, celle-ci sera téléchargée.

Comment définir un build

Un build est constitué de plusieurs projets et sous-projets. Le fichier de build est écrit en Scala. Un sous-projet contenu dans l répertoire principal du projet est défini comme suit :

lazy val root = (project in file("."))
  .settings(
    name := "Hello",
    scalaVersion := "2.12.1"
  )

Les sous-projets sont définis par des paires clé-valeur définies par la méthode settings().

Les clés de settings()

Types de clés

La méthode settings() à 3 types de clés différents pour les paires clé-valeurs :

  • SettingKey[T] : pour les valeurs définies une fois
  • TaskKey[T] : une clé pour une valeur (une tache) qui doit être recalculée à chaque utilisation
  • InputKey[T] : une clé pour une tache qui prend un argument en ligne de commande

Les clés de base

Plusieurs clés sont fournies de base et importées directement dans sbt (name, description, organization etc…). Vous pouvez en retrouver le détail ici : http://www.scala-sbt.org/0.13/sxr/sbt/Keys.scala.html

Les clés-maison

On peut définir des clés personnalisées dans le but de réutiliser certaines taches tout au long du build. Par exemple, pour créer une tache nommée hello, on écrira :

lazy val hello = taskKey[Unit]("An example task")
lazy val est utilisé plutôt que val pour éviter les problèmes d’initialisation

Clés de Tasks et clés de Settings

Les TaskKey[T] sont des taches comme compile ou package. Elles peuvent  renvoyer une Unit (void) ou une valeur associée à la tache. Par exemple, package renvoit un File représentant le jar créé.

Définition de tasks et de settings

Avec l’opérateur :=, on peut assigner à une clé la valeur de retour d’une task ou d’un setting. Dans le cas d’une tache, celle-ci sera recalculée à chaque appel de la tache. Pour les settings, celle-ci sera calculé seulement la première fois.

Pour implémenter une tache qui imprime Hello à l’écran, on écrira :

lazy val hello = taskKey[Unit]("An example task")

lazy val root = (project in file("."))
  .settings(
    hello := { println("Hello!") }
  )

Exécution depuis le shell sbt

Une fois la tache définie dans le fichier build.sbt, on peut exécuter cette tâche au même titre que compile ou package :

> reload
[info] Loading project definition from C:\dev\IdeaProjects\webapp-scala\project
[info] Set current project to webapp-scala (in build file:/C:/dev/IdeaProjects/webapp-scala/)
> hello
Hello!
[success] Total time: 0 s, completed 17 juil. 2017 15:44:32
>

Imports dans le build.sbt

Il est possible d’effectuer des imports tout en haut du fichier de build. Certains imports sont implicites :

import sbt._
import Process._
import Keys._

Ajout de dépendances

Pour ajouter des dépendances à un projet, on peut soit placer les jars dans le dossier lib/ à la racine du projet, soit laisser sbt gérer les dépendances :

val derby = "org.apache.derby" % "derby" % "10.4.1.3"

lazy val commonSettings = Seq(
  organization := "fr.demandeatonton",
  version := "0.1.0-SNAPSHOT",
  scalaVersion := "2.12.1"
)

lazy val root = (project in file("."))
  .settings(
    commonSettings,
    name := "Hello",
    libraryDependencies += derby
  )

On définit une dépendance à Derby en ligne 1 et on réutilise cette dépendance à la ligne 13 avec la clé libraryDependencies

Le % permet de définir un module au format Ivy

Conclusion

Voilà pour les principales informations concernant sbt. Je reviendrai à cet outil plus en détail dans  un prochain article.

Pour plus d’informations, consultez la documentation officielle : http://www.scala-sbt.org/0.13/docs/

2 thoughts on “SBT : le maven de Scala

Laisser un commentaire