gradle copy include closure not working - gradle

Gradle copySpec include closure not working:
def fileList = ["hello/world.xml"]
task foo(type: Copy) {
from (zipTree("/path/a.zip")) {
include { elem ->
fileList.contains(elem.path)
}
}
}
The a.zip contains "hello/world.xml".
Message:
Skipping task 'foo' as it has no source files and no previous output files.

A copySpec closure needs to be used with a copy task.
Your code is just the copy task, which requires a destination to copy into.
Your code should be more like this:
def fileList = ["hello/world.xml"]
def filesToCopy = copySpec {
from (zipTree("/path/a.zip")) {
include { elem ->
fileList.contains(elem.path)
}
}
}
task foo(type: Copy) {
into 'build/target/docs'
with filesToCopy
}
See the API for more detail: https://docs.gradle.org/3.3/dsl/org.gradle.api.tasks.Copy.html

Related

How to write a properties file using WriteProperties Gradle API?

I am trying to write some key-value pairs to a properties file in a gradle task. I looked up that Gradle provides an api WriteProperties for that, but I was unable to use it.
I tried different approaches (I am learning Gradle, so I don't know if I used some incorrect syntax):
1.
task myTask {
doLast {
WriteProperties {
outputFile = file 'prop.properties'
encoding = 'UTF-8'
properties = [TEST:42]
}
}
}
task myTask {
doLast {
def writer by register(WriteProperties.class) {
outputFile = file 'prop.properties'
encoding = 'UTF-8'
properties = [TEST:42]
}
}
}
task myTask {
doLast {
// Other stuff
}
}
task writeProperty(type: WriteProperties) {
outputFile = file 'prop.properties'
encoding = 'UTF-8'
properties = [TEST:42]
}
writeProperty.dependsOn myTask
task myTask {
doLast {
// Other stuff
}
finalizedBy writeProperty
}
task writeProperty(type: WriteProperties) {
outputFile = file 'prop.properties'
encoding = 'UTF-8'
properties = [TEST:42]
}
task myTask {
doLast {
// Other stuff
}
}
class MyPlugin implements Plugin<Project>{
void apply(Project project) {
project.task('writeProperty') {
WriteProperties {
outputFile = file 'prop.properties'
encoding = 'UTF-8'
properties = [TEST:42]
}
}
}
}
apply plugin: MyPlugin
writeProperty.dependsOn myTask
None of them created a file with the values. Is there some other way to do it? I wanted to know the proper way of using the WriteProperties api, since the documentation did now have any helpful examples.
I found solutions with java syntax to create Properties() object and writing to file, but none with this api.
I'm creating a property file like so, using pure Gradle/Groovy:
file "$buildDir/prop.properties" write [ TEST:42 ].collect{ k, v -> "$k=$v" }.join( '\n' )
OR
file "$buildDir/prop.properties" withWriter{ out ->
[ TEST:42 ].each{ k, v -> out << k << '=' << v << '\n' }
}

eachFile in Gradle Copy-task is not working

I have a Gradle rule like:
tasks.addRule("Pattern: updatelight<Path> (copies files to ../<Path>).") { String taskName ->
if (taskName.startsWith("updatelight")) {
task([ "type": Copy ], taskName) {
def projectGroups = (sub + root)
def testEnvPath = taskName - 'updatelight'
into ("../${testEnvPath}/")
logger.info("Copies user.xml")
projectGroups.each { project ->
if (!project.isEmpty()) {
from (project.output) {
into "cfg/${project.newPath}"
eachFile { file ->
println " ${file.sourcePath} -> ${file.path}"
println '----------------------------------------------'
}
}
}
}
[...]
My problem is, eachFile { ... } is not printing to console. Any hint? I am a Gradle-newbie and just try to add some logging to the existing task.
There was no problem with the code. Because of cache there were to actions taken therefore no logging.

Skipping task as it has no source files and no previous output files

This is my build.gradle which has three tasks (one for downloading the zip, one for unzipping it and other for executing the sh file). These tasks are dependent on each other. I am using Gradle 6. As these are dependent tasks I have used following command:
gradlew C
I get the error:
Skipping task 'B' as it has no source files and no previous output files.
build.gradle:
task A {
description = 'Rolls out new changes'
doLast {
def url = "https://${serverName}/xxx/try.zip"
def copiedZip = 'build/newdeploy/try.zip'
logger.lifecycle("Downloading $url...")
file('build/newdeploy').mkdirs()
ant.get(src: url, dest: copiedZip, verbose: true)
}
}
task B (type: Copy, dependsOn: 'A') {
doLast {
def zipFile = file('build/newdeploy/try.zip')
def outputDir = file("build/newdeploy")
from zipTree(zipFile)
into outputDir
}
}
task C (type: Exec, dependsOn: 'B') {
doLast {
workingDir 'build/newdeploy/try/bin'
executable 'sh'
args arguments, url
ext.output = { return standardOutput.toString() }
}
}
I tried following and it worked. Rather than adding a separate task to copy, added the copy function in the task A itself
task A {
description = 'Rolls out new changes'
doLast {
def url = "https://${serverName}/xxx/try.zip"
def copiedZip = 'build/newdeploy/try.zip'
logger.lifecycle("Downloading $url...")
file('build/newdeploy').mkdirs()
ant.get(src: url, dest: copiedZip, verbose: true)
def outputDir = file("build/newdeploy")
copy {
from zipTree(zipFile)
into outputDir
}
}
}
task C (type: Exec, dependsOn: 'A') {
doLast {
workingDir 'build/newdeploy/try/bin'
executable 'sh'
args arguments, url
ext.output = { return standardOutput.toString() }
}
}

gradle processResources: file path conversion

Grade: how to customize processResources to change the resource file path in the jar?
For example:
foo/a.xml --> foo/bar/a.xml
something similar to:
copy tree with gradle and change structure?
copy {
from("${sourceDir}") {
include 'modules/**/**'
}
into(destDir)
eachFile {details ->
// Top Level Modules
def targetPath = rawPathToModulesPath(details.path)
details.path = targetPath
}
}
....
def rawPathToModulesPath(def path) {
// Standard case modules/name/src -> module-name/src
def modified=path.replaceAll('modules/([^/]+)/.*src/(java/)?(.*)', {"module-${it[1]}/src/${it[3]}"})
return modified
}
How to add this in processResources? Thanks.
processResources is a task of type Copy. Therefore you should be able to do
processResources {
eachFile {details ->
// Top Level Modules
def targetPath = rawPathToModulesPath(details.path)
details.path = targetPath
}
}

How to copy files to more than one location using Gradle?

I'd like to define a Gradle task that copies files to four different directories. It seems that the copy task only allows a single target location.
// https://docs.gradle.org/current/userguide/working_with_files.html#sec:copying_files
task copyAssets(type: Copy) {
from 'src/docs/asciidoc/assets'
//into ['build/asciidoc/html5/assets', 'build/asciidoc/pdf/assets']
into 'build/asciidoc/pdf/assets'
}
task gen(dependsOn: ['copyAssets', 'asciidoctor']) << {
println "Files are generated."
}
How can I copy the files without defining four different tasks?
My current solution is:
// https://docs.gradle.org/current/userguide/working_with_files.html#sec:copying_files
task copyAssetsPDF(type: Copy) {
from 'src/docs/asciidoc/assets'
into 'build/asciidoc/pdf/assets'
}
task copyAssetsHTML5(type: Copy) {
from 'src/docs/asciidoc/assets'
into 'build/asciidoc/html5/assets'
}
task copyAssetsDB45(type: Copy) {
from 'src/docs/asciidoc/assets'
into 'build/asciidoc/docbook45/assets'
}
task copyAssetsDB5(type: Copy) {
from 'src/docs/asciidoc/assets'
into 'build/asciidoc/docbook5/assets'
}
task gen(dependsOn: ['copyAssetsPDF', 'copyAssetsHTML5', 'copyAssetsDB45', 'copyAssetsDB5', 'asciidoctor']) << {
println "Files are generated."
}
One of the solutions is to make a single task with a number of copy specifications like:
task copyAssets << {
copy {
from 'src/docs/asciidoc/assets'
into 'build/asciidoc/pdf/assets'
}
copy {
from 'src/docs/asciidoc/assets'
into 'build/asciidoc/pdf/assets'
}
}
Or you can do it within a loop:
//an array containing destination paths
def copyDestinations = ['build/asciidoc/pdf/assets', 'build/asciidoc/html5/assets']
//custom task to copy into all the target directories
task copyAssets << {
//iterate over the array with destination paths
copyDestinations.each { destination ->
//for every destination define new CopySpec
copy {
from 'src/docs/asciidoc/assets'
into destination
}
}
}

Resources