Skip to content

Commit

Permalink
feat: --sources and --files can now refer to directories
Browse files Browse the repository at this point in the history
  • Loading branch information
quintesse committed Jun 9, 2022
1 parent 8489101 commit 902c8cb
Show file tree
Hide file tree
Showing 4 changed files with 239 additions and 187 deletions.
4 changes: 2 additions & 2 deletions bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## in gradle we have plugin to generate BuildConfig with version info in it.
## For now just generate a placeholder. Ultimately could be some other script to generate the file.
mkdir generated
mkdir -p generated
cat << EOF > generated/BuildConfig.java
package dev.jbang;
Expand All @@ -15,4 +15,4 @@ public final class BuildConfig {
}
EOF

jbang export local --verbose --fresh --force --sources src/main/java/**.java,generated/**.java --files .=src/main/resources/** --repos mavencentral,jitpack --deps org.jboss:jandex:2.2.3.Final,org.slf4j:slf4j-nop:1.7.30,com.offbytwo:docopt:0.6.0.20150202,org.apache.commons:commons-text:1.9,org.apache.commons:commons-compress:1.20,info.picocli:picocli:4.6.1,io.quarkus.qute:qute-core:1.12.2.Final,kr.motd.maven:os-maven-plugin:1.7.0,org.codehaus.plexus:plexus-java:1.0.6,com.google.code.gson:gson:2.9.0,org.jsoup:jsoup:1.13.1,org.codejive:java-properties:0.0.4,com.github.jbangdev.jbang-resolver:shrinkwrap-resolver-api:3.1.5-allowpom,com.github.jbangdev.jbang-resolver:shrinkwrap-resolver-impl-maven:3.1.5-allowpom src/main/java/dev/jbang/Main.java
jbang export local --verbose --force -O jbang.jar --sources 'src/main/java,generated/' --files 'src/main/resources' --repos mavencentral,jitpack --deps org.jboss:jandex:2.2.3.Final,org.slf4j:slf4j-nop:1.7.30,com.offbytwo:docopt:0.6.0.20150202,org.apache.commons:commons-text:1.9,org.apache.commons:commons-compress:1.20,info.picocli:picocli:4.6.1,io.quarkus.qute:qute-core:1.12.2.Final,kr.motd.maven:os-maven-plugin:1.7.0,org.codehaus.plexus:plexus-java:1.0.6,com.google.code.gson:gson:2.9.0,org.jsoup:jsoup:1.13.1,org.codejive:java-properties:0.0.4,com.github.jbangdev.jbang-resolver:shrinkwrap-resolver-api:3.1.5-allowpom,com.github.jbangdev.jbang-resolver:shrinkwrap-resolver-impl-maven:3.1.5-allowpom src/main/java/dev/jbang/Main.java
110 changes: 58 additions & 52 deletions src/main/java/dev/jbang/util/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import dev.jbang.BuildConfig;
import dev.jbang.Cache;
import dev.jbang.Settings;
import dev.jbang.catalog.Catalog;
import dev.jbang.cli.BaseCommand;
import dev.jbang.cli.ExitException;
import dev.jbang.dependencies.DependencyUtil;
Expand Down Expand Up @@ -181,76 +182,81 @@ static public boolean isPattern(String pattern) {

/**
* Explodes filePattern found in baseDir returning list of relative Path names.
*
* TODO: this really should return some kind of abstraction of paths that allow
* it be portable for urls as wells as files...or have a filesystem for each...
*
* @param source
* @param baseDir
* @param filePattern
* @return
* If the filePattern refers to an existing folder the filePattern will be
* treated as if it ended in "/**".
*/
public static List<String> explode(String source, Path baseDir, String filePattern) {
List<String> results = new ArrayList<>();

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)) {
Util.warnMsg("Pattern " + filePattern + " used while using URL to run; this could result in errors.");
return results;
return Collections.emptyList();
} else {
results.add(filePattern);
return Collections.singletonList(filePattern);
}
} else if (Util.isURL(filePattern)) {
results.add(filePattern);
} else if (!isPattern(filePattern)) {
// not a pattern thus just as well return path directly
results.add(filePattern);
} else {
// it is a non-url let's try to locate it
final Path bd;
final boolean useAbsPath;
Path base = basePathWithoutPattern(filePattern);
String fp;
if (base.isAbsolute()) {
bd = base;
fp = filePattern.substring(bd.toString().length() + 1);
useAbsPath = true;
return Collections.singletonList(filePattern);
}

if (!isPattern(filePattern)) {
if (!Catalog.isValidCatalogReference(filePattern)
&& Util.isValidPath(filePattern) && Files.isDirectory(baseDir.resolve(filePattern))) {
// The filePattern refers to a folder, so let's add "/**"
if (!filePattern.endsWith("/") && !filePattern.endsWith(File.separator)) {
filePattern = filePattern + "/";
}
filePattern = filePattern + "**";
} else {
bd = baseDir.resolve(base);
fp = base.toString().isEmpty() ? filePattern : filePattern.substring(base.toString().length() + 1);
useAbsPath = false;
// not a pattern and not a folder thus just as well return path directly
return Collections.singletonList(filePattern);
}
PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + fp);

FileVisitor<Path> matcherVisitor = new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attribs) {
Path relpath = bd.relativize(file);
if (matcher.matches(relpath)) {
// to avoid windows fail.
if (file.toFile().exists()) {
Path p = useAbsPath ? file : base.resolve(relpath);
if (isWindows()) {
results.add(p.toString().replace("\\", "/"));
} else {
results.add(p.toString());
}
}

// it is a non-url let's try to locate it
final Path bd;
final boolean useAbsPath;
Path base = basePathWithoutPattern(filePattern);
String fp;
if (base.isAbsolute()) {
bd = base;
fp = filePattern.substring(bd.toString().length() + 1);
useAbsPath = true;
} else {
bd = baseDir.resolve(base);
fp = base.toString().isEmpty() ? filePattern : filePattern.substring(base.toString().length() + 1);
useAbsPath = false;
}
PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + fp);

List<String> results = new ArrayList<>();
FileVisitor<Path> matcherVisitor = new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attribs) {
Path relpath = bd.relativize(file);
if (matcher.matches(relpath)) {
// to avoid windows fail.
if (file.toFile().exists()) {
Path p = useAbsPath ? file : base.resolve(relpath);
if (isWindows()) {
results.add(p.toString().replace("\\", "/"));
} else {
Util.verboseMsg("Warning: " + relpath + " matches but does not exist!");
results.add(p.toString());
}
} else {
Util.verboseMsg("Warning: " + relpath + " matches but does not exist!");
}
return FileVisitResult.CONTINUE;
}
};

