name.remal.gradle_plugins.merge_resources.CopyTaskActionMerge Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of merge-resources Show documentation
Show all versions of merge-resources Show documentation
Remal Gradle plugins: merge-resources
The newest version!
package name.remal.gradle_plugins.merge_resources;
import static com.google.common.io.ByteStreams.copy;
import static java.nio.file.Files.newOutputStream;
import static name.remal.gradle_plugins.toolkit.ObjectUtils.isEmpty;
import static name.remal.gradle_plugins.toolkit.PathUtils.createParentDirectories;
import java.io.File;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import lombok.CustomLog;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.val;
import name.remal.gradle_plugins.toolkit.annotations.ReliesOnInternalGradleApi;
import org.gradle.api.file.RelativePath;
import org.gradle.api.tasks.AbstractCopyTask;
@RequiredArgsConstructor
@CustomLog
class CopyTaskActionMerge extends AbstractCopyTaskAction {
private final File mergedFilesDir;
private final ResourceMerger merger;
@Override
protected void execute(AbstractCopyTask task) {
val allFilesToMerge = getFilesToMerge(task, merger);
allFilesToMerge.entrySet().removeIf(entry -> {
val files = entry.getValue();
if (files.isEmpty()) {
return true;
} else if (files.size() == 1) {
val relativePath = entry.getKey();
logger.debug(
"{}: only one file for relative path `{}`, skip merging: {}",
this,
relativePath,
files.iterator().next()
);
return true;
}
return false;
});
if (allFilesToMerge.isEmpty()) {
return;
}
allFilesToMerge.forEach((relativePath, files) ->
mergeRelativePathResources(mergedFilesDir, merger, relativePath, files)
);
task.exclude(element -> {
val filesToMerge = allFilesToMerge.get(element.getRelativePath());
if (filesToMerge != null) {
val file = element.getFile();
if (filesToMerge.contains(file)) {
logger.debug("{}: excluding file, as it was merged: {}", this, file);
return true;
}
}
return false;
});
}
@ReliesOnInternalGradleApi
private Map> getFilesToMerge(AbstractCopyTask task, ResourceMerger merger) {
val includes = merger.getIncludes();
if (isEmpty(includes)) {
throw new IllegalStateException("No includes set for " + merger);
}
Map> allFilesToMerge = new LinkedHashMap<>();
task.getRootSpec().buildRootResolver().getAllSource()
.matching(filter -> {
filter.include(includes);
filter.exclude(merger.getExcludes());
})
.visit(details -> {
if (!details.isDirectory()) {
val relativePath = details.getRelativePath();
val filesToMerge = allFilesToMerge.computeIfAbsent(relativePath, __ -> new LinkedHashSet<>());
val file = details.getFile();
filesToMerge.add(file);
logger.debug(
"{}: found merging candidate for for relative path `{}`: {}",
this,
relativePath,
file
);
}
});
return allFilesToMerge;
}
@SneakyThrows
private void mergeRelativePathResources(
File mergedFilesDir,
ResourceMerger merger,
RelativePath relativePath,
Collection files
) {
logger.debug("{}: merging files for relative path `{}`: {}", this, relativePath, files);
try (val inputStream = merger.merge(relativePath, files)) {
val targetFilePath = new File(mergedFilesDir, relativePath.toString()).toPath();
createParentDirectories(targetFilePath);
try (val outputStream = newOutputStream(targetFilePath)) {
copy(inputStream, outputStream);
}
}
}
}