-
Notifications
You must be signed in to change notification settings - Fork 1.1k
add scripting support similar to scala2 scripting #11180
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
Conversation
Thanks for the proposal @philwalk!
This capability is already present in the existing scripting driver: dotty/compiler/src/dotty/tools/scripting/ScriptingDriver.scala:44
I believe if we implement 3rd party library support from scripts, it should also support library fetching. It is tedious to manage classpaths manually. We were considering adding something like Ammonite's magic imports – but the semantics is not mature enough, so we can only support Maven libraries (and not references to other scripts) in that way. Most probably a scripting solution with such support will require integration with Coursier and hence would be good to split into a separate project that depends on the compiler. |
1. pass @<argsFile> and -color:* options to compiler 2. add -save|-savecompiled option 3. recognize scripts with #!.*scala regardless of extension 4. if <scriptPath>.jar file is newer than <scriptPath> execute it (no compile) 5. set -Dscript.name for both script execution paths (script or .jar) changes to dotty.tools.scripting package: 1. moved mainMethod execution from ScriptingDriver to Main 2. detectMainMethod also detects main class name 3. on -save option: a. generate same-name jar file in <scriptPath> parent directory b. "java.class.path" appended to context classpath with deduplication c. write "Main-Class" and "Class-Path" to jar manifest 4. additional compiler args splitting and filtering 5. throw sys.error if .class file files generated (e.g., if script source is blank) added new tests to verify the following: 1. hash bang section is ignored by compiler 2. main class name in stack dump is as expected when main class is declared in script 3. main class name in stack dump is as expected when main class is not declared in script 4. script.name property matches scriptFile.getName 5. without -save option, no jar file is generated 6. -save option causes jar file with expected name to be generated 7. generated jar file is directly executable via "java -jar <scriptFile>.jar"
@anatoliykmetyuk - I didn't see your feedback this morning before I pushed code. The implementation provided in this PR is compatible with your suggestion regarding 3rd party tools. What I am submitting provides a maximally simple near-term default scripting environment that isn't dependent on other tools, such as sbt or coursier. The manual parts can be automated, and it can be extended in a backward-compatible way. I have been using this approach with scala2 for 9 years. and it's quite robust. This PR adds My default scripting environment has two components:
The With this arrangement, I can use scala scripts the same way I use python scripts, the only difference being the system used to install and update packages and libraries. In addition to fetching libraries, it would update the default @. To attract python scripters we need to offer a tool (probably coursier) that provides manual "install" and "update" commands. We can also offer automatic library fetching, but it should be optional, especially if it requires non-standard "magic" import syntax. If I understand it correctly, |
…walk/dotty into extend-scripting-capability
I created a new PR and closed this one, based on your comment about 3rd party tools. See #11379
@anatoliykmetyuk - it turns out that we also needed the "Main-Class" name in addition to the main Method, so, the return value was modified to a tuple, returning both. Because the main class name is needed in the A few questions:
Thanks for the help! |
@anatoliykmetyuk I like the idea of having scripting as a separator project that depends on the compiler, although in order for the solution to run in a single Hopefully the release will include minimal scripting support so scripters can start migrating from scala2. |
This is superceded by PR #11379, a redesign intended to provide a base design that can be easily leveraged by 3rd party tool developers. It implements all the basic features familiar to scala2 script developers. |
This proposal is related to these issues:
#10491
#4747
#10858
Design Rationale
In order for scala scripting to seriously contend with python or bash as a general scripting solution, scripts must be able to leverage the large catalog of available java and scala libraries without always having to specify the required classpath. Other scripting languages rely on a set of "installed" libraries, providing a default configuration. In the case of JVM languages, that implies the need for a default classpath.
Other scripting environments also typically provide a way to install libraries, making them available for import at runtime. Examples of package manager tools include
A comparable capability for managing a scala scripting environment might be based on coursier, sbt and/or mill. For a
jvm
library to be "installed" means:This proposal specifies a means for specifying named classpaths, but does not provide a package management tool.
Proposed features for the scala3 scripting solution:
-save
option, leveraging scalac -d <scriptname.jar>java -jar myScript.jar
The proposed design involves a single
jvm
startup latency on each script execution.Benchmark of prototyped solution
A prototype for the proposed solution (based on dotty compiler as of 2021-01-12) requires 4 jvm startups:
Class-Path
andMain-Class
properties to compiled jarThe benchmark script:
A rough guess is that the prototype benchmark overstates startup latency by about 300 mSeconds on my system. (java 11.0.9). This was estimated by averaging total jvm run times for
java -version
over 100 runs.The actual script startup latency for the prototype's compile versus cached runs:
The challenging parts (for me) are to figure out how to leverage the existing dotty compiler capabilities to:
A quick and dirty alternative would be to use existing prototype hacks.
Feedback and opinions are welcome!