try {
Files.walkFileTree(bd, matcherVisitor);
} catch (IOException e) {
throw new ExitException(BaseCommand.EXIT_INTERNAL_ERROR, "Problem looking for " + fp + " in " + bd, e);
return FileVisitResult.CONTINUE;
}
};

try {
Files.walkFileTree(bd, matcherVisitor);
} catch (IOException e) {
throw new ExitException(BaseCommand.EXIT_INTERNAL_ERROR, "Problem looking for " + fp + " in " + bd, e);
}

return results;
}

Expand Down
133 changes: 0 additions & 133 deletions src/test/java/dev/jbang/cli/TestRun.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static dev.jbang.util.Util.readString;
import static dev.jbang.util.Util.writeString;
import static org.hamcrest.CoreMatchers.endsWith;
import static org.hamcrest.CoreMatchers.nullValue;
Expand Down Expand Up @@ -53,7 +52,6 @@
import dev.jbang.Cache;
import dev.jbang.Settings;
import dev.jbang.catalog.Catalog;
import dev.jbang.catalog.CatalogUtil;
import dev.jbang.net.TrustedSources;
import dev.jbang.source.Code;
import dev.jbang.source.Jar;
Expand Down Expand Up @@ -1568,104 +1566,6 @@ protected void runCompiler(List<String> optionList)
}.setFresh(true).build();
}

@Test
void testAdditionalSourcesUsingAlias() throws IOException {
String mainFile = examplesTestFolder.resolve("foo.java").toString();
String incFile = examplesTestFolder.resolve("bar/Bar.java").toString();

CatalogUtil.addNearestAlias("bar", incFile, null, null, null, null, null, null, null, null, null, null, null);

CommandLine.ParseResult pr = JBang.getCommandLine().parseArgs("build", "-s", "bar", mainFile);
Build build = (Build) pr.subcommand().commandSpec().userObject();

RunContext ctx = build.getRunContext();
SourceSet ss = (SourceSet) ctx.forResource(mainFile);

new JavaBuilder(ss, ctx) {
@Override
protected void runCompiler(List<String> optionList)
throws IOException {
assertThat(optionList, hasItem(mainFile));
assertThat(optionList, hasItem(incFile));
// Skip the compiler
}
}.setFresh(true).build();
}

