Skip to content

Commit

Permalink
Fix executable file permissions in archives
Browse files Browse the repository at this point in the history
This change allows any file generated with the executable file
permission to be stored within the tgz or zip archive with executable
file permission.

Before this change only Maven and Gradle wrapper scrips would get
executable file permission within the archive, even though classes like
MultipleResourcesProjectContributor allow for setting the executable
file permission on other generated files.
  • Loading branch information
mzeijen committed Jun 17, 2024
1 parent 0c7882e commit 8b81056
Showing 1 changed file with 3 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@
import java.util.function.Function;
import java.util.stream.Stream;

import io.spring.initializr.generator.buildsystem.BuildSystem;
import io.spring.initializr.generator.buildsystem.maven.MavenBuildSystem;
import io.spring.initializr.generator.project.ProjectDescription;
import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.metadata.InitializrMetadataProvider;
import io.spring.initializr.web.project.InvalidProjectRequestException;
Expand Down Expand Up @@ -158,15 +155,14 @@ private <T extends ArchiveEntry> Path createArchive(ProjectGenerationResult resu
BiFunction<File, String, T> archiveEntry, BiConsumer<T, Integer> setMode) throws IOException {
Path archive = this.projectGenerationInvoker.createDistributionFile(result.getRootDirectory(),
"." + fileExtension);
String wrapperScript = getWrapperScript(result.getProjectDescription());
try (ArchiveOutputStream<T> output = archiveOutputStream.apply(Files.newOutputStream(archive))) {
Stream<Path> files = Files.walk(result.getRootDirectory());
try (files) {
files.filter((path) -> !result.getRootDirectory().equals(path)).forEach((path) -> {
try {
String entryName = getEntryName(result.getRootDirectory(), path);
T entry = archiveEntry.apply(path.toFile(), entryName);
setMode.accept(entry, getUnixMode(wrapperScript, entryName, path));
setMode.accept(entry, getUnixMode(path));
output.putArchiveEntry(entry);
if (!Files.isDirectory(path)) {
Files.copy(path, output);
Expand All @@ -190,11 +186,11 @@ private String getEntryName(Path root, Path path) {
return entryName;
}

private int getUnixMode(String wrapperScript, String entryName, Path path) {
private int getUnixMode(Path path) {
if (Files.isDirectory(path)) {
return UnixStat.DIR_FLAG | UnixStat.DEFAULT_DIR_PERM;
}
return UnixStat.FILE_FLAG | (entryName.equals(wrapperScript) ? 0755 : UnixStat.DEFAULT_FILE_PERM);
return UnixStat.FILE_FLAG | (Files.isExecutable(path) ? 0755 : UnixStat.DEFAULT_FILE_PERM);
}

private String generateFileName(String artifactId, String extension) {
Expand All @@ -203,12 +199,6 @@ private String generateFileName(String artifactId, String extension) {
return URLEncoder.encode(candidate, StandardCharsets.UTF_8) + "." + extension;
}

private static String getWrapperScript(ProjectDescription description) {
BuildSystem buildSystem = description.getBuildSystem();
String script = buildSystem.id().equals(MavenBuildSystem.ID) ? "mvnw" : "gradlew";
return (description.getBaseDirectory() != null) ? description.getBaseDirectory() + "/" + script : script;
}

private ResponseEntity<byte[]> upload(Path archive, Path dir, String fileName, String contentType)
throws IOException {
byte[] bytes = Files.readAllBytes(archive);
Expand Down

0 comments on commit 8b81056

Please sign in to comment.