Repository: joernio/joern (scala)

Issue:
[Bug] Pipe redirect doesn't work with --script
Pipe redirects `#>` `#>>` etc. don't work when used in script and passed with `--scirpt` parameter.

**script.sc:**
```scala
@main def exec(codePath: String, outFile: String) = {
   importCode.python(codePath)
   cpg.call.name("JSONField").toJsonPretty #> outFile
   cpg.call.name("HStoreField").toJsonPretty #>> outFile
}
```
**Output:**
```
 akomissarchuk@arkom-maibook  ~/reachable-testing/python  joern --script test.sc --param codePath=CVE-2019-14234/CVE-2019-14234 --param outFile=results.json
executing test.sc with params=Map(codePath -> CVE-2019-14234/CVE-2019-14234, outFile -> results.json)
-- [E008] Not Found Error: /tmp/wrapped-script11100807640546085911.sc:3:43 -----
  3 |   cpg.call.name("JSONField").toJsonPretty #> outFile
    |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |value #> is not a member of String, but could be made available as an extension method.
    |
    |The following import might fix the problem:
    |
    |  import replpp.Operators.#>
    |
-- [E008] Not Found Error: /tmp/wrapped-script11100807640546085911.sc:4:45 -----
  4 |   cpg.call.name("HStoreField").toJsonPretty #>> outFile
    |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |value #>> is not a member of String, but could be made available as an extension method.
    |
    |The following import might fix the problem:
    |
    |  import replpp.Operators.#>>
    |
2 errors found
Exception in thread "main" replpp.scripting.NonForkingScriptRunner$$anon$1: error during script execution: Error during compilation: Errors encountered during compilation - try `--verbose` for more output
Please check error output above!
For given input files: /tmp/wrapped-script11100807640546085911.sc
Re-run with `--verbose` for more details

replpp.scripting.ScriptRunner$: error while invoking replpp.scripting.NonForkingScriptRunner: exit code was 1
```

But when the same code is run in the repl console, it works properly:

```
 akomissarchuk@arkom-maibook  ~/joern  ↰ master  joern

     ██╗ ██████╗ ███████╗██████╗ ███╗   ██╗
     ██║██╔═══██╗██╔════╝██╔══██╗████╗  ██║
     ██║██║   ██║█████╗  ██████╔╝██╔██╗ ██║
██   ██║██║   ██║██╔══╝  ██╔══██╗██║╚██╗██║
╚█████╔╝╚██████╔╝███████╗██║  ██║██║ ╚████║
 ╚════╝  ╚═════╝ ╚══════╝╚═╝  ╚═╝╚═╝  ╚═══╝
Version: 4.0.383
Type `help` to begin


joern> importCode("/home/akomissarchuk/reachable-testing/python/CVE-2019-14234/CVE-2019-14234/")
Using generator for language: PYTHONSRC: PythonSrcCpgGenerator
Creating project `CVE-2019-14234` for code at `/home/akomissarchuk/reachable-testing/python/CVE-2019-14234/CVE-2019-14234/`
=======================================================================================================
Invoking CPG generator in a separate process. Note that the new process will consume additional memory.
If you are importing a large codebase (and/or running into memory issues), please try the following:
1) exit joern
2) invoke the frontend: /home/akomissarchuk/bin/joern/joern-cli/pysrc2cpg -J-Xmx1934m /home/akomissarchuk/reachable-testing/python/CVE-2019-14234/CVE-2019-14234/ -o /home/akomissarchuk/joern/workspace/CVE-2019-14234/cpg.bin.zip
3) start joern, import the cpg: `importCpg("path/to/cpg")`
=======================================================================================================

moving cpg.bin.zip to cpg.bin because it is already a database file
Creating working copy of CPG to be safe
Loading base CPG from: /home/akomissarchuk/joern/workspace/CVE-2019-14234/cpg.bin.tmp
Code successfully imported. You can now query it using `cpg`.
For an overview of all imported code, type `workspace`.
Adding default overlays to base CPG
The graph has been modified. You may want to use the `save` command to persist changes to disk.  All changes will also be saved collectively on exit
The graph has been modified. You may want to use the `save` command to persist changes to disk.  All changes will also be saved collectively on exit
val res0: io.shiftleft.codepropertygraph.generated.Cpg = Cpg[Graph[1163 nodes]]

joern> cpg.call.name("JSONField").toJsonPretty #> "out.json"

joern>cpg.call.name("HStoreField").toJsonPretty #>> "out.json"

joern>
```