@Test
void testIncludedSourcesUsingAlias(@TempDir Path dir) throws IOException {
Path mainFile = dir.resolve("foo.java");
String incFile = examplesTestFolder.resolve("bar/Bar.java").toString();

Path fooFile = examplesTestFolder.resolve("foo.java");
String fooScript = readString(fooFile);
writeString(mainFile, "//SOURCES bar@" + jbangTempDir + "\n" + fooScript);

CatalogUtil.addNearestAlias("bar", incFile, null, null, null, null, null, null, null, null, null, null, null);

CommandLine.ParseResult pr = JBang.getCommandLine().parseArgs("build", mainFile.toString());
Build build = (Build) pr.subcommand().commandSpec().userObject();

RunContext ctx = build.getRunContext();
SourceSet ss = (SourceSet) ctx.forResource(mainFile.toString());

new JavaBuilder(ss, ctx) {
@Override
protected void runCompiler(List<String> optionList)
throws IOException {
assertThat(optionList, hasItem(mainFile.toString()));
assertThat(optionList, hasItem(incFile));
// Skip the compiler
}
}.setFresh(true).build();
}

@Test
void testAdditionalSourcesGlobbing() throws IOException {
Util.setCwd(examplesTestFolder);
String mainFile = examplesTestFolder.resolve("foo.java").toString();
String incFile = examplesTestFolder.resolve("bar/Bar.java").toString();

CommandLine.ParseResult pr = JBang.getCommandLine().parseArgs("build", "-s", "bar/*.java", "foo.java");
Build build = (Build) pr.subcommand().commandSpec().userObject();

RunContext ctx = build.getRunContext();
SourceSet ss = (SourceSet) ctx.forResource(mainFile);

new JavaBuilder(ss, ctx) {
@Override
protected void runCompiler(List<String> optionList)
throws IOException {
assertThat(optionList, hasItem(mainFile));
assertThat(optionList, hasItem(incFile));
// Skip the compiler
}
}.setFresh(true).build();
}

@Test
void testAdditionalSourcesAbsGlobbing() throws IOException {
String mainFile = examplesTestFolder.resolve("foo.java").toString();
String incGlob = examplesTestFolder.resolve("bar").toString() + File.separatorChar + "*.java";
String incFile = examplesTestFolder.resolve("bar/Bar.java").toString();

CommandLine.ParseResult pr = JBang.getCommandLine().parseArgs("build", "-s", incGlob, mainFile);
Build build = (Build) pr.subcommand().commandSpec().userObject();

RunContext ctx = build.getRunContext();
SourceSet ss = (SourceSet) ctx.forResource(mainFile);

new JavaBuilder(ss, ctx) {
@Override
protected void runCompiler(List<String> optionList)
throws IOException {
assertThat(optionList, hasItem(mainFile));
assertThat(optionList, hasItem(incFile));
// Skip the compiler
}
}.setFresh(true).build();
}

@Test
void testAdditionalResources() throws IOException {
Util.setCwd(examplesTestFolder);
Expand Down Expand Up @@ -1698,39 +1598,6 @@ public void createJar() throws IOException {
}.setFresh(true).build();
}

@Test
void testAdditionalResourcesGlobbing() throws IOException {
Util.setCwd(examplesTestFolder);
String mainFile = "foo.java";

CommandLine.ParseResult pr = JBang .getCommandLine()
.parseArgs("build", "--files", "res/**.properties", mainFile);
Build build = (Build) pr.subcommand().commandSpec().userObject();

RunContext ctx = build.getRunContext();
SourceSet ss = (SourceSet) ctx.forResource(mainFile);

new JavaBuilder(ss, ctx) {
@Override
protected void runCompiler(List<String> optionList) {
assertThat(optionList, hasItem(endsWith(File.separator + "foo.java")));
// Skip the compiler
}

@Override
public void createJar() throws IOException {
assertThat(ss.getResources().size(), is(3));
List<String> ps = ss.getResources()
.stream()
.map(r -> r.getSource().getFile().toPath().toString())
.collect(Collectors.toList());
assertThat(ps, hasItem(endsWith("resource.properties")));
assertThat(ps, hasItem(endsWith("test.properties")));
assertThat(ps, hasItem(endsWith("sub" + File.separator + "sub.properties")));
}
}.setFresh(true).build();
}

WireMockServer wms;

@BeforeEach
Expand Down
Loading

0 comments on commit 902c8cb

Please sign in to comment.