Skip to content
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

Gradle-plugin: properly handle read-only files #33901

Merged
merged 1 commit into from
Jun 9, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ private void assembleFastJar() {
getLogger().info("Synchronizing Quarkus build for {} packaging from {} and {} into {}", packageType(),
appBuildDir, depBuildDir, appTargetDir);
getFileSystemOperations().sync(sync -> {
sync.eachFile(new CopyActionDeleteNonWriteableTarget(appTargetDir.toPath()));
sync.into(appTargetDir);
sync.from(appBuildDir, depBuildDir);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package io.quarkus.gradle.tasks;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import java.util.stream.Collectors;

import javax.inject.Inject;

import org.gradle.api.Action;
import org.gradle.api.GradleException;
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.FileCopyDetails;
import org.gradle.api.file.FileSystemOperations;
import org.gradle.api.logging.LogLevel;
import org.gradle.api.tasks.Classpath;
Expand Down Expand Up @@ -168,6 +172,9 @@ void generateBuild() {
PackageConfig.BuiltInType packageType = packageType();
getLogger().info("Building Quarkus app for package type {} in {}", packageType, genDir);

// Need to delete app-cds.jsa specially, because it's usually read-only and Gradle's delete file-system
// operation doesn't delete "read only" files :(
deleteFileIfExists(genDir.resolve(outputDirectory()).resolve("app-cds.jsa"));
getFileSystemOperations().delete(delete -> {
// Caching and "up-to-date" checks depend on the inputs, this 'delete()' should ensure that the up-to-date
// checks work against "clean" outputs, considering that the outputs depend on the package-type.
Expand Down Expand Up @@ -223,6 +230,7 @@ void generateBuild() {
getFileSystemOperations().copy(copy -> {
copy.from(buildDir);
copy.into(genDir);
copy.eachFile(new CopyActionDeleteNonWriteableTarget(genDir));
switch (packageType) {
case NATIVE:
copy.include(nativeRunnerFileName());
Expand Down Expand Up @@ -261,4 +269,32 @@ void abort(String message, Object... args) {
});
throw new StopExecutionException();
}

public static final class CopyActionDeleteNonWriteableTarget implements Action<FileCopyDetails> {
private final Path destDir;

public CopyActionDeleteNonWriteableTarget(Path destDir) {
this.destDir = destDir;
}

@Override
public void execute(FileCopyDetails details) {
// Delete a pre-existing non-writeable file, otherwise a copy or sync operation would fail.
// This situation happens for 'app-cds.jsa' files, which are created as "read only" files,
// prefer to keep those files read-only.

Path destFile = destDir.resolve(details.getPath());
if (Files.exists(destFile) && !Files.isWritable(destFile)) {
deleteFileIfExists(destFile);
}
}
}

protected static void deleteFileIfExists(Path file) {
try {
Files.deleteIfExists(file);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.gradle.api.file.FileCollection;
import org.gradle.api.tasks.CacheableTask;
import org.gradle.api.tasks.CompileClasspath;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.PathSensitive;
Expand Down Expand Up @@ -62,6 +63,11 @@ public void setCompileClasspath(Configuration compileClasspath) {
this.compileClasspath = compileClasspath;
}

@Input
public Map<String, String> getCachingRelevantInput() {
return extension().baseConfig().quarkusProperties();
}

@InputFiles
@PathSensitive(PathSensitivity.RELATIVE)
public Set<File> getInputDirectory() {
Expand Down