Skip to content

Commit

Permalink
[patch] enable debug
Browse files Browse the repository at this point in the history
  • Loading branch information
maxandersen committed Dec 28, 2019
1 parent 7fb719f commit f87621b
Show file tree
Hide file tree
Showing 8 changed files with 230 additions and 56 deletions.
8 changes: 8 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ jar {
}
}



shadowJar {
minimize()
// warning is printed about deprecation in 7.0 but if I fix this shadowjar turns into a bogus file
Expand All @@ -93,6 +95,12 @@ test {
useJUnitPlatform()
}

task copyTestResources(type: Copy) {
from "${projectDir}/examples"
into "${buildDir}/classes/java/test/examples"
}
processTestResources.dependsOn copyTestResources

task createChecksum(type: Checksum) {
dependsOn(assembleDist)
files = distZip.outputs.files
Expand Down
14 changes: 13 additions & 1 deletion readme.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Then try `jbang` which gives you:

* Dependency declarations using `//DEPS <gav>` for automatic dependency resolution
* Dependency resolution caching
* (PLANNED) Launch with debug enabled for instant debugging from your favorite IDE
* Launch with debug enabled for instant debugging from your favorite IDE
* (PLANNED) Generate gradle/maven file with dependencies for easy editing in your favorite IDE
* (PLANNED) Lookup dependencies with a short-hand name, i.e. `// DEPS log4j:1.2+,picocli` for quick getting started.
Expand Down Expand Up @@ -124,6 +124,18 @@ $ ./classpath_example.java
1 [main] INFO classpath_example - Hello from Java!
```

## Debugging

When running `.java` scripts with `jbang` you can pass the `--debug`-flag and the script will enable debug,
suspend the execution and wait until you connect a debugger to port 5005.

```
jbang --debug helloworld.java
Listening for transport dt_socket at address: 5005
```

NOTE: Be sure to put a breakpoint in your IDE/debugger before you connect to make the debugger actually stop when you need it.

## FAQ

[qanda]
Expand Down
17 changes: 14 additions & 3 deletions src/main/java/dk/xam/jbang/ExitException.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
package dk.xam.jbang;

public class ExitException extends Throwable {
public ExitException(int status) {
}
/**
* Used when wanting to exit app from a command.
*/
public class ExitException extends RuntimeException {

private final int status;

public ExitException(int status) {
this.status = status;
}

public int getStatus() {
return status;
}
}
68 changes: 42 additions & 26 deletions src/main/java/dk/xam/jbang/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
import picocli.CommandLine;
import picocli.CommandLine.Model.CommandSpec;

@Command(name="jbang", mixinStandardHelpOptions = false, versionProvider = VersionProvider.class, description = "Compiles and runs .java/.jsh scripts.")
@Command(name = "jbang", footer = "\nCopyright: 2020 Max Rydahl Andersen, License: MIT\nWebsite: https://github.com/maxandersen/jbang", mixinStandardHelpOptions = false, versionProvider = VersionProvider.class, description = "Compiles and runs .java/.jsh scripts.")
public class Main implements Callable<Integer> {

@Spec
CommandSpec spec;

@Option(names = {"-d", "--debug"}, arity = "0", description = "Launch with java debug enabled.")
@Option(names = {"-d", "--debug"}, description = "Launch with java debug enabled.")
boolean debug;

@Option(names = {"-h", "--help"}, usageHelp = true, description = "Display help/info")
Expand All @@ -28,20 +28,23 @@ public class Main implements Callable<Integer> {
@Option(names = {"--version"}, versionHelp = true, arity = "0", description = "Display version info")
boolean versionRequested;

@Parameters
String script;

@Parameters(arity = "1..*")
List<String> params;
@Parameters(index = "0", description = "A file with java code or if named .jsh will be run with jshell")
String scriptOrFile;

@Parameters(index = "1..*", arity = "0..*", description = "Parameters to pass on to the script")
List<String> params = new ArrayList<String>();

void info(String msg) {
spec.commandLine().getErr().println(msg);
}

void warn(String msg) {
info("[jbang] [WARNING] " + msg);
}

void quit(int status) {
out.println(status == 0 ? "true" : "false");
exit(status);
throw new ExitException(status);
}

static String USAGE = "j'bang - Enhanced scripting support for Java on *nix-based systems.\n" + "\n"
Expand All @@ -52,12 +55,15 @@ void quit(int status) {
private static File prepareScript;

public static void main(String... args) throws FileNotFoundException {
var main = new Main();

int exitcode = new CommandLine(main).setStopAtPositional(true).setOut(new PrintWriter(err, true)).setErr(new PrintWriter(err, true)).execute(args);
int exitcode = getCommandLine().execute(args);
System.exit(exitcode);
}

static CommandLine getCommandLine() {
return new CommandLine(new Main()).setExitCodeExceptionMapper(new VersionProvider()).setStopAtPositional(true)
.setOut(new PrintWriter(err, true)).setErr(new PrintWriter(err, true));
}

@Override
public Integer call() throws FileNotFoundException {

Expand All @@ -69,7 +75,15 @@ public Integer call() throws FileNotFoundException {
quit(0);
}

prepareScript = prepareScript(script);
String cmdline = generateCommandLine();

out.println(cmdline);

return 0;
}

String generateCommandLine() throws FileNotFoundException {
prepareScript = prepareScript(scriptOrFile);

Scanner sc = new Scanner(prepareScript);
sc.useDelimiter("\\Z");
Expand All @@ -79,32 +93,35 @@ public Integer call() throws FileNotFoundException {
List<String> dependencies = script.collectDependencies();

var classpath = new DependencyUtil().resolveDependencies(dependencies, Collections.emptyList(), true);
StringBuffer optionalArgs = new StringBuffer(" ");
List<String> optionalArgs = new ArrayList<String>();

var javacmd = "java";
var sourceargs = " --source 11";
if (prepareScript.getName().endsWith(".jsh")) {
javacmd = "jshell";
sourceargs = "";
if (!classpath.isBlank()) {
optionalArgs.append("--class-path " + classpath);
optionalArgs.add("--class-path " + classpath);
}
if (debug) {
info("debug not possible when running via jshell.");
}

} else {
// optionalArgs.append("
// -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005");
optionalArgs.add("--source 11");
if (debug) {
optionalArgs.add("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005");
}
if (!classpath.isBlank()) {
optionalArgs.append("-classpath " + classpath);
optionalArgs.add("-classpath " + classpath);
}
}

var cmdline = new StringBuffer(javacmd).append(optionalArgs).append(sourceargs)
.append(" " + getenv("JBANG_FILE"))
.append(" " + params.stream().skip(1).collect(Collectors.joining(" ")));
List<String> fullArgs = new ArrayList<>();
fullArgs.add(javacmd);
fullArgs.addAll(optionalArgs);
fullArgs.add(scriptOrFile);
fullArgs.addAll(params);

out.println(cmdline);

return 0;
return fullArgs.stream().collect(Collectors.joining(" "));
}

/**
Expand Down Expand Up @@ -201,5 +218,4 @@ private static File prepareScript(String scriptresouce) {
return scriptFile;
}


}
2 changes: 1 addition & 1 deletion src/main/java/dk/xam/jbang/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ static public void errorMsg(String msg) {

static public void quit(int status) {
System.out.print(status > 0 ? "true" : "false");
System.exit(status);
throw new ExitException(status);
}

}
10 changes: 9 additions & 1 deletion src/main/java/dk/xam/jbang/VersionProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,17 @@

import picocli.CommandLine;

public class VersionProvider implements CommandLine.IVersionProvider {
public class VersionProvider implements CommandLine.IVersionProvider, CommandLine.IExitCodeExceptionMapper {
@Override
public String[] getVersion() throws Exception {
return new String[]{dk.xam.jbang.BuildConfig.VERSION};
}

@Override
public int getExitCode(Throwable t) {
if (t instanceof ExitException) {
return ((ExitException) t).getStatus();
}
return CommandLine.ExitCode.SOFTWARE;
}
}
79 changes: 55 additions & 24 deletions src/test/java/dk/xam/jbang/TestArguments.java
Original file line number Diff line number Diff line change
@@ -1,47 +1,78 @@
package dk.xam.jbang;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

import java.util.Arrays;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import picocli.CommandLine;

import static org.junit.jupiter.api.Assertions.*;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.MatcherAssert.assertThat;

class TestArguments {

private CommandLine cli;
private Main main;

@BeforeEach
void setup() {
cli = Main.getCommandLine();
main = cli.getCommand();
}

@Test
public void testBasicArguments() {
var arg = new Main();
new CommandLine(arg).parseArgs("-h", "--debug", "myfile.java");
cli.parseArgs("-h", "--debug", "myfile.java");

assert arg.helpRequested;
assert arg.debug;
assertEquals(1, arg.params.size());
assert main.helpRequested;
assertThat(main.debug, is(true));
assertThat(main.scriptOrFile, is("myfile.java"));
assertThat(main.params.size(), is(0));

}

@Test
public void testArgumentsForJbang() {

var a = Main.argsForJbang("test.java");
assertThat(a, is(new String[] {"test.java"}));

a = Main.argsForJbang("--debug", "test.java");
assertThat(a, is(new String[]{"--debug", "--", "test.java"}));
public void testDoubleDebug() {
cli.parseArgs("--debug", "test.java", "--debug", "wonka");
assertThat(main.debug, is(true));
assertThat(main.scriptOrFile, is("test.java"));
assertThat(main.params, is(Arrays.asList("--debug", "wonka")));
}

a = Main.argsForJbang("test.java", "-h");
assertThat(a, is(new String[]{"test.java", "-h"}));
/**
* @Test public void testInit() { cli.parseArgs("--init", "x.java", "y.java");
* assertThat(main.script, is("x.java")); assertThat(main.params,
* is(Arrays.asList("x.java", "y.java"))); }
**/

a = Main.argsForJbang("-", "--help");
assertThat(a, is(new String[]{"-", "--help"}));
@Test
public void testStdInWithHelpParam() {
cli.parseArgs("-", "--help");
assertThat(main.scriptOrFile, is("-"));
assertThat(main.helpRequested, is(false));
assertThat(main.params, is(Arrays.asList("--help")));
}

a = Main.argsForJbang("--init", "x.java", "y.java");
assertThat(a, is(new String[]{"--init", "--", "x.java", "y.java"}));
@Test
public void testScriptWithHelpParam() {
cli.parseArgs("test.java", "-h");
assertThat(main.scriptOrFile, is("test.java"));
assertThat(main.helpRequested, is(false));
assertThat(main.params, is(Arrays.asList("-h")));
}

a = Main.argsForJbang("--debug", "test.java", "--debug", "wonka");
assertThat(a, is(new String[]{"--debug", "--", "test.java", "--debug", "wonka"}));
@Test
public void testDebugWithScript() {
cli.parseArgs("--debug", "test.java");
assertThat(main.scriptOrFile, is("test.java"));
assertThat(main.debug, is(true));
}

@Test
public void testSimpleScript() {
cli.parseArgs("test.java");
assertThat(main.scriptOrFile, is("test.java"));
}

}
Loading

0 comments on commit f87621b

Please sign in to comment.