8
votes

Configuration de plusieurs projets SBT où les fichiers de construction d'un sous-projet dépendent de JAR non gérés

Scénario:

  • Je souhaite développer un projectA écrit en Scala, qui dépend de projectB, également écrit en Scala.
  • Il sera souvent nécessaire que je modifie également projectB. Par conséquent, j'aurai un clone Git local de projectB (comme dans mon référentiel comme un sous-module).
  • À présent, projectA doit extraire la dépendance sur projectB directement à partir de ce référentiel Git cloné de projectB.

J'ai maintenant la configuration suivante, qui est également disponible sur GitHub: https://github.com/ComFreek/sbt-multi-project-question

[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>

Dans projectA / build.sbt essayé :

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)

Cependant, il semble que projectB / src / build.sbt utilise des bibliothèques non gérées placées dans projectB / deploy / lib qui ne peut pas être trouvé lorsque sbt compile est exécuté à partir de la portée de projectA - même avec la propriété unmanagedBase définie.

Concrètement, vous pouvez le reproduire comme suit:

  1. Ouvrez un shell SBT dans projectA
  2. Exécutez compile et obtenez
    | - .git
    |
    | - projectA
    | | - src
    | | - build.sbt
    |
    | - projectB (Git submodule)
    | | - src
    | | | - build.sbt
    | | | - project
    | | | - project.sbt
    | | | - ...
    

Cependant, ce qui suit fonctionne:

  1. Ouvrez un shell SBT dans projectB / src .
  2. Exécutez compile
    Attention, cela prend environ 12 minutes sur ma machine et génère beaucoup d'avertissements, mais aucune erreur.

Recherche. Il existe des ressources expliquant comment partager des bibliothèques non gérées entre des sous-projets (par exemple 1 et 2 ci-dessous), mais aucune d'entre elles ne semble être confrontée au problème que construit setup (pas seulement le code!) dépend également de ces bibliothèques non gérées.

  1. Comment hériter des dépendances non gérées dans les sous-modules de sbt?
  2. Comment faire pour que les builds multi-projets sbt configurent les paramètres des sous-projets? )


7 commentaires

votre configuration fonctionne-t-elle si vous n'avez aucune dépendance non gérée?


@pme Je ne suis pas sûr, je suppose qu'il faudrait beaucoup de travail pour extraire ces dépendances non gérées sans trop modifier la configuration de construction du projet de dépendance.


Avez-vous déjà trouvé la solution sur ce projet @ComFreek?


@Rex Pas encore, actuellement, je teste la suggestion de pme , voir les commentaires ici.


Ahh je vois. mais je pense que tout ce qu'ils suggèrent sont de bonnes réponses. Voici le mot clé le plus important ici .aggregate () et .dependsOn ()


@Rex Si vous êtes intéressé, thirstycrow a publié une solution fonctionnelle .


Pourriez-vous également suggérer vos précieuses contributions pour la question ci-dessous stackoverflow.com/questions/63084177/...


3 Réponses :


1
votes

Ok avec ces changements dans build.sbt cela fonctionne sur ma machine:

//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)

Voici ma configuration de fichier: entrez la description de l'image ici


4 commentaires

Merci! Maintenant, la configuration de build SBT est correctement chargée, cependant, il semble que les sous-projets de projectB ne sont pas mis dans la portée de projectA. Par exemple. projectB définit dans src / mmt-api / src une API que je ne peux pas importer dans projectA: pastebin. com / Asa4j59R .


J'ai déjà essayé de spécifier un autre projet lazy val mmtApi = RootProject (file ("../ mmt / src / mmt-api")) à dépendre via ) .dependsOn (projectB, mmtApi) , mais cela échoue avec les mêmes messages d'erreur, à savoir que les importations sont introuvables (lors de la compilation).


ce que vous pouvez essayer d'ajouter le sous-module également - j'ai ajusté ma réponse - mais je n'ai pas essayé cela


