SlideShare a Scribd company logo
(Simple ?) Build Tool
                                        David Galichet (@Xebia)
                                               Jonathan Winandy




mercredi 23 novembre 2011
Schedule

              • SBT basics
                 • installation and project setup,
                 • SBT usages,
                 • dependency management
                 • defining and using scopes, settings and tasks,
                 • cross building
               • SBT demo
                 • using SBT
                 • using plugins
                 • writing plugin
mercredi 23 novembre 2011
A build system for Scala & Java
            Applications

              •     compile Scala and Java code source
              •     create Artifacts
              •     manage dependencies  (ivy)
              •     run tests
              •     extensible architecture (with plugins)
              •     integrated with Eclipse & Intellij
              •     plugin with Hudson/Jenkins
              •     ...


mercredi 23 novembre 2011
More than a build system



              •     run your applications,
              •     launch scala REPL,
              •     triggered execution,
              •     ...




mercredi 23 novembre 2011
SBT History



              • Created by Mark Harrah
              • First popular branch until 0.7.7
              • A new popular (and incompatible) branch from 0.9 →
                    actually 0.11.1 (aka. XSBT)




mercredi 23 novembre 2011
SBT Setup



              • Download the launch-sbt.jar (rename it xsbt-
                    launch.jar   if version   >= 0.9.x)


              • Create a launch script (xsbt) available in your PATH :
                    java -Dfile.encoding=UTF8 -Xmx1536M -Xss1M -XX:
                    +CMSClassUnloadingEnabled -XX:MaxPermSize=256m -jar
                    `dirname $0`/xsbt-launch.jar "$@"




mercredi 23 novembre 2011
SBT project anatomy
            /
            build.sbt
            src/
              main/
                 scala/
                 java/
                 resources/
              test/
                 scala/
                 java/
                 resources/
            project/
              Build.scala
              plugins.sbt
              project/
                 target/
                 ...
              target/
                              Add to your .gitignore !
                 ...
            target/
              ...

mercredi 23 novembre 2011
Using SBT


                  % xsbt
                  [info] Loading project definition from ...test/project
                  [info] Updating {file:/...test/project/}default-a285df...
                  [info] Done updating.
                  [info] Set current project to Test (in build
                  file:...test/)
                  >




mercredi 23 novembre 2011
Creating a simple project


            • create project directory,
            • create the src/ directory hierarchy (optional),
            • create a build.sbt in project root.

            • Or use the interactive mode !
                  > set name := "test"
                  > session save
                  This will automatically create the build.sbt.


mercredi 23 novembre 2011
First build definition

            name := "test"

            version := "0.1-SNAPSHOT"

            scalaVersion := "2.9.1"

            libraryDependencies += "org.specs2" %% "specs2" % "1.6.1" %
            "test"




mercredi 23 novembre 2011
SBT basics



              • name, version ... are Keys defining settings,
              • settings are typed (String, Seq[String], Int, ModuleId ...)
              • := is an assignation operator (override previous value)
              • += is a modification operator (add a value to a sequence)




mercredi 23 novembre 2011
ModuleID



                            "org.specs2" %% "specs2" % "1.6.1" % "test"
                            ============    ========   =======   ======
                              groupId       artifact   version configuration


                  String       is implicitly converted to finally create a ModuleID.




mercredi 23 novembre 2011
Common commands

              •     reload
              •     clean
              •     compile
              •     test
              •     console
              •     console-project
              •     publish
              •     show
              •     set
              •     inspect
              •     project
              •     ...


mercredi 23 novembre 2011
Triggered execution



              • use ~ to trigger task execution when code change (compile
                or test for example),
              • SBT uses incremental compilation → recompile only what is
                needed.




mercredi 23 novembre 2011
Manual dependency management




                  All jar files in lib directory will be added to the classpath so
                  they will be available when using compile, test, run,
                  console ...




mercredi 23 novembre 2011
Automatic dependency
            management
                  Dependencies are added to settings :
                            libraryDependencies += groupID % artifactID % revision
                            % configuration
                  where configuration (compile, test, run ...) is optional.

                  We can also encounter :
                      libraryDependencies += groupID %% artifactID %
                  revision


                  %% implies that SBT will use the right version according to
                  project scalaVersion (for example specs2_2.9.1)


mercredi 23 novembre 2011
Dependency management -
            Resolvers
                  add a dependency resolver :
                  resolvers += "Repository name" at "http://the-repository/
                  releases"


                  add local maven repository to resolvers :
                  resolvers += "Local Mvn Repository" at
                  "file://"+Path.userHome.absolutePath+"/.m2/repository"


                  dependency explicit resolver :
                  libraryDependencies += "slinky" % "slinky" % "2.1" from
                  "http://slinky2.googlecode.com/svn/artifacts/2.1/
                  slinky.jar"

                  /! →use with caution, the explicit resolver doesn't appear in
                  the pom.xml when the artifact is published.
mercredi 23 novembre 2011
Dependency management - extra
            configuration
                  extra configuration : 
                     • intransitive() → disable transitivity for this
                        dependency,
                     • classifier(..) → add a classifier (ex : "jdk5"), 
                     • exclude(groupId,artifactName) → exclude specified
                        artefact (since 0.11.1),
                     • excludeAll(..) → exclude based on exclusion rules
                        (since 0.11.1),
                     • ...
                  It's also possible to add Ivy configuration directly :
                            ivyXML := "<ivysettings>...</ivysettings>

