Skip to content

fix: export maven/gradle, install runtime wrappers #1991

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 14 commits into from
Apr 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
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
15 changes: 1 addition & 14 deletions src/main/java/dev/jbang/cli/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.PosixFilePermission;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
Expand Down Expand Up @@ -185,19 +184,7 @@ private static void installShellScript(Path file, String scriptRef, List<String>
List<String> lines = Arrays.asList("#!/bin/sh", cb.asCommandLine(Util.Shell.bash) + " \"$@\"");
Files.write(file, lines, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE);
if (!Util.isWindows()) {
setExecutable(file);
}
}

private static void setExecutable(Path file) {
final Set<PosixFilePermission> permissions;
try {
permissions = Files.getPosixFilePermissions(file);
permissions.add(PosixFilePermission.OWNER_EXECUTE);
permissions.add(PosixFilePermission.GROUP_EXECUTE);
Files.setPosixFilePermissions(file, permissions);
} catch (UnsupportedOperationException | IOException e) {
throw new ExitException(EXIT_GENERIC_ERROR, "Couldn't mark script as executable: " + file, e);
Util.setExecutable(file);
}
}

Expand Down
45 changes: 45 additions & 0 deletions src/main/java/dev/jbang/cli/Export.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.*;
Expand Down Expand Up @@ -584,6 +585,9 @@ private void createProjectForExport(BuildContext ctx, Path projectDir) throws IO

// Build file
renderBuildFile(ctx, projectDir);

// Wrapper files
installWrapperFiles(ctx, projectDir);
}

private Path copySource(ResourceRef sourceRef, Path srcJavaDir)
Expand All @@ -609,6 +613,8 @@ private Path copySource(ResourceRef sourceRef, Path srcJavaDir)

abstract void renderBuildFile(BuildContext ctx, Path projectDir) throws IOException;

abstract void installWrapperFiles(BuildContext ctx, Path projectDir) throws IOException;

String getJavaVersion(Project prj, boolean minorVersionFor8) {
if (prj.getJavaVersion() == null) {
return null;
Expand All @@ -619,6 +625,24 @@ String getJavaVersion(Project prj, boolean minorVersionFor8) {
}
return javaVersion >= 9 ? Integer.toString(javaVersion) : "1." + javaVersion;
}

void copyWrapperFile(String srcPath, String dstPath, boolean execFlag) throws IOException {
File dstFile = new File(dstPath);
File dstDir = new File(dstFile.getParent());

dstDir.mkdirs();
InputStream ifs = this.getClass().getResourceAsStream(srcPath);
Files.copy(ifs, Paths.get(dstPath), StandardCopyOption.REPLACE_EXISTING);

if (Util.isWindows())
return;

if (execFlag) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, everything is perfect for merging, but .... I wonder if you could do me a favor and perform a small refactor: there is already some code in JBang to set a file as executable (See https://github.com/jbangdev/jbang/blob/main/src/main/java/dev/jbang/cli/App.java#L192). Could you perhaps extract that, move it to Util.java (just below the isExecutable() method for example) and make Export use that one as well?

Copy link
Contributor Author

@wfouche wfouche Apr 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good idea. I'll implement the requested changes.

Copy link
Contributor Author

@wfouche wfouche Apr 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@quintesse , I tested the refactored code using the new Util.setExecutable() method on Linux and Windows, with Maven and Gradle. All tests were successful.

The build failed again, so when you have a chance please restart it. Thanks.

Util.setExecutable(dstFile.toPath());
}

}

}

@Command(name = "gradle", description = "Exports a Gradle project")
Expand Down Expand Up @@ -683,6 +707,17 @@ void renderBuildFile(BuildContext ctx, Path projectDir) throws IOException {
Util.writeString(projectDir.resolve("gradle.properties"), "org.gradle.configuration-cache=true\n");
}

@Override
void installWrapperFiles(BuildContext ctx, Path projectDir) throws IOException {
String dir = projectDir.getFileName().toString();
copyWrapperFile("/dist/gradle/gradlew", Paths.get(dir, "gradlew").toString(), true);
copyWrapperFile("/dist/gradle/gradlew.bat", Paths.get(dir, "gradlew.bat").toString(), false);
copyWrapperFile("/dist/gradle/gradle/wrapper/gradle-wrapper.properties",
Paths.get(dir, "gradle", "wrapper", "gradle-wrapper.properties").toString(), false);
copyWrapperFile("/dist/gradle/gradle/wrapper/gradle-wrapper-jar",
Paths.get(dir, "gradle", "wrapper", "gradle-wrapper.jar").toString(), false);
}

private List<String> gradleify(List<String> collectDependencies) {
return collectDependencies.stream().map(item -> {
if (item.endsWith("@pom")) {
Expand Down Expand Up @@ -772,4 +807,14 @@ void renderBuildFile(BuildContext ctx, Path projectDir) throws IOException {
.render();
Util.writeString(destination, result);
}

@Override
void installWrapperFiles(BuildContext ctx, Path projectDir) throws IOException {
String dir = projectDir.getFileName().toString();
copyWrapperFile("/dist/maven/mvnw", Paths.get(dir, "mvnw").toString(), true);
copyWrapperFile("/dist/maven/mvnw.cmd", Paths.get(dir, "mvnw.cmd").toString(), false);
copyWrapperFile("/dist/maven/.mvn/wrapper/maven-wrapper.properties",
Paths.get(dir, ".mvn", "wrapper", "maven-wrapper.properties").toString(), false);
}

}
13 changes: 13 additions & 0 deletions src/main/java/dev/jbang/util/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.nio.file.attribute.PosixFilePermission;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Duration;
Expand Down Expand Up @@ -1688,6 +1689,18 @@ private static boolean isExecutable(Path file) {
return false;
}

public static void setExecutable(Path file) {
final Set<PosixFilePermission> permissions;
try {
permissions = Files.getPosixFilePermissions(file);
permissions.add(PosixFilePermission.OWNER_EXECUTE);
permissions.add(PosixFilePermission.GROUP_EXECUTE);
Files.setPosixFilePermissions(file, permissions);
} catch (UnsupportedOperationException | IOException e) {
throw new ExitException(BaseCommand.EXIT_GENERIC_ERROR, "Couldn't mark script as executable: " + file, e);
}
}

/**
* Converts a Path to a String. This is normally a trivial operation, but this
* method handles the special case when running in a Bash shell on Windows,
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading
Loading