From 7038a03c0c44e8dd7b5bb182ebd24859d16a15f7 Mon Sep 17 00:00:00 2001 From: Piotr Chabelski Date: Mon, 24 Apr 2023 09:23:41 +0200 Subject: [PATCH] Support declaring test custom jars from the main scope --- .../preprocessing/ScalaPreprocessor.scala | 2 +- .../preprocessing/directives/CustomJar.scala | 36 +++++++-- .../cli/integration/RunTestDefinitions.scala | 74 +++++++++++++++++++ website/docs/reference/directives.md | 2 + .../reference/scala-command/directives.md | 2 + 5 files changed, 107 insertions(+), 9 deletions(-) diff --git a/modules/build/src/main/scala/scala/build/preprocessing/ScalaPreprocessor.scala b/modules/build/src/main/scala/scala/build/preprocessing/ScalaPreprocessor.scala index 641742e359..a09f003a07 100644 --- a/modules/build/src/main/scala/scala/build/preprocessing/ScalaPreprocessor.scala +++ b/modules/build/src/main/scala/scala/build/preprocessing/ScalaPreprocessor.scala @@ -67,7 +67,6 @@ case object ScalaPreprocessor extends Preprocessor { val usingDirectiveHandlers: Seq[DirectiveHandler[BuildOptions]] = Seq[DirectiveHandler[_ <: HasBuildOptions]]( - directives.CustomJar.handler, directives.JavaHome.handler, directives.Jvm.handler, directives.MainClass.handler, @@ -89,6 +88,7 @@ case object ScalaPreprocessor extends Preprocessor { val usingDirectiveWithReqsHandlers : Seq[DirectiveHandler[List[WithBuildRequirements[BuildOptions]]]] = Seq[DirectiveHandler[_ <: HasBuildOptionsWithRequirements]]( + directives.CustomJar.handler, directives.Dependency.handler, directives.JavaOptions.handler, directives.JavacOptions.handler, diff --git a/modules/directives/src/main/scala/scala/build/preprocessing/directives/CustomJar.scala b/modules/directives/src/main/scala/scala/build/preprocessing/directives/CustomJar.scala index 4ddcf2c631..a608184afc 100644 --- a/modules/directives/src/main/scala/scala/build/preprocessing/directives/CustomJar.scala +++ b/modules/directives/src/main/scala/scala/build/preprocessing/directives/CustomJar.scala @@ -1,9 +1,10 @@ package scala.build.preprocessing.directives -import scala.build.Ops._ +import scala.build.Ops.* import scala.build.directives.* import scala.build.errors.{BuildException, CompositeBuildException, WrongJarPathError} -import scala.build.options.{BuildOptions, ClassPathOptions} +import scala.build.options.{BuildOptions, ClassPathOptions, Scope, WithBuildRequirements} import scala.build.preprocessing.ScopePath +import scala.build.preprocessing.directives.CustomJar.buildOptions import scala.build.{Logger, Positioned} import scala.cli.commands.SpecificationLevel import scala.util.{Failure, Success, Try} @@ -11,6 +12,8 @@ import scala.util.{Failure, Success, Try} @DirectiveGroupName("Custom JAR") @DirectiveExamples( "//> using jar \"/Users/alexandre/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/com/chuusai/shapeless_2.13/2.3.7/shapeless_2.13-2.3.7.jar\"" +) @DirectiveExamples( + "//> using test.jar \"/Users/alexandre/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/com/chuusai/shapeless_2.13/2.3.7/shapeless_2.13-2.3.7.jar\"" ) @DirectiveUsage( "`//> using jar `_path_ | `//> using jars `_path1_, _path2_ …", @@ -23,9 +26,30 @@ import scala.util.{Failure, Success, Try} final case class CustomJar( @DirectiveName("jars") jar: DirectiveValueParser.WithScopePath[List[Positioned[String]]] = + DirectiveValueParser.WithScopePath.empty(Nil), + @DirectiveName("test.jar") + @DirectiveName("test.jars") + testJar: DirectiveValueParser.WithScopePath[List[Positioned[String]]] = DirectiveValueParser.WithScopePath.empty(Nil) -) extends HasBuildOptions { - def buildOptions: Either[BuildException, BuildOptions] = { +) extends HasBuildOptionsWithRequirements { + override def buildOptionsWithRequirements + : Either[BuildException, List[WithBuildRequirements[BuildOptions]]] = + Seq( + buildOptions(jar).map(_.withEmptyRequirements), + buildOptions(testJar).map(_.withScopeRequirement(Scope.Test)) + ) + .sequence + .left + .map(CompositeBuildException(_)) + .map(_.toList) + +} + +object CustomJar { + val handler: DirectiveHandler[CustomJar] = DirectiveHandler.derive + + def buildOptions(jar: DirectiveValueParser.WithScopePath[List[Positioned[String]]]) + : Either[BuildException, BuildOptions] = { val cwd = jar.scopePath jar.value .map { posPathStr => @@ -48,7 +72,3 @@ final case class CustomJar( } } } - -object CustomJar { - val handler: DirectiveHandler[CustomJar] = DirectiveHandler.derive -} diff --git a/modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala index 324cca877b..3dd506f0a8 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala @@ -1253,4 +1253,78 @@ abstract class RunTestDefinitions(val scalaVersionOpt: Option[String]) .call(cwd = root, stderr = os.Pipe) } } + test("declare test scope custom jar from main scope") { + val projectFile = "project.scala" + val testMessageFile = "TestMessage.scala" + val mainMessageFile = "MainMessage.scala" + val validMainFile = "ValidMain.scala" + val invalidMainFile = "InvalidMain.scala" + val testFile = "Tests.test.scala" + val expectedMessage1 = "Hello" + val expectedMessage2 = " world!" + val jarPathsWithFiles @ Seq((mainMessageJar, _), (testMessageJar, _)) = + Seq( + os.rel / "MainMessage.jar" -> mainMessageFile, + os.rel / "TestMessage.jar" -> testMessageFile + ) + TestInputs( + os.rel / projectFile -> + s"""//> using jar "$mainMessageJar" + |//> using test.jar "$testMessageJar" + |//> using test.dep "org.scalameta::munit::0.7.29" + |""".stripMargin, + os.rel / mainMessageFile -> + """case class MainMessage(value: String) + |""".stripMargin, + os.rel / testMessageFile -> + """case class TestMessage(value: String) + |""".stripMargin, + os.rel / invalidMainFile -> + s"""object InvalidMain extends App { + | println(TestMessage("$expectedMessage1").value) + |} + |""".stripMargin, + os.rel / validMainFile -> + s"""object ValidMain extends App { + | println(MainMessage("$expectedMessage1").value) + |} + |""".stripMargin, + os.rel / testFile -> + s"""class Tests extends munit.FunSuite { + | val msg1 = MainMessage("$expectedMessage1").value + | val msg2 = TestMessage("$expectedMessage2").value + | val testName = msg1 + msg2 + | test(testName) { + | assert(1 + 1 == 2) + | } + |} + |""".stripMargin + ).fromRoot { root => + // package the MainMessage and TestMessage jars + for ((jarPath, sourcePath) <- jarPathsWithFiles) + os.proc( + TestUtil.cli, + "--power", + "package", + sourcePath, + "--library", + "-o", + jarPath, + extraOptions + ) + .call(cwd = root) + // running `invalidMainFile` should fail, as it's in the main scope and depends on the test scope jar + val res1 = os.proc(TestUtil.cli, "run", projectFile, invalidMainFile) + .call(cwd = root, check = false) + expect(res1.exitCode == 1) + // running `validMainFile` should succeed, since it only depends on the main scope jar + val res2 = os.proc(TestUtil.cli, "run", projectFile, validMainFile) + .call(cwd = root) + expect(res2.out.trim() == expectedMessage1) + // test scope should have access to both main and test deps + val res3 = os.proc(TestUtil.cli, "test", projectFile, testFile) + .call(cwd = root, stderr = os.Pipe) + expect(res3.out.trim().contains(s"$expectedMessage1$expectedMessage2")) + } + } } diff --git a/website/docs/reference/directives.md b/website/docs/reference/directives.md index 09a319f85d..711ae15147 100644 --- a/website/docs/reference/directives.md +++ b/website/docs/reference/directives.md @@ -40,6 +40,8 @@ Manually add JAR(s) to the class path #### Examples `//> using jar "/Users/alexandre/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/com/chuusai/shapeless_2.13/2.3.7/shapeless_2.13-2.3.7.jar"` +`//> using test.jar "/Users/alexandre/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/com/chuusai/shapeless_2.13/2.3.7/shapeless_2.13-2.3.7.jar"` + ### Custom sources Manually add sources to the project diff --git a/website/docs/reference/scala-command/directives.md b/website/docs/reference/scala-command/directives.md index 063c63bc59..49131d76c6 100644 --- a/website/docs/reference/scala-command/directives.md +++ b/website/docs/reference/scala-command/directives.md @@ -110,6 +110,8 @@ Manually add JAR(s) to the class path #### Examples `//> using jar "/Users/alexandre/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/com/chuusai/shapeless_2.13/2.3.7/shapeless_2.13-2.3.7.jar"` +`//> using test.jar "/Users/alexandre/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/com/chuusai/shapeless_2.13/2.3.7/shapeless_2.13-2.3.7.jar"` + ### Custom sources Manually add sources to the project