Skip to content

Commit 4d62e1b

Browse files
committed
scriptrunner: use default imports, which fixes e.g. Operator usage
re joernio/joern#5558
1 parent 057a013 commit 4d62e1b

File tree

7 files changed

+53
-30
lines changed

7 files changed

+53
-30
lines changed

core/src/main/scala-3.7.1/replpp/InteractiveShell.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ package replpp
22

33
import dotty.tools.repl.State
44

5-
import scala.util.control.NoStackTrace
6-
75
object InteractiveShell {
86

97
def run(config: Config): Unit = {

core/src/main/scala/replpp/scripting/ScriptRunner.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package replpp.scripting
22

3-
import replpp.{Config, verboseEnabled}
3+
import replpp.{Colors, Config, DefaultRunBeforeLines, globalRunBeforeLines, verboseEnabled}
44
import replpp.util.ClasspathHelper
55

66
import scala.util.{Failure, Success, Try}
@@ -18,16 +18,18 @@ object ScriptRunner {
1818
def exec(config: Config): Try[Unit] = {
1919
val classpath = ClasspathHelper.create(config, quiet = true)
2020
val mainClass = "replpp.scripting.NonForkingScriptRunner"
21+
val defaultRunBeforeLines = DefaultRunBeforeLines(using Colors.BlackWhite) ++ globalRunBeforeLines
22+
val config0 = config.copy(runBefore = defaultRunBeforeLines ++ config.runBefore)
2123
val args = {
2224
val builder = Seq.newBuilder[String]
2325
if (config.remoteJvmDebugEnabled) builder += RemoteJvmDebugConfig
2426
builder ++= Seq("-classpath", classpath)
2527
builder += mainClass
26-
builder ++= config.asJavaArgs
28+
builder ++= config0.asJavaArgs
2729

2830
builder.result()
2931
}
30-
if (replpp.verboseEnabled(config))
32+
if (replpp.verboseEnabled(config0))
3133
println(s"executing `java ${args.mkString(" ")}`")
3234

3335
Process("java", args).run().exitValue() match {

core/src/test/scala/replpp/OperatorsTests.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import System.lineSeparator
1717
import scala.jdk.CollectionConverters.*
1818
Seq("this is a test", "another one").asJava #|^ "less"
1919
```
20+
21+
Note: additional tests are in 'ScriptRunnerTests'
2022
*/
2123
class OperatorsTests extends AnyWordSpec with Matchers {
2224
given Colors = Colors.BlackWhite

core/src/test/scala/replpp/scripting/ScriptRunnerTests.scala

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,19 @@ class ScriptRunnerTests extends AnyWordSpec with Matchers {
1010
if (scala.util.Properties.isWin) {
1111
info("tests were cancelled currently fail on windows - not sure why - I'm testing the `--script` mode manually for now and will replace these tests in the future")
1212
} else {
13-
"execute simple single-statement script" in {
13+
"execute a simple script" in {
1414
execTest { testOutputPath =>
15-
TestSetup(s"""java.nio.file.Files.writeString(java.nio.file.Path.of("$testOutputPath"), "iwashere-simple")""")
16-
}.get shouldBe "iwashere-simple"
15+
TestSetup(
16+
s"""
17+
|Seq("aa", "bb", "cc") #> "$testOutputPath"
18+
|"dd" #>> "$testOutputPath"
19+
|""".stripMargin)
20+
}.get shouldBe
21+
"""aa
22+
|bb
23+
|cc
24+
|dd
25+
|""".stripMargin
1726
}
1827

1928
"main entry point" in {
@@ -330,9 +339,10 @@ object ScriptRunnerTests {
330339
val scriptSrc =
331340
s"""val i = 2 + 10
332341
|println("in main/script: i=" + i)
342+
|"foo" #> "out.txt"
333343
|""".stripMargin
334344
val scriptFile = os.temp(scriptSrc).toNIO
335-
val config = Config(scriptFile = Some(scriptFile), verbose = true)
345+
val config = Config(scriptFile = Some(scriptFile))// , verbose = true)
336346
ScriptRunner.exec(config)
337347
}
338348
}

server/src/main/scala/replpp/server/EmbeddedRepl.scala

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@ class EmbeddedRepl(
2525
private val replDriver = ReplDriver(compilerArgs, new PrintStream(replOutputStream), classLoader = None)
2626

2727
private var state: State = {
28-
if (runBeforeCode.nonEmpty)
28+
if (runBeforeCode.nonEmpty) {
29+
if (verbose) logger.info(s"executing runBeforeCode: \n${runBeforeCode.mkString("\n")}")
2930
replDriver.execute(runBeforeCode)
30-
else
31+
} else
3132
replDriver.initialState
3233
}
3334

@@ -42,7 +43,9 @@ class EmbeddedRepl(
4243
def queryAsync(inputLines: IterableOnce[String]): (UUID, Future[String]) = {
4344
val uuid = UUID.randomUUID()
4445
val future = Future {
45-
state = replDriver.execute(inputLines)(using state)
46+
val lines = inputLines.iterator.toSeq
47+
if (verbose) logger.info(s"executing: \n${lines.mkString("\n")}")
48+
state = replDriver.execute(lines)(using state)
4649
readAndResetReplOutputStream()
4750
} (using singleThreadedJobExecutor)
4851

@@ -72,14 +75,17 @@ class EmbeddedRepl(
7275
logger.info("shutting down")
7376
if (runAfterCode.nonEmpty) {
7477
if (verbose) logger.info(s"executing: $runAfterCode")
75-
replDriver.execute(runAfterCode)
78+
state = replDriver.execute(runAfterCode)(using state)
79+
val output = readAndResetReplOutputStream()
80+
logger.info(output)
7681
}
7782
singleThreadedJobExecutor.shutdown()
7883
}
7984
}
8085

8186
class ReplDriver(args: Array[String], out: PrintStream, classLoader: Option[ClassLoader])
8287
extends ReplDriverBase(args, out, maxHeight = None, classLoader)(using BlackWhite) {
83-
def execute(inputLines: IterableOnce[String])(using state: State = initialState): State =
88+
def execute(inputLines: IterableOnce[String])(using state: State = initialState): State = {
8489
interpretInput(inputLines, state, pwd)
90+
}
8591
}

server/src/main/scala/replpp/server/ReplServer.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package replpp.server
22

3-
import cask.model.{Request, Response}
3+
import cask.model.Response
44
import org.slf4j.LoggerFactory
5-
import replpp.precompilePredefFiles
5+
import replpp.{Colors, DefaultRunBeforeLines, globalRunBeforeLines, precompilePredefFiles}
66
import ujson.Obj
77

88
import java.io.{PrintWriter, StringWriter}
@@ -23,7 +23,8 @@ object ReplServer {
2323

2424
val baseConfig = precompilePredefFiles(serverConfig.baseConfig)
2525
val compilerArgs = replpp.compilerArgs(baseConfig)
26-
val embeddedRepl = new EmbeddedRepl(compilerArgs, baseConfig.runBefore, baseConfig.runAfter, baseConfig.verbose)
26+
val runBeforeCode = DefaultRunBeforeLines(using Colors.BlackWhite) ++ globalRunBeforeLines ++ baseConfig.runBefore
27+
val embeddedRepl = new EmbeddedRepl(compilerArgs, runBeforeCode, baseConfig.runAfter, baseConfig.verbose)
2728
Runtime.getRuntime.addShutdownHook(new Thread(() => {
2829
logger.info("Shutting down embedded repl...")
2930
embeddedRepl.shutdown()

server/src/test/scala/replpp/server/ReplServerTests.scala

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import cask.util.Logger.Console.*
44
import castor.Context.Simple.global
55
import org.scalatest.matchers.should.Matchers
66
import org.scalatest.wordspec.AnyWordSpec
7+
import replpp.{Colors, DefaultRunBeforeLines, globalRunBeforeLines}
78
import replpp.util.{ClasspathHelper, SimpleDriver, pathAsString}
89
import requests.RequestFailedException
910
import ujson.Value.Value
@@ -97,7 +98,7 @@ class ReplServerTests extends AnyWordSpec with Matchers {
9798
val getResultResponse = getResponse(url, queryUUID)
9899
getResultResponse.obj.keySet should contain("success")
99100
getResultResponse("uuid").str shouldBe queryResultWSMessage
100-
getResultResponse("stdout").str shouldBe "val res0: Int = 1\n"
101+
getResultResponse("stdout").str should include("val res0: Int = 1")
101102
}
102103

103104
"use predefined code" in Fixture("val foo = 40") { url =>
@@ -120,7 +121,7 @@ class ReplServerTests extends AnyWordSpec with Matchers {
120121
val getResultResponse = getResponse(url, queryUUID)
121122
getResultResponse.obj.keySet should contain("success")
122123
getResultResponse("uuid").str shouldBe queryResultWSMessage
123-
getResultResponse("stdout").str shouldBe "val bar: Int = 42\n"
124+
getResultResponse("stdout").str should include("val bar: Int = 42")
124125
}
125126

126127
"use runBefore code" in Fixture(runBeforeCode = Seq("import Int.MaxValue")) { url =>
@@ -143,20 +144,20 @@ class ReplServerTests extends AnyWordSpec with Matchers {
143144
val getResultResponse = getResponse(url, queryUUID)
144145
getResultResponse.obj.keySet should contain("success")
145146
getResultResponse("uuid").str shouldBe queryResultWSMessage
146-
getResultResponse("stdout").str shouldBe "val bar: Int = 2147483647\n"
147+
getResultResponse("stdout").str should include("val bar: Int = 2147483647")
147148
}
148149

149150
"use runAfter code" in {
150-
val expectedFileContent = "this should be written to the test output file"
151151
val testOutputFile = os.temp(deleteOnExit = false)
152152
val testOutputPath = replpp.util.pathAsString(testOutputFile.toNIO)
153153
Fixture(runAfterCode = Seq(
154-
"import java.nio.file.*",
155-
s"""Files.writeString(Path.of("$testOutputPath"), "$expectedFileContent")""",
156-
)) { _ =>
157-
// no need to execute anything, we only want to verify the `runAfter` code
154+
s"""definedInTest #> "$testOutputPath"""",
155+
)) { url =>
156+
val response = postQuerySync(url, "val definedInTest = 123456")
157+
response.obj.keySet should contain("success")
158+
response("stdout").str should include("val definedInTest: Int = 123456")
158159
}
159-
os.read(testOutputFile) shouldBe expectedFileContent
160+
os.read(testOutputFile).trim shouldBe "123456"
160161
}
161162

162163
"disallow fetching the result of a completed query with an invalid auth header" in Fixture() { url =>
@@ -205,7 +206,7 @@ class ReplServerTests extends AnyWordSpec with Matchers {
205206
getResultResponse.obj.keySet should contain("stdout")
206207
getResultResponse.obj.keySet should not contain "err"
207208
getResultResponse("uuid").str shouldBe queryResultWSMessage
208-
getResultResponse("stdout").str shouldBe "val res0: Int = 1\n"
209+
getResultResponse("stdout").str should include("val res0: Int = 1")
209210
}
210211
}
211212

@@ -363,13 +364,13 @@ class ReplServerTests extends AnyWordSpec with Matchers {
363364
"work for simple case" in Fixture() { url =>
364365
val response = postQuerySync(url, "1")
365366
response.obj.keySet should contain("success")
366-
response("stdout").str shouldBe "val res0: Int = 1\n"
367+
response("stdout").str should include("val res0: Int = 1")
367368
}
368369

369370
"using predef code" in Fixture("val predefCode = 2") { url =>
370371
val response = postQuerySync(url, "val foo = predefCode + 40")
371372
response.obj.keySet should contain("success")
372-
response("stdout").str shouldBe "val foo: Int = 42\n"
373+
response("stdout").str should include("val foo: Int = 42")
373374
}
374375

375376
"fail for invalid auth" in Fixture() { url =>
@@ -430,6 +431,8 @@ object Fixture {
430431
predefCode: String = "",
431432
runBeforeCode: Seq[String] = Seq.empty,
432433
runAfterCode: Seq[String] = Seq.empty)(urlToResult: String => T): T = {
434+
435+
val runBeforeCode0 = DefaultRunBeforeLines(using Colors.BlackWhite) ++ globalRunBeforeLines ++ runBeforeCode
433436
val additionalClasspathEntryMaybe: Option[Path] =
434437
if (predefCode.trim.isEmpty) None
435438
else {
@@ -440,7 +443,8 @@ object Fixture {
440443
Files.delete(predefFile)
441444
predefClassfiles.toOption
442445
}
443-
val embeddedRepl = new EmbeddedRepl(compilerArgs(additionalClasspathEntryMaybe), runBeforeCode, runAfterCode)
446+
447+
val embeddedRepl = new EmbeddedRepl(compilerArgs(additionalClasspathEntryMaybe), runBeforeCode0, runAfterCode, verbose = true)
444448

445449
val host = "localhost"
446450
val port = 8081

0 commit comments

Comments
 (0)