From 25b321ea9431590d5852366585f1691717651fea Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Mon, 26 Mar 2018 20:16:43 -0700 Subject: Ensure that transitive ivy jars are not directly aggregated under a module's `runClasspath`; only the ivy coordinates are aggregated, and every module resolves it's own set of ivy jars using coursier, which avoids duplicate jars entering the classpath through ivy Fixes https://github.com/lihaoyi/mill/issues/211 --- scalalib/src/mill/scalalib/ScalaModule.scala | 22 ++++++++++--------- .../test/src/mill/scalalib/HelloWorldTests.scala | 25 ++++++++++++++++++++++ 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/scalalib/src/mill/scalalib/ScalaModule.scala b/scalalib/src/mill/scalalib/ScalaModule.scala index 08e87909..fdc83cbf 100644 --- a/scalalib/src/mill/scalalib/ScalaModule.scala +++ b/scalalib/src/mill/scalalib/ScalaModule.scala @@ -79,8 +79,10 @@ trait ScalaModule extends mill.Module with TaskModule { outer => Task.traverse(moduleDeps)(_.compile) } - def upstreamRunClasspath: T[Agg[PathRef]] = T{ - Task.traverse(moduleDeps)(_.runClasspath)().flatten + def transitiveLocalClasspath: T[Agg[PathRef]] = T{ + Task.traverse(moduleDeps)(m => + T.task{m.localClasspath() ++ m.transitiveLocalClasspath()} + )().flatten } def resolveDeps(deps: Task[Agg[Dep]], sources: Boolean = false) = T.task{ @@ -170,25 +172,25 @@ trait ScalaModule extends mill.Module with TaskModule { outer => upstreamCompileOutput() ) } - + def localClasspath = T{ + resources() ++ Agg(compile().classes) + } def compileClasspath = T{ - upstreamRunClasspath() ++ + transitiveLocalClasspath() ++ resources() ++ unmanagedClasspath() ++ resolveDeps(T.task{compileIvyDeps() ++ scalaLibraryIvyDeps() ++ transitiveIvyDeps()})() } def upstreamAssemblyClasspath = T{ - upstreamRunClasspath() ++ + transitiveLocalClasspath() ++ unmanagedClasspath() ++ resolveDeps(T.task{runIvyDeps() ++ scalaLibraryIvyDeps() ++ transitiveIvyDeps()})() } def runClasspath = T{ - Agg(compile().classes) ++ - resources() ++ + localClasspath() ++ upstreamAssemblyClasspath() - } /** @@ -203,7 +205,7 @@ trait ScalaModule extends mill.Module with TaskModule { outer => def assembly = T{ createAssembly( - Agg.from(resources().map(_.path)) ++ Agg(compile().classes.path), + Agg.from(localClasspath().map(_.path)), mainClass(), prependShellScript(), Some(upstreamAssembly().path) @@ -213,7 +215,7 @@ trait ScalaModule extends mill.Module with TaskModule { outer => def jar = T{ createJar( - (resources() ++ Seq(compile().classes)).map(_.path).filter(exists), + localClasspath().map(_.path).filter(exists), mainClass() ) } diff --git a/scalalib/test/src/mill/scalalib/HelloWorldTests.scala b/scalalib/test/src/mill/scalalib/HelloWorldTests.scala index 8b7c459f..74078221 100644 --- a/scalalib/test/src/mill/scalalib/HelloWorldTests.scala +++ b/scalalib/test/src/mill/scalalib/HelloWorldTests.scala @@ -87,6 +87,17 @@ object HelloWorldTests extends TestSuite { override def scalaVersion: Target[String] = "2.11.11" } } + + object HelloWorldIvyDeps extends HelloBase{ + object moduleA extends HelloWorldModule { + + override def ivyDeps = Agg(ivy"com.lihaoyi::sourcecode:0.1.3") + } + object moduleB extends HelloWorldModule { + override def moduleDeps = Seq(moduleA) + override def ivyDeps = Agg(ivy"com.lihaoyi::sourcecode:0.1.4") + } + } val resourcePath = pwd / 'scalalib / 'test / 'resources / "hello-world" def jarMainClass(jar: JarFile): Option[String] = { @@ -413,6 +424,20 @@ object HelloWorldTests extends TestSuite { ) } } + + 'ivyDeps - workspaceTest(HelloWorldIvyDeps){ eval => + val Right((result, _)) = eval.apply(HelloWorldIvyDeps.moduleA.runClasspath) + assert( + result.exists(_.path.last == "sourcecode_2.12-0.1.3.jar"), + !result.exists(_.path.last == "sourcecode_2.12-0.1.4.jar") + ) + + val Right((result2, _)) = eval.apply(HelloWorldIvyDeps.moduleB.runClasspath) + assert( + result2.exists(_.path.last == "sourcecode_2.12-0.1.4.jar"), + !result2.exists(_.path.last == "sourcecode_2.12-0.1.3.jar") + ) + } } -- cgit v1.2.3