I could achieve writing to file by using the deprecated `|>` `|>>` operators which I found in joern souce code, and it worked, but this anyway is a bug, because the intended way described in the documentation doesn't work.

Pull request:
fixes https://github.com/joernio/joern/issues/5558

Patch:
diff --git a/project/Versions.scala b/project/Versions.scala
index e91aec863388..f40a07fb35f1 100644
--- a/project/Versions.scala
+++ b/project/Versions.scala
@@ -31,7 +31,7 @@ object Versions {
   val requests               = "0.8.0"
   val scalaParallel          = "1.0.4"
   val scalaParserCombinators = "2.4.0"
-  val scalaReplPP            = "0.5.4"
+  val scalaReplPP            = "0.6.1"
   val scalatest              = "3.2.18"
   val scopt                  = "4.1.0"
   val semverParser           = "0.0.6"
diff --git a/project/build.properties b/project/build.properties
index bbb0b608cac0..c02c575fdb50 100644
--- a/project/build.properties
+++ b/project/build.properties
@@ -1,1 +1,1 @@
-sbt.version=1.11.2
+sbt.version=1.11.3


Test patch:
diff --git a/joern-cli/src/test/scala/io/joern/joerncli/RunScriptTests.scala b/joern-cli/src/test/scala/io/joern/joerncli/RunScriptTests.scala
index 4efec2123843..09419e6b095f 100644
--- a/joern-cli/src/test/scala/io/joern/joerncli/RunScriptTests.scala
+++ b/joern-cli/src/test/scala/io/joern/joerncli/RunScriptTests.scala
@@ -34,14 +34,7 @@ class RunScriptTests extends AnyWordSpec with Matchers {
     "execute a simple script" in new Fixture {
       def test(scriptFile: Path, outputFile: Path) = {
         val escScriptPath = outputFile.toString.replace("\\", "\\\\")
-        Files.writeString(
-          scriptFile,
-          s"""
-        |val fw = new java.io.FileWriter("$escScriptPath", true)
-        |fw.write("michael was here")
-        |fw.close()
-        """.stripMargin
-        )
+        Files.writeString(scriptFile, s""""michael was here" #> "$escScriptPath"""".stripMargin)
 
         ReplBridge.main(Array("--script", scriptFile.toString))
 
@@ -57,9 +50,7 @@ class RunScriptTests extends AnyWordSpec with Matchers {
           scriptFile,
           s"""
           |@main def foo(outFile: String, magicNumber: Int) = {
-          |  val fw = new java.io.FileWriter(outFile, true)
-          |  fw.write(magicNumber.toString)
-          |  fw.close() 
+          |  magicNumber #> outFile
           |}
           """.stripMargin
         )
@@ -88,14 +79,10 @@ class RunScriptTests extends AnyWordSpec with Matchers {
           scriptFile,
           s"""
           |@main def foo() = {
-          |  val fw = new java.io.FileWriter("$escScriptPath", true)
-          |  fw.write("foo was called")
-          |  fw.close() 
+          |  "foo was called" #> "$escScriptPath"
           |}
           |@main def bar() = {
-          |  val fw = new java.io.FileWriter("$escScriptPath", true)
-          |  fw.write("bar was called")
-          |  fw.close() 
+          |  "bar was called" #> "$escScriptPath"
           |}
           """.stripMargin
         )
@@ -116,9 +103,7 @@ class RunScriptTests extends AnyWordSpec with Matchers {
           scriptFile,
           s"""
           |//> using file $additionalImportFile
-          |val fw = new java.io.FileWriter("$escScriptPath", true)
-          |fw.write(sayHello("michael")) //function defined in additionalImportFile
-          |fw.close() 
+          |sayHello("michael") #> "$escScriptPath"
           """.stripMargin
         )
 
@@ -137,9 +122,7 @@ class RunScriptTests extends AnyWordSpec with Matchers {
         Files.writeString(
           scriptFile,
           s"""
-          |val fw = new java.io.FileWriter("$escScriptPath", true)
-          |fw.write(sayHello("michael")) //function defined in additionalImportFile
-          |fw.close() 
+          |sayHello("michael") #> "$escScriptPath"
           """.stripMargin
         )