Copy file from another project in a Gradle task - gradle

Given is the following Gradle task:
task copyResource(type: Copy) {
from('.') {
include '../anotherProject/password.txt'
}
into 'build/docker'
}
On task execution the include is ignored. What is the correct way to reference to a file from another project directory?

Try this :
task copyResource(type: Copy) {
from('../anotherProject') {
include 'password.txt'
}
into 'build/docker'
}
or even simpler :
task copyResource(type: Copy) {
from('../anotherProject/password.txt')
into 'build/docker'
}

Related

Gradle JAR Creation Timing

i have a gradle build that retrieves properties file and such that are remote (to keep passwords out of github) but the remote retrieval doesn't complete by the time the JAR is built.
i figured i either had to get the JAR created in the execution phase instead of configuration phase or add the remote files in the execution phase but i couldn't get either working.
any suggestions?
task fatJar(type: Jar) {
doFirst {
exec {
executable './scripts/getRemoteResources.sh'
}
}
...
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it)
}
//some resources are retrieved remotely & b/c of timing they don't get included here
from ('src/main/java/resources') {
include '*'
}
with jar
//tried this but doesn't work
//doLast {
// jar {
// from ('src/main/java/resources') {
// include '*'
// }
// }
//}
}
You shouldn't use the task graph for this. Also you shouldn't download the file to src/main/
Instead, you should
Create a task to download the remote resources to a directory under $buildDir (so it's cleaned via the "clean" task)
Configure the TaskOutputs so that the result can be cached and re-used.
Wire the task into Gradle's DAG
Add the directory to the "processResources" task so it ends up on the runtime classpath (ie in the jar)
Eg:
tasks.register('remoteResources', Exec) {
inputs.property('environment', project.property('env')) // this assumes there's a project property named 'env'
outputs.dir "$buildDir/remoteResources" // point 2 (above)
commandLine = [
'./scripts/getRemoteResources.sh',
'--environment', project.property('env'),
'--outputdir', "$buildDir/remoteResources"
]
doFirst {
delete "$buildDir/remoteResources"
mkdir "$buildDir/remoteResources"
}
}
processResources {
from tasks.remoteResources // points 3 & 4 (above)
}
See The Java Plugin - Tasks
processResources — Copy
Copies production resources into the production resources directory.
this seems to work so i'm going with it unless someone has a better solution...
gradle.taskGraph.beforeTask { Task task ->
println "just before $task.name"
// i just chose to kick this off with the first task sent through here
if (task.name=="compileJava") {
exec {
executable './scripts/getRemoteResources.sh'
}
}
}
task fatJar(type: Jar) {
...
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it)
}
from ('src/main/java/resources') {
include '*'
}
with jar
}

How do I perform a rename on only one "from" in a Gradle Copy task?

I am trying to copy from multiple "from" locations on a single Gradle Copy task. For one of those - and only one - I want to also perform a rename operation.
This code works:
task dist(type: Copy) {
from task1
rename { filename -> filename.replace '-all.jar', '.jar' }
from task2 { exclude "lib" }
into "${projectDir}/dist"
}
But the renaming operation also affects task2. I tried doing it this way:
task dist(type: Copy) {
from task1 { rename { filename -> filename.replace '-all.jar', '.jar' } }
from task2 { exclude "lib" }
into "${projectDir}/dist"
}
But it does not do the renaming operation. The exclude operation on task2 works as expected. Is it possible? Am I missing something in the syntax?
Someone posted the solution here and deleted it before I could accept/reply, so I'm posting the correct form here for future reference:
task dist(type: Copy) {
from (task1) { rename { filename -> filename.replace '-all.jar', '.jar' } }
from (task2) { exclude "lib" }
into "${projectDir}/dist"
}
Thanks, Opalo!

Gradle Copy Task Is UP-TO-DATE After Manually Deleting a File

