Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Corral, shade & embed jline. #4563

Merged
merged 2 commits into from Jun 19, 2015
Merged

Corral, shade & embed jline. #4563

merged 2 commits into from Jun 19, 2015

Conversation

adriaanm
Copy link
Contributor

As usual, we still expect a jline 2 jar on the classpath for the repl's console.
However, we now support classpaths that do not provide a (compatible) one.

The core of the repl (src/repl) no longer depends on jline.
The jline interface is now in src/repl-jline.

If the property repl.reader is set to the FQN of a class that
looks like YourInteractiveReader below, we try to reflectively instantiate it.

import scala.tools.nsc.interpreter.Completion
import scala.tools.nsc.interpreter.InteractiveReader

class YourInteractiveReader(completer: () => Completion) extends InteractiveReader

Otherwise, we interface to the standard jline on the class path by
instantiating scala.tools.nsc.interpreter.jline.InteractiveReader.

If that fails (a linkage error will result if jline is missing
or if it's not binary compatible -- the constructor exercises
quite a bit of the interface, so that should be sufficient
to detect versions).

If this also fails, we instantiate the class
scala.tools.nsc.interpreter.jline_embedded.InteractiveReader,
which interfaces to the embedded jline. This package is derived
from the bytecode generated for scala.tools.nsc.interpreter.jline._

The repl logs which classes it tried to instantiate under -Ydebug.

The embedded jline + our interface to it are generated by the quick.repl target.
The build now also enforces that only src/repl-jline depends on jline.
The sources in src/repl are now sure to be independent of it,
though they do use reflection to instantiate a suitable subclass
of InteractiveReader, as explained above.

The quick.repl target builds the sources in src/repl and src/repl-jline,
producing a jar for the repl-jline classes, which is then transformed using
jarjar to obtain a shaded copy of the scala.tools.nsc.interpreter.jline package.

Jarjar is used to combine the jline jar and the repl-jline into a new jar,
rewriting package names as follows:

  • org.fusesource -> scala.tools.fusesource_embedded
  • jline -> scala.tools.jline_embedded
  • scala.tools.nsc.interpreter.jline -> scala.tools.nsc.interpreter.jline_embedded

Classes not reachable from scala.tools.** are pruned, as well as empty dirs.

The classes in the repl-jline jar as well as those in the rewritten one
are copied to the repl's output directory.

PS: The sbt build is not updated, sorry.
PPS: A more recent fork of jarjar: https://github.com/shevek/jarjar.

@scala-jenkins scala-jenkins added this to the 2.11.8 milestone Jun 17, 2015
Code that depends on jline is now in package `scala.tools.nsc.interpreter.jline`.

To make this possible, remove the `entries` functionality from `History`,
and add the `historicize` method. Also provide an overload for `asStrings`.

Clean up a little along the way in `JLineHistory.scala` and `JLineReader.scala`.

Next step: fall back to an embedded jline when the expected jline jar
is not on the classpath.

The gist of the refactor: https://gist.github.com/adriaanm/02e110d4da0a585480c1
@adriaanm
Copy link
Contributor Author

Manual testing of falling back when old jline is on class path:

➜  scala git:(jline-shade) java -Xbootclasspath/a:/Users/adriaan/git/scala/build/quick/classes/library:/Users/adriaan/git/scala/build/libs/classes/forkjoin:/usr/local/Cellar/ant/1.9.4/libexec/lib/ant.jar:/Users/adriaan/git/scala/build/quick/classes/reflect:/Users/adriaan/git/scala/build/quick/classes/compiler:/Users/adriaan/.m2/repository/org/scala-lang/modules/scala-asm/5.0.4-scala-1/scala-asm-5.0.4-scala-1.jar
:/Users/adriaan/git/scala/build/quick/classes/repl
:/Users/adriaan/.m2/repository/jline/jline/0.9.94/jline-0.9.94.jar
:/Users/adriaan/git/scala/build/quick/classes/actors:/Users/adriaan/git/scala/build/quick/classes/scalap:/Users/adriaan/git/scala/build/quick/classes/scaladoc:/Users/adriaan/.m2/repository/org/scala-lang/modules/scala-xml_2.11/1.0.4/scala-xml_2.11-1.0.4.jar:/Users/adriaan/.m2/repository/org/scala-lang/modules/scala-parser-combinators_2.11/1.0.4/scala-parser-combinators_2.11-1.0.4.jar:/Users/adriaan/.m2/repository/org/scala-lang/plugins/scala-continuations-plugin_2.11.6/1.0.2/scala-continuations-plugin_2.11.6-1.0.2.jar:/Users/adriaan/.m2/repository/org/scala-lang/plugins/scala-continuations-library_2.11/1.0.2/scala-continuations-library_2.11-1.0.2.jar:/Users/adriaan/.m2/repository/org/scala-lang/modules/scala-swing_2.11/1.0.2/scala-swing_2.11-1.0.2.jar -classpath '""' -Dscala.home=/Users/adriaan/git/scala/build/quick -Dscala.usejavacp=true -Denv.emacs= scala.tools.nsc.MainGenericRunner -Ydebug
Trying to instantiate a InteractiveReader from scala.tools.nsc.interpreter.jline.InteractiveReader
Trying to instantiate a InteractiveReader from scala.tools.nsc.interpreter.jline_embedded.InteractiveReader
All InteractiveReaders tried: Stream(Failure(java.lang.reflect.InvocationTargetException), Success(scala.tools.nsc.interpreter.jline_embedded.InteractiveReader@3fee733d), ?)
Welcome to Scala version 2.11.7-20150616-093756-43a56fb5a1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_25).
Type in expressions to have them evaluated.
Type :help for more information.

scala>

@adriaanm
Copy link
Contributor Author

Manually testing sbt:

$ ant -Dmaven.version.suffix=-shaded-jline publish-local -Ddocs.skip=1
$ cd ~/Desktop/scratch && sbt
> set resolvers += Resolver.mavenLocal
> set scalaVersion := "2.11.7-shaded-jline"
> set scalacOptions += "-Ydebug"
> console
Trying to instantiate a InteractiveReader from scala.tools.nsc.interpreter.jline.InteractiveReader
All InteractiveReaders tried: Stream(Success(scala.tools.nsc.interpreter.jline.InteractiveReader@1fbc785c), ?)
Welcome to Scala version 2.11.7-20150616-093756-43a56fb5a1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_25).
Type in expressions to have them evaluated.
Type :help for more information.

scala>

@adriaanm adriaanm modified the milestones: 2.11.7, 2.11.8 Jun 17, 2015
@adriaanm
Copy link
Contributor Author

Review by @dragos, @retronym

@som-snytt
Copy link
Contributor

History repeats itself in parallel dimensions. In case it is any solace.

---------- Forwarded message ----------
From: Jan Lahoda xxxx.xxxx@oracle.com
Date: Thu, May 28, 2015 at 1:11 AM
Subject: jline integrated in the kulla repositories
To: kulla-dev@openjdk.java.net

jline 2.12.1 is now part of the kulla repositories. So when building full JDK, no additional parameters to make are needed, and the jshell command should work.

Regarding the scripts in langtools/repl/scripts, as jline is repackaged to jdk.internal.jline, the official jline.jar cannot be used anymore. [snip instructions]

Unfortunately, this won't work on Windows, as a little bit of native code is needed there. Please let me know if it is important to have these scripts work also for Windows.

@adriaanm
Copy link
Contributor Author

Some[solace], thank you. I'm pleased with our compromise, a talent for which us Belgians are known by our neighbors (though this one's not as compromised as our federal structure).

Unless there's a conflict, we still use the jline provided on the class path as before.

@dragos
Copy link
Contributor

dragos commented Jun 18, 2015

I'm trying to reproduce a build on the Spark side and check that things work as intended. That's hard because some things moved around and the spark-repl won't compile anymore. I'll let you know as soon as I get some fixes in there, but my first impression is that these changes might break way more clients than simply shading the dependency. I really don't think there's anyone relying on that.

@adriaanm
Copy link
Contributor Author

Happy to try myself if you can post some hints on how to get started. Can also see about moving some classes back if needed -- would be good to know which of these were considered public, because we certainly assumed they are internal.

In any case, the only classes that moved depend directly on jline. It doesn't seem like a good idea to reuse them while also putting a conflicting jline on the class path. We only guarantee compiler API stability through inclusion in the community build (or manually, in this case), so I don't think it's an issue per se to move internal classes around.

