Skip to content

Commit 4206b76

Browse files
Watch the artifact files for changes too
So that users doing a publishLocal and using it from a watched Scala CLI project get their Scala CLI build re-run upon newly locally published stuff, for example.
1 parent e2453db commit 4206b76

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

modules/build/src/main/scala/scala/build/Build.scala

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,26 @@ object Build {
713713
}
714714
}
715715
}
716+
717+
val artifacts = res
718+
.map { builds =>
719+
def artifacts(build: Build): Seq[os.Path] =
720+
build.successfulOpt.toSeq.flatMap(_.artifacts.classPath)
721+
val main = artifacts(builds.main)
722+
val test = builds.get(Scope.Test).map(artifacts).getOrElse(Nil)
723+
(main ++ test).distinct
724+
}
725+
.getOrElse(Nil)
726+
for (artifact <- artifacts) {
727+
val depth = if (os.isFile(artifact)) -1 else Int.MaxValue
728+
val watcher0 = watcher.newWatcher()
729+
watcher0.register(artifact.toNIO, depth)
730+
watcher0.addObserver {
731+
onChangeBufferedObserver { _ =>
732+
watcher.schedule()
733+
}
734+
}
735+
}
716736
}
717737

718738
try doWatch()

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

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package scala.cli.integration
22

33
import com.eed3si9n.expecty.Expecty.expect
44

5+
import scala.concurrent.ExecutionContext
6+
import scala.concurrent.duration.Duration
57
import scala.util.Properties
68

79
class RunTestsDefault extends RunTestDefinitions(scalaVersionOpt = None) {
@@ -64,4 +66,67 @@ class RunTestsDefault extends RunTestDefinitions(scalaVersionOpt = None) {
6466
}
6567
}
6668

69+
test("watch artifacts") {
70+
val libSourcePath = os.rel / "lib" / "Messages.scala"
71+
def libSource(hello: String) =
72+
s"""//> using publish.organization "test-org"
73+
|//> using publish.name "messages"
74+
|//> using publish.version "0.1.0"
75+
|
76+
|package messages
77+
|
78+
|object Messages {
79+
| def hello(name: String) = s"$hello $$name"
80+
|}
81+
|""".stripMargin
82+
val inputs = TestInputs(
83+
libSourcePath -> libSource("Hello"),
84+
os.rel / "app" / "TestApp.scala" ->
85+
"""//> using lib "test-org::messages:0.1.0"
86+
|
87+
|package testapp
88+
|
89+
|import messages.Messages
90+
|
91+
|@main
92+
|def run(): Unit =
93+
| println(Messages.hello("user"))
94+
|""".stripMargin
95+
)
96+
inputs.fromRoot { root =>
97+
val testRepo = root / "test-repo"
98+
99+
def publishLib(): Unit =
100+
os.proc(TestUtil.cli, "publish", "--publish-repo", testRepo, "lib")
101+
.call(cwd = root)
102+
103+
publishLib()
104+
105+
val proc = os.proc(TestUtil.cli, "run", "app", "-w", "-r", testRepo.toNIO.toUri.toASCIIString)
106+
.spawn(cwd = root)
107+
108+
try
109+
TestUtil.withThreadPool("watch-artifacts-test", 2) { pool =>
110+
val timeout = Duration("20 seconds")
111+
val ec = ExecutionContext.fromExecutorService(pool)
112+
113+
val output = TestUtil.readLine(proc.stdout, ec, timeout)
114+
expect(output == "Hello user")
115+
116+
os.write.over(root / libSourcePath, libSource("Hola"))
117+
publishLib()
118+
119+
val secondOutput = TestUtil.readLine(proc.stdout, ec, timeout)
120+
expect(secondOutput == "Hola user")
121+
}
122+
finally
123+
if (proc.isAlive()) {
124+
proc.destroy()
125+
Thread.sleep(200L)
126+
if (proc.isAlive())
127+
proc.destroyForcibly()
128+
}
129+
}
130+
}
131+
67132
}

0 commit comments

Comments
 (0)