From 57501fca3b6c2c64d32744e6d534b9de3a6674f6 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Sat, 13 Jan 2018 13:00:21 -0800 Subject: Migrate most classpath-related code onto `Loose.OSet` abstraction, to enforce deduplication --- .../src/main/scala/mill/scalalib/GenIdea.scala | 3 +- scalalib/src/main/scala/mill/scalalib/Lib.scala | 27 +++++++----- .../src/main/scala/mill/scalalib/MiscModule.scala | 15 ++++--- scalalib/src/main/scala/mill/scalalib/Module.scala | 51 +++++++++++----------- .../main/scala/mill/scalalib/PublishModule.scala | 2 +- .../src/main/scala/mill/scalalib/TestRunner.scala | 13 +++--- .../src/main/scala/mill/scalalib/publish/Ivy.scala | 4 +- .../src/main/scala/mill/scalalib/publish/Pom.scala | 4 +- .../scala/mill/scalalib/ResolveDepsTests.scala | 11 ++--- 9 files changed, 71 insertions(+), 59 deletions(-) (limited to 'scalalib/src') diff --git a/scalalib/src/main/scala/mill/scalalib/GenIdea.scala b/scalalib/src/main/scala/mill/scalalib/GenIdea.scala index 24daef2c..cd664495 100644 --- a/scalalib/src/main/scala/mill/scalalib/GenIdea.scala +++ b/scalalib/src/main/scala/mill/scalalib/GenIdea.scala @@ -5,7 +5,8 @@ import mill.define.{Segment, Segments, Target} import mill.discover.{Discovered, Mirror} import mill.eval.{Evaluator, PathRef} import mill.util.Ctx.{LoaderCtx, LogCtx} -import mill.util.{OSet, PrintLogger} +import mill.util.{PrintLogger} +import mill.util.Strict.OSet object GenIdea { diff --git a/scalalib/src/main/scala/mill/scalalib/Lib.scala b/scalalib/src/main/scala/mill/scalalib/Lib.scala index 098da786..54b1a817 100644 --- a/scalalib/src/main/scala/mill/scalalib/Lib.scala +++ b/scalalib/src/main/scala/mill/scalalib/Lib.scala @@ -9,7 +9,8 @@ import ammonite.ops._ import coursier.{Cache, Fetch, MavenRepository, Repository, Resolution, Module => CoursierModule} import mill.define.Worker import mill.eval.{PathRef, Result} -import mill.util.Ctx +import mill.util.{Ctx} +import mill.util.Loose.OSet import sbt.internal.inc._ import sbt.internal.util.{ConsoleOut, MainAppender} import sbt.util.LogExchange @@ -38,7 +39,7 @@ object Lib{ Locate.definesClass(classpathEntry) } - def grepJar(classPath: Seq[Path], s: String) = { + def grepJar(classPath: OSet[Path], s: String) = { classPath .find(_.toString.endsWith(s)) .getOrElse(throw new Exception("Cannot find " + s)) @@ -47,13 +48,13 @@ object Lib{ def compileScala(zincWorker: ZincWorker, scalaVersion: String, - sources: Seq[Path], - compileClasspath: Seq[Path], - compilerClasspath: Seq[Path], - pluginClasspath: Seq[Path], + sources: OSet[Path], + compileClasspath: OSet[Path], + compilerClasspath: OSet[Path], + pluginClasspath: OSet[Path], compilerBridge: Path, scalacOptions: Seq[String], - scalacPluginClasspath: Seq[Path], + scalacPluginClasspath: OSet[Path], javacOptions: Seq[String], upstreamCompileOutput: Seq[CompilationResult]) (implicit ctx: Ctx): CompilationResult = { @@ -171,8 +172,8 @@ object Lib{ def resolveDependencies(repositories: Seq[Repository], scalaVersion: String, scalaBinaryVersion: String, - deps: Seq[Dep], - sources: Boolean = false): Result[Seq[PathRef]] = { + deps: TraversableOnce[Dep], + sources: Boolean = false): Result[OSet[PathRef]] = { val flattened = deps.map{ case Dep.Java(dep) => dep case Dep.Scala(dep) => @@ -206,14 +207,16 @@ object Lib{ .unsafePerformSync .flatMap(_.toOption) - localArtifacts.map(p => PathRef(Path(p), quick = true)).filter(_.path.ext == "jar") + OSet.from( + localArtifacts.map(p => PathRef(Path(p), quick = true)).filter(_.path.ext == "jar") + ) } } - def scalaCompilerIvyDeps(scalaVersion: String) = Seq( + def scalaCompilerIvyDeps(scalaVersion: String) = OSet[Dep]( Dep.Java("org.scala-lang", "scala-compiler", scalaVersion), Dep.Java("org.scala-lang", "scala-reflect", scalaVersion) ) - def scalaRuntimeIvyDeps(scalaVersion: String) = Seq[Dep]( + def scalaRuntimeIvyDeps(scalaVersion: String) = OSet[Dep]( Dep.Java("org.scala-lang", "scala-library", scalaVersion) ) def compilerBridgeIvyDep(scalaVersion: String) = diff --git a/scalalib/src/main/scala/mill/scalalib/MiscModule.scala b/scalalib/src/main/scala/mill/scalalib/MiscModule.scala index 60d9d1ce..26609bcd 100644 --- a/scalalib/src/main/scala/mill/scalalib/MiscModule.scala +++ b/scalalib/src/main/scala/mill/scalalib/MiscModule.scala @@ -1,18 +1,19 @@ package mill package scalalib +import mill.define.Cross.Resolver import mill.define.{Cross, Task} import mill.eval.{PathRef, Result} -import mill.define.Cross.Resolver +import mill.util.Loose.OSet trait SbtModule extends Module { outer => - override def sources = T.input{ Seq(PathRef(basePath / 'src / 'main / 'scala)) } - override def resources = T.input{ Seq(PathRef(basePath / 'src / 'main / 'resources)) } + override def sources = T.input{ OSet(PathRef(basePath / 'src / 'main / 'scala)) } + override def resources = T.input{ OSet(PathRef(basePath / 'src / 'main / 'resources)) } trait Tests extends super.Tests { override def basePath = outer.basePath - override def sources = T.input{ Seq(PathRef(basePath / 'src / 'test / 'scala)) } - override def resources = T.input{ Seq(PathRef(basePath / 'src / 'test / 'resources)) } + override def sources = T.input{ OSet(PathRef(basePath / 'src / 'test / 'scala)) } + override def resources = T.input{ OSet(PathRef(basePath / 'src / 'test / 'resources)) } } } @@ -45,7 +46,7 @@ trait CrossSbtModule extends SbtModule { outer => } } - override def resources = T.input{ Seq(PathRef(basePath / 'src / 'main / 'resources)) } + override def resources = T.input{ OSet(PathRef(basePath / 'src / 'main / 'resources)) } trait Tests extends super.Tests { override def basePath = outer.basePath override def sources = T.input{ @@ -54,7 +55,7 @@ trait CrossSbtModule extends SbtModule { outer => s => PathRef{ basePath / 'src / 'test / s"scala-$s" } } } - override def resources = T.input{ Seq(PathRef(basePath / 'src / 'test / 'resources)) } + override def resources = T.input{ OSet(PathRef(basePath / 'src / 'test / 'resources)) } } } diff --git a/scalalib/src/main/scala/mill/scalalib/Module.scala b/scalalib/src/main/scala/mill/scalalib/Module.scala index d0041fb5..2a7d6edb 100644 --- a/scalalib/src/main/scala/mill/scalalib/Module.scala +++ b/scalalib/src/main/scala/mill/scalalib/Module.scala @@ -10,6 +10,7 @@ import mill.modules.Jvm import mill.modules.Jvm.{createAssembly, createJar, interactiveSubprocess, subprocess} import Lib._ import mill.define.Cross.Resolver +import mill.util.Loose.OSet import sbt.testing.Status /** @@ -25,10 +26,10 @@ trait Module extends mill.Module with TaskModule { outer => def mainClass: T[Option[String]] = None def scalaBinaryVersion = T{ scalaVersion().split('.').dropRight(1).mkString(".") } - def ivyDeps = T{ Seq[Dep]() } - def compileIvyDeps = T{ Seq[Dep]() } - def scalacPluginIvyDeps = T{ Seq[Dep]() } - def runIvyDeps = T{ Seq[Dep]() } + def ivyDeps = T{ OSet.empty[Dep] } + def compileIvyDeps = T{ OSet.empty[Dep] } + def scalacPluginIvyDeps = T{ OSet.empty[Dep] } + def runIvyDeps = T{ OSet.empty[Dep] } def scalacOptions = T{ Seq.empty[String] } def javacOptions = T{ Seq.empty[String] } @@ -39,7 +40,7 @@ trait Module extends mill.Module with TaskModule { outer => ) def projectDeps = Seq.empty[Module] - def depClasspath = T{ Seq.empty[PathRef] } + def depClasspath = T{ OSet.empty[PathRef] } def upstreamRunClasspath = T{ @@ -57,7 +58,7 @@ trait Module extends mill.Module with TaskModule { outer => Task.traverse(projectDeps)(_.compileDepClasspath)().flatten } - def resolveDeps(deps: Task[Seq[Dep]], sources: Boolean = false) = T.task{ + def resolveDeps(deps: Task[OSet[Dep]], sources: Boolean = false) = T.task{ resolveDependencies( repositories, scalaVersion(), @@ -67,15 +68,15 @@ trait Module extends mill.Module with TaskModule { outer => ) } - def externalCompileDepClasspath: T[Seq[PathRef]] = T{ - Task.traverse(projectDeps)(_.externalCompileDepClasspath)().flatten ++ + def externalCompileDepClasspath: T[OSet[PathRef]] = T{ + OSet.from(Task.traverse(projectDeps)(_.externalCompileDepClasspath)().flatten) ++ resolveDeps( T.task{ivyDeps() ++ compileIvyDeps() ++ scalaCompilerIvyDeps(scalaVersion())} )() } - def externalCompileDepSources: T[Seq[PathRef]] = T{ - Task.traverse(projectDeps)(_.externalCompileDepSources)().flatten ++ + def externalCompileDepSources: T[OSet[PathRef]] = T{ + OSet.from(Task.traverse(projectDeps)(_.externalCompileDepSources)().flatten) ++ resolveDeps( T.task{ivyDeps() ++ compileIvyDeps() ++ scalaCompilerIvyDeps(scalaVersion())}, sources = true @@ -86,7 +87,7 @@ trait Module extends mill.Module with TaskModule { outer => * Things that need to be on the classpath in order for this code to compile; * might be less than the runtime classpath */ - def compileDepClasspath: T[Seq[PathRef]] = T{ + def compileDepClasspath: T[OSet[PathRef]] = T{ upstreamCompileClasspath() ++ depClasspath() } @@ -108,7 +109,7 @@ trait Module extends mill.Module with TaskModule { outer => ) classpath match { case Result.Success(resolved) => - resolved.filterNot(_.path.ext == "pom") match { + resolved.filter(_.path.ext != "pom").toSeq match { case Seq(single) => PathRef(single.path, quick = true) case Seq() => throw new Exception(dep + " resolution failed") // TODO: find out, is it possible? case _ => throw new Exception(dep + " resolution resulted in more than one file") @@ -118,7 +119,7 @@ trait Module extends mill.Module with TaskModule { outer => } } - def scalacPluginClasspath: T[Seq[PathRef]] = + def scalacPluginClasspath: T[OSet[PathRef]] = resolveDeps( T.task{scalacPluginIvyDeps()} )() @@ -126,7 +127,7 @@ trait Module extends mill.Module with TaskModule { outer => /** * Classpath of the Scala Compiler & any compiler plugins */ - def scalaCompilerClasspath: T[Seq[PathRef]] = T{ + def scalaCompilerClasspath: T[OSet[PathRef]] = T{ resolveDeps( T.task{scalaCompilerIvyDeps(scalaVersion()) ++ scalaRuntimeIvyDeps(scalaVersion())} )() @@ -135,19 +136,19 @@ trait Module extends mill.Module with TaskModule { outer => /** * Things that need to be on the classpath in order for this code to run */ - def runDepClasspath: T[Seq[PathRef]] = T{ - upstreamRunClasspath().flatten ++ + def runDepClasspath: T[OSet[PathRef]] = T{ + OSet.from(upstreamRunClasspath().flatten) ++ depClasspath() ++ resolveDeps( - T.task{ivyDeps() ++ runIvyDeps() ++ scalaRuntimeIvyDeps(scalaVersion())}, + T.task{ivyDeps() ++ runIvyDeps() ++ scalaRuntimeIvyDeps(scalaVersion())} )() } def prependShellScript: T[String] = T{ "" } - def sources = T.input{ Seq(PathRef(basePath / 'src)) } - def resources = T.input{ Seq(PathRef(basePath / 'resources)) } - def generatedSources = T { Seq.empty[PathRef] } + def sources = T.input{ OSet(PathRef(basePath / 'src)) } + def resources = T.input{ OSet(PathRef(basePath / 'resources)) } + def generatedSources = T { OSet.empty[PathRef] } def allSources = T{ sources() ++ generatedSources() } def compile: T[CompilationResult] = T.persistent{ compileScala( @@ -203,11 +204,11 @@ trait Module extends mill.Module with TaskModule { outer => subprocess( "scala.tools.nsc.ScalaDoc", - compileDepClasspath().filterNot(_.path.ext == "pom").map(_.path), - options = options + compileDepClasspath().filter(_.path.ext != "pom").map(_.path), + options = options.toSeq ) - createJar(Seq(javadocDir))(outDir / "javadoc.jar") + createJar(OSet(javadocDir))(outDir / "javadoc.jar") } def sourcesJar = T { @@ -283,7 +284,7 @@ trait TestModule extends Module with TaskModule { jvmOptions = forkArgs(), options = Seq( testFramework(), - runClasspath().map(_.path).distinct.mkString(" "), + runClasspath().map(_.path).mkString(" "), Seq(compile().classes.path).mkString(" "), args.mkString(" "), outputPath.toString, @@ -301,7 +302,7 @@ trait TestModule extends Module with TaskModule { val (doneMsg, results) = TestRunner( testFramework(), runClasspath().map(_.path), - Seq(compile().classes.path), + OSet(compile().classes.path), args ) TestModule.handleResults(doneMsg, results) diff --git a/scalalib/src/main/scala/mill/scalalib/PublishModule.scala b/scalalib/src/main/scala/mill/scalalib/PublishModule.scala index 1b1a0f44..211c94d2 100644 --- a/scalalib/src/main/scala/mill/scalalib/PublishModule.scala +++ b/scalalib/src/main/scala/mill/scalalib/PublishModule.scala @@ -3,7 +3,7 @@ package scalalib import ammonite.ops._ import mill.eval.{PathRef, Result} - +import mill.util.Loose.OSet /** * Configuration necessary for publishing a Scala module to Maven Central or similar */ diff --git a/scalalib/src/main/scala/mill/scalalib/TestRunner.scala b/scalalib/src/main/scala/mill/scalalib/TestRunner.scala index 0d1768f6..d129e0d4 100644 --- a/scalalib/src/main/scala/mill/scalalib/TestRunner.scala +++ b/scalalib/src/main/scala/mill/scalalib/TestRunner.scala @@ -8,7 +8,8 @@ import java.util.zip.ZipInputStream import ammonite.ops.{Path, ls, pwd} import ammonite.util.Colors import mill.util.Ctx.LogCtx -import mill.util.PrintLogger +import mill.util.{PrintLogger} +import mill.util.Loose.OSet import sbt.testing._ import upickle.Js import mill.util.JsonFormatters._ @@ -23,7 +24,7 @@ object TestRunner { Iterator.continually(zip.getNextEntry).takeWhile(_ != null).map(_.getName).filter(_.endsWith(".class")) } } - def runTests(cl: ClassLoader, framework: Framework, classpath: Seq[Path]) = { + def runTests(cl: ClassLoader, framework: Framework, classpath: OSet[Path]) = { val fingerprints = framework.fingerprints() @@ -48,8 +49,8 @@ object TestRunner { def main(args: Array[String]): Unit = { val result = apply( frameworkName = args(0), - entireClasspath = args(1).split(" ").map(Path(_)), - testClassfilePath = args(2).split(" ").map(Path(_)), + entireClasspath = OSet.from(args(1).split(" ").map(Path(_))), + testClassfilePath = OSet.from(args(2).split(" ").map(Path(_))), args = args(3) match{ case "" => Nil case x => x.split(" ").toList } )(new PrintLogger( args(5) == "true", @@ -69,8 +70,8 @@ object TestRunner { System.exit(0) } def apply(frameworkName: String, - entireClasspath: Seq[Path], - testClassfilePath: Seq[Path], + entireClasspath: OSet[Path], + testClassfilePath: OSet[Path], args: Seq[String]) (implicit ctx: LogCtx): (String, Seq[Result]) = { val outerClassLoader = getClass.getClassLoader diff --git a/scalalib/src/main/scala/mill/scalalib/publish/Ivy.scala b/scalalib/src/main/scala/mill/scalalib/publish/Ivy.scala index ff21c9ac..288b63d0 100644 --- a/scalalib/src/main/scala/mill/scalalib/publish/Ivy.scala +++ b/scalalib/src/main/scala/mill/scalalib/publish/Ivy.scala @@ -1,5 +1,7 @@ package mill.scalalib.publish +import mill.util.Loose.OSet + import scala.xml.PrettyPrinter object Ivy { @@ -8,7 +10,7 @@ object Ivy { def apply( artifact: Artifact, - dependencies: Seq[Dependency] + dependencies: OSet[Dependency] ): String = { val xml = diff --git a/scalalib/src/main/scala/mill/scalalib/publish/Pom.scala b/scalalib/src/main/scala/mill/scalalib/publish/Pom.scala index 32ad036a..c1ce3e2a 100644 --- a/scalalib/src/main/scala/mill/scalalib/publish/Pom.scala +++ b/scalalib/src/main/scala/mill/scalalib/publish/Pom.scala @@ -1,5 +1,7 @@ package mill.scalalib.publish +import mill.util.Loose.OSet + import scala.xml.{Elem, NodeSeq, PrettyPrinter} object Pom { @@ -8,7 +10,7 @@ object Pom { //TODO - not only jar packaging support? def apply(artifact: Artifact, - dependencies: Seq[Dependency], + dependencies: OSet[Dependency], name: String, pomSettings: PomSettings): String = { val xml = diff --git a/scalalib/src/test/scala/mill/scalalib/ResolveDepsTests.scala b/scalalib/src/test/scala/mill/scalalib/ResolveDepsTests.scala index c5a05d02..c4404fe6 100644 --- a/scalalib/src/test/scala/mill/scalalib/ResolveDepsTests.scala +++ b/scalalib/src/test/scala/mill/scalalib/ResolveDepsTests.scala @@ -4,34 +4,35 @@ import coursier.Cache import coursier.maven.MavenRepository import mill.eval.Result.{Failure, Success} import mill.eval.{PathRef, Result} +import mill.util.Loose.OSet import utest._ object ResolveDepsTests extends TestSuite { val repos = Seq(Cache.ivy2Local, MavenRepository("https://repo1.maven.org/maven2")) - def evalDeps(deps: Seq[Dep]): Result[Seq[PathRef]] = Lib.resolveDependencies(repos, "2.12.4", "2.12", deps) + def evalDeps(deps: OSet[Dep]): Result[OSet[PathRef]] = Lib.resolveDependencies(repos, "2.12.4", "2.12", deps) val tests = Tests { 'resolveValidDeps - { - val deps = Seq(Dep("com.lihaoyi", "pprint", "0.5.3")) + val deps = OSet(Dep("com.lihaoyi", "pprint", "0.5.3")) val Success(paths) = evalDeps(deps) assert(paths.nonEmpty) } 'errOnInvalidOrgDeps - { - val deps = Seq(Dep("xxx.yyy.invalid", "pprint", "0.5.3")) + val deps = OSet(Dep("xxx.yyy.invalid", "pprint", "0.5.3")) val Failure(errMsg) = evalDeps(deps) assert(errMsg.contains("xxx.yyy.invalid")) } 'errOnInvalidVersionDeps - { - val deps = Seq(Dep("com.lihaoyi", "pprint", "invalid.version.num")) + val deps = OSet(Dep("com.lihaoyi", "pprint", "invalid.version.num")) val Failure(errMsg) = evalDeps(deps) assert(errMsg.contains("invalid.version.num")) } 'errOnPartialSuccess - { - val deps = Seq(Dep("com.lihaoyi", "pprint", "0.5.3"), Dep("fake", "fake", "fake")) + val deps = OSet(Dep("com.lihaoyi", "pprint", "0.5.3"), Dep("fake", "fake", "fake")) val Failure(errMsg) = evalDeps(deps) assert(errMsg.contains("fake")) } -- cgit v1.2.3