Skip to content

Commit 7123556

Browse files
authored
Merge pull request #3175 from Gedochao/maintenance/watch-using-directives
NIT Refactor existing `--watch` tests
2 parents a708ae9 + c30f908 commit 7123556

File tree

6 files changed

+282
-279
lines changed

6 files changed

+282
-279
lines changed

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

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -305,9 +305,7 @@ object Build {
305305
testDocOpt: Option[Build]
306306
)
307307

308-
def doBuild(
309-
overrideOptions: BuildOptions
310-
): Either[BuildException, NonCrossBuilds] = either {
308+
def doBuild(overrideOptions: BuildOptions): Either[BuildException, NonCrossBuilds] = either {
311309

312310
val inputs0 = updateInputs(
313311
inputs,
@@ -685,9 +683,9 @@ object Build {
685683
val threads = BuildThreads.create()
686684
val classesDir0 = classesRootDir(inputs.workspace, inputs.projectName)
687685
val info = either {
688-
val (crossSources, inputs0) = value(allInputs(inputs, options, logger))
689-
val sharedOptions = crossSources.sharedOptions(options)
690-
val compiler = value {
686+
val (crossSources: CrossSources, inputs0: Inputs) = value(allInputs(inputs, options, logger))
687+
val sharedOptions = crossSources.sharedOptions(options)
688+
val compiler: ScalaCompiler = value {
691689
compilerMaker.create(
692690
inputs0.workspace / Constants.workspaceDirName,
693691
classesDir0,
@@ -696,7 +694,7 @@ object Build {
696694
sharedOptions
697695
)
698696
}
699-
val docCompilerOpt = docCompilerMakerOpt.map(_.create(
697+
val docCompilerOpt: Option[ScalaCompiler] = docCompilerMakerOpt.map(_.create(
700698
inputs0.workspace / Constants.workspaceDirName,
701699
classesDir0,
702700
buildClient,
@@ -711,20 +709,26 @@ object Build {
711709
def run(): Unit = {
712710
try {
713711
res =
714-
info.flatMap { case (compiler, docCompilerOpt, crossSources, inputs) =>
715-
build(
716-
inputs,
717-
crossSources,
718-
options,
719-
logger,
720-
buildClient,
721-
compiler,
722-
docCompilerOpt,
723-
crossBuilds = crossBuilds,
724-
buildTests = buildTests,
725-
partial = partial,
726-
actionableDiagnostics = actionableDiagnostics
727-
)
712+
info.flatMap {
713+
case (
714+
compiler: ScalaCompiler,
715+
docCompilerOpt: Option[ScalaCompiler],
716+
crossSources: CrossSources,
717+
inputs: Inputs
718+
) =>
719+
build(
720+
inputs = inputs,
721+
crossSources = crossSources,
722+
options = options,
723+
logger = logger,
724+
buildClient = buildClient,
725+
compiler = compiler,
726+
docCompilerOpt = docCompilerOpt,
727+
crossBuilds = crossBuilds,
728+
buildTests = buildTests,
729+
partial = partial,
730+
actionableDiagnostics = actionableDiagnostics
731+
)
728732
}
729733
action(res)
730734
}
@@ -742,7 +746,7 @@ object Build {
742746

743747
def doWatch(): Unit = {
744748
val elements: Seq[Element] =
745-
if (res == null) inputs.elements
749+
if res == null then inputs.elements
746750
else
747751
res
748752
.map { builds =>
@@ -777,10 +781,7 @@ object Build {
777781
case _: Virtual =>
778782
}
779783
watcher0.addObserver {
780-
onChangeBufferedObserver { event =>
781-
if (eventFilter(event))
782-
watcher.schedule()
783-
}
784+
onChangeBufferedObserver(event => if eventFilter(event) then watcher.schedule())
784785
}
785786
}
786787

@@ -797,14 +798,10 @@ object Build {
797798
}
798799
.getOrElse(Nil)
799800
for (artifact <- artifacts) {
800-
val depth = if (os.isFile(artifact)) -1 else Int.MaxValue
801+
val depth = if os.isFile(artifact) then -1 else Int.MaxValue
801802
val watcher0 = watcher.newWatcher()
802803
watcher0.register(artifact.toNIO, depth)
803-
watcher0.addObserver {
804-
onChangeBufferedObserver { _ =>
805-
watcher.schedule()
806-
}
807-
}
804+
watcher0.addObserver(onChangeBufferedObserver(_ => watcher.schedule()))
808805
}
809806
}
810807

modules/cli/src/main/scala/scala/cli/commands/run/Run.scala

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -223,16 +223,15 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {
223223
Some(name),
224224
inputArgs
225225
)
226-
if (CommandUtils.shouldCheckUpdate)
227-
Update.checkUpdateSafe(logger)
226+
if CommandUtils.shouldCheckUpdate then Update.checkUpdateSafe(logger)
228227

229228
val configDb = ConfigDbUtils.configDb.orExit(logger)
230229
val actionableDiagnostics =
231230
options.shared.logging.verbosityOptions.actions.orElse(
232231
configDb.get(Keys.actions).getOrElse(None)
233232
)
234233

235-
if (options.sharedRun.watch.watchMode) {
234+
if options.sharedRun.watch.watchMode then {
236235

237236
/** A handle to the Runner process, used to kill the process if it's still alive when a change
238237
* occured and restarts are allowed or to wait for it if restarts are not allowed
@@ -251,20 +250,18 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {
251250
val mainThreadOpt = AtomicReference(Option.empty[Thread])
252251

253252
val watcher = Build.watch(
254-
inputs,
255-
initialBuildOptions,
256-
compilerMaker,
257-
None,
258-
logger,
253+
inputs = inputs,
254+
options = initialBuildOptions,
255+
compilerMaker = compilerMaker,
256+
docCompilerMakerOpt = None,
257+
logger = logger,
259258
crossBuilds = cross,
260259
buildTests = false,
261260
partial = None,
262261
actionableDiagnostics = actionableDiagnostics,
263262
postAction = () =>
264-
if (processOpt.get().exists(_._1.isAlive()))
265-
WatchUtil.printWatchWhileRunningMessage()
266-
else
267-
WatchUtil.printWatchMessage()
263+
if processOpt.get().exists(_._1.isAlive()) then WatchUtil.printWatchWhileRunningMessage()
264+
else WatchUtil.printWatchMessage()
268265
) { res =>
269266
for ((process, onExitProcess) <- processOpt.get()) {
270267
onExitProcess.cancel(true)
@@ -296,8 +293,7 @@ object Run extends ScalaCommand[RunOptions] with BuildCommandHelpers {
296293
(proc, onExit)
297294
}
298295
s.copyOutput(options.shared)
299-
if (options.sharedRun.watch.restart)
300-
processOpt.set(maybeProcess)
296+
if options.sharedRun.watch.restart then processOpt.set(maybeProcess)
301297
else {
302298
for ((proc, onExit) <- maybeProcess)
303299
ProcUtil.waitForProcess(proc, onExit)

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

Lines changed: 0 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ import java.io.{ByteArrayOutputStream, File}
66
import java.nio.charset.Charset
77

88
import scala.cli.integration.util.DockerServer
9-
import scala.concurrent.ExecutionContext
10-
import scala.concurrent.duration.Duration
119
import scala.io.Codec
1210
import scala.jdk.CollectionConverters.*
1311
import scala.util.Properties
@@ -1507,99 +1505,6 @@ abstract class RunTestDefinitions
15071505
}
15081506
}
15091507

1510-
test("watch with interactive, with multiple main classes") {
1511-
val fileName = "watch.scala"
1512-
1513-
val inputs = TestInputs(
1514-
os.rel / fileName ->
1515-
"""object Run1 extends App {println("Run1 launched")}
1516-
|object Run2 extends App {println("Run2 launched")}
1517-
|""".stripMargin
1518-
)
1519-
inputs.fromRoot { root =>
1520-
val confDir = root / "config"
1521-
val confFile = confDir / "test-config.json"
1522-
1523-
os.write(confFile, "{}", createFolders = true)
1524-
1525-
if (!Properties.isWin)
1526-
os.perms.set(confDir, "rwx------")
1527-
1528-
val configEnv = Map("SCALA_CLI_CONFIG" -> confFile.toString)
1529-
1530-
val proc = os.proc(TestUtil.cli, "run", "--watch", "--interactive", fileName)
1531-
.spawn(
1532-
cwd = root,
1533-
mergeErrIntoOut = true,
1534-
stdout = os.Pipe,
1535-
stdin = os.Pipe,
1536-
env = Map("SCALA_CLI_INTERACTIVE" -> "true") ++ configEnv
1537-
)
1538-
1539-
try
1540-
TestUtil.withThreadPool("run-watch-interactive-multi-main-class-test", 2) { pool =>
1541-
val timeout = Duration("60 seconds")
1542-
implicit val ec = ExecutionContext.fromExecutorService(pool)
1543-
1544-
def lineReaderIter = Iterator.continually {
1545-
val line = TestUtil.readLine(proc.stdout, ec, timeout)
1546-
println(s"Line read: $line")
1547-
line
1548-
}
1549-
1550-
def checkLinesForError(lines: Seq[String]) = munit.Assertions.assert(
1551-
!lines.exists { line =>
1552-
TestUtil.removeAnsiColors(line).contains("[error]")
1553-
},
1554-
clues(lines.toSeq)
1555-
)
1556-
1557-
def answerInteractivePrompt(id: Int) = {
1558-
val interactivePromptLines = lineReaderIter
1559-
.takeWhile(!_.startsWith("[1]" /* probably [1] Run2 or [1] No*/ ))
1560-
.toList
1561-
expect(interactivePromptLines.nonEmpty)
1562-
checkLinesForError(interactivePromptLines)
1563-
proc.stdin.write(s"$id\n")
1564-
proc.stdin.flush()
1565-
}
1566-
1567-
def analyzeRunOutput(restart: Boolean) = {
1568-
val runResultLines = lineReaderIter
1569-
.takeWhile(!_.contains("press Enter to re-run"))
1570-
.toList
1571-
expect(runResultLines.nonEmpty)
1572-
checkLinesForError(runResultLines)
1573-
if (restart)
1574-
proc.stdin.write("\n")
1575-
proc.stdin.flush()
1576-
}
1577-
1578-
// You have run the current scala-cli command with the --interactive mode turned on.
1579-
// Would you like to leave it on permanently?
1580-
answerInteractivePrompt(0)
1581-
1582-
// Found several main classes. Which would you like to run?
1583-
answerInteractivePrompt(0)
1584-
expect(TestUtil.readLine(proc.stdout, ec, timeout) == "Run1 launched")
1585-
1586-
analyzeRunOutput( /* restart */ true)
1587-
1588-
answerInteractivePrompt(1)
1589-
expect(TestUtil.readLine(proc.stdout, ec, timeout) == "Run2 launched")
1590-
1591-
analyzeRunOutput( /* restart */ false)
1592-
}
1593-
finally
1594-
if (proc.isAlive()) {
1595-
proc.destroy()
1596-
Thread.sleep(200L)
1597-
if (proc.isAlive())
1598-
proc.destroyForcibly()
1599-
}
1600-
}
1601-
}
1602-
16031508
test("decoded classNames in interactive ask") {
16041509
val fileName = "watch.scala"
16051510

0 commit comments

Comments
 (0)