diff --git a/modules/cli-tests/src/main/scala/coursier/clitests/LaunchTests.scala b/modules/cli-tests/src/main/scala/coursier/clitests/LaunchTests.scala index f2237f7cc3..7d90e6be5c 100644 --- a/modules/cli-tests/src/main/scala/coursier/clitests/LaunchTests.scala +++ b/modules/cli-tests/src/main/scala/coursier/clitests/LaunchTests.scala @@ -6,7 +6,7 @@ import utest._ import scala.util.Properties -abstract class LaunchTests extends TestSuite { +abstract class LaunchTests extends TestSuite with LauncherOptions { def launcher: String @@ -175,5 +175,38 @@ abstract class LaunchTests extends TestSuite { assert(output.containsSlice(expectedFirstLines)) } } + + test("extra jars with properties") { + if (acceptsJOptions) + extraJarsWithProperties() + else + "Disabled" + } + def extraJarsWithProperties(): Unit = { + val files = os.proc(launcher, "fetch", "org.scala-lang:scala3-compiler_3:3.1.3") + .call() + .out.lines() + .map(os.Path(_, os.pwd)) + TestUtil.withTempDir { tmpDir0 => + val tmpDir = os.Path(tmpDir0, os.pwd) + val dir = tmpDir / "cp" + for (f <- files) + os.copy.into(f, dir, createFolders = true) + val output = os.proc( + launcher, + s"-J-Dthe.directory=$dir", + "launch", + "--extra-jars", + s"$${the.directory}/*", + "-M", + "dotty.tools.MainGenericCompiler" + ).call(mergeErrIntoOut = true).out.lines() + val expectedFirstLines = Seq( + "Usage: scalac ", + "where possible standard options include:" + ) + assert(output.containsSlice(expectedFirstLines)) + } + } } } diff --git a/modules/cli-tests/src/test/scala/coursier/clitests/PackLaunchTests.scala b/modules/cli-tests/src/test/scala/coursier/clitests/PackLaunchTests.scala index c4235062a9..929df13e2d 100644 --- a/modules/cli-tests/src/test/scala/coursier/clitests/PackLaunchTests.scala +++ b/modules/cli-tests/src/test/scala/coursier/clitests/PackLaunchTests.scala @@ -1,5 +1,5 @@ package coursier.clitests -object PackLaunchTests extends LaunchTests { +object PackLaunchTests extends LaunchTests with PackLauncherOptions { val launcher = LauncherTestUtil.launcher } diff --git a/modules/cli/src/main/scala/coursier/cli/params/SharedLaunchParams.scala b/modules/cli/src/main/scala/coursier/cli/params/SharedLaunchParams.scala index 8bc9f1c26d..9fd6ffa2a1 100644 --- a/modules/cli/src/main/scala/coursier/cli/params/SharedLaunchParams.scala +++ b/modules/cli/src/main/scala/coursier/cli/params/SharedLaunchParams.scala @@ -79,7 +79,7 @@ object SharedLaunchParams { } // check if those exist? - val extraJars = options.extraJars.flatMap(ClassPathUtil.classPath) + val extraJars = options.extraJars.flatMap(ClassPathUtil.classPath(_, sys.props.get)) (resolveV, artifactV, sharedLoaderV, propertiesV).mapN { (resolve, artifact, sharedLoader, properties) => diff --git a/modules/cli/src/main/scala/coursier/cli/util/ClassPathUtil.scala b/modules/cli/src/main/scala/coursier/cli/util/ClassPathUtil.scala index 60b5fa5058..331b8a0c94 100644 --- a/modules/cli/src/main/scala/coursier/cli/util/ClassPathUtil.scala +++ b/modules/cli/src/main/scala/coursier/cli/util/ClassPathUtil.scala @@ -2,13 +2,35 @@ package coursier.cli.util import java.io.File import java.nio.file.{Files, Path, Paths} +import java.util.regex.{Matcher, Pattern} import scala.collection.JavaConverters._ object ClassPathUtil { - def classPath(input: String): Seq[Path] = + private val propertyRegex = Pattern.compile( + Pattern.quote("${") + "[^" + Pattern.quote("{[()]}") + "]*" + Pattern.quote("}") + ) + + def classPath(input: String, getProperty: String => Option[String]): Seq[Path] = input.split(File.pathSeparator).filter(_.nonEmpty).flatMap { elem => + val processedElem = { + var value = elem + var matcher: Matcher = null + + while ({ + matcher = propertyRegex.matcher(value) + matcher.find() + }) { + val start = matcher.start(0) + val end = matcher.end(0) + val subKey = value.substring(start + 2, end - 1) + val subValue = getProperty(subKey).getOrElse("") + value = value.substring(0, start) + subValue + value.substring(end) + } + + value + } def allJarsOf(dir: Path): Seq[Path] = Files.list(dir) .iterator @@ -19,16 +41,16 @@ object ClassPathUtil { name.substring(name.length() - ".jar".length).equalsIgnoreCase(".jar") } .toVector - if (elem.endsWith("/*")) { - val dir = Paths.get(elem.stripSuffix("/*")) + if (processedElem.endsWith("/*")) { + val dir = Paths.get(processedElem.stripSuffix("/*")) allJarsOf(dir) } - else if (elem.endsWith("/*.jar")) { - val dir = Paths.get(elem.stripSuffix("/*.jar")) + else if (processedElem.endsWith("/*.jar")) { + val dir = Paths.get(processedElem.stripSuffix("/*.jar")) allJarsOf(dir) } else - Seq(Paths.get(elem)) + Seq(Paths.get(processedElem)) } }