mercredi 23 novembre 2011
Publish artifacts

                  To publish artifact locally (in ~/.ivy local repository) :
                            > publish-local


                  To define a nexus repository (and publish with publish) :
                            publishTo := Some("Scala Tools Nexus" at "http://
                            mydomain.org/content/repositories/releases/")


                  or an arbitrary location :
                            publishTo := Some(Resolver.file("file",   new File
                            ( "path/to/my/maven-repo/releases" )) )


                  To define nexus credentials :
                            credentials += Credentials(Path.userHome / ".ivy2" /
                            ".credentials")

mercredi 23 novembre 2011
Cross building

                  To define all scala versions that we want to build for :
                            crossScalaVersions := Seq("2.8.0", "2.8.1", "2.9.1")


                  Then prefix the action we want to run with + :
                            > + package
                            > + publish


                  If some dependencies versions depends on scala version :
                  libraryDependencies <+= (scalaVersion) { sv =>
                      val vMap = Map("2.8.1" -> "0.5.2", "2.9.1" -> "0.6.3")
                      val v = vMap.getOrElse(sv, error("Unsupported ..."))
                      "org.scala" %% "mylib" % v
                    }
                  We can also use ++       <version>   to temporarily switch version.
mercredi 23 novembre 2011
Full configuration

                  Defined in project/Build.scala :

                  import sbt._
                  import Keys._

                  object Test extends Build {
                    lazy val root = Project("root", file("."))
                      .settings(
                        name := "Test",
                        version := "0.1-SNAPSHOT",
                        ...
                      )
                  }



mercredi 23 novembre 2011
Multi-projects build
            • We can define a multi-projects in a full build description :
                  object Test extends Build {
                      lazy val root = Project(id = "root",
                          base = file(".")) aggregate(foo, bar)

                            lazy val foo = Project(id = "test-foo",
                                base = file("foo")) dependsOn(bar)

                            lazy val bar = Project(id = "test-bar",
                                base = file("bar"))
                  }

            • Settings in all .sbt project description (i.e. foo/build.sbt)
                  will form the project definition and be scoped to the project,
            •     project/*.scala files in sub-project will be ignored,
            •     projects list projects and project <name> change project.
mercredi 23 novembre 2011
Scopes



                  We can define settings and use tasks on multiple axis :
                   • on full build,
                   • by project,
                   • by configuration,
                   • by task.



mercredi 23 novembre 2011
Define scope

                  Setting defined globally :
                            name := "test"


                  Setting restricted on specified configuration :
                            name in (Compile) := "test compile"


                  Inspect :
                            > show name
                            [info] test

                            > show compile:name
                            [info] test compile



mercredi 23 novembre 2011
Inspect scope


                  > inspect name
                  [info] Setting: java.lang.String = Test1
                  [info] Description:
                  [info] Project name.
                  [info] Provided by:
                  [info] {file:/...test/}default-914d18/*:name
                  ...

                  {<build-uri>}<project-id>/config:key(for task-key)




mercredi 23 novembre 2011
Projects scope

            • On a multi-project definition, some Settings are defined in
                  each project definition and assigned to project Scope. For
                  example :

                            > show   version
                            [info]   test-foo/*:version
                            [info]     0.7
                            [info]   test-bar/*:version
                            [info]     0.9
                            [info]   root/*:version
                            [info]     0.5




mercredi 23 novembre 2011
Build scope

                  To add a setting on build scope in build.sbt :
                            myKey in ThisBuild := value


                  and in Build.scala (out of project settings definition) :
                            override val settings += ( myKey := value )


                  then inspect : 
                            {file:/home/hp/checkout/hello/}/*:myKey




mercredi 23 novembre 2011
Custom configuration
                  lazy val RunDebug = config("debug") extend(Runtime)

                  lazy val root = Project("root", file("."))
                    .configs( RunDebug )
                    .settings( inConfig(RunDebug)(Defaults.configTasks):_* )
                    .settings(
                      ...
                      javaOptions in RunDebug ++= Seq("-Xdebug", "-
                  Xrunjdwp:...")
                      ...
                    )


                  then use this configuration : debug:run


mercredi 23 novembre 2011
SBT settings
                • defined by typed keys (SettingKey[T] ...),
                • keys are defined in sbt.Keys (or in plugin, project, build
                      definition...),
                •     Keys have assignation methods that returns a Setting[T],
                •     each Setting[T] defines a transformation of SBT internal
                      build definition Map.

                  For example :
                            name := "test"
                  defines a transformation that returns the previous settings
                  Map with a new entry.

mercredi 23 novembre 2011
Kinds of Settings

                      The three kinds of Keys :
                        • SettingKey[T] → the Setting is evaluated once,
                        • TaskKey[T] → the Task is evaluated on each use;
                           Can create side effects,
                        • InputKey[T] → similar to Tasks but evaluation
                           depends on command line arguments.

                      When assignation method (:=, ~=, <<= ...) are used on a :
                       • SettingKey[T], it returns a Setting[T],
                       • TaskKey[T], it returns a Setting[Task[T]],
                       • InputKey[T], it returns a Setting[InputTask[T]].
mercredi 23 novembre 2011
Modify settings


              • := is used to replace the setting value :
                    name := "test"
              • += is used to add a value to a setting of type Seq[T] :
                    libraryDependencies += "org.specs2" %% "specs2" % "1.6.1"
                    % "test"
              • ++= is used to add some values to a setting of type Seq[T] :
                    libraryDependencies ++= Seq("se.scalablesolutions.akka" %
                    "akka-actor" % "1.2", "se.scalablesolutions.akka" %
                    "akka-remote" % "1.2")




mercredi 23 novembre 2011
Modify settings - transform a
            value

                  Sometimes we want to modify the value of an existing.

                  There's an operator for that :
                            name ~= { name => name.toUpperCase }


                  or more succinctly :
                            name ~= { _.toUpperCase }




mercredi 23 novembre 2011
Modify settings - use dependency

                  We want to compute a value based on other value(s) :
                            organization <<= name(_.toUpperCase)


                  that is equivalent to :
                            organization <<= name.apply { n => n.toUpperCase }


                  where SettingKey[T]         <<=   method is defined as :
                            <<=(app:Initialize[T]):Setting[T]


                  Setting[T] defines         the apply method :
                            apply[U](f: T => U):Initialize[U]


                  apply       transforms a Setting[T] to a Initialize[U].
mercredi 23 novembre 2011
Modify settings - use
            dependencies
                  In case we want to rely on many dependencies :
                            name <<= (name, version)( _ + "-" + _ )


                  that is equivalent to :
                            name <<= (name, version).apply { (n, v) =>
                              n + "-" + v
                            }


                  Tuples (Initialize[T1],..., Initialize[T9]) are
                  implicitly converted to obtain the apply method.


mercredi 23 novembre 2011
Modify settings - use
            dependencies


                  Add a value with dependencies to a Seq[File] :
                            cleanFiles <+= (name) { n => file(.) / (n + ".log") }


                  Add some values with dependencies to a Seq[File] :
                            unmanagedJars in Compile <++= baseDirectory map {
                              base => ((base / "myLibs") ** "*.jar").classpath
                            }




mercredi 23 novembre 2011
Modify settings - tasks with
            dependencies
                  Setting[S] apply    method returns a Initialize[T] but
                  for a TaskKey[T], <<= method expects a Initialize[Task
                  [T]]

                  The Setting[S] method map comes to the rescue :
                            map[T](f: S => T):Initialize[Task[T]]


                  We can set a SettingKey to a TaskKey :
                            taskKey <<= settingKey map identity


                  For multiple dependencies :
                            watchSources <+= (baseDirectory, name) map{(dir, n) =>
                                dir / "conf" / (n + ".properties")
                            }
mercredi 23 novembre 2011
Settings and tasks definition

                  A setting key definition sample:
                      val scalaVersion = SettingKey[String]("scala-version",
                  "The version of Scala used for building.")
                  A task key definition sample:
                      val clean = TaskKey[Unit]("clean", "Deletes files
                  produced by the build, such as generated sources, compiled
                  classes, and task caches.")


                  Here the clean task returns Unit when executed but can
                  have side effects (produced artefacts are deleted).

                  Most SBT tasks are defined in Default.scala.

mercredi 23 novembre 2011
Define your own tasks

                  Define a task that print and returns the current time :
                      val time = TaskKey[Date]("time", "returns current
                  time")

                            lazy val root = Project("test", file(".")).settings(
                                time := {
                                    val now = new Date()
                                    println("%s".format(now))
                                    now
                                })
                  Usage :
                            > time
                            Wed Nov 16 13:55:38 CET 2011
                  Tasks unlike Settings are evaluated each time they are called.
mercredi 23 novembre 2011
Input tasks

            • Similar to a Task but can take user input as parameter,
            • SBT provides a powerful input parsing system (based on scala
                  parser combinators) and easy tab completion feature,
            •     Key defined in a way similar to SettingKey or TaskKey :
                            val release = InputKey[Unit]("release", "release
                            version")

            • Defining it in settings :
                            release <<= InputTask(releaseParser)(releaseDef)

            • Similar to a Command (a kind of tasks that is not defined in
                  Settings and with no return value).

mercredi 23 novembre 2011
Input tasks - input parser

            • Input parser sample :
                    val releaseParser:Initialize[State => Parser[String]] =
                  (version) { (v:String) => {
                      val ReleaseExtractor(vMaj, vMin, vFix) = v
                      val major = token("major" ^^^ "%s.%s.%s".format
                  (vMaj.toInt + 1, vMin.toInt, vFix.toInt))
                      val minor = token("minor" ^^^ "%s.%s.%s".format
                  (vMaj.toInt, vMin.toInt + 1, vFix.toInt))
                      val fix = token("fix" ^^^ "%s.%s.%s".format
                  (vMaj.toInt, vMin.toInt, vFix.toInt + 1))
                      (state:State) => Space ~> (major | minor | fix)
                    }
                  }


mercredi 23 novembre 2011
Input tasks - task implementation

            • Task input implementation :
                    val releaseDef = (nextVersion:TaskKey[String]) => {
                      (version, nextVersion) map { case (currentV, nextV) =>
                        println("next version : " + nextV)
                        val result = ("git tag " + currentV).lines_!.collect
                          { case s:String if s.contains("fatal") => s }
                        if (result.mkString.isEmpty)
                          println(result.mkString)
                        else {
                          println("Release tagged ! Next one is " +
                  nextV.mkString)
                          // ...
                        }
                      }

mercredi 23 novembre 2011
Settings prevalence rules


                                                                          Lowest

            •     Build and Project settings in .scala files,
            •     User global settings in ~/.sbt/*.sbt,
            •     Settings injected by plugins,
            •     Settings from .sbt files in the project,
            •     Settings from build definition project (i.e. project/
                  plugins.sbt)
                                                                          Highest
                                                                         prevalence


mercredi 23 novembre 2011
Inspect Settings - general
            informations


                  > inspect compile
                  [info] Task: sbt.inc.Analysis
                  [info] Description:
                  [info] Compiles sources.
                  [info] Provided by:
                  [info] {file:/Users/.../test/}test/compile:compile
                  ...




mercredi 23 novembre 2011
Inspect Settings - dependencies


                  ...
                  [info] Dependencies:
                  [info] compile:compile-inputs
                  [info] compile:streams(for compile)
                  [info] Reverse dependencies:
                  [info] compile:products
                  [info] compile:defined-sbt-plugins
                  [info] compile:exported-products
                  [info] compile:discovered-main-classes
                  ...




mercredi 23 novembre 2011
Inspect Settings - delegates

                  ...
                  [info] Delegates:
                  [info] compile:compile
                  [info] *:compile
                  [info] {.}/compile:compile
                  [info] {.}/*:compile
                  [info] */compile:compile
                  [info] */*:compile
                  [info] Related:
                  [info] test:compile
                  [info] debug:compile




mercredi 23 novembre 2011
Extending SBT

            • SBT can be extended using plugins,
            • Plugins are new Settings/Tasks added to SBT,
            • To add a plugin in the project or globally, add :
                  resolvers += Classpaths.typesafeResolver
                  addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse" %
                  "1.4.0")
                  in your project/plugins.sbt or in ~/.sbt/plugins/
                  build.sbt




mercredi 23 novembre 2011
What is a plugin ?
            • A plugin is an SBT project added as a dependency to the build
              definition !
            • Recursive nature of SBT :
                  /
                  build.sbt
                  project/          Project definition
                    Build.scala
                    plugins.sbt
                    project/          Build definition
                      Build.scala
                    ...


            • We can load build definition project with reload    plugins
                  and go back to project with reload   return.

mercredi 23 novembre 2011
Enhance build definition project


            • To use a specific library in your project/Build.scala, you
                  can add the following in project/plugins.sbt (or
                  project/project/Build.scala) :
                            libraryDependencies += "net.databinder" %% "dispatch-
                            http" % "0.8.5"


            • To test some build code snippets in a scala REPL :
                            > console-project
                      this will load all build dependencies.


mercredi 23 novembre 2011
Some powerful APIs


            • IO operations with Path API,
            • Invoking external process with process API,
            • Input parsers and tab-completion for Tasks and Commands,
            • Launcher to launch application without a local Scala
              installation,
            • All the power of Scala API ...


mercredi 23 novembre 2011
Finally...

                      Is Simple Build Tool Simple ?
            •     Limited key concepts to understand,
            •     A powerful API,
            •     Easy access to scala ecosystem power,
            •     Increasing number of plugins ...




mercredi 23 novembre 2011

More Related Content

What's hot

Scala and Play with Gradle
Scala and Play with GradleScala and Play with Gradle
Scala and Play with Gradle
Wei Chen
 
Gradle Introduction
Gradle IntroductionGradle Introduction
Gradle Introduction
Dmitry Buzdin
 
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Gradle build tool that rocks with DSL JavaOne India 4th May 2012Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Rajmahendra Hegde
 
State of the Jenkins Automation
State of the Jenkins AutomationState of the Jenkins Automation
State of the Jenkins Automation
Julien Pivotto
 
Gradle talk, Javarsovia 2010
Gradle talk, Javarsovia 2010Gradle talk, Javarsovia 2010
Gradle talk, Javarsovia 2010
Tomek Kaczanowski
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin Writing
Schalk Cronjé
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin Writing
Schalk Cronjé
 
GradleFX
GradleFXGradleFX
Basic Gradle Plugin Writing
Basic Gradle Plugin WritingBasic Gradle Plugin Writing
Basic Gradle Plugin Writing
Schalk Cronjé
 
Jenkins Pipelines
Jenkins PipelinesJenkins Pipelines
Jenkins Pipelines
Steffen Gebert
 
In the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: GradleIn the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: Gradle
Skills Matter
 
3 Git
3 Git3 Git
Faster Java EE Builds with Gradle
Faster Java EE Builds with GradleFaster Java EE Builds with Gradle
Faster Java EE Builds with Gradle
Ryan Cuprak
 
Gradle in 45min
Gradle in 45minGradle in 45min
Gradle in 45min
Schalk Cronjé
 
Continuous Integration and DevOps with Open Build Service(OBS)
Continuous Integration and DevOps with Open Build Service(OBS)Continuous Integration and DevOps with Open Build Service(OBS)
Continuous Integration and DevOps with Open Build Service(OBS)
Ralf Dannert
 
Gradle - Build system evolved
Gradle - Build system evolvedGradle - Build system evolved
Gradle - Build system evolved
Bhagwat Kumar
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin Writing
Schalk Cronjé
 
openQA hands on with openSUSE Leap 42.1 - openSUSE.Asia Summit ID 2016
openQA hands on with openSUSE Leap 42.1 - openSUSE.Asia Summit ID 2016openQA hands on with openSUSE Leap 42.1 - openSUSE.Asia Summit ID 2016
openQA hands on with openSUSE Leap 42.1 - openSUSE.Asia Summit ID 2016
Ben Chou
 
Gradle - time for another build
Gradle - time for another buildGradle - time for another build
Gradle - time for another build
Igor Khotin
 
Idiomatic gradle plugin writing
Idiomatic gradle plugin writingIdiomatic gradle plugin writing
Idiomatic gradle plugin writing
Schalk Cronjé
 

What's hot (20)

Scala and Play with Gradle
Scala and Play with GradleScala and Play with Gradle
Scala and Play with Gradle
 
Gradle Introduction
Gradle IntroductionGradle Introduction
Gradle Introduction
 
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Gradle build tool that rocks with DSL JavaOne India 4th May 2012Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
 
State of the Jenkins Automation
State of the Jenkins AutomationState of the Jenkins Automation
State of the Jenkins Automation
 
Gradle talk, Javarsovia 2010
Gradle talk, Javarsovia 2010Gradle talk, Javarsovia 2010
Gradle talk, Javarsovia 2010
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin Writing
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin Writing
 
GradleFX
GradleFXGradleFX
GradleFX
 
Basic Gradle Plugin Writing
Basic Gradle Plugin WritingBasic Gradle Plugin Writing
Basic Gradle Plugin Writing
 
Jenkins Pipelines
Jenkins PipelinesJenkins Pipelines
Jenkins Pipelines
 
In the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: GradleIn the Brain of Hans Dockter: Gradle
In the Brain of Hans Dockter: Gradle
 
3 Git
3 Git3 Git
3 Git
 
Faster Java EE Builds with Gradle
Faster Java EE Builds with GradleFaster Java EE Builds with Gradle
Faster Java EE Builds with Gradle
 
Gradle in 45min
Gradle in 45minGradle in 45min
Gradle in 45min
 
Continuous Integration and DevOps with Open Build Service(OBS)
Continuous Integration and DevOps with Open Build Service(OBS)Continuous Integration and DevOps with Open Build Service(OBS)
Continuous Integration and DevOps with Open Build Service(OBS)
 
Gradle - Build system evolved
Gradle - Build system evolvedGradle - Build system evolved
Gradle - Build system evolved
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin Writing
 
openQA hands on with openSUSE Leap 42.1 - openSUSE.Asia Summit ID 2016
openQA hands on with openSUSE Leap 42.1 - openSUSE.Asia Summit ID 2016openQA hands on with openSUSE Leap 42.1 - openSUSE.Asia Summit ID 2016
openQA hands on with openSUSE Leap 42.1 - openSUSE.Asia Summit ID 2016
 
Gradle - time for another build
Gradle - time for another buildGradle - time for another build
Gradle - time for another build
 
Idiomatic gradle plugin writing
Idiomatic gradle plugin writingIdiomatic gradle plugin writing
Idiomatic gradle plugin writing
 

Viewers also liked

A day with sbt
A day with sbtA day with sbt
A day with sbt
Marcus Lönnberg
 
Sbt tutorial
Sbt tutorialSbt tutorial
Sbt tutorial
Gary Gai
 
SBT Made Simple
SBT Made SimpleSBT Made Simple
SBT Made Simple
Fuqiang Wang
 
Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...
Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...
Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...
Anton Kirillov
 
Banco de la republica
Banco de la republicaBanco de la republica
Banco de la republica
cecoa
 
Eidn 3-sinamob
Eidn 3-sinamobEidn 3-sinamob
Eidn 3-sinamob
liviacalmeida
 
Los virus informáticos
Los virus informáticosLos virus informáticos
Los virus informáticos
Alfredo Aguayo
 
Treamentsheet 1
Treamentsheet 1Treamentsheet 1
Treamentsheet 1
Serena Chu
 
Tugas batubara ii lingkungan dan bentuk endapan batubara, kalsifikasi dan jen...
Tugas batubara ii lingkungan dan bentuk endapan batubara, kalsifikasi dan jen...Tugas batubara ii lingkungan dan bentuk endapan batubara, kalsifikasi dan jen...
Tugas batubara ii lingkungan dan bentuk endapan batubara, kalsifikasi dan jen...
Sylvester Saragih
 
Projects
ProjectsProjects
Projects
Ashdeep Singh
 
Khmer culture, civilization (part1)
Khmer culture, civilization (part1)Khmer culture, civilization (part1)
Khmer culture, civilization (part1)
Mut Somoeun
 
Preliminary Task by Reece Taylor
Preliminary Task by Reece TaylorPreliminary Task by Reece Taylor
Preliminary Task by Reece Taylor
Reecetaylormedia
 
Kamus istilah tambang
Kamus istilah tambangKamus istilah tambang
Kamus istilah tambang
Sylvester Saragih
 
Eidn 6-simobe
Eidn 6-simobeEidn 6-simobe
Eidn 6-simobe
liviacalmeida
 
Eidn 8-diferenca eidn e eed
Eidn 8-diferenca eidn e eedEidn 8-diferenca eidn e eed
Eidn 8-diferenca eidn e eed
liviacalmeida
 
Metallurgi 2
Metallurgi 2Metallurgi 2
Metallurgi 2
Sylvester Saragih
 
Vnetlengkap2010 100316230706-phpapp01
Vnetlengkap2010 100316230706-phpapp01Vnetlengkap2010 100316230706-phpapp01
Vnetlengkap2010 100316230706-phpapp01
Eka Rachman
 

Viewers also liked (17)

A day with sbt
A day with sbtA day with sbt
A day with sbt
 
Sbt tutorial
Sbt tutorialSbt tutorial
Sbt tutorial
 
SBT Made Simple
SBT Made SimpleSBT Made Simple
SBT Made Simple
 
Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...
Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...
Data processing platforms architectures with Spark, Mesos, Akka, Cassandra an...
 
Banco de la republica
Banco de la republicaBanco de la republica
Banco de la republica
 
Eidn 3-sinamob
Eidn 3-sinamobEidn 3-sinamob
Eidn 3-sinamob
 
Los virus informáticos
Los virus informáticosLos virus informáticos
Los virus informáticos
 
Treamentsheet 1
Treamentsheet 1Treamentsheet 1
Treamentsheet 1
 
Tugas batubara ii lingkungan dan bentuk endapan batubara, kalsifikasi dan jen...
Tugas batubara ii lingkungan dan bentuk endapan batubara, kalsifikasi dan jen...Tugas batubara ii lingkungan dan bentuk endapan batubara, kalsifikasi dan jen...
Tugas batubara ii lingkungan dan bentuk endapan batubara, kalsifikasi dan jen...
 
Projects
ProjectsProjects
Projects
 
Khmer culture, civilization (part1)
Khmer culture, civilization (part1)Khmer culture, civilization (part1)
Khmer culture, civilization (part1)
 
Preliminary Task by Reece Taylor
Preliminary Task by Reece TaylorPreliminary Task by Reece Taylor
Preliminary Task by Reece Taylor
 
Kamus istilah tambang
Kamus istilah tambangKamus istilah tambang
Kamus istilah tambang
 
Eidn 6-simobe
Eidn 6-simobeEidn 6-simobe
Eidn 6-simobe
 
Eidn 8-diferenca eidn e eed
Eidn 8-diferenca eidn e eedEidn 8-diferenca eidn e eed
Eidn 8-diferenca eidn e eed
 
Metallurgi 2
Metallurgi 2Metallurgi 2
Metallurgi 2
 
Vnetlengkap2010 100316230706-phpapp01
Vnetlengkap2010 100316230706-phpapp01Vnetlengkap2010 100316230706-phpapp01
Vnetlengkap2010 100316230706-phpapp01
 

Similar to Simple Build Tool

How to start using Scala
How to start using ScalaHow to start using Scala
How to start using Scala
Ngoc Dao
 
Gradle
GradleGradle
How to integrate_custom_openstack_services_with_devstack
How to integrate_custom_openstack_services_with_devstackHow to integrate_custom_openstack_services_with_devstack
How to integrate_custom_openstack_services_with_devstack
Sławomir Kapłoński
 
Implementing Quality on Java projects
Implementing Quality on Java projectsImplementing Quality on Java projects
Implementing Quality on Java projects
Vincent Massol
 
Jenkins shared librar
Jenkins shared librarJenkins shared librar
Jenkins shared librar
Aleksei Bulgak
 
Kolla talk at OpenStack Summit 2017 in Sydney
Kolla talk at OpenStack Summit 2017 in SydneyKolla talk at OpenStack Summit 2017 in Sydney
Kolla talk at OpenStack Summit 2017 in Sydney
Vikram G Hosakote
 
Apache Maven - eXo TN presentation
Apache Maven - eXo TN presentationApache Maven - eXo TN presentation
Apache Maven - eXo TN presentation
Arnaud Héritier
 
Play framework
Play frameworkPlay framework
Play framework
Andrew Skiba
 
Riga Dev Day - Automated Android Continuous Integration
Riga Dev Day - Automated Android Continuous IntegrationRiga Dev Day - Automated Android Continuous Integration
Riga Dev Day - Automated Android Continuous Integration
Nicolas Fränkel
 
Sbt職人のススメ
Sbt職人のススメSbt職人のススメ
Sbt職人のススメ
潤一 加藤
 
Liferay maven sdk
Liferay maven sdkLiferay maven sdk
Liferay maven sdk
Mika Koivisto
 
Developing Liferay Plugins with Maven
Developing Liferay Plugins with MavenDeveloping Liferay Plugins with Maven
Developing Liferay Plugins with Maven
Mika Koivisto
 
Buildr In Action @devoxx france 2012
Buildr In Action @devoxx france 2012Buildr In Action @devoxx france 2012
Buildr In Action @devoxx france 2012
alexismidon
 
In-Cluster Continuous Testing Framework for Docker Containers
In-Cluster Continuous Testing Framework for Docker ContainersIn-Cluster Continuous Testing Framework for Docker Containers
In-Cluster Continuous Testing Framework for Docker Containers
Neil Gehani
 
How maven makes your development group look like a bunch of professionals.
How maven makes your development group look like a bunch of professionals.How maven makes your development group look like a bunch of professionals.
How maven makes your development group look like a bunch of professionals.
Fazreil Amreen Abdul Jalil
 
IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...
IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...
IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...
Eric Smalling
 
Learn you some Ansible for great good!
Learn you some Ansible for great good!Learn you some Ansible for great good!
Learn you some Ansible for great good!
David Lapsley
 
Continuous Deployment Pipeline with maven
Continuous Deployment Pipeline with mavenContinuous Deployment Pipeline with maven
Continuous Deployment Pipeline with maven
Alan Parkinson
 
Oscon London 2016 - Docker from Development to Production
Oscon London 2016 - Docker from Development to ProductionOscon London 2016 - Docker from Development to Production
Oscon London 2016 - Docker from Development to Production
Patrick Chanezon
 
Sbt, idea and eclipse
Sbt, idea and eclipseSbt, idea and eclipse
Sbt, idea and eclipse
Mike Slinn
 

Similar to Simple Build Tool (20)

How to start using Scala
How to start using ScalaHow to start using Scala
How to start using Scala
 
Gradle
GradleGradle
Gradle
 
How to integrate_custom_openstack_services_with_devstack
How to integrate_custom_openstack_services_with_devstackHow to integrate_custom_openstack_services_with_devstack
How to integrate_custom_openstack_services_with_devstack
 
Implementing Quality on Java projects
Implementing Quality on Java projectsImplementing Quality on Java projects
Implementing Quality on Java projects
 
Jenkins shared librar
Jenkins shared librarJenkins shared librar
Jenkins shared librar
 
Kolla talk at OpenStack Summit 2017 in Sydney
Kolla talk at OpenStack Summit 2017 in SydneyKolla talk at OpenStack Summit 2017 in Sydney
Kolla talk at OpenStack Summit 2017 in Sydney
 
Apache Maven - eXo TN presentation
Apache Maven - eXo TN presentationApache Maven - eXo TN presentation
Apache Maven - eXo TN presentation
 
Play framework
Play frameworkPlay framework
Play framework
 
Riga Dev Day - Automated Android Continuous Integration
Riga Dev Day - Automated Android Continuous IntegrationRiga Dev Day - Automated Android Continuous Integration
Riga Dev Day - Automated Android Continuous Integration
 
Sbt職人のススメ
Sbt職人のススメSbt職人のススメ
Sbt職人のススメ
 
Liferay maven sdk
Liferay maven sdkLiferay maven sdk
Liferay maven sdk
 
Developing Liferay Plugins with Maven
Developing Liferay Plugins with MavenDeveloping Liferay Plugins with Maven
Developing Liferay Plugins with Maven
 
Buildr In Action @devoxx france 2012
Buildr In Action @devoxx france 2012Buildr In Action @devoxx france 2012
Buildr In Action @devoxx france 2012
 
In-Cluster Continuous Testing Framework for Docker Containers
In-Cluster Continuous Testing Framework for Docker ContainersIn-Cluster Continuous Testing Framework for Docker Containers
In-Cluster Continuous Testing Framework for Docker Containers
 
How maven makes your development group look like a bunch of professionals.
How maven makes your development group look like a bunch of professionals.How maven makes your development group look like a bunch of professionals.
How maven makes your development group look like a bunch of professionals.
 
IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...
IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...
IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...
 
Learn you some Ansible for great good!
Learn you some Ansible for great good!Learn you some Ansible for great good!
Learn you some Ansible for great good!
 
Continuous Deployment Pipeline with maven
Continuous Deployment Pipeline with mavenContinuous Deployment Pipeline with maven
Continuous Deployment Pipeline with maven
 
Oscon London 2016 - Docker from Development to Production
Oscon London 2016 - Docker from Development to ProductionOscon London 2016 - Docker from Development to Production
Oscon London 2016 - Docker from Development to Production
 
Sbt, idea and eclipse
Sbt, idea and eclipseSbt, idea and eclipse
Sbt, idea and eclipse
 

More from David Galichet

Property Based Testing with ScalaCheck
Property Based Testing with ScalaCheckProperty Based Testing with ScalaCheck
Property Based Testing with ScalaCheck
David Galichet
 
Writing DSL with Applicative Functors
Writing DSL with Applicative FunctorsWriting DSL with Applicative Functors
Writing DSL with Applicative Functors
David Galichet
 
Introducing Monads and State Monad at PSUG
Introducing Monads and State Monad at PSUGIntroducing Monads and State Monad at PSUG
Introducing Monads and State Monad at PSUG
David Galichet
 
Playing with State Monad
Playing with State MonadPlaying with State Monad
Playing with State Monad
David Galichet
 
Demystifying Scala Type System
Demystifying Scala Type SystemDemystifying Scala Type System
Demystifying Scala Type System
David Galichet
 
Crypto and PKI
Crypto and PKICrypto and PKI
Crypto and PKI
David Galichet
 

More from David Galichet (6)

Property Based Testing with ScalaCheck
Property Based Testing with ScalaCheckProperty Based Testing with ScalaCheck
Property Based Testing with ScalaCheck
 
Writing DSL with Applicative Functors
Writing DSL with Applicative FunctorsWriting DSL with Applicative Functors
Writing DSL with Applicative Functors
 
Introducing Monads and State Monad at PSUG
Introducing Monads and State Monad at PSUGIntroducing Monads and State Monad at PSUG
Introducing Monads and State Monad at PSUG
 
Playing with State Monad
Playing with State MonadPlaying with State Monad
Playing with State Monad
 
Demystifying Scala Type System
Demystifying Scala Type SystemDemystifying Scala Type System
Demystifying Scala Type System
 
Crypto and PKI
Crypto and PKICrypto and PKI
Crypto and PKI
 

Recently uploaded

Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
Brandon Minnick, MBA
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
Zilliz
 
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with SlackLet's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
shyamraj55
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems S.M.S.A.
 
Things to Consider When Choosing a Website Developer for your Website | FODUU
Things to Consider When Choosing a Website Developer for your Website | FODUUThings to Consider When Choosing a Website Developer for your Website | FODUU
Things to Consider When Choosing a Website Developer for your Website | FODUU
FODUU
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
Octavian Nadolu
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
Quotidiano Piemontese
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
Matthew Sinclair
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Malak Abu Hammad
 
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdfAI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
Techgropse Pvt.Ltd.
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
Jason Packer
 
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial IntelligenceAI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
IndexBug
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
DianaGray10
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Speck&Tech
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
danishmna97
 
Generating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and MilvusGenerating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and Milvus
Zilliz
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Tosin Akinosho
 
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
Edge AI and Vision Alliance
 

Recently uploaded (20)

Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
 
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with SlackLet's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
 
Things to Consider When Choosing a Website Developer for your Website | FODUU
Things to Consider When Choosing a Website Developer for your Website | FODUUThings to Consider When Choosing a Website Developer for your Website | FODUU
Things to Consider When Choosing a Website Developer for your Website | FODUU
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
 
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdfAI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
 
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial IntelligenceAI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
 
Generating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and MilvusGenerating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and Milvus
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
 
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
 

Simple Build Tool

  • 1. (Simple ?) Build Tool David Galichet (@Xebia) Jonathan Winandy mercredi 23 novembre 2011
  • 2. Schedule • SBT basics • installation and project setup, • SBT usages, • dependency management • defining and using scopes, settings and tasks, • cross building • SBT demo • using SBT • using plugins • writing plugin mercredi 23 novembre 2011
  • 3. A build system for Scala & Java Applications • compile Scala and Java code source • create Artifacts • manage dependencies  (ivy) • run tests • extensible architecture (with plugins) • integrated with Eclipse & Intellij • plugin with Hudson/Jenkins • ... mercredi 23 novembre 2011
  • 4. More than a build system • run your applications, • launch scala REPL, • triggered execution, • ... mercredi 23 novembre 2011
  • 5. SBT History • Created by Mark Harrah • First popular branch until 0.7.7 • A new popular (and incompatible) branch from 0.9 → actually 0.11.1 (aka. XSBT) mercredi 23 novembre 2011
  • 6. SBT Setup • Download the launch-sbt.jar (rename it xsbt- launch.jar if version >= 0.9.x) • Create a launch script (xsbt) available in your PATH : java -Dfile.encoding=UTF8 -Xmx1536M -Xss1M -XX: +CMSClassUnloadingEnabled -XX:MaxPermSize=256m -jar `dirname $0`/xsbt-launch.jar "$@" mercredi 23 novembre 2011
  • 7. SBT project anatomy / build.sbt src/ main/ scala/ java/ resources/ test/ scala/ java/ resources/ project/ Build.scala plugins.sbt project/ target/ ... target/ Add to your .gitignore ! ... target/ ... mercredi 23 novembre 2011
  • 8. Using SBT % xsbt [info] Loading project definition from ...test/project [info] Updating {file:/...test/project/}default-a285df... [info] Done updating. [info] Set current project to Test (in build file:...test/) > mercredi 23 novembre 2011
  • 9. Creating a simple project • create project directory, • create the src/ directory hierarchy (optional), • create a build.sbt in project root. • Or use the interactive mode ! > set name := "test" > session save This will automatically create the build.sbt. mercredi 23 novembre 2011
  • 10. First build definition name := "test" version := "0.1-SNAPSHOT" scalaVersion := "2.9.1" libraryDependencies += "org.specs2" %% "specs2" % "1.6.1" % "test" mercredi 23 novembre 2011
  • 11. SBT basics • name, version ... are Keys defining settings, • settings are typed (String, Seq[String], Int, ModuleId ...) • := is an assignation operator (override previous value) • += is a modification operator (add a value to a sequence) mercredi 23 novembre 2011
  • 12. ModuleID "org.specs2" %% "specs2" % "1.6.1" % "test" ============ ======== ======= ====== groupId artifact version configuration String is implicitly converted to finally create a ModuleID. mercredi 23 novembre 2011
  • 13. Common commands • reload • clean • compile • test • console • console-project • publish • show • set • inspect • project • ... mercredi 23 novembre 2011
  • 14. Triggered execution • use ~ to trigger task execution when code change (compile or test for example), • SBT uses incremental compilation → recompile only what is needed. mercredi 23 novembre 2011
  • 15. Manual dependency management All jar files in lib directory will be added to the classpath so they will be available when using compile, test, run, console ... mercredi 23 novembre 2011
  • 16. Automatic dependency management Dependencies are added to settings : libraryDependencies += groupID % artifactID % revision % configuration where configuration (compile, test, run ...) is optional. We can also encounter : libraryDependencies += groupID %% artifactID % revision %% implies that SBT will use the right version according to project scalaVersion (for example specs2_2.9.1) mercredi 23 novembre 2011
  • 17. Dependency management - Resolvers add a dependency resolver : resolvers += "Repository name" at "http://the-repository/ releases" add local maven repository to resolvers : resolvers += "Local Mvn Repository" at "file://"+Path.userHome.absolutePath+"/.m2/repository" dependency explicit resolver : libraryDependencies += "slinky" % "slinky" % "2.1" from "http://slinky2.googlecode.com/svn/artifacts/2.1/ slinky.jar" /! →use with caution, the explicit resolver doesn't appear in the pom.xml when the artifact is published. mercredi 23 novembre 2011
  • 18. Dependency management - extra configuration extra configuration :  • intransitive() → disable transitivity for this dependency, • classifier(..) → add a classifier (ex : "jdk5"),  • exclude(groupId,artifactName) → exclude specified artefact (since 0.11.1), • excludeAll(..) → exclude based on exclusion rules (since 0.11.1), • ... It's also possible to add Ivy configuration directly : ivyXML := "<ivysettings>...</ivysettings> mercredi 23 novembre 2011
  • 19. Publish artifacts To publish artifact locally (in ~/.ivy local repository) : > publish-local To define a nexus repository (and publish with publish) : publishTo := Some("Scala Tools Nexus" at "http:// mydomain.org/content/repositories/releases/") or an arbitrary location : publishTo := Some(Resolver.file("file", new File ( "path/to/my/maven-repo/releases" )) ) To define nexus credentials : credentials += Credentials(Path.userHome / ".ivy2" / ".credentials") mercredi 23 novembre 2011
  • 20. Cross building To define all scala versions that we want to build for : crossScalaVersions := Seq("2.8.0", "2.8.1", "2.9.1") Then prefix the action we want to run with + : > + package > + publish If some dependencies versions depends on scala version : libraryDependencies <+= (scalaVersion) { sv => val vMap = Map("2.8.1" -> "0.5.2", "2.9.1" -> "0.6.3") val v = vMap.getOrElse(sv, error("Unsupported ...")) "org.scala" %% "mylib" % v } We can also use ++ <version> to temporarily switch version. mercredi 23 novembre 2011
  • 21. Full configuration Defined in project/Build.scala : import sbt._ import Keys._ object Test extends Build { lazy val root = Project("root", file(".")) .settings( name := "Test", version := "0.1-SNAPSHOT", ... ) } mercredi 23 novembre 2011
  • 22. Multi-projects build • We can define a multi-projects in a full build description : object Test extends Build { lazy val root = Project(id = "root", base = file(".")) aggregate(foo, bar) lazy val foo = Project(id = "test-foo", base = file("foo")) dependsOn(bar) lazy val bar = Project(id = "test-bar", base = file("bar")) } • Settings in all .sbt project description (i.e. foo/build.sbt) will form the project definition and be scoped to the project, • project/*.scala files in sub-project will be ignored, • projects list projects and project <name> change project. mercredi 23 novembre 2011
  • 23. Scopes We can define settings and use tasks on multiple axis : • on full build, • by project, • by configuration, • by task. mercredi 23 novembre 2011
  • 24. Define scope Setting defined globally : name := "test" Setting restricted on specified configuration : name in (Compile) := "test compile" Inspect : > show name [info] test > show compile:name [info] test compile mercredi 23 novembre 2011
  • 25. Inspect scope > inspect name [info] Setting: java.lang.String = Test1 [info] Description: [info] Project name. [info] Provided by: [info] {file:/...test/}default-914d18/*:name ... {<build-uri>}<project-id>/config:key(for task-key) mercredi 23 novembre 2011
  • 26. Projects scope • On a multi-project definition, some Settings are defined in each project definition and assigned to project Scope. For example : > show version [info] test-foo/*:version [info] 0.7 [info] test-bar/*:version [info] 0.9 [info] root/*:version [info] 0.5 mercredi 23 novembre 2011
  • 27. Build scope To add a setting on build scope in build.sbt : myKey in ThisBuild := value and in Build.scala (out of project settings definition) : override val settings += ( myKey := value ) then inspect :  {file:/home/hp/checkout/hello/}/*:myKey mercredi 23 novembre 2011
  • 28. Custom configuration lazy val RunDebug = config("debug") extend(Runtime) lazy val root = Project("root", file(".")) .configs( RunDebug ) .settings( inConfig(RunDebug)(Defaults.configTasks):_* ) .settings( ... javaOptions in RunDebug ++= Seq("-Xdebug", "- Xrunjdwp:...") ... ) then use this configuration : debug:run mercredi 23 novembre 2011
  • 29. SBT settings • defined by typed keys (SettingKey[T] ...), • keys are defined in sbt.Keys (or in plugin, project, build definition...), • Keys have assignation methods that returns a Setting[T], • each Setting[T] defines a transformation of SBT internal build definition Map. For example : name := "test" defines a transformation that returns the previous settings Map with a new entry. mercredi 23 novembre 2011
  • 30. Kinds of Settings The three kinds of Keys : • SettingKey[T] → the Setting is evaluated once, • TaskKey[T] → the Task is evaluated on each use; Can create side effects, • InputKey[T] → similar to Tasks but evaluation depends on command line arguments. When assignation method (:=, ~=, <<= ...) are used on a : • SettingKey[T], it returns a Setting[T], • TaskKey[T], it returns a Setting[Task[T]], • InputKey[T], it returns a Setting[InputTask[T]]. mercredi 23 novembre 2011
  • 31. Modify settings • := is used to replace the setting value : name := "test" • += is used to add a value to a setting of type Seq[T] : libraryDependencies += "org.specs2" %% "specs2" % "1.6.1" % "test" • ++= is used to add some values to a setting of type Seq[T] : libraryDependencies ++= Seq("se.scalablesolutions.akka" % "akka-actor" % "1.2", "se.scalablesolutions.akka" % "akka-remote" % "1.2") mercredi 23 novembre 2011
  • 32. Modify settings - transform a value Sometimes we want to modify the value of an existing. There's an operator for that : name ~= { name => name.toUpperCase } or more succinctly : name ~= { _.toUpperCase } mercredi 23 novembre 2011
  • 33. Modify settings - use dependency We want to compute a value based on other value(s) : organization <<= name(_.toUpperCase) that is equivalent to : organization <<= name.apply { n => n.toUpperCase } where SettingKey[T] <<= method is defined as : <<=(app:Initialize[T]):Setting[T] Setting[T] defines the apply method : apply[U](f: T => U):Initialize[U] apply transforms a Setting[T] to a Initialize[U]. mercredi 23 novembre 2011
  • 34. Modify settings - use dependencies In case we want to rely on many dependencies : name <<= (name, version)( _ + "-" + _ ) that is equivalent to : name <<= (name, version).apply { (n, v) => n + "-" + v } Tuples (Initialize[T1],..., Initialize[T9]) are implicitly converted to obtain the apply method. mercredi 23 novembre 2011
  • 35. Modify settings - use dependencies Add a value with dependencies to a Seq[File] : cleanFiles <+= (name) { n => file(.) / (n + ".log") } Add some values with dependencies to a Seq[File] : unmanagedJars in Compile <++= baseDirectory map { base => ((base / "myLibs") ** "*.jar").classpath } mercredi 23 novembre 2011
  • 36. Modify settings - tasks with dependencies Setting[S] apply method returns a Initialize[T] but for a TaskKey[T], <<= method expects a Initialize[Task [T]] The Setting[S] method map comes to the rescue : map[T](f: S => T):Initialize[Task[T]] We can set a SettingKey to a TaskKey : taskKey <<= settingKey map identity For multiple dependencies : watchSources <+= (baseDirectory, name) map{(dir, n) => dir / "conf" / (n + ".properties") } mercredi 23 novembre 2011
  • 37. Settings and tasks definition A setting key definition sample: val scalaVersion = SettingKey[String]("scala-version", "The version of Scala used for building.") A task key definition sample: val clean = TaskKey[Unit]("clean", "Deletes files produced by the build, such as generated sources, compiled classes, and task caches.") Here the clean task returns Unit when executed but can have side effects (produced artefacts are deleted). Most SBT tasks are defined in Default.scala. mercredi 23 novembre 2011
  • 38. Define your own tasks Define a task that print and returns the current time : val time = TaskKey[Date]("time", "returns current time") lazy val root = Project("test", file(".")).settings( time := { val now = new Date() println("%s".format(now)) now }) Usage : > time Wed Nov 16 13:55:38 CET 2011 Tasks unlike Settings are evaluated each time they are called. mercredi 23 novembre 2011
  • 39. Input tasks • Similar to a Task but can take user input as parameter, • SBT provides a powerful input parsing system (based on scala parser combinators) and easy tab completion feature, • Key defined in a way similar to SettingKey or TaskKey : val release = InputKey[Unit]("release", "release version") • Defining it in settings : release <<= InputTask(releaseParser)(releaseDef) • Similar to a Command (a kind of tasks that is not defined in Settings and with no return value). mercredi 23 novembre 2011
  • 40. Input tasks - input parser • Input parser sample : val releaseParser:Initialize[State => Parser[String]] = (version) { (v:String) => { val ReleaseExtractor(vMaj, vMin, vFix) = v val major = token("major" ^^^ "%s.%s.%s".format (vMaj.toInt + 1, vMin.toInt, vFix.toInt)) val minor = token("minor" ^^^ "%s.%s.%s".format (vMaj.toInt, vMin.toInt + 1, vFix.toInt)) val fix = token("fix" ^^^ "%s.%s.%s".format (vMaj.toInt, vMin.toInt, vFix.toInt + 1)) (state:State) => Space ~> (major | minor | fix) } } mercredi 23 novembre 2011
  • 41. Input tasks - task implementation • Task input implementation : val releaseDef = (nextVersion:TaskKey[String]) => { (version, nextVersion) map { case (currentV, nextV) => println("next version : " + nextV) val result = ("git tag " + currentV).lines_!.collect { case s:String if s.contains("fatal") => s } if (result.mkString.isEmpty) println(result.mkString) else { println("Release tagged ! Next one is " + nextV.mkString) // ... } } mercredi 23 novembre 2011
  • 42. Settings prevalence rules Lowest • Build and Project settings in .scala files, • User global settings in ~/.sbt/*.sbt, • Settings injected by plugins, • Settings from .sbt files in the project, • Settings from build definition project (i.e. project/ plugins.sbt) Highest prevalence mercredi 23 novembre 2011
  • 43. Inspect Settings - general informations > inspect compile [info] Task: sbt.inc.Analysis [info] Description: [info] Compiles sources. [info] Provided by: [info] {file:/Users/.../test/}test/compile:compile ... mercredi 23 novembre 2011
  • 44. Inspect Settings - dependencies ... [info] Dependencies: [info] compile:compile-inputs [info] compile:streams(for compile) [info] Reverse dependencies: [info] compile:products [info] compile:defined-sbt-plugins [info] compile:exported-products [info] compile:discovered-main-classes ... mercredi 23 novembre 2011
  • 45. Inspect Settings - delegates ... [info] Delegates: [info] compile:compile [info] *:compile [info] {.}/compile:compile [info] {.}/*:compile [info] */compile:compile [info] */*:compile [info] Related: [info] test:compile [info] debug:compile mercredi 23 novembre 2011
  • 46. Extending SBT • SBT can be extended using plugins, • Plugins are new Settings/Tasks added to SBT, • To add a plugin in the project or globally, add : resolvers += Classpaths.typesafeResolver addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse" % "1.4.0") in your project/plugins.sbt or in ~/.sbt/plugins/ build.sbt mercredi 23 novembre 2011
  • 47. What is a plugin ? • A plugin is an SBT project added as a dependency to the build definition ! • Recursive nature of SBT : / build.sbt project/ Project definition Build.scala plugins.sbt project/ Build definition Build.scala ... • We can load build definition project with reload plugins and go back to project with reload return. mercredi 23 novembre 2011
  • 48. Enhance build definition project • To use a specific library in your project/Build.scala, you can add the following in project/plugins.sbt (or project/project/Build.scala) : libraryDependencies += "net.databinder" %% "dispatch- http" % "0.8.5" • To test some build code snippets in a scala REPL : > console-project this will load all build dependencies. mercredi 23 novembre 2011
  • 49. Some powerful APIs • IO operations with Path API, • Invoking external process with process API, • Input parsers and tab-completion for Tasks and Commands, • Launcher to launch application without a local Scala installation, • All the power of Scala API ... mercredi 23 novembre 2011
  • 50. Finally... Is Simple Build Tool Simple ? • Limited key concepts to understand, • A powerful API, • Easy access to scala ecosystem power, • Increasing number of plugins ... mercredi 23 novembre 2011