I've been developing my own gradle plugin, and I need to skip bundling some classes from the default classes directory and instead bundle mine instead. I managed to "do" this by changing the output directories of source-sets, but this breaks a lot of things in our build chain. Currently, I'm trying to exclude classes if they exist in the modified source set, but they don't seem to be excluded. It's like gradle copies the classes by default any, and then processes my exclude closure.
I have tried the following:
tasks.named<Jar>("jar") {
from(sourceSets.main.get().output) {
exclude("*")
}
}
I have also tried:
jar.from(freshTree, copySpec -> {
copySpec.eachFile(file -> {
System.out.println("[CUSTOM] adding: " + file.getRelativePath().getPathString());
});
});
jar.from(sourceSet.getOutput(), copySpec -> {
copySpec.exclude(details -> {
Set<String> altClassNames = freshTree.get().getFiles().stream()
.map(file -> {
String relative = project.relativePath(file);
return relative.replace(File.separatorChar, '/');
})
.map(str -> {
String loc = "build/weaved-classes/java/" + sourceSetName + "/";
int idx = str.indexOf(loc);
return idx >= 0 ? str.substring(idx + loc.length()) : str;
})
.collect(Collectors.toSet());
String archivePath = details.getRelativePath().getPathString();
boolean shouldSkip = altClassNames.contains(archivePath);
System.out.println((shouldSkip ? "[SOURCESET] skipped: " : "[SOURCESET] included: ") + archivePath);
return true; // debug purposes, skip all files
});
copySpec.setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE);
});
Unfortunately, it fails:
> Task :jar FAILED
[SOURCESET] included: com
[SOURCESET] included: main
[SOURCESET] included: com
[SOURCESET] included: integration
[SOURCESET] included: com
[SOURCESET] included: test
[CUSTOM] adding: some/package/MyClazz.class
...
> Entry some/package/MyClazz.class is a duplicate but no duplicate handling strategy has been set.
Preferably, I can do this within my gradle plugin.
EDIT: I have tried using doFirst {} to attempt to configure the inputs before gradle registers the default inputs, but gradle disallows configuration during execution :(
As @Slaw stated in comments, I can use AbstractCopyTask#exclude. I don't know how I broke that before, but it works now with the following code:
jar.exclude((fileTreeElem) -> {
File theFile = fileTreeElem.getFile();
if (theFile.getPath().startsWith(customDir.getPath()))
return false;
// ... rest of the code
}