My take on this is that there are orders of magnitude fewer programmatic consumers of the repl (sbt, spark,..) than there are repl users on, say, windows who may once in a while benefit from swapping the jline jar (maybe after 2.11 goes EOL but jline keeps evolving). We also only promise best-effort compiler API stability, i.e., we can only maintain stability for dependencies we know about (community build, manual).

@dragos
Copy link
Contributor

dragos commented Jun 18, 2015

I understand there are no compatibility guarantees, I'm just noticing that it's way more work than I anticipated.

Part of the problem is that spark-repl is 50% of a fork, with a few places where changes are significant. I can get rid of a lot of duplicated code (involving references to JLine code as well), but some things are impossible to reuse without some more changes in the Scala REPL. For instance, static members of IMain or ILoop are impossible to override, and some of the code duplication stems from the need to override callers of these static methods.

Lastly, I'd like to add Spark to the community build, but so far there are other forks (like genjavadoc) that are compiler plugins, so they need to be either part of the community build as well, or removed (my preference goes to this one).

@adriaanm
Copy link
Contributor Author

I recognize these are all real challenges, but I would hope this PR helps in overcoming them since it makes the InteractiveReader interface configurable and also makes the core of the REPL independent of JLine. It also sounds like some of the problems you mentioned are orthogonal to this.

Since we have more REPL refactorings in the works (presentation compiler for auto-complete) I suggest the Scala team takes a look at the spark repl. Are there instructions anywhere on how to build it? Ideally as a separate module from the rest of Spark? I can spend all day today on this.

@dragos
Copy link
Contributor

dragos commented Jun 18, 2015

I doubt one day would be enough, but all the code is in https://github.com/apache/spark/tree/master/repl You can build it with Maven or Sbt, it's pretty straight forward. You'll notice though that you won't be able to use 2.11.7-SNAPSHOT as a dependency because of the said compiler plugin dependencies, so you'll need to find some workaround (mine is to replace 2.11.6 directly on the classpath, inside the IDE).

Spark build instructions for 2.11

Edit: Some of the issues I mentioned may seem orthogonal, but I didn't find a way to use the Scala REPL without fixing those first (other than copy-pasting a more recent version of the REPL from your PR).

@dragos
Copy link
Contributor

dragos commented Jun 18, 2015

Ok, I got somewhat farther. I'm happy with the amount of code I managed to scrap. Things seem to work fine on the Spark side, but the problem is I don't understand why :)

I see this in the output

Trying to instantiate a InteractiveReader from scala.tools.nsc.interpreter.jline.InteractiveReader
Trying to instantiate a InteractiveReader from scala.tools.nsc.interpreter.jline_embedded.InteractiveReader
All InteractiveReaders tried: Stream(Failure(java.lang.reflect.InvocationTargetException), Failure(java.lang.reflect.InvocationTargetException), ?)

Nevertheless, I get completion and history on the command prompt. The Hive CLI works as well, meaning that the assembly packaged jline 0.9.94. I manually checked and the jline_embedded is in the spark assembly jar.

@adriaanm
Copy link
Contributor Author

Cool & bizarre at the same time!

@dragos
Copy link
Contributor

dragos commented Jun 18, 2015

Past experience tells me this is trouble down the line. We need to find out what fails and why it works...

@adriaanm
Copy link
Contributor Author

Agreed. I tried locally with both jars on the class path and cannot reproduce:

java -Xmx256M -Xms32M -Xbootclasspath/a:/Users/adriaan/git/scala/build/quick/classes/library:/Users/adriaan/git/scala/build/libs/classes/forkjoin:/usr/local/Cellar/ant/1.9.4/libexec/lib/ant.jar:/Users/adriaan/git/scala/build/quick/classes/reflect:/Users/adriaan/git/scala/build/quick/classes/compiler:/Users/adriaan/.m2/repository/org/scala-lang/modules/scala-asm/5.0.4-scala-1/scala-asm-5.0.4-scala-1.jar:/Users/adriaan/git/scala/build/quick/classes/repl
:/Users/adriaan/.m2/repository/jline/jline/2.12.1/jline-2.12.1.jar
:/Users/adriaan/.m2/repository/jline/jline/0.9.94/jline-0.9.94.jar:/Users/adriaan/git/scala/build/quick/classes/actors:/Users/adriaan/git/scala/build/quick/classes/scalap:/Users/adriaan/git/scala/build/quick/classes/scaladoc:/Users/adriaan/.m2/repository/org/scala-lang/modules/scala-xml_2.11/1.0.4/scala-xml_2.11-1.0.4.jar:/Users/adriaan/.m2/repository/org/scala-lang/modules/scala-parser-combinators_2.11/1.0.4/scala-parser-combinators_2.11-1.0.4.jar:/Users/adriaan/.m2/repository/org/scala-lang/plugins/scala-continuations-plugin_2.11.6/1.0.2/scala-continuations-plugin_2.11.6-1.0.2.jar:/Users/adriaan/.m2/repository/org/scala-lang/plugins/scala-continuations-library_2.11/1.0.2/scala-continuations-library_2.11-1.0.2.jar:/Users/adriaan/.m2/repository/org/scala-lang/modules/scala-swing_2.11/1.0.2/scala-swing_2.11-1.0.2.jar -classpath '""' -Dscala.home=/Users/adriaan/git/scala/build/quick -Dscala.usejavacp=true -Denv.emacs= scala.tools.nsc.MainGenericRunner -Ydebug

Trying to instantiate a InteractiveReader from scala.tools.nsc.interpreter.jline.InteractiveReader
All InteractiveReaders tried: Stream(Success(scala.tools.nsc.interpreter.jline.InteractiveReader@7a81197d), ?)

@adriaanm
Copy link
Contributor Author

Could you recompile with a compiler that prints the stack trace for the exception in the Failure?

@adriaanm
Copy link
Contributor Author

When I swap the order of the jars, I get:

java -Xmx256M -Xms32M -Xbootclasspath/a:/Users/adriaan/git/scala/build/quick/classes/library:/Users/adriaan/git/scala/build/libs/classes/forkjoin:/usr/local/Cellar/ant/1.9.4/libexec/lib/ant.jar:/Users/adriaan/git/scala/build/quick/classes/reflect:/Users/adriaan/git/scala/build/quick/classes/compiler:/Users/adriaan/.m2/repository/org/scala-lang/modules/scala-asm/5.0.4-scala-1/scala-asm-5.0.4-scala-1.jar:/Users/adriaan/git/scala/build/quick/classes/repl
:/Users/adriaan/.m2/repository/jline/jline/0.9.94/jline-0.9.94.jar
:/Users/adriaan/.m2/repository/jline/jline/2.12.1/jline-2.12.1.jar:/Users/adriaan/git/scala/build/quick/classes/actors:/Users/adriaan/git/scala/build/quick/classes/scalap:/Users/adriaan/git/scala/build/quick/classes/scaladoc:/Users/adriaan/.m2/repository/org/scala-lang/modules/scala-xml_2.11/1.0.4/scala-xml_2.11-1.0.4.jar:/Users/adriaan/.m2/repository/org/scala-lang/modules/scala-parser-combinators_2.11/1.0.4/scala-parser-combinators_2.11-1.0.4.jar:/Users/adriaan/.m2/repository/org/scala-lang/plugins/scala-continuations-plugin_2.11.6/1.0.2/scala-continuations-plugin_2.11.6-1.0.2.jar:/Users/adriaan/.m2/repository/org/scala-lang/plugins/scala-continuations-library_2.11/1.0.2/scala-continuations-library_2.11-1.0.2.jar:/Users/adriaan/.m2/repository/org/scala-lang/modules/scala-swing_2.11/1.0.2/scala-swing_2.11-1.0.2.jar -classpath '""' -Dscala.home=/Users/adriaan/git/scala/build/quick -Dscala.usejavacp=true -Denv.emacs= scala.tools.nsc.MainGenericRunner -Ydebug
Trying to instantiate a InteractiveReader from scala.tools.nsc.interpreter.jline.InteractiveReader
[ERROR] Terminal initialization failed; falling back to unsupported
java.lang.IncompatibleClassChangeError: Found class jline.Terminal, but interface was expected
    at jline.TerminalFactory.create(TerminalFactory.java:101)
    at jline.TerminalFactory.get(TerminalFactory.java:158)
    at jline.console.ConsoleReader.<init>(ConsoleReader.java:229)
    at jline.console.ConsoleReader.<init>(ConsoleReader.java:221)
    at jline.console.ConsoleReader.<init>(ConsoleReader.java:209)
    at scala.tools.nsc.interpreter.jline.JLineConsoleReader.<init>(JLineReader.scala:61)
    at scala.tools.nsc.interpreter.jline.InteractiveReader.<init>(JLineReader.scala:33)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
    at scala.tools.nsc.interpreter.ILoop$$anonfun$scala$tools$nsc$interpreter$ILoop$$instantiate$1$1.apply(ILoop.scala:873)
    at scala.tools.nsc.interpreter.ILoop$$anonfun$scala$tools$nsc$interpreter$ILoop$$instantiate$1$1.apply(ILoop.scala:870)
    at scala.tools.nsc.interpreter.ILoop.scala$tools$nsc$interpreter$ILoop$$mkReader$1(ILoop.scala:879)
    at scala.tools.nsc.interpreter.ILoop$$anonfun$15$$anonfun$apply$8.apply(ILoop.scala:883)
    at scala.tools.nsc.interpreter.ILoop$$anonfun$15$$anonfun$apply$8.apply(ILoop.scala:883)
    at scala.util.Try$.apply(Try.scala:192)
    at scala.tools.nsc.interpreter.ILoop$$anonfun$15.apply(ILoop.scala:883)
    at scala.tools.nsc.interpreter.ILoop$$anonfun$15.apply(ILoop.scala:883)
    at scala.collection.immutable.Stream.map(Stream.scala:418)
    at scala.tools.nsc.interpreter.ILoop.chooseReader(ILoop.scala:883)
    at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1$$anonfun$apply$mcZ$sp$2.apply(ILoop.scala:918)
    at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1$$anonfun$apply$mcZ$sp$2.apply(ILoop.scala:918)
    at scala.Option.fold(Option.scala:158)
    at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply$mcZ$sp(ILoop.scala:918)
    at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:913)
    at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:913)
    at scala.reflect.internal.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:97)
    at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:913)
    at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:74)
    at scala.tools.nsc.MainGenericRunner.run$1(MainGenericRunner.scala:87)
    at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:98)
    at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:103)
    at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

