Skip to content

Fix #21242: Add REPL flag to quit after evaluating init script #22636

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

Merged
merged 5 commits into from
Feb 28, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions bin/replQ
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env bash

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" >& /dev/null && pwd)/.."
. $ROOT/bin/commonQ

java -Dscala.usejavacp=true -cp $cp dotty.tools.repl.Main -usejavacp "$@"
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ trait CommonScalaSettings:
val usejavacp: Setting[Boolean] = BooleanSetting(RootSetting, "usejavacp", "Utilize the java.class.path in classpath resolution.", aliases = List("--use-java-class-path"))
val scalajs: Setting[Boolean] = BooleanSetting(RootSetting, "scalajs", "Compile in Scala.js mode (requires scalajs-library.jar on the classpath).", aliases = List("--scalajs"))
val replInitScript: Setting[String] = StringSetting(RootSetting, "repl-init-script", "code", "The code will be run on REPL startup.", "", aliases = List("--repl-init-script"))
val replEvalOnly: Setting[Boolean] = BooleanSetting(RootSetting, "repl-eval", "Quit REPL after evaluating the init script.", aliases = List("--repl-eval"))
end CommonScalaSettings

/** -P "plugin" settings. Various tools might support plugins. */
Expand Down
4 changes: 3 additions & 1 deletion compiler/src/dotty/tools/repl/ReplDriver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,9 @@ class ReplDriver(settings: Array[String],
*
* Possible reason for unsuccessful run are raised flags in CLI like --help or --version
*/
final def tryRunning = if shouldStart then runUntilQuit()
final def tryRunning = if shouldStart then
if rootCtx.settings.replEvalOnly.value(using rootCtx) then initialState
else runUntilQuit()

/** Run REPL with `state` until `:quit` command found
*
Expand Down
5 changes: 4 additions & 1 deletion compiler/test/dotty/tools/scripting/BashExitCodeTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ class BashExitCodeTests:
s"expected $expectedExitCode but got $exitCode${pp("out", stdout)}${pp("err", stderr)}"
}, expectedExitCode, exitCode)

// Helpers for running scala, scalac, and scalac without the output directory ("raw")
// Helpers for running scala, scalac, scalac, and repl without the output directory ("raw")
def scala(args: String*) = verifyExit(scalaPath, ("--power" +: args :+ "--offline" :+ "--server=false")*)
def scalacRaw(args: String*) = verifyExit(scalacPath, args*)
def scalac(args: String*) = scalacRaw(("-d" +: tmpDir +: args)*)
def repl(args: String*) = verifyExit(replPath, args*)

/** The path to the test file for this class. */
def f(body: String, suffix: String = ".scala"): String =
Expand Down Expand Up @@ -72,6 +73,8 @@ class BashExitCodeTests:
@Test def xPluginList = scala("-Xplugin-list")(0)
@Test def vPhases = scala("-Vphases")(0)

@Test def replEval = repl("--repl-eval", "--repl-init-script", "\'println(\"Hello from init script!\"); val i = 2 * 2\'")(0)

/** A utility for running two commands in a row, like you do in bash. */
extension (inline u1: Unit) inline def & (inline u2: Unit): Unit = { u1; u2 }
end BashExitCodeTests
5 changes: 3 additions & 2 deletions compiler/test/dotty/tools/scripting/ScriptTestEnv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -292,10 +292,11 @@ object ScriptTestEnv {

lazy val cwd: Path = Paths.get(".").toAbsolutePath.normalize

lazy val (scalacPath: String, scalaPath: String) = {
lazy val (scalacPath: String, scalaPath: String, replPath: String) = {
val scalac = s"$workingDirectory/$packBinDir/scalac".toPath.normalize
val scala = s"$workingDirectory/$packBinDir/scala".toPath.normalize
(scalac.norm, scala.norm)
val repl = s"$workingDirectory/$packBinDir/repl".toPath.normalize
(scalac.norm, scala.norm, repl.norm)
}


Expand Down
88 changes: 88 additions & 0 deletions dist/bin/repl
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/usr/bin/env bash

#set -o nounset ; set -o errexit

# Try to autodetect real location of the script
if [ -z "${PROG_HOME-}" ] ; then
## resolve links - $0 may be a link to PROG_HOME
PRG="$0"

# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done

saveddir=`pwd`

PROG_HOME=`dirname "$PRG"`/..

# make it fully qualified
PROG_HOME=`cd "$PROG_HOME" && pwd`

cd "$saveddir"
fi

source "$PROG_HOME/libexec/common"
default_java_opts="-Xmx768m -Xms768m"
withCompiler=true

CompilerMain=dotty.tools.dotc.Main
DecompilerMain=dotty.tools.dotc.decompiler.Main
ReplMain=dotty.tools.repl.Main
ScriptingMain=dotty.tools.scripting.Main
JVM_CP_ARGS="$PROG_HOME/lib/scaladoc.jar"

PROG_NAME=$CompilerMain

addJava () {
java_args+=("'$1'")
}
addScala () {
scala_args+=("'$1'")
}
addResidual () {
residual_args+=("'$1'")
}
addScrip() {
script_args+=("'$1'")
}

#for A in "$@" ; do echo "A[$A]" ; done ; exit 2

while [[ $# -gt 0 ]]; do
case "$1" in
--) shift; for arg; do addResidual "$arg"; done; set -- ;;
-v|-verbose) verbose=true && addScala "-verbose" && shift ;;
-q|-quiet) quiet=true && shift ;;

-colors) colors=true && shift ;;
-no-colors) unset colors && shift ;;
# break out -D and -J options and add them to java_args so
# they reach the JVM in time to do some good. The -D options
# will be available as system properties.
-D*) addJava "$1" && shift ;;
-J*) addJava "${1:2}" && shift ;;
*) addResidual "$1"
shift
;;
esac
done

