Skip to content

Commit b5fcec7

Browse files
authored
Merge pull request #3221 from Gedochao/maintenance/watch-improvements-2
Ensure resource directories passed via a using directive aren't ignored in `--watch` mode
2 parents fd960bb + 40753eb commit b5fcec7

File tree

3 files changed

+84
-25
lines changed

3 files changed

+84
-25
lines changed

modules/build/src/main/scala/scala/build/CrossSources.scala

+22-13
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,19 @@ object CrossSources {
273273
)
274274
}).flatten
275275

276+
val resourceDirectoriesFromDirectives = {
277+
val resourceDirsFromCli =
278+
allInputs.elements.flatMap { case rd: ResourceDirectory => Some(rd.path); case _ => None }
279+
val resourceDirsFromBuildOptions: Seq[os.Path] =
280+
buildOptions.flatMap(_.value.classPathOptions.resourcesDir).distinct
281+
resourceDirsFromBuildOptions
282+
.filter(!resourceDirsFromCli.contains(_))
283+
.map(ResourceDirectory(_))
284+
}
285+
val finalInputs = allInputs.add(resourceDirectoriesFromDirectives)
286+
276287
val defaultMainElemPath = for {
277-
defaultMainElem <- allInputs.defaultMainClassElement
288+
defaultMainElem <- finalInputs.defaultMainClassElement
278289
} yield defaultMainElem.path
279290

280291
val pathsWithDirectivePositions
@@ -284,7 +295,7 @@ object CrossSources {
284295
val baseReqs0 = baseReqs(d.scopePath)
285296
WithBuildRequirements(
286297
d.requirements.fold(baseReqs0)(_ orElse baseReqs0),
287-
(d.path, d.path.relativeTo(allInputs.workspace))
298+
(d.path, d.path.relativeTo(finalInputs.workspace))
288299
) -> d.directivesPositions
289300
}
290301
val inMemoryWithDirectivePositions
@@ -309,7 +320,7 @@ object CrossSources {
309320
}
310321

311322
val resourceDirs: Seq[WithBuildRequirements[os.Path]] =
312-
resolveResourceDirs(allInputs, preprocessedSources)
323+
resolveResourceDirs(finalInputs, preprocessedSources)
313324

