diff --git a/docs/modules/ROOT/pages/usage.adoc b/docs/modules/ROOT/pages/usage.adoc index 95f75031b..97e61b75d 100644 --- a/docs/modules/ROOT/pages/usage.adoc +++ b/docs/modules/ROOT/pages/usage.adoc @@ -230,6 +230,12 @@ jbang init -t hello.kt hello.kt Hello World ---- +== Running script passed as argument + +jbang can run scripts that are passed directly on the command line using the `--code` option: + +`jbang --code System.out.println("Hello World!")` + == Running script from standard input jbang can run scripts directly from standard input using `-` or `/dev/stdin` as input. diff --git a/itests/bar/Bar.java b/itests/bar/Bar.java new file mode 100755 index 000000000..cb74578cf --- /dev/null +++ b/itests/bar/Bar.java @@ -0,0 +1,6 @@ +import static java.lang.System.*; +public class Bar { + public static void main(String... args) { + out.println("Hello World"); + } +} diff --git a/itests/foo.java b/itests/foo.java new file mode 100755 index 000000000..9b4304af3 --- /dev/null +++ b/itests/foo.java @@ -0,0 +1,7 @@ +import static java.lang.System.*; + +public class foo { + public static void main(String... args) { + out.println(Bar.class.getName()); + } +} diff --git a/itests/jsh.feature b/itests/jsh.feature index 7a3f49266..c8436be40 100644 --- a/itests/jsh.feature +++ b/itests/jsh.feature @@ -43,3 +43,7 @@ Scenario: jsh with deps 1 Then match err !contains ".NoClassDef" Then match out contains "Fake output:" +Scenario: as code option + * command('jbang --code "System.out.println(\\\"Hello\\\")" jbangtest') + * match out == "Hello\n" + \ No newline at end of file diff --git a/itests/run-nix.feature b/itests/run-nix.feature new file mode 100644 index 000000000..cf397e06c --- /dev/null +++ b/itests/run-nix.feature @@ -0,0 +1,14 @@ +Feature: run on non-windows + +Background: + * if (windows) karate.abort() + +Scenario: as code option 2 + * command('jbang --code "$(cat helloworld.java)" jbangtest') + * match err == "[jbang] Building jar...\n" + * match out == "Hello jbangtest\n" + +Scenario: as code option 3 + * command('jbang "--code=$(cat helloworld.java)" jbangtest') + * match err == "[jbang] Building jar...\n" + * match out == "Hello jbangtest\n" diff --git a/itests/run.feature b/itests/run.feature index 93d5add5b..82538ff1c 100644 --- a/itests/run.feature +++ b/itests/run.feature @@ -28,6 +28,10 @@ Scenario: java run multiple matching sources Then match out contains "NestedOne" Then match out contains "NestedTwo" +Scenario: java run multiple sources via cli + When command('jbang -s bar/Bar.java foo.java') + Then match out contains "Bar" + Scenario: java run multiple files When command('jbang res/resource.java') Then match out contains "hello properties" diff --git a/src/main/java/dev/jbang/Main.java b/src/main/java/dev/jbang/Main.java index e83838737..45330d855 100644 --- a/src/main/java/dev/jbang/Main.java +++ b/src/main/java/dev/jbang/Main.java @@ -31,7 +31,8 @@ private static String[] handleDefaultRun(CommandLine.Model.CommandSpec spec, Str } // Check if we have a parameter and it's not the same as any of the subcommand // names - if (!remainingArgs.isEmpty() && !spec.subcommands().containsKey(remainingArgs.get(0))) { + if (!remainingArgs.isEmpty() && !spec.subcommands().containsKey(remainingArgs.get(0)) + || hasRunOpts(leadingOpts)) { List result = new ArrayList<>(); result.add("run"); result.addAll(leadingOpts); @@ -40,4 +41,13 @@ private static String[] handleDefaultRun(CommandLine.Model.CommandSpec spec, Str } return args; } + + private static boolean hasRunOpts(List opts) { + boolean res = opts.contains("-i") || opts.contains("--interactive") + || opts.contains("-c") || opts.contains("--code"); + res = res || opts .stream() + .anyMatch(o -> o.startsWith("-i=") || o.startsWith("--interactive=") + || o.startsWith("-c=") || o.startsWith("--code=")); + return res; + } } diff --git a/src/main/java/dev/jbang/catalog/Alias.java b/src/main/java/dev/jbang/catalog/Alias.java index 24c5ae5da..6b8bb71f2 100644 --- a/src/main/java/dev/jbang/catalog/Alias.java +++ b/src/main/java/dev/jbang/catalog/Alias.java @@ -20,6 +20,7 @@ public class Alias extends CatalogItem { public final List arguments; @SerializedName(value = "java-options") public final List javaOptions; + public final List sources; public final List dependencies; public final List repositories; public final List classpaths; @@ -30,13 +31,14 @@ public class Alias extends CatalogItem { public final String mainClass; private Alias() { - this(null, null, null, null, null, null, null, null, null, null, null); + this(null, null, null, null, null, null, null, null, null, null, null, null); } public Alias(String scriptRef, String description, List arguments, List javaOptions, + List sources, List dependencies, List repositories, List classpaths, @@ -49,6 +51,7 @@ public Alias(String scriptRef, this.description = description; this.arguments = arguments; this.javaOptions = javaOptions; + this.sources = sources; this.dependencies = dependencies; this.repositories = repositories; this.classpaths = classpaths; @@ -118,6 +121,8 @@ private static Alias merge(Alias a1, String name, Function findUn List args = a1.arguments != null && !a1.arguments.isEmpty() ? a1.arguments : a2.arguments; List opts = a1.javaOptions != null && !a1.javaOptions.isEmpty() ? a1.javaOptions : a2.javaOptions; + List srcs = a1.sources != null && !a1.sources.isEmpty() ? a1.sources + : a2.sources; List deps = a1.dependencies != null && !a1.dependencies.isEmpty() ? a1.dependencies : a2.dependencies; List repos = a1.repositories != null && !a1.repositories.isEmpty() ? a1.repositories @@ -129,7 +134,7 @@ private static Alias merge(Alias a1, String name, Function findUn String javaVersion = a1.javaVersion != null ? a1.javaVersion : a2.javaVersion; String mainClass = a1.mainClass != null ? a1.mainClass : a2.mainClass; Catalog catalog = a2.catalog != null ? a2.catalog : a1.catalog; - return new Alias(a2.scriptRef, desc, args, opts, deps, repos, cpaths, props, javaVersion, mainClass, + return new Alias(a2.scriptRef, desc, args, opts, srcs, deps, repos, cpaths, props, javaVersion, mainClass, catalog); } else { return a1; diff --git a/src/main/java/dev/jbang/catalog/Catalog.java b/src/main/java/dev/jbang/catalog/Catalog.java index cb93a13cc..7a84879f1 100644 --- a/src/main/java/dev/jbang/catalog/Catalog.java +++ b/src/main/java/dev/jbang/catalog/Catalog.java @@ -56,8 +56,8 @@ public Catalog(String baseRef, String description, ResourceRef catalogRef, Map this.catalogs.put(key, new CatalogRef(c.catalogRef, c.description, this))); aliases.forEach((key, a) -> this.aliases.put(key, - new Alias(a.scriptRef, a.description, a.arguments, a.javaOptions, a.dependencies, a.repositories, - a.classpaths, a.properties, a.javaVersion, a.mainClass, this))); + new Alias(a.scriptRef, a.description, a.arguments, a.javaOptions, a.sources, a.dependencies, + a.repositories, a.classpaths, a.properties, a.javaVersion, a.mainClass, this))); templates.forEach((key, t) -> this.templates.put(key, new Template(t.fileRefs, t.description, t.properties, this))); } diff --git a/src/main/java/dev/jbang/catalog/CatalogUtil.java b/src/main/java/dev/jbang/catalog/CatalogUtil.java index d18deadb4..78be19976 100644 --- a/src/main/java/dev/jbang/catalog/CatalogUtil.java +++ b/src/main/java/dev/jbang/catalog/CatalogUtil.java @@ -35,6 +35,7 @@ public static Path addNearestAlias(String name, String scriptRef, String description, List arguments, + List sources, List dependencies, List repositories, List classPaths, @@ -43,8 +44,8 @@ public static Path addNearestAlias(String name, String javaVersion, String mainClass) { Path catalogFile = Catalog.getCatalogFile(null); - addAlias(catalogFile, name, scriptRef, description, arguments, javaRuntimeOptions, dependencies, repositories, - classPaths, properties, javaVersion, mainClass); + addAlias(catalogFile, name, scriptRef, description, arguments, javaRuntimeOptions, sources, dependencies, + repositories, classPaths, properties, javaVersion, mainClass); return catalogFile; } @@ -60,6 +61,7 @@ public static Alias addAlias(Path catalogFile, String description, List arguments, List javaRuntimeOptions, + List sources, List dependencies, List repositories, List classPaths, @@ -70,7 +72,8 @@ public static Alias addAlias(Path catalogFile, catalogFile = cwd.resolve(catalogFile); Catalog catalog = Catalog.get(catalogFile); scriptRef = catalog.relativize(scriptRef); - Alias alias = new Alias(scriptRef, description, arguments, javaRuntimeOptions, dependencies, repositories, + Alias alias = new Alias(scriptRef, description, arguments, javaRuntimeOptions, sources, dependencies, + repositories, classPaths, properties, javaVersion, mainClass, catalog); catalog.aliases.put(name, alias); try { diff --git a/src/main/java/dev/jbang/cli/Alias.java b/src/main/java/dev/jbang/cli/Alias.java index 6c103bd9b..92bab29f6 100644 --- a/src/main/java/dev/jbang/cli/Alias.java +++ b/src/main/java/dev/jbang/cli/Alias.java @@ -61,6 +61,9 @@ class AliasAdd extends BaseAliasCommand { @CommandLine.Mixin DependencyInfoMixin dependencyInfoMixin; + @CommandLine.Option(names = { "-s", "--sources" }, description = "Add additional sources.") + List sources; + @CommandLine.Option(names = { "--description", "-d" }, description = "A description for the alias") String description; @@ -102,11 +105,11 @@ public Integer doCall() { Path catFile = getCatalog(false); if (catFile != null) { - CatalogUtil.addAlias(catFile, name, scriptOrFile, desc, userParams, javaRuntimeOptions, + CatalogUtil.addAlias(catFile, name, scriptOrFile, desc, userParams, javaRuntimeOptions, sources, dependencyInfoMixin.getDependencies(), dependencyInfoMixin.getRepositories(), dependencyInfoMixin.getClasspaths(), dependencyInfoMixin.getProperties(), javaVersion, mainClass); } else { - catFile = CatalogUtil.addNearestAlias(name, scriptOrFile, desc, userParams, javaRuntimeOptions, + catFile = CatalogUtil.addNearestAlias(name, scriptOrFile, desc, userParams, javaRuntimeOptions, sources, dependencyInfoMixin.getDependencies(), dependencyInfoMixin.getRepositories(), dependencyInfoMixin.getClasspaths(), dependencyInfoMixin.getProperties(), javaVersion, mainClass); } diff --git a/src/main/java/dev/jbang/cli/BaseBuildCommand.java b/src/main/java/dev/jbang/cli/BaseBuildCommand.java index 59fb02c06..b23a3d6d5 100644 --- a/src/main/java/dev/jbang/cli/BaseBuildCommand.java +++ b/src/main/java/dev/jbang/cli/BaseBuildCommand.java @@ -59,6 +59,9 @@ public abstract class BaseBuildCommand extends BaseScriptCommand { @CommandLine.Mixin DependencyInfoMixin dependencyInfoMixin; + @CommandLine.Option(names = { "-s", "--sources" }, description = "Add additional sources.") + List sources; + @CommandLine.Option(names = { "-m", "--main" }, description = "Main class to use when running. Used primarily for running jar's.") String main; @@ -179,7 +182,7 @@ public static IntegrationResult buildJar(ScriptSource src, RunContext ctx, File // add source files to compile optionList.add(src.getResourceRef().getFile().getPath()); - optionList.addAll(src .getAllSources() + optionList.addAll(ctx .getAllSources(src) .stream() .map(x -> x.getResourceRef().getFile().getPath()) .collect(Collectors.toList())); diff --git a/src/main/java/dev/jbang/cli/BaseScriptCommand.java b/src/main/java/dev/jbang/cli/BaseScriptCommand.java index 4bb53024c..2f2a5d4d4 100644 --- a/src/main/java/dev/jbang/cli/BaseScriptCommand.java +++ b/src/main/java/dev/jbang/cli/BaseScriptCommand.java @@ -24,9 +24,15 @@ public abstract class BaseScriptCommand extends BaseCommand { @CommandLine.Option(names = { "--jsh" }, description = "Force input to be interpreted with jsh/jshell") boolean forcejsh = false; - @CommandLine.Parameters(index = "0", arity = "1", description = "A file with java code or if named .jsh will be run with jshell") + @CommandLine.Parameters(index = "0", arity = "0..1", description = "A reference to a source file") String scriptOrFile; + protected void requireScriptArgument() { + if (scriptOrFile == null) { + throw new IllegalArgumentException("Missing required parameter: ''"); + } + } + static protected boolean needsJar(Source source, RunContext context) { // anything but .jar and .jsh files needs jar return !(source.isJar() || context.isForceJsh() || source.isJShell()); diff --git a/src/main/java/dev/jbang/cli/Build.java b/src/main/java/dev/jbang/cli/Build.java index 7d7374313..4fc6dffd0 100644 --- a/src/main/java/dev/jbang/cli/Build.java +++ b/src/main/java/dev/jbang/cli/Build.java @@ -12,6 +12,7 @@ public class Build extends BaseBuildCommand { @Override public Integer doCall() throws IOException { + requireScriptArgument(); if (insecure) { enableInsecure(); } @@ -35,6 +36,7 @@ RunContext getRunContext() { ctx.setMainClass(main); ctx.setNativeImage(nativeImage); ctx.setCatalog(catalog); + ctx.setAdditionalSources(sources); return ctx; } } diff --git a/src/main/java/dev/jbang/cli/Edit.java b/src/main/java/dev/jbang/cli/Edit.java index d5ab6002d..f09021d31 100644 --- a/src/main/java/dev/jbang/cli/Edit.java +++ b/src/main/java/dev/jbang/cli/Edit.java @@ -58,7 +58,7 @@ public class Edit extends BaseScriptCommand { @Override public Integer doCall() throws IOException { - + requireScriptArgument(); if (insecure) { enableInsecure(); } @@ -258,7 +258,7 @@ File createProjectForEdit(ScriptSource src, RunContext ctx, boolean reload) thro Path srcFile = srcDir.toPath().resolve(name); Util.createLink(srcFile, originalFile.toPath()); - for (ScriptSource source : src.getAllSources()) { + for (ScriptSource source : ctx.getAllSources(src)) { File sfile = null; if (source.getJavaPackage().isPresent()) { File packageDir = new File(srcDir, source.getJavaPackage().get().replace(".", File.separator)); diff --git a/src/main/java/dev/jbang/cli/Info.java b/src/main/java/dev/jbang/cli/Info.java index 7489f0497..7250e7e8e 100644 --- a/src/main/java/dev/jbang/cli/Info.java +++ b/src/main/java/dev/jbang/cli/Info.java @@ -138,6 +138,7 @@ public ScriptInfo(Source src, RunContext ctx) { private static Set scripts; ScriptInfo getInfo() { + requireScriptArgument(); if (insecure) { enableInsecure(); } diff --git a/src/main/java/dev/jbang/cli/Init.java b/src/main/java/dev/jbang/cli/Init.java index 71797fe24..c9a19cf52 100644 --- a/src/main/java/dev/jbang/cli/Init.java +++ b/src/main/java/dev/jbang/cli/Init.java @@ -46,6 +46,7 @@ public class Init extends BaseScriptCommand { @Override public Integer doCall() throws IOException { + requireScriptArgument(); dev.jbang.catalog.Template tpl = dev.jbang.catalog.Template.get(initTemplate); if (tpl == null) { throw new ExitException(BaseCommand.EXIT_INVALID_INPUT, diff --git a/src/main/java/dev/jbang/cli/Run.java b/src/main/java/dev/jbang/cli/Run.java index d3a27bbba..b4a1cbc51 100644 --- a/src/main/java/dev/jbang/cli/Run.java +++ b/src/main/java/dev/jbang/cli/Run.java @@ -18,6 +18,7 @@ import dev.jbang.source.RunContext; import dev.jbang.source.ScriptSource; import dev.jbang.source.Source; +import dev.jbang.source.resolvers.LiteralScriptResourceResolver; import dev.jbang.util.JavaUtil; import dev.jbang.util.Util; @@ -60,20 +61,50 @@ boolean debug() { @CommandLine.Option(names = { "--javaagent" }, parameterConsumer = KeyOptionalValueConsumer.class) public Map> javaAgentSlots; - @CommandLine.Option(names = { "--interactive" }, description = "activate interactive mode") + @CommandLine.Option(names = { "-i", "--interactive" }, description = "Activate interactive mode") public boolean interactive; + @CommandLine.Option(names = { "-c", + "--code" }, arity = "0..1", description = "Run the given string as code", preprocessor = StrictParameterPreprocessor.class) + public Optional literalScript; + @CommandLine.Parameters(index = "1..*", arity = "0..*", description = "Parameters to pass on to the script") public List userParams = new ArrayList<>(); @Override public Integer doCall() throws IOException { + if (scriptOrFile == null && !interactive && !literalScript.isPresent()) { + throw new IllegalArgumentException("Missing required parameter: ''"); + } + if (insecure) { enableInsecure(); } RunContext ctx = getRunContext(); - Source src = ctx.forResource(scriptOrFile); + Source src; + if (literalScript.isPresent()) { + String script; + if (!literalScript.get().isEmpty()) { + script = literalScript.get(); + if (scriptOrFile != null) { + userParams.add(0, scriptOrFile); + scriptOrFile = null; + } + } else { + script = scriptOrFile; + } + src = ctx.forResourceRef(LiteralScriptResourceResolver.stringToResourceRef(null, script)); + } else { + if (scriptOrFile != null) { + src = ctx.forResource(scriptOrFile); + } else { + // HACK it's a crappy way to work around the fact that in the case of + // interactive we might not have a file to reference but all the code + // expects one to exist + src = ctx.forResourceRef(LiteralScriptResourceResolver.stringToResourceRef(null, "")); + } + } src = prepareArtifacts(src, ctx); String cmdline = generateOSCommandLine(src, ctx); @@ -94,6 +125,7 @@ RunContext getRunContext() { ctx.setMainClass(main); ctx.setNativeImage(nativeImage); ctx.setCatalog(catalog); + ctx.setAdditionalSources(sources); return ctx; } @@ -322,7 +354,7 @@ List generateCommandLineList(Source src, RunContext ctx) throws IOExcept } else { if (ctx.isForceJsh() || src.isJShell()) { if (src instanceof ScriptSource) { - for (Source s : ((ScriptSource) src).getAllSources()) { + for (Source s : ctx.getAllSources((ScriptSource) src)) { fullArgs.add(s.getResourceRef().getFile().toString()); } } diff --git a/src/main/java/dev/jbang/source/MarkdownScriptSource.java b/src/main/java/dev/jbang/source/MarkdownScriptSource.java index b93f81832..cbba7371d 100644 --- a/src/main/java/dev/jbang/source/MarkdownScriptSource.java +++ b/src/main/java/dev/jbang/source/MarkdownScriptSource.java @@ -8,7 +8,7 @@ import dev.jbang.cli.BaseCommand; import dev.jbang.cli.ExitException; -import dev.jbang.source.resolvers.StdinScriptResourceResolver; +import dev.jbang.source.resolvers.LiteralScriptResourceResolver; public class MarkdownScriptSource extends ScriptSource { @@ -22,7 +22,7 @@ public static ScriptSource create(ResourceRef resourceRef, Function { // cache folder it is stored inside private final File file; + public static final ResourceRef nullRef = new ResourceRef(null, null); + private ResourceRef(String ref, File file) { this.originalResource = ref; this.file = file; @@ -54,7 +57,8 @@ public ResourceRef asSibling(String siblingResource) { sr = Paths.get(originalResource.substring(11)).resolveSibling(siblingResource).toString(); sr = "classpath:" + sr; } else { - sr = Paths.get(originalResource).resolveSibling(siblingResource).toString(); + Path baseDir = originalResource != null ? Paths.get(originalResource) : Util.getCwd().resolve("dummy"); + sr = baseDir.resolveSibling(siblingResource).toString(); } ResourceRef result = forResource(sr); if (result == null) { diff --git a/src/main/java/dev/jbang/source/ResourceResolver.java b/src/main/java/dev/jbang/source/ResourceResolver.java index cc115c2c7..1a3e7f320 100644 --- a/src/main/java/dev/jbang/source/ResourceResolver.java +++ b/src/main/java/dev/jbang/source/ResourceResolver.java @@ -38,7 +38,7 @@ public interface ResourceResolver { static ResourceResolver forScripts(Function depResolver) { return new CombinedResourceResolver( new RenamingScriptResourceResolver(), - new StdinScriptResourceResolver(), + new LiteralScriptResourceResolver(), new RemoteResourceResolver(RemoteResourceResolver::fetchScriptFromUntrustedURL), new ClasspathResourceResolver(), new GavResourceResolver(depResolver), diff --git a/src/main/java/dev/jbang/source/RunContext.java b/src/main/java/dev/jbang/source/RunContext.java index 3936c37c4..9c0881d6e 100644 --- a/src/main/java/dev/jbang/source/RunContext.java +++ b/src/main/java/dev/jbang/source/RunContext.java @@ -28,6 +28,7 @@ public class RunContext { private List javaOptions; private Map properties; + private List additionalSources = Collections.emptyList(); private List additionalDeps = Collections.emptyList(); private List additionalRepos = Collections.emptyList(); private List additionalClasspaths = Collections.emptyList(); @@ -63,7 +64,8 @@ public static RunContext create(List arguments, List javaRuntime } public static RunContext create(List arguments, List javaRuntimeOptions, - Map properties, List dependencies, List repositories, + Map properties, + List dependencies, List repositories, List classpaths, boolean forceJsh) { RunContext ctx = new RunContext(arguments, javaRuntimeOptions, properties); ctx.setAdditionalDependencies(dependencies); @@ -99,6 +101,35 @@ public void setProperties(Map properties) { this.properties = properties; } + public List getAllSources(ScriptSource src) { + List ssrcs = src.getAllSources(); + List asrcs = getAdditionalSources() .stream() + .map(src::getSibling) + .collect(Collectors.toList()); + if (asrcs.isEmpty()) { + return ssrcs; + } else if (ssrcs.isEmpty()) { + return asrcs; + } else { + ArrayList result = new ArrayList<>(); + result.addAll(ssrcs); + result.addAll(asrcs); + return result; + } + } + + public List getAdditionalSources() { + return additionalSources; + } + + public void setAdditionalSources(List sources) { + if (sources != null) { + this.additionalSources = new ArrayList<>(sources); + } else { + this.additionalSources = Collections.emptyList(); + } + } + public List getAdditionalDependencies() { return additionalDeps; } @@ -378,6 +409,9 @@ public Source forResource(String resource) { if (getJavaOptions() == null || getJavaOptions().isEmpty()) { setJavaOptions(alias.javaOptions); } + if (getAdditionalSources() == null || getAdditionalSources().isEmpty()) { + setAdditionalSources(alias.sources); + } if (getAdditionalDependencies() == null || getAdditionalDependencies().isEmpty()) { setAdditionalDependencies(alias.dependencies); } diff --git a/src/main/java/dev/jbang/source/ScriptSource.java b/src/main/java/dev/jbang/source/ScriptSource.java index 34991b7f5..79769e67e 100644 --- a/src/main/java/dev/jbang/source/ScriptSource.java +++ b/src/main/java/dev/jbang/source/ScriptSource.java @@ -531,26 +531,26 @@ public List collectSources() { if (getLines() == null) { return Collections.emptyList(); } else { + String org = getResourceRef().getOriginalResource(); + Path baseDir = org != null ? getResourceRef().getFile().getAbsoluteFile().getParentFile().toPath() + : Util.getCwd(); return getLines() .stream() .filter(f -> f.startsWith(SOURCES_COMMENT_PREFIX)) .flatMap(line -> Arrays .stream(line.split(" // ")[0].split("[ ;,]+")) .skip(1) .map(String::trim)) .map(replaceProperties) - .flatMap(line -> Util - .explode(getResourceRef().getOriginalResource(), - getResourceRef().getFile() - .getAbsoluteFile() - .getParentFile() - .toPath(), - line) - .stream()) - .map(resourceRef::asSibling) - .map(it -> prepareScript(it, replaceProperties)) + .flatMap(line -> Util.explode(org, baseDir, line).stream()) + .map(this::getSibling) .collect(Collectors.toCollection(ArrayList::new)); } } + public ScriptSource getSibling(String resource) { + ResourceRef siblingRef = resourceRef.asSibling(resource); + return prepareScript(siblingRef, replaceProperties); + } + protected List collectAll(Function> func) { Stream subs = getAllSources().stream().flatMap(s -> func.apply(s).stream()); return Stream.concat(func.apply(this).stream(), subs).collect(Collectors.toList()); diff --git a/src/main/java/dev/jbang/source/resolvers/StdinScriptResourceResolver.java b/src/main/java/dev/jbang/source/resolvers/LiteralScriptResourceResolver.java similarity index 96% rename from src/main/java/dev/jbang/source/resolvers/StdinScriptResourceResolver.java rename to src/main/java/dev/jbang/source/resolvers/LiteralScriptResourceResolver.java index 422e3b69c..5c5375fea 100644 --- a/src/main/java/dev/jbang/source/resolvers/StdinScriptResourceResolver.java +++ b/src/main/java/dev/jbang/source/resolvers/LiteralScriptResourceResolver.java @@ -23,7 +23,7 @@ * will try to create a copy in the cache with a proper file name and return a * reference to that file. */ -public class StdinScriptResourceResolver implements ResourceResolver { +public class LiteralScriptResourceResolver implements ResourceResolver { @Override public ResourceRef resolve(String resource) { ResourceRef result = null; diff --git a/src/main/java/dev/jbang/util/Util.java b/src/main/java/dev/jbang/util/Util.java index 23f5d2f26..fd4643b44 100644 --- a/src/main/java/dev/jbang/util/Util.java +++ b/src/main/java/dev/jbang/util/Util.java @@ -202,7 +202,7 @@ public static List explode(String source, Path baseDir, String filepatte List results = new ArrayList<>(); - if (Util.isURL(source)) { + if (source != null && Util.isURL(source)) { // if url then just return it back for others to resolve. // TODO: technically this is really where it should get resolved! if (isPattern(filepattern)) { diff --git a/src/test/java/dev/jbang/cli/TestAliasNearest.java b/src/test/java/dev/jbang/cli/TestAliasNearest.java index d4f5f43e0..36e16d889 100644 --- a/src/test/java/dev/jbang/cli/TestAliasNearest.java +++ b/src/test/java/dev/jbang/cli/TestAliasNearest.java @@ -150,7 +150,7 @@ void testAddLocalFile() throws IOException { void testAddLocal(String ref, String result) throws IOException { Path cwd = Util.getCwd(); Path localCatalog = cwd.resolve(Catalog.JBANG_CATALOG_JSON); - CatalogUtil.addNearestAlias("new", ref, null, null, null, null, null, null, null, null, null); + CatalogUtil.addNearestAlias("new", ref, null, null, null, null, null, null, null, null, null, null); clearSettingsCaches(); Catalog catalog = Catalog.get(localCatalog); assertThat(catalog.aliases.keySet(), hasItem("new")); @@ -162,8 +162,8 @@ void testAddLocalExplicit() throws IOException { Path cwd = Util.getCwd(); Path localCatalog = cwd.resolve(Catalog.JBANG_CATALOG_JSON); CatalogUtil.addAlias(Paths.get(Catalog.JBANG_CATALOG_JSON), "new", "dummy.java", null, null, null, null, null, - null, null, null, - null); + null, + null, null, null, null); clearSettingsCaches(); Catalog catalog = Catalog.get(localCatalog); assertThat(catalog.aliases.keySet(), hasItem("new")); @@ -185,7 +185,7 @@ void testAddDotLocal(String ref, String result) throws IOException { Path localCatalog = cwd.resolve(Catalog.JBANG_CATALOG_JSON); Path dotLocalCatalog = cwd.resolve(Settings.JBANG_DOT_DIR).resolve(Catalog.JBANG_CATALOG_JSON); Files.delete(localCatalog); - CatalogUtil.addNearestAlias("new", ref, null, null, null, null, null, null, null, null, null); + CatalogUtil.addNearestAlias("new", ref, null, null, null, null, null, null, null, null, null, null); assertThat(localCatalog.toFile(), not(anExistingFile())); clearSettingsCaches(); Catalog catalog = Catalog.get(dotLocalCatalog); @@ -210,7 +210,7 @@ void testAddParent(String ref, String result) throws IOException { Path parentCatalog = cwd.getParent().resolve(Settings.JBANG_DOT_DIR).resolve(Catalog.JBANG_CATALOG_JSON); Files.delete(localCatalog); Files.delete(dotLocalCatalog); - CatalogUtil.addNearestAlias("new", ref, null, null, null, null, null, null, null, null, null); + CatalogUtil.addNearestAlias("new", ref, null, null, null, null, null, null, null, null, null, null); assertThat(localCatalog.toFile(), not(anExistingFile())); assertThat(dotLocalCatalog.toFile(), not(anExistingFile())); clearSettingsCaches(); @@ -239,7 +239,7 @@ void testAddGlobal(String ref, String result) throws IOException { Files.delete(localCatalog); Files.delete(dotLocalCatalog); Files.delete(parentCatalog); - CatalogUtil.addNearestAlias("new", ref, null, null, null, null, null, null, null, null, null); + CatalogUtil.addNearestAlias("new", ref, null, null, null, null, null, null, null, null, null, null); assertThat(localCatalog.toFile(), not(anExistingFile())); assertThat(dotLocalCatalog.toFile(), not(anExistingFile())); assertThat(parentCatalog.toFile(), not(anExistingFile())); diff --git a/src/test/java/dev/jbang/cli/TestAliasNearestWithBaseRef.java b/src/test/java/dev/jbang/cli/TestAliasNearestWithBaseRef.java index 31e0f32fa..8250b778c 100644 --- a/src/test/java/dev/jbang/cli/TestAliasNearestWithBaseRef.java +++ b/src/test/java/dev/jbang/cli/TestAliasNearestWithBaseRef.java @@ -64,7 +64,8 @@ void init() throws IOException { void testAddLocal() throws IOException { Path cwd = Util.getCwd(); Path localCatalog = cwd.resolve(Catalog.JBANG_CATALOG_JSON); - CatalogUtil.addNearestAlias("new", "scripts/local.java", null, null, null, null, null, null, null, null, null); + CatalogUtil.addNearestAlias("new", "scripts/local.java", null, null, null, null, null, null, null, null, null, + null); clearSettingsCaches(); Catalog catalog = Catalog.get(localCatalog); assertThat(catalog.aliases.keySet(), hasItem("new")); @@ -77,7 +78,8 @@ void testAddDotLocal() throws IOException { Path localCatalog = cwd.resolve(Catalog.JBANG_CATALOG_JSON); Path dotLocalCatalog = cwd.resolve(Settings.JBANG_DOT_DIR).resolve(Catalog.JBANG_CATALOG_JSON); Files.delete(localCatalog); - CatalogUtil.addNearestAlias("new", "scripts/local.java", null, null, null, null, null, null, null, null, null); + CatalogUtil.addNearestAlias("new", "scripts/local.java", null, null, null, null, null, null, null, null, null, + null); assertThat(localCatalog.toFile(), not(anExistingFile())); clearSettingsCaches(); Catalog catalog = Catalog.get(dotLocalCatalog); @@ -93,7 +95,8 @@ void testAddParent1() throws IOException { Path parentCatalog = cwd.getParent().resolve(Settings.JBANG_DOT_DIR).resolve(Catalog.JBANG_CATALOG_JSON); Files.delete(localCatalog); Files.delete(dotLocalCatalog); - CatalogUtil.addNearestAlias("new", "scripts/local.java", null, null, null, null, null, null, null, null, null); + CatalogUtil.addNearestAlias("new", "scripts/local.java", null, null, null, null, null, null, null, null, null, + null); assertThat(localCatalog.toFile(), not(anExistingFile())); assertThat(dotLocalCatalog.toFile(), not(anExistingFile())); clearSettingsCaches(); @@ -111,6 +114,7 @@ void testAddParent2() throws IOException { Files.delete(localCatalog); Files.delete(dotLocalCatalog); CatalogUtil.addNearestAlias("new", "../scripts/parent.java", null, null, null, null, null, null, null, null, + null, null); assertThat(localCatalog.toFile(), not(anExistingFile())); assertThat(dotLocalCatalog.toFile(), not(anExistingFile()));