eval "\"$JAVACMD\"" \
${JAVA_OPTS:-$default_java_opts} \
"${java_args[@]}" \
-classpath "${JVM_CP_ARGS}" \
-Dscala.expandjavacp=true \
-Dscala.usejavacp=true \
"dotty.tools.repl.Main" \
"${scala_args[@]}" \
"${residual_args[@]}" \
"${scripting_string-}"
scala_exit_status=$?
onExit
110 changes: 110 additions & 0 deletions dist/bin/repl.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
@echo off
setlocal enabledelayedexpansion

@rem #########################################################################
@rem ## Environment setup

set _EXITCODE=0

for %%f in ("%~dp0.") do (
set "_PROG_HOME=%%~dpf"
@rem get rid of the trailing slash
set "_PROG_HOME=!_PROG_HOME:~0,-1!"
)
call "%_PROG_HOME%\libexec\common.bat"
if not %_EXITCODE%==0 goto end

set _DEFAULT_JAVA_OPTS=-Xmx768m -Xms768m

call :args %*

@rem #########################################################################
@rem ## Main

if defined JAVA_OPTS ( set _JAVA_OPTS=%JAVA_OPTS%
) else ( set _JAVA_OPTS=%_DEFAULT_JAVA_OPTS%
)

@rem we need to escape % in the java command path, for some reason this doesnt work in common.bat
set "_JAVACMD=!_JAVACMD:%%=%%%%!"

call "%_JAVACMD%" %_JAVA_OPTS% %_JAVA_DEBUG% %_JAVA_ARGS% ^
-classpath "%_LIB_DIR%\scaladoc.jar" ^
-Dscala.expandjavacp=true ^
-Dscala.usejavacp=true ^
dotty.tools.repl.Main %_SCALA_ARGS% %_RESIDUAL_ARGS%
if not %ERRORLEVEL%==0 (
@rem echo Error: Scaladoc execution failed 1>&2
set _EXITCODE=1
goto end
)
goto end

@rem #########################################################################
@rem ## Subroutines

:args
set _JAVA_DEBUG=
set _HELP=
set _VERBOSE=
set _QUIET=
set _COLORS=
set _SCALA_ARGS=
set _JAVA_ARGS=
set _RESIDUAL_ARGS=

:args_loop
if "%~1"=="" goto args_done
set "__ARG=%~1"
if "%__ARG%"=="--" (
@rem for arg; do addResidual "$arg"; done; set -- ;;
) else if "%__ARG%"=="-h" (
set _HELP=true
call :addScala "-help"
) else if "%__ARG%"=="-help" (
set _HELP=true
call :addScala "-help"
) else if "%__ARG%"=="-v" (
set _VERBOSE=true
call :addScala "-verbose"
) else if "%__ARG%"=="-verbose" (
set _VERBOSE=true
call :addScala "-verbose"
) else if "%__ARG%"=="-debug" ( set "_JAVA_DEBUG=%_DEBUG_STR%"
) else if "%__ARG%"=="-q" ( set _QUIET=true
) else if "%__ARG%"=="-quiet" ( set _QUIET=true
) else if "%__ARG%"=="-colors" ( set _COLORS=true
) else if "%__ARG%"=="-no-colors" ( set _COLORS=
) else if "%__ARG:~0,2%"=="-D" ( call :addJava "%__ARG%"
) else if "%__ARG:~0,2%"=="-J" ( call :addJava "%__ARG:~2%"
) else (
if defined _IN_SCRIPTING_ARGS ( call :addScripting "%__ARG%"
) else ( call :addResidual "%__ARG%"
)
)
shift
goto args_loop
:args_done
goto :eof

@rem output parameter: _SCALA_ARGS
:addScala
set _SCALA_ARGS=%_SCALA_ARGS% %~1
goto :eof

@rem output parameter: _JAVA_ARGS
:addJava
set _JAVA_ARGS=%_JAVA_ARGS% %~1
goto :eof

@rem output parameter: _RESIDUAL_ARGS
:addResidual
set _RESIDUAL_ARGS=%_RESIDUAL_ARGS% %~1
goto :eof

@rem #########################################################################
@rem ## Cleanups

:end
exit /b %_EXITCODE%
endlocal
Loading