I would like to override the behaviour of a copy task, and sign a jar while copying it. For this I’m using the ant.signjar task and need the paths of the source and destination. But the FileCopyDetails only give me relative names of the files. I found the destinationDir
(I’m guessing from the Copy task), but I can’t find any way to get the source directory. For example:
shadowJar {
baseName = jar.baseName
classifier = jar.classifier
}
task signJar(type: Copy) {
into "${buildDir}/signed"
dependsOn shadowJar
from(shadowJar) {
eachFile { fileCopyDetails ->
def sourceFile = fileCopyDetails.relativeSourcePath.getFile(new File(buildDir, "libs"))
def destinationFile = fileCopyDetails.relativePath.getFile(destinationDir)
println "IT2: ${sourceFile} -> ${destinationFile}"
ant.signjar(signerSettings << [jar: sourceFile, signedjar: destinationFile])
// and exclude?
}
}
}
Is there a better way to write a task that generates a singed jar from another jar?
Regards
Levon
You can get the full path via fileCopyDetails.file.path
.
That said, I’m not sure why this is being implemented as a Copy
task, seeing how you are only ever copying a single file. You could just as well implement this as an ad-hoc task.
task signJar {
inputs.file shadowJar
outputs.file "$buildDir/signed/${shadowJar.archiveName}"
doLast {
ant.signjar(jar: shadowJar.archivePath, signedjar: "$buildDir/signed/${shadowJar.archiveName}")
}
}
I ended up writing a custom task that inherits from AbstractArchiveTask
, since I wanted it to be recognized by gradle as an archive.
I had a similar problem though, since I had to implement a copy action. Ended up using a CopySpecResolver
(mainSpec.buildRootResolver()
) and then resolver.source.singleFile
as source and archivePath
as destination.
We should probably make all this stuff rely on a marker interface rather than a base class.
Disclaimer, this is all internal stuff and likely to change without notice. I’m not sure this is worth the convenience of having Gradle automatically treat your task as an archive.
Your ad-hoc task seemed nicer. How would I do to use it and let Gradle know that it generated an archive? So that other projects that depend on this project used the archive automatically?
Are you currently using artifacts { }
for this?
Yes:
artifacts {
archives signJar
}
Yeah, so if you simply implement this as a custom task that doesn’t extend AbstractArchiveTask
you would just expose a property on that task which is the file it creates, let’s call it outputFile
.
artifacts {
archives (signJar.outputFile) {
builtBy signJar
}
}
This adds outputFile
to the ‘archives’ configuration as well as instructs Gradle that the signJar
task is responsible for creating this archive so all the task dependencies get setup exactly the same as if this was an AbstractArchiveTask
.
1 Like