diff --git a/build.sbt b/build.sbt index 7a981fa5c..f104ee403 100644 --- a/build.sbt +++ b/build.sbt @@ -158,6 +158,7 @@ lazy val cli = project shared, dontPublishIn("2.10", "2.12"), coursierPrefix, + unmanagedResources.in(Test) += packageBin.in(bootstrap).in(Compile).value, libs ++= { if (scalaBinaryVersion.value == "2.11") Seq( diff --git a/cli/src/main/scala-2.11/coursier/cli/Bootstrap.scala b/cli/src/main/scala-2.11/coursier/cli/Bootstrap.scala index 5155de2ce..5ff00ac1d 100644 --- a/cli/src/main/scala-2.11/coursier/cli/Bootstrap.scala +++ b/cli/src/main/scala-2.11/coursier/cli/Bootstrap.scala @@ -11,7 +11,7 @@ import caseapp._ import coursier.cli.util.Zip import coursier.internal.FileUtil -final case class Bootstrap( +case class Bootstrap( @Recurse artifactOptions: ArtifactOptions, @Recurse @@ -96,26 +96,32 @@ final case class Bootstrap( options.isolated.targets.foldLeft((Vector.empty[String], Map.empty[String, (Seq[String], Seq[File])])) { case ((done, acc), target) => val subRes = helper.res.subset(isolatedDeps.getOrElse(target, Nil).toSet) - val subArtifacts = subRes.artifacts.map(_.url) - val filteredSubArtifacts = subArtifacts.diff(done) + val (done0, subUrls, subFiles) = + if (options.standalone) { + val subFiles0 = helper.fetch( + sources = false, + javadoc = false, + artifactTypes = artifactOptions.artifactTypes(sources = false, javadoc = false), + subset = isolatedDeps.getOrElse(target, Seq.empty).toSet + ) - def subFiles0 = helper.fetch( - sources = false, - javadoc = false, - artifactTypes = artifactOptions.artifactTypes(sources = false, javadoc = false), - subset = isolatedDeps.getOrElse(target, Seq.empty).toSet - ) - - val (subUrls, subFiles) = - if (options.standalone) - (Nil, subFiles0) - else - (filteredSubArtifacts, Nil) + (done, Nil, subFiles0) + } else { + val subArtifacts0 = subRes.dependencyArtifacts.map(_._2) + val artifactTypes = artifactOptions.artifactTypes(sources = false, javadoc = false) + val subArtifacts = + if (artifactTypes("*")) + subArtifacts0 + else + subArtifacts0.filter(a => artifactTypes(a.`type`)) + val filteredSubArtifacts = subArtifacts.map(_.url).diff(done) + (done ++ filteredSubArtifacts, filteredSubArtifacts, Nil) + } val updatedAcc = acc + (target -> (subUrls, subFiles)) - (done ++ filteredSubArtifacts, updatedAcc) + (done0, updatedAcc) } val (urls, files) = diff --git a/cli/src/test/scala-2.11/coursier/cli/CliIntegrationTest.scala b/cli/src/test/scala-2.11/coursier/cli/CliIntegrationTest.scala index c751f1904..c8626e0a9 100644 --- a/cli/src/test/scala-2.11/coursier/cli/CliIntegrationTest.scala +++ b/cli/src/test/scala-2.11/coursier/cli/CliIntegrationTest.scala @@ -1,6 +1,7 @@ package coursier.cli -import java.io.{File, FileWriter} +import java.io._ +import java.util.zip.ZipInputStream import argonaut.Argonaut._ import coursier.cli.util.{DepNode, ReportNode} @@ -414,4 +415,70 @@ class CliIntegrationTest extends FlatSpec { assert(node.dependencies.exists(_.coord.startsWith("org.scala-lang:scala-library:2.10."))) assert(!node.dependencies.exists(_.coord.startsWith("org.scala-lang:scala-library:2.11."))) } + + "bootstrap" should "not add POMs to the classpath" in withFile() { + + def zipEntryContent(zis: ZipInputStream, path: String): Array[Byte] = { + val e = zis.getNextEntry + if (e == null) + throw new NoSuchElementException(s"Entry $path in zip file") + else if (e.getName == path) + coursier.Platform.readFullySync(zis) + else + zipEntryContent(zis, path) + } + + (bootstrapFile, _) => + val artifactOptions = ArtifactOptions() + val common = CommonOptions( + repository = List("bintray:scalameta/maven") + ) + val isolatedLoaderOptions = IsolatedLoaderOptions( + isolateTarget = List("foo"), + isolated = List("foo:org.scalameta:trees_2.12:1.7.0") + ) + val bootstrapOptions = BootstrapOptions( + output = bootstrapFile.getPath, + isolated = isolatedLoaderOptions, + force = true + ) + + val bootstrap = new Bootstrap(artifactOptions, bootstrapOptions) with TestOnlyExtraArgsApp + bootstrap.setRemainingArgs(Seq("com.geirsson:scalafmt-cli_2.12:1.4.0"), Seq()) + bootstrap.apply() + + var fis: InputStream = null + + val content = try { + fis = new FileInputStream(bootstrapFile) + coursier.Platform.readFullySync(fis) + } finally { + if (fis != null) fis.close() + } + + val actualContent = { + val header = Seq[Byte](0x50, 0x4b, 0x03, 0x04) + val idx = content.indexOfSlice(header) + if (idx < 0) + throw new Exception(s"ZIP header not found in ${bootstrapFile.getPath}") + else + content.drop(idx) + } + + val zis = new ZipInputStream(new ByteArrayInputStream(actualContent)) + + val lines = new String(zipEntryContent(zis, "bootstrap-isolation-foo-jar-urls"), "UTF-8").lines.toVector + + val extensions = lines + .map { l => + val idx = l.lastIndexOf('.') + if (idx < 0) + l + else + l.drop(idx + 1) + } + .toSet + + assert(extensions == Set("jar")) + } }