I am forced to use Gradle 2.3 in this project.
I am trying to copy a set of dependencies from a custom configuration to a specific dir.
If I delete one of the files manually, Gradle still marks the task as UP-TO-DATE and I end up with an incomplete set of files.
task copyFiles(type: Copy) {
from configurations.zips
into 'zip-dir'
configurations.zips.allDependencies.each {
rename "-${it.version}", ''
}
}
This works as expected in v4.0.2 though.
To work around it I am counting files in that dir.
task copyFiles(type: Copy) {
outputs.upToDateWhen {
def count = new File('zip-dir').listFiles().count { it.name ==~ /.*zip/ }
count == configurations.zips.files.size()
}
from configurations.zips
into 'zip-dir'
configurations.zips.allDependencies.each {
rename "-${it.version}", ''
}
}
Which issue and version of gradle was this fixed in and is there a better workaround than what I have so far?
You can just run it always with
outputs.upToDateWhen { false }
or not use a type Copy for your task and
task copyFiles {
doLast {
copy {
from configurations.zips
into 'zip-dir'
configurations.zips.allDependencies.each {
rename "-${it.version}", ''
}
}
}
}
Note that this is a workaround not the solution

Gradle copy task fails silently

I have a copy task for 1 file
task myCopyTask(type: Copy) {
copy {
from "/path/to/my/file"
into "path/to/out/dir"
}
}
How to do, so the task fails if the copy fails? Right now if the file does not exist, it does not give an error.
Fail Gradle Copy task if source directory not exist gives a solution. This does not work, because if everything is not inside of
copy { ... }
the task does not work at all.
I tried also
task myCopyTask(type: Copy) {
copy {
from "/path/to/my/file"
into "path/to/out/dir"
inputs.sourceFiles.stopExecutionIfEmpty()
}
}
The above would fail, as inputs.sourceFiles would be empty.
Why don't you specify your task as:
task myCopyTask(type: Copy) {
from "/path/to/my/file"
into "path/to/out/dir"
inputs.sourceFiles.stopExecutionIfEmpty()
}
This would work as expected during execution phase, while your solution would try to copy something during configuration phase of the build every time you call any task.
The very first definition of the tasks actually doesn't do what you expect from the task:
task myCopyTask(type: Copy) {
copy {
from "/path/to/my/file"
into "path/to/out/dir"
}
is acutually same as
task myCopyTask(type: Copy) {
project.copy {
from "/path/to/my/file"
into "path/to/out/dir"
}
}
And it will execute copy action during task configuration, no matter if the task is called or not.
What you need is:
task myCopyTask(type: Copy) {
from "/path/to/my/file"
into "path/to/out/dir"
doFirst {
if(inputs.empty) throw new GradleException("Input source for myCopyTask doesn't exist")
}
}
This solution for Kotlin DSL works for me:
tasks.register<Copy>("myCopyTask") {
val path = "/path/to/my/file"
from(path)
into("path/to/out/dir")
if (inputs.sourceFiles.isEmpty) {
throw GradleException("File not found: $path")
}
}

What is the best way to parameterize a task on Gradle?

I need to create two different .properties files from two different .properties.dist if they don't exist, so I'm using a Copy task and I'm specifying the from and the into accordingly.
At the moment I had to create two different tasks, each of which is creating a file like this:
task copyAndRenameDialling(type: Copy){
if(!file("./properties/dialling.properties").exists()){
from './dist/dialling.properties.dist'
into './properties/'
rename{ String fileName ->
fileName.replace('.dist','')
}
}
}
task copyAndRenameFiles(type: Copy){
if(!file("./properties/file.properties").exists()){
from './dist/files.properties.dist'
into './properties/'
rename{ String fileName ->
fileName.replace('.dist','')
}
}
}
task copyAndRenameProperties {
dependsOn << copyAndRenameDialling
dependsOn << copyAndRenameFiles
}
and I run the task with gradle copyAndRenameProperties.
Is it possible to make the two Copy tasks parameterized based on the name of the file, so that I have only one generic copyAndRename?
If so, how can I pass the parameter to the task?
I'd do it like this:
task copyAndRenameProperties(type: Copy) {
from 'dist'
include '*.properties.dist'
into 'properties'
rename { it - ~/\.dist$/ }
eachFile { if (file("properties/$it.name").file) it.exclude() }
}
or if you really only want those two specific files
task copyAndRenameProperties(type: Copy) {
from 'dist/dialling.properties.dist'
from 'dist/file.properties.dist'
into 'properties'
rename { it - ~/\.dist$/ }
eachFile { if (file("properties/$it.name").file) it.exclude() }
}
or
task copyAndRenameProperties(type: Copy) {
from 'dist'
include 'dialling.properties.dist', 'file.properties.dist'
into 'properties'
rename { it - ~/\.dist$/ }
eachFile { if (file("properties/$it.name").file) it.exclude() }
}

Resources