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

Must specify --repl to enable debug server #10709

Merged
merged 2 commits into from
Jul 29, 2024
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
74 changes: 38 additions & 36 deletions engine/runner/src/main/java/org/enso/runner/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
import scala.runtime.BoxedUnit;

/** The main CLI entry point class. */
public final class Main {
public class Main {
private static final String JVM_OPTION = "jvm";
private static final String RUN_OPTION = "run";
private static final String INSPECT_OPTION = "inspect";
Expand Down Expand Up @@ -98,6 +98,8 @@ public final class Main {

private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Main.class);

Main() {}

private static boolean isDevBuild() {
return Info.ensoVersion().matches(".+-SNAPSHOT$");
}
Expand All @@ -106,11 +108,8 @@ private static Option.Builder cliOptionBuilder() {
return Option.builder();
}

/**
* Builds the [[Options]] object representing the CLI syntax.
*
* @return an [[Options]] object representing the CLI syntax
*/
private static final Options CLI_OPTIONS = buildOptions();

private static Options buildOptions() {
var help =
cliOptionBuilder().option("h").longOpt(HELP_OPTION).desc("Displays this message.").build();
Expand Down Expand Up @@ -512,22 +511,22 @@ private static Options buildOptions() {
*
* @param options object representing the CLI syntax
*/
private static void printHelp(Options options) {
new HelpFormatter().printHelp(LanguageInfo.ID, options);
private static void printHelp() {
new HelpFormatter().printHelp(LanguageInfo.ID, CLI_OPTIONS);
}

/** Terminates the process with a failure exit code. */
private static RuntimeException exitFail() {
private RuntimeException exitFail() {
return doExit(1);
}

/** Terminates the process with a success exit code. */
private static RuntimeException exitSuccess() {
private final RuntimeException exitSuccess() {
return doExit(0);
}

/** Shuts down the logging service and terminates the process. */
private static RuntimeException doExit(int exitCode) {
RuntimeException doExit(int exitCode) {
RunnerLogging.tearDown();
System.exit(exitCode);
return null;
Expand Down Expand Up @@ -665,7 +664,7 @@ private void compile(
* @param executionEnvironment name of the execution environment to use during execution or {@code
* null}
*/
private void run(
private void handleRun(
String path,
java.util.List<String> additionalArgs,
String projectPath,
Expand All @@ -675,6 +674,7 @@ private void run(
boolean disablePrivateCheck,
boolean enableAutoParallelism,
boolean enableStaticAnalysis,
boolean enableDebugServer,
boolean inspect,
boolean dump,
String executionEnvironment,
Expand Down Expand Up @@ -708,9 +708,13 @@ private void run(
.options(options);

if (inspect) {
if (enableDebugServer) {
println("Cannot use --inspect and --repl and --run at once");
throw exitFail();
}
options.put("inspect", "");
} else {
// by default running with debug server enabled
}
if (enableDebugServer) {
factory.messageTransport(replTransport());
options.put(DebugServerInfo.ENABLE_OPTION, "true");
}
Expand Down Expand Up @@ -960,7 +964,7 @@ private void displayVersion(boolean useJson) {
}

/** Parses the log level option. */
private static Level parseLogLevel(String levelOption) {
private Level parseLogLevel(String levelOption) {
var name = levelOption.toLowerCase();
var found =
Stream.of(Level.values()).filter(x -> name.equals(x.name().toLowerCase())).findFirst();
Expand All @@ -977,7 +981,7 @@ private static Level parseLogLevel(String levelOption) {
}

/** Parses an URI that specifies the logging service connection. */
private static URI parseUri(String string) {
private URI parseUri(String string) {
try {
return new URI(string);
} catch (URISyntaxException ex) {
Expand All @@ -1001,15 +1005,13 @@ public static void main(String[] args) throws Exception {
/**
* Main entry point for the CLI program.
*
* @param options the command line options
* @param line the provided command line arguments
* @param logLevel the provided log level
* @param logMasking the flag indicating if the log masking is enabled
*/
private void runMain(Options options, CommandLine line, Level logLevel, boolean logMasking)
throws IOException {
final void mainEntry(CommandLine line, Level logLevel, boolean logMasking) throws IOException {
if (line.hasOption(HELP_OPTION)) {
printHelp(options);
printHelp();
throw exitSuccess();
}
if (line.hasOption(VERSION_OPTION)) {
Expand Down Expand Up @@ -1089,7 +1091,7 @@ private void runMain(Options options, CommandLine line, Level logLevel, boolean
}

if (line.hasOption(RUN_OPTION)) {
run(
handleRun(
line.getOptionValue(RUN_OPTION),
Arrays.asList(line.getArgs()),
line.getOptionValue(IN_PROJECT_OPTION),
Expand All @@ -1099,14 +1101,15 @@ private void runMain(Options options, CommandLine line, Level logLevel, boolean
line.hasOption(DISABLE_PRIVATE_CHECK_OPTION),
line.hasOption(AUTO_PARALLELISM_OPTION),
line.hasOption(ENABLE_STATIC_ANALYSIS_OPTION),
line.hasOption(REPL_OPTION),
line.hasOption(INSPECT_OPTION),
line.hasOption(DUMP_GRAPHS_OPTION),
line.getOptionValue(EXECUTION_ENVIRONMENT_OPTION),
scala.Option.apply(line.getOptionValue(WARNINGS_LIMIT))
.map(Integer::parseInt)
.getOrElse(() -> 100));
}
if (line.hasOption(REPL_OPTION)) {
if (line.hasOption(REPL_OPTION) && !line.hasOption(RUN_OPTION)) {
runRepl(
line.getOptionValue(IN_PROJECT_OPTION),
logLevel,
Expand All @@ -1122,7 +1125,7 @@ private void runMain(Options options, CommandLine line, Level logLevel, boolean
preinstallDependencies(line.getOptionValue(IN_PROJECT_OPTION), logLevel);
}
if (line.getOptions().length == 0) {
printHelp(options);
printHelp();
throw exitFail();
}
}
Expand Down Expand Up @@ -1240,16 +1243,15 @@ private static final <T> scala.collection.immutable.List<T> join(
return scala.collection.immutable.$colon$colon$.MODULE$.apply(head, tail);
}

private void println(String msg) {
void println(String msg) {
System.out.println(msg);
}

private void launch(String[] args) throws IOException, InterruptedException, URISyntaxException {
var options = buildOptions();
var line = preprocessArguments(options, args);
var line = preprocessArguments(args);

var logMasking = new boolean[1];
var logLevel = setupLogging(options, line, logMasking);
var logLevel = setupLogging(line, logMasking);

if (line.hasOption(JVM_OPTION)) {
var jvm = line.getOptionValue(JVM_OPTION);
Expand Down Expand Up @@ -1332,36 +1334,36 @@ private void launch(String[] args) throws IOException, InterruptedException, URI
}
}

launch(options, line, logLevel, logMasking[0]);
launch(line, logLevel, logMasking[0]);
}

protected CommandLine preprocessArguments(Options options, String[] args) {
final CommandLine preprocessArguments(String... args) {
var parser = new DefaultParser();
try {
var startParsing = System.currentTimeMillis();
var line = parser.parse(options, args);
var line = parser.parse(CLI_OPTIONS, args);
logger.trace(
"Parsing Language Server arguments took {0}ms",
System.currentTimeMillis() - startParsing);
return line;
} catch (Exception e) {
printHelp(options);
printHelp();
throw exitFail();
}
}

private static Level setupLogging(Options options, CommandLine line, boolean[] logMasking) {
private Level setupLogging(CommandLine line, boolean[] logMasking) {
var logLevel =
scala.Option.apply(line.getOptionValue(LOG_LEVEL))
.map(Main::parseLogLevel)
.map(this::parseLogLevel)
.getOrElse(() -> defaultLogLevel);
var connectionUri = scala.Option.apply(line.getOptionValue(LOGGER_CONNECT)).map(Main::parseUri);
var connectionUri = scala.Option.apply(line.getOptionValue(LOGGER_CONNECT)).map(this::parseUri);
logMasking[0] = !line.hasOption(NO_LOG_MASKING);
RunnerLogging.setup(connectionUri, logLevel, logMasking[0]);
return logLevel;
}

private void launch(Options options, CommandLine line, Level logLevel, boolean logMasking) {
private void launch(CommandLine line, Level logLevel, boolean logMasking) {
if (line.hasOption(LANGUAGE_SERVER_OPTION)) {
try {
var conf = parseProfilingConfig(line);
Expand All @@ -1379,7 +1381,7 @@ private void launch(Options options, CommandLine line, Level logLevel, boolean l
conf,
ExecutionContext.global(),
() -> {
runMain(options, line, logLevel, logMasking);
mainEntry(line, logLevel, logMasking);
return BoxedUnit.UNIT;
});
} catch (IOException ex) {
Expand Down
46 changes: 46 additions & 0 deletions engine/runner/src/test/java/org/enso/runner/EngineMainTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.enso.runner;

import static org.junit.Assert.assertEquals;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.slf4j.event.Level;

public class EngineMainTest {
private final List<String> linesOut = new ArrayList<>();

@Test
public void cannotUseReplAndInspectAtOnce() throws Exception {
try {
var m =
new Main() {
@Override
RuntimeException doExit(int code) {
throw new ExitCode(code);
}

void println(String line) {
linesOut.add(line);
}
};
var file = File.createTempFile("some", ".enso");
file.deleteOnExit();
var line = m.preprocessArguments("--repl", "--inspect", "--run", file.getAbsolutePath());
m.mainEntry(line, Level.INFO, false);
} catch (ExitCode ex) {
assertEquals("Execution fails", 1, ex.exitCode);
assertEquals("One line printed", 1, linesOut.size());
assertEquals("Cannot use --inspect and --repl and --run at once", linesOut.get(0));
}
}

private static final class ExitCode extends RuntimeException {
final int exitCode;

ExitCode(int exitCode) {
this.exitCode = exitCode;
}
}
}
4 changes: 4 additions & 0 deletions test/Base_Tests/src/Semantic/Runtime_Spec.enso
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Standard.Base.Runtime
import Standard.Base.Runtime.Debug
import Standard.Base.Data.Numbers.Integer
import Standard.Base.Any.Any
import Standard.Base.Nothing.Nothing
Expand Down Expand Up @@ -38,6 +39,9 @@ add_specs suite_builder =

r2 = Panic.catch Any (Runtime.with_disabled_context Input environment=Runtime.current_execution_environment <| in_fn (out_fn 10)) p-> p.payload.to_text
r2 . should_equal "(Forbidden_Operation.Error 'The Input context is disabled.')"
suite_builder.group "Debug" group_builder->
group_builder.specify "Debug.breakpoint doesn't stop indefinitly" <|
Debug.breakpoint

main filter=Nothing =
suite = Test.build suite_builder->
Expand Down
Loading