Trying to instantiate a InteractiveReader from scala.tools.nsc.interpreter.jline_embedded.InteractiveReader
All InteractiveReaders tried: Stream(Failure(java.lang.reflect.InvocationTargetException), Success(scala.tools.nsc.interpreter.jline_embedded.InteractiveReader@372f7a8d), ?)
Welcome to Scala version 2.11.7-20150616-093756-43a56fb5a1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_25).
Type in expressions to have them evaluated.
Type :help for more information.

@adriaanm
Copy link
Contributor Author

Since spark knows the first try is going to fail, can you try with -Drepl.reader=scala.tools.nsc.interpreter.jline_embedded.InteractiveReader?

@adriaanm
Copy link
Contributor Author

I should probably make that scala.repl.reader

@adriaanm
Copy link
Contributor Author

Here's the snippet for ILoop that will print the stack trace for these failures:

      if (settings.debug) {
        val readerDiags = (readerClasses, readers).zipped map { 
          case (cls, Failure(e)) => s"  - $cls --> " + e.getStackTrace.mkString(e.toString+"\n\t", "\n\t","\n")
          case (cls, Success(_)) => s"  - $cls OK"
        }
        Console.println(s"All InteractiveReaders tried: ${readerDiags.mkString("\n","\n","\n")}")
      }

As usual, the repl will use whatever jline 2 jar on the classpath,
if there is one. Failing that, there's a fallback and an override.

If instantiating the standard `jline.InteractiveReader` fails,
we fall back to an embedded, shaded, version of jline,
provided by `jline_embedded.InteractiveReader`.

(Assume `import scala.tools.nsc.interpreter._` for this message.)

The instantiation of `InteractiveReader` eagerly exercises jline,
so that a linkage error will result if jline is missing or if the
provided one is not binary compatible.

The property `scala.repl.reader` overrides this behavior, if set to
the FQN of a class that looks like `YourInteractiveReader` below.

