设想:

  • 我想开发一个用Scala编写的projectA,它依赖于也用Scala编写的projectB。
  • 通常,经常也需要修改projectB。因此,我将有一个projectB的本地Git克隆(如my repository中的子模块一样)。
  • 现在projectA应该直接从克隆的projectB的Git存储库中直接提取对projectB的依赖关系。

  • 我现在有以下设置,也可以在GitHub上使用:https://github.com/ComFreek/sbt-multi-project-question
    | - .git
    |
    | - projectA
    | | - src
    | | - build.sbt
    |
    | - projectB (Git submodule)
    | | - src
    | | | - build.sbt
    | | | - project
    | | | - project.sbt
    | | | - ...
    

    projectA/build.sbt中尝试过:

    unmanagedBase := baseDirectory.value / ".." / "projectB" / "deploy" / "lib"
    
    lazy val projectB = RootProject(file("../projectB/src/project"))
    
    lazy val projectA = Project(id = "projectA", base = file(".")).settings(
      name := "projectA",
      version := "0.1",
      scalaVersion := "2.12.8",
      scalacOptions in ThisBuild ++= Seq("-unchecked", "-deprecation")
    ).dependsOn(projectB)
    

    但是,似乎 projectB/src/build.sbt 使用了放入 projectB/deploy/lib 中的非托管库,当从projectA的范围内运行sbt compile时,即使设置了unmanagedBase属性,也无法找到该库。

    具体而言,您可以按照以下方式重现它:
  • projectA
  • 中打开SBT shell
  • 运行compile并获取
    [IJ]sbt:projectA> compile
    [info] Compiling 13 Scala sources to ...\sbt-multi-project-question\projectB\src\project\target\scala-2.12\classes ...
    [error] ...\sbt-multi-project-question\projectB\src\project\File.scala:19:11: object tools is not a member of package scala
    [error]     scala.tools.nsc.io.File(f.toString).appendAll(strings:_*)
    [error]           ^
    [error] ...\sbt-multi-project-question\projectB\src\project\Utils.scala:31:14: object Keys is not a member of package sbt
    [error]   import sbt.Keys.packageBin
    [error]              ^
    [error] ...\sbt-multi-project-question\projectB\src\project\Utils.scala:33:36: not found: value Def
    [error]   def deployPackage(name: String): Def.Initialize[Task[Unit]] =
    [error]                                    ^
    [error] ...\sbt-multi-project-question\projectB\src\project\Utils.scala:34:5: not found: value packageBin
    [error]     packageBin in Compile map {jar => deployTo(Utils.deploy / name)(jar)}
    [error]     ^
    [error] ...\sbt-multi-project-question\projectB\src\project\Utils.scala:34:19: not found: value Compile
    [error]     packageBin in Compile map {jar => deployTo(Utils.deploy / name)(jar)}
    [error]                   ^
    [error] ...\sbt-multi-project-question\projectB\src\project\Utils.scala:45:39: type File is not a member of package sbt
    [error]   def deployTo(target: File)(jar: sbt.File): Unit = {
    [error]                                       ^
    [error] ...\sbt-multi-project-question\projectB\src\project\Utils.scala:39:36: not found: value Def
    [error]   def deployMathHub(target: File): Def.Initialize[Task[Unit]] =
    [error]                                    ^
    [error] ...\sbt-multi-project-question\projectB\src\project\Utils.scala:40:5: not found: value packageBin
    [error]     packageBin in Compile map {jar => deployTo(target)(jar)}
    [error]     ^
    [error] ...\sbt-multi-project-question\projectB\src\project\Utils.scala:40:19: not found: value Compile
    [error]     packageBin in Compile map {jar => deployTo(target)(jar)}
    [error]                   ^
    [error] ...\sbt-multi-project-question\projectB\src\project\Utils.scala:123:25: not found: type Logger
    [error]   def delRecursive(log: Logger, path: File): Unit = {
    [error]                         ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:8:44: not found: type Project
    [error] case class VersionSpecificProject(project: Project, excludes: Exclusions) {
    [error]                                            ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:13:48: not found: type Project
    [error]   def aggregate(projects: ProjectReference*) : Project = project.aggregate(excludes(projects.toList) :_*)
    [error]                                                ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:13:27: not found: type ProjectReference
    [error]   def aggregate(projects: ProjectReference*) : Project = project.aggregate(excludes(projects.toList) :_*)
    [error]                           ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:17:48: not found: type Project
    [error]   def dependsOn(projects: ProjectReference*) : Project = {
    [error]                                                ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:17:27: not found: type ProjectReference
    [error]   def dependsOn(projects: ProjectReference*) : Project = {
    [error]                           ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:18:47: not found: type ClasspathDep
    [error]     def toClassPathDep(p: ProjectReference) : ClasspathDep[ProjectReference] = p
    [error]                                               ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:18:27: not found: type ProjectReference
    [error]     def toClassPathDep(p: ProjectReference) : ClasspathDep[ProjectReference] = p
    [error]                           ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:23:59: not found: type Project
    [error]   def aggregatesAndDepends(projects: ProjectReference*) : Project = {
    [error]                                                           ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:23:38: not found: type ProjectReference
    [error]   def aggregatesAndDepends(projects: ProjectReference*) : Project = {
    [error]                                      ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:24:47: not found: type ClasspathDep
    [error]     def toClassPathDep(p: ProjectReference) : ClasspathDep[ProjectReference] = p
    [error]                                               ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:24:27: not found: type ProjectReference
    [error]     def toClassPathDep(p: ProjectReference) : ClasspathDep[ProjectReference] = p
    [error]                           ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:30:37: not found: type Project
    [error]   implicit def fromProject(project: Project) : VersionSpecificProject = VersionSpecificProject(project, Exclusions())
    [error]                                     ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:34:28: not found: type ProjectReference
    [error] case class Exclusions(lst: ProjectReference*) {
    [error]                            ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:31:61: not found: type Project
    [error]   implicit def toProject(vProject: VersionSpecificProject): Project = vProject.project
    [error]                                                             ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:35:68: not found: type ProjectReference
    [error]   private def javaVersion(versions: List[String], exclusions: List[ProjectReference]) : Exclusions = {
    [error]                                                                    ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:43:22: not found: type ProjectReference
    [error]   def :::(lst2: List[ProjectReference]) = Exclusions(lst.toList ::: lst2 : _*)
    [error]                      ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:39:25: not found: type ProjectReference
    [error]   def java7(exclusions: ProjectReference*): Exclusions = javaVersion(List("1.7", "7"), exclusions.toList)
    [error]                         ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:40:25: not found: type ProjectReference
    [error]   def java8(exclusions: ProjectReference*): Exclusions = javaVersion(List("1.8", "8"), exclusions.toList)
    [error]                         ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:41:25: not found: type ProjectReference
    [error]   def java9(exclusions: ProjectReference*): Exclusions = javaVersion(List("1.9", "9"), exclusions.toList)
    [error]                         ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:46:18: not found: value ScopeFilter
    [error]   def toFilter : ScopeFilter.ProjectFilter = {
    [error]                  ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:47:5: not found: value inAnyProject
    [error]     inAnyProject -- inProjects(lst :_*)
    [error]     ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:47:21: not found: value inProjects
    [error]     inAnyProject -- inProjects(lst :_*)
    [error]                     ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:51:28: not found: type ProjectReference
    [error]   private def equals(left: ProjectReference, right: ProjectReference) : Boolean = {
    [error]                            ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:51:53: not found: type ProjectReference
    [error]   private def equals(left: ProjectReference, right: ProjectReference) : Boolean = {
    [error]                                                     ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:61:25: not found: type ProjectReference
    [error]   def excludes(project: ProjectReference) : Boolean = lst.exists(equals(_, project))
    [error]                         ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:62:54: not found: type ProjectReference
    [error]   def apply(projects: List[ProjectReference]) : List[ProjectReference] = projects.filterNot(this.excludes)
    [error]                                                      ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:62:28: not found: type ProjectReference
    [error]   def apply(projects: List[ProjectReference]) : List[ProjectReference] = projects.filterNot(this.excludes)
    [error]                            ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:64:17: not found: type ProjectReference
    [error]   def map[B](f: ProjectReference => B) : Seq[B] = lst.map(f)
    [error]                 ^
    [error] ...\sbt-multi-project-question\projectB\src\project\VersionSpecificProject.scala:65:21: not found: type ProjectReference
    [error]   def foreach[U](f: ProjectReference => U) : Exclusions = {lst.foreach[U](f); this }
    [error]                     ^
    [error] 39 errors found
    [error] (ProjectRef(uri("file:/.../sbt-multi-project-question/projectB/src/project/"), "project") / Compile / compileIncremental) Compilation failed
    [error] Total time: 5 s, completed 04.03.2019, 10:10:34
    [IJ]sbt:projectA>
    

  • 但是,以下工作原理:
  • projectB/src打开一个SBT shell。
  • 运行compile请注意,这在我的计算机上花费了大约12分钟的时间,并且会输出很多警告,但不会出现错误。

  • 研究。 有一些资源说明了如何在子项目之间共享非托管库(例如下面的1和2),但是似乎没有一个资源面临build设置(不仅是代码!)还取决于那些非托管库的问题。
  • How to inherit unmanaged dependencies in submodules in sbt?
  • How to have sbt multi-project builds configure setting for subprojects?)
  • 最佳答案

    我设法通过以下更改来编译项目。

    首先,在尝试编译projectB @ b558245修订版时遇到编译错误,该错误在您的GitHub项目中被引用。我检查了最新的标签v15.0.0,并对其进行了编译。

    其次,在projectA/build.sbt中,projectB应该定义为

    lazy val projectB = RootProject(file("../projectB/src"))
    
    ../projectB/src/project是用于构建projectB的构建器项目。它需要scala编译器和sbt中的内容,因此会产生尝试直接编译时看到的错误。

    第三,projectB无法编译为projectA的依赖项。这是因为,用于引用Utils布局的projectB/src/project/Utils.scala对象(在projectB中)是用错误的目录(../projectA)初始化的
    object Utils {
       /** MMT root directory */
       val root = File("..").canonical  // Got the wrong directory when compiled with projectA
    

    因此,我们必须对Utils.scala及其依赖项进行一些修改,以确保它始终找到projectB的正确位置。这是projectB的补丁程序,可从projectA进行编译。可能不是最好的解决方案,但是它可以在我的笔记本电脑上使用。
    diff --git a/src/build.sbt b/src/build.sbt
    index 059ef9c8e..b7495c8eb 100644
    --- a/src/build.sbt
    +++ b/src/build.sbt
    @@ -1,10 +1,13 @@
     import scala.io.Source
     import sbt.Keys._
    +import Utils.utils
    +
    +utils in ThisBuild := Utils((baseDirectory in src).value)
    
     // =================================
     // META-DATA and Versioning
     // =================================
    -version in ThisBuild := {Source.fromFile("mmt-api/resources/versioning/system.txt").getLines.mkString.trim}
    +version in ThisBuild := {Source.fromFile(baseDirectory.value / "mmt-api/resources/versioning/system.txt").getLines.mkString.trim}
    
     val now = {
       import java.text.SimpleDateFormat
    @@ -106,7 +109,7 @@ def mmtProjectsSettings(nameStr: String) = commonSettings(nameStr) ++ Seq(
    
       unmanagedBase := baseDirectory.value  / "lib",
    
    -  publishTo := Some(Resolver.file("file", Utils.deploy.toJava / " main")),
    +  publishTo := Some(Resolver.file("file", utils.value.deploy.toJava / " main")),
    
       install := {},
       deploy := Utils.deployPackage("main/" + nameStr + ".jar").value
    @@ -153,8 +156,12 @@ lazy val mmt = (project in file("mmt")).
       settings(
         exportJars := false,
         publish := {},
    -    deploy := {
    -      assembly in Compile map Utils.deployTo(Utils.deploy / "mmt.jar")
    +    deploy := Def.taskDyn {
    +      val jar = (assembly in Compile).value
    +      val u = utils.value
    +      Def.task {
    +        Utils.deployTo(u.deploy / "mmt.jar")(jar)
    +      }
         }.value,
         assemblyExcludedJars in assembly := {
           val cp = (fullClasspath in assembly).value
    @@ -172,13 +179,13 @@ lazy val mmt = (project in file("mmt")).
    
     // MMT is split into multiple subprojects to that are managed independently.
    
    -val apiJars = Seq(
    +def apiJars(u: Utils) = Seq(
       "scala-compiler.jar",
       "scala-reflect.jar",
       "scala-parser-combinators.jar",
       "scala-xml.jar",
       "xz.jar",
    -).map(Utils.lib.toJava / _ )
    +).map(u.lib.toJava / _ )
    
     // The kernel upon which everything else depends. Maintainer: Florian
     lazy val api = (project in file("mmt-api")).
    @@ -188,8 +195,8 @@ lazy val api = (project in file("mmt-api")).
       settings(
         scalacOptions in Compile ++= Seq("-language:existentials"),
         scalaSource in Compile := baseDirectory.value / "src" / "main",
    -    unmanagedJars in Compile ++= apiJars,
    -    unmanagedJars in Test ++= apiJars,
    +    unmanagedJars in Compile ++= apiJars(utils.value),
    +    unmanagedJars in Test ++= apiJars(utils.value),
       )
    
    
    @@ -226,7 +233,7 @@ lazy val jedit = (project in file("jEdit-mmt")).
         resourceDirectory in Compile := baseDirectory.value / "src/resources",
         unmanagedJars in Compile ++= jeditJars map (baseDirectory.value / "lib" / _),
         deploy := Utils.deployPackage("main/MMTPlugin.jar").value,
    -    install := Utils.installJEditJars
    +    install := utils.value.installJEditJars
       )
    
     // MMT IntelliJ-Plugin. Maintainer: Dennis
    @@ -299,7 +306,7 @@ lazy val concepts = (project in file("concept-browser")).
         libraryDependencies ++= Seq(
           "org.ccil.cowan.tagsoup" % "tagsoup" % "1.2"
         ),
    -    unmanagedJars in Compile += Utils.lib.toJava / "scala-xml.jar"
    +    unmanagedJars in Compile += utils.value.lib.toJava / "scala-xml.jar"
      )
    
     // =================================
    @@ -389,7 +396,7 @@ lazy val oeis = (project in file("mmt-oeis")).
       dependsOn(planetary).
       settings(mmtProjectsSettings("mmt-oeis"): _*).
       settings(
    -    unmanagedJars in Compile += Utils.lib.toJava / "scala-parser-combinators.jar"
    +    unmanagedJars in Compile += utils.value.lib.toJava / "scala-parser-combinators.jar"
       )
    
     // =================================
    @@ -416,11 +423,15 @@ lazy val lfcatalog = (project in file("lfcatalog")).
       settings(commonSettings("lfcatalog")).
       settings(
         scalaSource in Compile := baseDirectory.value / "src",
    -    publishTo := Some(Resolver.file("file", Utils.deploy.toJava / " main")),
    -    deployLFCatalog := {
    -      assembly in Compile map Utils.deployTo(Utils.deploy / "lfcatalog" / "lfcatalog.jar")
    +    publishTo := Some(Resolver.file("file", utils.value.deploy.toJava / " main")),
    +    deployLFCatalog := Def.taskDyn {
    +      val jar = (assembly in Compile).value
    +      val u = utils.value
    +      Def.task {
    +        Utils.deployTo(u.deploy / "lfcatalog" / "lfcatalog.jar")(jar)
    +      }
         }.value,
    -    unmanagedJars in Compile += Utils.lib.toJava / "scala-xml.jar"
    +    unmanagedJars in Compile += utils.value.lib.toJava / "scala-xml.jar"
       )
    
     // =================================
    diff --git a/src/project/Utils.scala b/src/project/Utils.scala
    index 2f9b94fd4..8f862666e 100644
    --- a/src/project/Utils.scala
    +++ b/src/project/Utils.scala
    @@ -1,9 +1,84 @@
     import java.nio.file.Files
     import java.nio.file.StandardCopyOption._
    +import sbt.Keys.packageBin
    +import sbt._
    
     object Utils {
    +
    +  val utils = settingKey[Utils]("Utils")
    +
    +  def apply(base: java.io.File) = new Utils(File(base))
    +
    +  def error(s: String) = throw new Exception(s)
    +
    +  // ************************************************** deploy-specific code (see also the TaskKey's deploy and deployFull)
    +
    +  /*
    +   * copies files to deploy folder
    +   */
    +  def deployTo(target: File)(jar: sbt.File): Unit = {
    +    Files.copy(jar.toPath, target.toPath, REPLACE_EXISTING)
    +    println("copied file: " + jar)
    +    println("to file: " + target)
    +  }
    +
    +  /**
    +    * packages the compiled binaries and copies to deploy
    +    */
    +  def deployPackage(name: String) : Def.Initialize[Task[Unit]] = Def.taskDyn {
    +    val j = (packageBin in Compile).value
    +    val u = utils.value
    +    Def.task {
    +      deployTo(u.deploy / name)(j)
    +    }
    +  }
    +
    +  /**
    +    * packages the compiled binaries and copies to deploy
    +    */
    +  def deployMathHub(target: File): Def.Initialize[Task[Unit]] =
    +    packageBin in Compile map {jar => deployTo(target)(jar)}
    +
    +  // ************************************************** file system utilities
    +
    +  /** copy a file */
    +  def copy(from: File, to: File) {
    +    println(s"copying $from to $to")
    +    if (!from.exists) {
    +      error(s"error: file $from not found (when trying to copy it to $to)")
    +    } else if (!to.exists || from.lastModified > to.lastModified) {
    +      Files.copy(from.toPath, to.toPath, REPLACE_EXISTING)
    +    } else {
    +      println("skipped (up-to-date)")
    +    }
    +    println("\n")
    +  }
    +
    +  /**
    +    * Recursively deletes a given folder
    +    * @param log
    +    * @param path
    +    */
    +  def delRecursive(log: Logger, path: File): Unit = {
    +    def delRecursive(path: File): Unit = {
    +      path.listFiles foreach { f =>
    +        if (f.isDirectory) delRecursive(f)
    +        else {
    +          f.delete()
    +          log.debug("deleted file: " + path)
    +        }
    +      }
    +      path.delete()
    +      log.debug("deleted directory: " + path)
    +    }
    +    if (path.exists && path.isDirectory) delRecursive(path)
    +    else log.warn("ignoring missing directory: " + path)
    +  }
    +}
    +
    +class Utils(base: File) {
        /** MMT root directory */
    -   val root = File("..").canonical
    +   val root = (base / "..").canonical
        /** source folder */
        val src = root / "src"
        /** MMT deploy directory */
    @@ -21,33 +96,6 @@ object Utils {
        /** executes a shell command (in the src folder) */
        def runscript(command: String) = sys.process.Process(Seq(command), src.getAbsoluteFile).!!
    
    -   def error(s: String) = throw new Exception(s)
    -
    -  // ************************************************** deploy-specific code (see also the TaskKey's deploy and deployFull)
    -
    - /**
    -   * packages the compiled binaries and copies to deploy
    -   */
    -  import sbt.Keys.packageBin
    -  import sbt._
    -  def deployPackage(name: String): Def.Initialize[Task[Unit]] =
    -    packageBin in Compile map {jar => deployTo(Utils.deploy / name)(jar)}
    -
    - /**
    -   * packages the compiled binaries and copies to deploy
    -   */
    -  def deployMathHub(target: File): Def.Initialize[Task[Unit]] =
    -    packageBin in Compile map {jar => deployTo(target)(jar)}
    -
    -  /*
    -   * copies files to deploy folder
    -   */
    -  def deployTo(target: File)(jar: sbt.File): Unit = {
    -    Files.copy(jar.toPath, target.toPath, REPLACE_EXISTING)
    -    println("copied file: " + jar)
    -    println("to file: " + target)
    -  }
    -
    
       // ************************************************** MathHub-specific code
    
    @@ -79,7 +127,7 @@ object Utils {
           settings.get(killJEdit).foreach {x => runscript(x)}
          Thread.sleep(500)
           val fname = settings.get(jeditSettingsFolder).getOrElse {
    -        error(s"cannot copy jars because there is no setting '$jeditSettingsFolder' in $settingsFile")
    +        Utils.error(s"cannot copy jars because there is no setting '$jeditSettingsFolder' in $settingsFile")
             return
           }
           val jsf = File(fname) / "jars"
    @@ -92,47 +140,10 @@ object Utils {
        }
        /** copy all jEdit jars to a directory */
        def copyJEditJars(to: File) {
    -      copy(deploy/"mmt.jar", to/"MMTPlugin.jar")
    +      Utils.copy(deploy/"mmt.jar", to/"MMTPlugin.jar")
           // all other jars are bundled with the above
           // val jEditDeps = List("scala-library.jar","scala-parser-combinators.jar","scala-reflect.jar","scala-xml.jar","tiscaf.jar")
           // jEditDeps.foreach {f => copy(deploy/"lib"/f, to/f)}
           // copy(deploy/"lfcatalog"/"lfcatalog.jar", to/"lfcatalog.jar")
        }
    -
    -
    -  // ************************************************** file system utilities
    -
    -   /** copy a file */
    -   def copy(from: File, to: File) {
    -      println(s"copying $from to $to")
    -      if (!from.exists) {
    -         error(s"error: file $from not found (when trying to copy it to $to)")
    -      } else if (!to.exists || from.lastModified > to.lastModified) {
    -         Files.copy(from.toPath, to.toPath, REPLACE_EXISTING)
    -      } else {
    -         println("skipped (up-to-date)")
    -      }
    -      println("\n")
    -   }
    -
    -  /**
    -    * Recursively deletes a given folder
    -    * @param log
    -    * @param path
    -    */
    -  def delRecursive(log: Logger, path: File): Unit = {
    -    def delRecursive(path: File): Unit = {
    -      path.listFiles foreach { f =>
    -        if (f.isDirectory) delRecursive(f)
    -        else {
    -          f.delete()
    -          log.debug("deleted file: " + path)
    -        }
    -      }
    -      path.delete()
    -      log.debug("deleted directory: " + path)
    -    }
    -    if (path.exists && path.isDirectory) delRecursive(path)
    -    else log.warn("ignoring missing directory: " + path)
    -  }
     }
    diff --git a/src/project/build.properties b/src/project/build.properties
    index 9f782f704..1fc4b8093 100644
    --- a/src/project/build.properties
    +++ b/src/project/build.properties
    @@ -1 +1 @@
    -sbt.version=1.1.1
    \ No newline at end of file
    +sbt.version=1.2.8
    \ No newline at end of file
    diff --git a/src/travis.sbt b/src/travis.sbt
    index 88fb446d3..a71be9d2e 100644
    --- a/src/travis.sbt
    +++ b/src/travis.sbt
    @@ -2,6 +2,7 @@ import sbt._
     import sbt.Keys._
     import travis.Matrix._
     import travis.Config._
    +import Utils.utils
    
     import scala.io.Source
    
    @@ -86,11 +87,11 @@ travisConfig := {
     val genTravisYML = taskKey[Unit]("Print out travis.yml configuration")
     genTravisYML := {
       // read the prefix and the config
    -  val prefix = Source.fromFile(Utils.src / "project" / "prefix.travis.yml").getLines.filter(!_.startsWith("##")).mkString("\n")
    +  val prefix = Source.fromFile(utils.value.src / "project" / "prefix.travis.yml").getLines.filter(!_.startsWith("##")).mkString("\n")
       val config = travisConfig.value.serialize
    
       // and write it into .travis.yml
    -  val outFile = Utils.root / ".travis.yml"
    +  val outFile = utils.value.root / ".travis.yml"
       IO.write(outFile, prefix + "\n" + config)
       streams.value.log.info(s"Wrote $outFile")
     }
    

    10-06 13:39