314325
lazy val allPathsWithDirectivesByScope: Map[Scope, Seq[(os.Path, Position.File)]] =
315326
(pathsWithDirectivePositions ++ inMemoryWithDirectivePositions ++ unwrappedScriptsWithDirectivePositions)
@@ -362,17 +373,15 @@ object CrossSources {
362373
val paths = pathsWithDirectivePositions.map(_._1)
363374
val inMemory = inMemoryWithDirectivePositions.map(_._1)
364375
val unwrappedScripts = unwrappedScriptsWithDirectivePositions.map(_._1)
365-
(
366-
CrossSources(
367-
paths,
368-
inMemory,
369-
defaultMainElemPath,
370-
resourceDirs,
371-
buildOptions,
372-
unwrappedScripts
373-
),
374-
allInputs
376+
val crossSources = CrossSources(
377+
paths,
378+
inMemory,
379+
defaultMainElemPath,
380+
resourceDirs,
381+
buildOptions,
382+
unwrappedScripts
375383
)
384+
crossSources -> finalInputs
376385
}
377386

378387
/** @return

modules/integration/src/test/scala/scala/cli/integration/RunTestDefinitions.scala

+20-12
Original file line numberDiff line numberDiff line change
@@ -560,8 +560,10 @@ abstract class RunTestDefinitions
560560
forbiddenDirTest()
561561
}
562562

563-
private def resourcesInputs(directive: String = "") = {
564-
val resourceContent = "Hello from resources"
563+
protected def resourcesInputs(
564+
directive: String = "",
565+
resourceContent: String = "Hello from resources"
566+
): TestInputs =
565567
TestInputs(
566568
os.rel / "src" / "proj" / "resources" / "test" / "data" -> resourceContent,
567569
os.rel / "src" / "proj" / "Test.scala" ->
@@ -571,24 +573,30 @@ abstract class RunTestDefinitions
571573
| val cl = Thread.currentThread().getContextClassLoader
572574
| val is = cl.getResourceAsStream("test/data")
573575
| val content = scala.io.Source.fromInputStream(is)(scala.io.Codec.UTF8).mkString
574-
| assert(content == "$resourceContent")
576+
| println(content)
575577
| }
576578
|}
577579
|""".stripMargin
578580
)
579-
}
580581

581-
test("resources") {
582-
resourcesInputs().fromRoot { root =>
583-
os.proc(TestUtil.cli, "run", "src", "--resource-dirs", "./src/proj/resources").call(cwd =
584-
root
585-
)
582+
test("resources via command line") {
583+
val expectedMessage = "hello"
584+
resourcesInputs(resourceContent = expectedMessage).fromRoot { root =>
585+
val res = os.proc(TestUtil.cli, "run", "src", "--resource-dirs", "./src/proj/resources")
586+
.call(cwd = root)
587+
expect(res.out.trim() == expectedMessage)
586588
}
587589
}
588590
test("resources via directive") {
589-
resourcesInputs("//> using resourceDirs \"./resources\"").fromRoot { root =>
590-
os.proc(TestUtil.cli, "run", ".").call(cwd = root)
591-
}
591+
val expectedMessage = "hello"
592+
resourcesInputs(
593+
directive = "//> using resourceDirs \"./resources\"",
594+
resourceContent = expectedMessage
595+
)
596+
.fromRoot { root =>
597+
val res = os.proc(TestUtil.cli, "run", ".").call(cwd = root)
598+
expect(res.out.trim() == expectedMessage)
599+
}
592600
}
593601

594602
def argsAsIsTest(): Unit = {

modules/integration/src/test/scala/scala/cli/integration/RunWithWatchTestDefinitions.scala

+42
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,18 @@ trait RunWithWatchTestDefinitions { _: RunTestDefinitions =>
4242
TestInputs(inputPath -> code(expectedMessage1)),
4343
code(expectedMessage2)
4444
)
45+
}, {
46+
val inputPath = os.rel / "Main.java"
47+
def code(message: String) = s"""public class Main {
48+
| public static void main(String[] args) {
49+
| System.out.println("$message");
50+
| }
51+
|}""".stripMargin
52+
(
53+
inputPath,
54+
TestInputs(inputPath -> code(expectedMessage1)),
55+
code(expectedMessage2)
56+
)
4557
}, {
4658
val inputPath = os.rel / "markdown.md"
4759
def code(message: String) =
@@ -296,4 +308,34 @@ trait RunWithWatchTestDefinitions { _: RunTestDefinitions =>
296308
}
297309
}
298310
}
311+
312+
for {
313+
useDirective <- Seq(false, true)
314+
// TODO make this pass reliably on Mac CI
315+
if !Properties.isMac || !TestUtil.isCI
316+
directive = if (useDirective) "//> using resourceDirs ./resources" else ""
317+
resourceOptions = if (useDirective) Nil else Seq("--resource-dirs", "./src/proj/resources")
318+
title = if (useDirective) "directive" else "command line"
319+
} test(s"resources via $title with --watch") {
320+
val expectedMessage1 = "Hello"
321+
val expectedMessage2 = "world"
322+
resourcesInputs(directive = directive, resourceContent = expectedMessage1)
323+
.fromRoot { root =>
324+
TestUtil.withProcessWatching(
325+
os.proc(TestUtil.cli, "run", "src", "--watch", resourceOptions, extraOptions)
326+
.spawn(cwd = root, stderr = os.Pipe)
327+
) { (proc, timeout, ec) =>
328+
val output1 = TestUtil.readLine(proc.stdout, ec, timeout)
329+
expect(output1 == expectedMessage1)
330+
proc.printStderrUntilRerun(timeout)(ec)
331+
val Some((resourcePath, newResourceContent)) =
332+
resourcesInputs(directive = directive, resourceContent = expectedMessage2)
333+
.files
334+
.find(_._1.toString.contains("resources"))
335+
os.write.over(root / resourcePath, newResourceContent)
336+
val output2 = TestUtil.readLine(proc.stdout, ec, timeout)
337+
expect(output2 == expectedMessage2)
338+
}
339+
}
340+
}
299341
}

0 commit comments

Comments
 (0)