From 130a955d53e62016ea0c98ec34caa2c1941ae5f1 Mon Sep 17 00:00:00 2001 From: Piotr Chabelski Date: Fri, 4 Oct 2024 16:06:06 +0200 Subject: [PATCH] Ensure resource directories passed via a `using` directive aren't ignored in `--watch` mode --- .../src/main/scala/scala/build/Build.scala | 19 +++++++++++-- .../RunWithWatchTestDefinitions.scala | 28 +++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/modules/build/src/main/scala/scala/build/Build.scala b/modules/build/src/main/scala/scala/build/Build.scala index d22552c71c..73fe4a2fe5 100644 --- a/modules/build/src/main/scala/scala/build/Build.scala +++ b/modules/build/src/main/scala/scala/build/Build.scala @@ -687,10 +687,23 @@ object Build { either { val (crossSources: CrossSources, inputs0: Inputs) = value(allInputs(inputs, options, logger)) + val resourceDirectoriesFromDirectives = { + // resource directories passed via a command line option are registered as Input elements. + // however, those passed via a using directive are only passed via build options. + // TODO: refactor and clean this up + val resourceDirsFromCli = + inputs0.elements.flatMap { case rd: ResourceDirectory => Some(rd.path); case _ => None } + val latestResourceDirsFromBuildOptions: Seq[os.Path] = + crossSources.buildOptions.flatMap(_.value.classPathOptions.resourcesDir).distinct + latestResourceDirsFromBuildOptions + .filter(!resourceDirsFromCli.contains(_)) + .map(ResourceDirectory(_)) + } + val finalInputs = inputs0.add(resourceDirectoriesFromDirectives) val sharedOptions = crossSources.sharedOptions(options) val compiler: ScalaCompiler = value { compilerMaker.create( - inputs0.workspace / Constants.workspaceDirName, + finalInputs.workspace / Constants.workspaceDirName, classesDir0, buildClient, logger, @@ -698,13 +711,13 @@ object Build { ) } val docCompilerOpt: Option[ScalaCompiler] = docCompilerMakerOpt.map(_.create( - inputs0.workspace / Constants.workspaceDirName, + finalInputs.workspace / Constants.workspaceDirName, classesDir0, buildClient, logger, sharedOptions )).map(value) - (compiler, docCompilerOpt, crossSources, inputs0) + (compiler, docCompilerOpt, crossSources, finalInputs) } var res: Either[BuildException, Builds] = null diff --git a/modules/integration/src/test/scala/scala/cli/integration/RunWithWatchTestDefinitions.scala b/modules/integration/src/test/scala/scala/cli/integration/RunWithWatchTestDefinitions.scala index a298d03849..c740aa1a69 100644 --- a/modules/integration/src/test/scala/scala/cli/integration/RunWithWatchTestDefinitions.scala +++ b/modules/integration/src/test/scala/scala/cli/integration/RunWithWatchTestDefinitions.scala @@ -308,4 +308,32 @@ trait RunWithWatchTestDefinitions { _: RunTestDefinitions => } } } + + for { + useDirective <- Seq(false, true) + directive = if (useDirective) "//> using resourceDirs ./resources" else "" + resourceOptions = if (useDirective) Nil else Seq("--resource-dirs", "./src/proj/resources") + title = if (useDirective) "directive" else "command line" + } test(s"resources via $title with --watch") { + val expectedMessage1 = "Hello" + val expectedMessage2 = "world" + resourcesInputs(directive = directive, resourceContent = expectedMessage1) + .fromRoot { root => + TestUtil.withProcessWatching( + os.proc(TestUtil.cli, "run", "src", "--watch", resourceOptions, extraOptions) + .spawn(cwd = root, stderr = os.Pipe) + ) { (proc, timeout, ec) => + val output1 = TestUtil.readLine(proc.stdout, ec, timeout) + expect(output1 == expectedMessage1) + proc.printStderrUntilRerun(timeout)(ec) + val Some((resourcePath, newResourceContent)) = + resourcesInputs(directive = directive, resourceContent = expectedMessage2) + .files + .find(_._1.toString.contains("resources")) + os.write.over(root / resourcePath, newResourceContent) + val output2 = TestUtil.readLine(proc.stdout, ec, timeout) + expect(output2 == expectedMessage2) + } + } + } }