```
class YourInteractiveReader(completer: () => Completion) extends InteractiveReader
```

The repl logs which classes it tried to instantiate under `-Ydebug`.

 # Changes to source & build

The core of the repl (`src/repl`) no longer depends on jline.
The jline interface is now in `src/repl-jline`.

The embedded jline + our interface to it are generated by the `quick.repl` target.
The build now also enforces that only `src/repl-jline` depends on jline.
The sources in `src/repl` are now sure to be independent of it,
though they do use reflection to instantiate a suitable subclass
of `InteractiveReader`, as explained above.

The `quick.repl` target builds the sources in `src/repl` and `src/repl-jline`,
producing a jar for the `repl-jline` classes, which is then transformed using
jarjar to obtain a shaded copy of the `scala.tools.nsc.interpreter.jline` package.

Jarjar is used to combine the `jline` jar and the `repl-jline` into a new jar,
rewriting package names as follows:
  - `org.fusesource` -> `scala.tools.fusesource_embedded`
  - `jline` -> `scala.tools.jline_embedded`
  - `scala.tools.nsc.interpreter.jline` -> `scala.tools.nsc.interpreter.jline_embedded`

Classes not reachable from `scala.tools.**` are pruned, as well as empty dirs.

The classes in the `repl-jline` jar as well as those in the rewritten one
are copied to the repl's output directory.

PS: The sbt build is not updated, sorry.
PPS: A more recent fork of jarjar: https://github.com/shevek/jarjar.
@adriaanm
Copy link
Contributor Author

So, @dragos, does this mean the PR LGTY? We are hoping to stage the release today or tomorrow.

@retronym
Copy link
Member

/cc @ScrapCodes

@dragos
Copy link
Contributor

dragos commented Jun 19, 2015

no LGTM yet. I need to track down those failures, I'll look into it today.

@ScrapCodes
Copy link
Contributor

Looks good to me, I have tried with spark. This should relieve us of the trouble two jlines on classpath.

@dragos I am unsure of your concerns, I can share the code that I used to build spark with this PR and it works fine. Basically I could get rid of explicit dependence on jline. This should not be harmful hopefully ?

@dragos
Copy link
Contributor

dragos commented Jun 19, 2015

@ScrapCodes it works all right, check my comment though for my concerns. Does your log show two Failures or a Failure and a Success?

@dragos
Copy link
Contributor

dragos commented Jun 19, 2015

@adriaanm After adding debugging code on the Scala REPL side I can see the second one succeeds. But once I remove it the stream still prints two Failures. I would say LGTM though I'm still not entirely clear why it would print it that way.

@dragos
Copy link
Contributor

dragos commented Jun 19, 2015

LGTM.

If you want to have a look at the Spark REPL code (still in progress), check this commit, or even better, this file. The Scala REPL interface that's used is down to:

  • a way to replace the welcome message
  • a way to hide some commands (like power, type, kind, etc.)
  • a way to execute initialization code before loading any script files

I am not happy with the last one (override loadFiles), it'd be nicer if the REPL offered a way to do that as a hook in the initialization process. But in the mean time, this workswith 2.11.6 as well, so we could merge this in Spark already.

@adriaanm
Copy link
Contributor Author

Great! I have a slight amount of polish for this PR waiting for me on my computer at the office. As soon as I'm at my desk, I'll push it. I'd be curious to understand this weird failure you're seeing, though, and whether it's alleviated by setting the repl.reader property as I suggested above. (Soon to become scala.repl.reader after applying said polish.)

@dragos
Copy link
Contributor

dragos commented Jun 19, 2015

@adriaanm Are you ok with the API surface? Should we add a hook for custom initialization routines?

@adriaanm
Copy link
Contributor Author

Sure let's add those. Thanks for the links, that'll do for inspiration I think :)

@adriaanm
Copy link
Contributor Author

On second thought, I'm still in favor of improving customizing the repl, but this PR is only about shading JLine. Its intent was not to nail down the REPL's API surface -- that's going to take more time, and this release needs to be cut today.

@adriaanm
Copy link
Contributor Author

/nothingtoseehere -- the build was green, and my push -f was only rewording and more verbosity for a debug message

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
7 participants