SBT 多项目设置,其中子项目构建文件依赖于非托管 JAR
SBT multiproject setup where a subproject's build files depend on unmanaged JARs
场景:
- 我想开发一个用Scala写的projectA,它依赖projectB,也是用Scala写的。
- 通常情况下我也需要修改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
uses unmanaged libraries put into projectB/deploy/lib
在 sbt compile
时找不到 运行 来自项目 A 的范围 - 即使 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 分钟并输出大量警告,但没有错误。
Research. 有一些资源解释了如何在子项目之间共享非托管库(例如下面的 1 和 2),但是 none 他们似乎面临这样的问题构建设置(不仅是代码!)还取决于那些非托管库。
- How to inherit unmanaged dependencies in submodules in sbt?
- How to have sbt multi-project builds configure setting for subprojects?)
好的 build.sbt
这些更改在我的机器上有效:
//unmanagedBase := baseDirectory.value / ".." / "projectB" / "deploy" / "lib"
// this only defines the unmanagedBase of Project A
//lazy val projectB = RootProject(file("../projectB/src/project"))
// see the project setup below
lazy val projectB = RootProject(file("../projectB"))
lazy val projectBmmt = RootProject(file("../projectB/mmt"))
lazy val projectA = Project(id = "projectA", base = file(".")).settings(
name := "projectA",
version := "0.1",
scalaVersion := "2.12.8",
scalacOptions in ThisBuild ++= Seq("-unchecked", "-deprecation"),
// unmanagedBase in ThisBuild := baseDirectory.value / ".." / "projectB" / "deploy" / "lib"
// this only defines the unmanagedBase of Project A
).dependsOn(projectB, projectBmmt)
这里是我的文件设置:
好吧,我认为我的第一个答案进入了死胡同;(.
这里有一个全新的想法:
将您的项目 (projectA) 添加为项目 B 的子模块。
这是结构:
来自 projectB
的 build.sbt
需要小幅调整:
// added for my project
lazy val projectA = (project in file("projectA")).
dependsOn(api)
如果您可以处理 git
问题 - 这可能是您正在寻找的解决方案;)。
我设法通过以下更改编译项目。
首先,我在尝试编译您的 GitHub 项目中引用的 projectB @ b558245 修订版时遇到编译错误。我检查了最新的标签,v15.0.0,它编译了。
其次,在projectA/build.sbt
中,projectB
应该定义为
lazy val projectB = RootProject(file("../projectB/src"))
../projectB/src/project
是构建projectB的builder项目。它需要 scala 编译器和 sbt 中的东西,因此产生了您在尝试直接编译时看到的错误。
第三,projectB
作为projectA
的依赖编译失败。那是因为 Utils
对象(在 projectB/src/project/Utils.scala
中)是用错误的目录(../projectA
)[=26= 初始化的,该对象旨在引用 projectB
的布局]
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")
}
场景:
- 我想开发一个用Scala写的projectA,它依赖projectB,也是用Scala写的。
- 通常情况下我也需要修改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
uses unmanaged libraries put into projectB/deploy/lib
在 sbt compile
时找不到 运行 来自项目 A 的范围 - 即使 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 分钟并输出大量警告,但没有错误。
Research. 有一些资源解释了如何在子项目之间共享非托管库(例如下面的 1 和 2),但是 none 他们似乎面临这样的问题构建设置(不仅是代码!)还取决于那些非托管库。
- How to inherit unmanaged dependencies in submodules in sbt?
- How to have sbt multi-project builds configure setting for subprojects?)
好的 build.sbt
这些更改在我的机器上有效:
//unmanagedBase := baseDirectory.value / ".." / "projectB" / "deploy" / "lib"
// this only defines the unmanagedBase of Project A
//lazy val projectB = RootProject(file("../projectB/src/project"))
// see the project setup below
lazy val projectB = RootProject(file("../projectB"))
lazy val projectBmmt = RootProject(file("../projectB/mmt"))
lazy val projectA = Project(id = "projectA", base = file(".")).settings(
name := "projectA",
version := "0.1",
scalaVersion := "2.12.8",
scalacOptions in ThisBuild ++= Seq("-unchecked", "-deprecation"),
// unmanagedBase in ThisBuild := baseDirectory.value / ".." / "projectB" / "deploy" / "lib"
// this only defines the unmanagedBase of Project A
).dependsOn(projectB, projectBmmt)
这里是我的文件设置:
好吧,我认为我的第一个答案进入了死胡同;(.
这里有一个全新的想法:
将您的项目 (projectA) 添加为项目 B 的子模块。
这是结构:
来自 projectB
的 build.sbt
需要小幅调整:
// added for my project
lazy val projectA = (project in file("projectA")).
dependsOn(api)
如果您可以处理 git
问题 - 这可能是您正在寻找的解决方案;)。
我设法通过以下更改编译项目。
首先,我在尝试编译您的 GitHub 项目中引用的 projectB @ b558245 修订版时遇到编译错误。我检查了最新的标签,v15.0.0,它编译了。
其次,在projectA/build.sbt
中,projectB
应该定义为
lazy val projectB = RootProject(file("../projectB/src"))
../projectB/src/project
是构建projectB的builder项目。它需要 scala 编译器和 sbt 中的东西,因此产生了您在尝试直接编译时看到的错误。
第三,projectB
作为projectA
的依赖编译失败。那是因为 Utils
对象(在 projectB/src/project/Utils.scala
中)是用错误的目录(../projectA
)[=26= 初始化的,该对象旨在引用 projectB
的布局]
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")
}