C'est ce que j'ai essayé. Le chemin est cependant file ("../ projectB / src / mmt-api") . Désolé si je confond de temps en temps projectB et "MMT". Les deux font référence au même projet ../projectB .



1
votes

Ok, je pense que ma première réponse est dans une impasse; (.

Voici une toute nouvelle idée:

Ajoutez votre projet (projectA) en tant que sous-module de projectB.

Voici la structure:

 entrez la description de l'image ici

Le build.sbt du projectB a besoin d'un petit ajustement:

// added for my project 
lazy val projectA = (project in file("projectA")).
  dependsOn(api)

Si vous pouvez gérer les trucs git - c'est peut-être la solution que vous cherchez;).


2 commentaires

Merci encore! Bien que je puisse modifier projectB, je préfère ne pas introduire de dépendance sur projectA. Il peut y avoir plusieurs projets indépendants de plusieurs personnes. Je pense que cela peut être facilement résolu en faisant une "inclusion" conditionnelle dans le build.sbt de projectB d'un fichier ignoré par git que les gens peuvent modifier à leur guise. Laissez-moi tester cela.


Apparemment, inclure d'autres fichiers SBT à partir d'un fichier SBT n'est pas trivial. Je n'ai pas trouvé de solution sur Internet. Cependant, thirstycrow a publié une réponse de travail en résolvant la cause profonde réelle. Néanmoins, vos deux réponses pourraient être bénéfiques pour les autres visiteurs :)



2
votes

J'ai réussi à compiler les projets avec les changements suivants.

Premièrement, j'ai eu des erreurs de compilation en essayant de compiler la révision projectB @ b558245, qui est référencée dans votre projet GitHub. J'ai vérifié la dernière balise, v15.0.0, et elle a été compilée.

Deuxièmement, dans projectA / build.sbt , projectB doit être défini comme

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")
 }

../projectB/src/project est le projet de construction qui construit projectB. Il nécessite des éléments dans le compilateur scala et sbt, et a donc produit les erreurs que vous avez vues lorsque vous avez essayé de le compiler directement.

Troisièmement, projectB n'a pas pu être compilé en tant que dépendance de projectA . En effet, l'objet Utils (dans projectB / src / project / Utils.scala ) qui était destiné à faire référence à la mise en page de projectB , a été initialisé avec un mauvais répertoire ( ../projectA )

object Utils {
   /** MMT root directory */
   val root = File("..").canonical  // Got the wrong directory when compiled with projectA

Nous devons donc apporter quelques modifications à Utils.scala et ses dépendants, pour s'assurer qu'il trouve toujours la bonne position de projectB . Voici le patch de projectB pour le faire compiler à partir de projectA . Ce n'est peut-être pas la meilleure solution, mais cela fonctionne sur mon ordinateur portable.

lazy val projectB = RootProject(file("../projectB/src"))


4 commentaires

Merci beaucoup! Fonctionne très bien! La partie sur le mauvais répertoire relatif était sur place! PS: J'ai dû appliquer votre patch Git manuellement car les espaces sur les lignes vides avaient été supprimés par StackOverflow. Je publierai un Git-diff en ligne à partir de GitHub une fois les modifications fusionnées. Quoi qu'il en soit, je ne pense pas qu'un futur visiteur se souciera de chaque petit changement, juste qu'il faut utiliser baseDirectory.value .


Git diff: github.com/UniFormal/MMT/commit/…


Désolé d'être un vampire d'aide! Savez-vous comment exécuter des tâches de projectB à partir du shell SBT de projectA ? Par exemple. projectB déclare la tâche deploy dans son sous-projet mmt , donc mmt / deploy fonctionne normalement à partir de projectB , mais pas depuis projectA ("Pas une commande valide: mmt"). Changer de projet ne fonctionne pas non plus: project mmt m'indique qu'il ne trouve pas le projet même si projets le répertorie.


Oh attendez, avoir ) .dependsOn (projectB) .aggregates (projectB) dans projectA build.sbt me permet au moins d'exécuter < code> déployer . Attendons que cela se termine.