Gradle Version: 3.1 (and earlier)
Operating System and JVM version:
Red Hat Enterprise Linux Server release 6.7 (Santiago)
java version "1.8.0_77"
Java™ SE Runtime Environment (build 1.8.0_77-b03)
Java HotSpot™ 64-Bit Server VM (build 25.77-b03, mixed mode)
Is this a regression? If yes, which version of Gradle do you know it last worked for?
No
NOTE: I have updated this post. The previous version was based on a run where the code was not as stated below.
I have defined a simple exec task. It deletes everything in a directory that is outside of the build tree.
Task nativeClean = project.tasks.create('nativeClean', Exec) {
// does not depend on anything, must be manually invoked.
workingDir nativeDir
commandLine 'rm', '-rfv', "*"
}
If I then run the task
$ gradlew nativeClean -i
I see that the task does execute but the contents of nativeDir remain undeleted:
Starting process 'command 'rm''. Working directory: /usr/local/openssl Command: rm -rfv *
Successfully started process 'command 'rm''
:openssl64:nativeClean (Thread[Daemon worker Thread 18,5,main]) completed. Took 0.02 secs.
If it were some sort of permissions error, say, I would expect an exception to be thrown. But I tried forcing that by changing the permissions, and the results were the same.
I think the process is starting but never actually executing. It only says it’s started the process. It’s as if gradle isn’t waiting for the process to complete.
Okay, I don’t know what to try next. It certainly seems like Gradle thinks it’s performing the rm but nothing is happening. Nothing I try is giving me any visibility into this situation.
I’ve rewritten the task to provide as much info as possible:
Task nativeClean = project.tasks.create('nativeClean', Exec) {
// does not depend on anything, must be manually invoked.
workingDir nativeDir
commandLine 'rm', '-rfv', "*"
standardOutput = new ByteArrayOutputStream()
errorOutput = new ByteArrayOutputStream()
ext.stdout = {
return standardOutput.toString()
}
ext.stderr = {
return errorOutput.toString()
}
doLast {
println "rm output:" + ext.stdout()
println "rm error output:" + ext.stderr()
}
}
Now running under debug logging, it still looks like everything is working - yet nothing gets deleted:
12:33:02.801 [LIFECYCLE] [class org.gradle.internal.buildevents.TaskExecutionLogger] :openssl64:nativeClean
12:33:02.801 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Starting to execute task ':openssl64:nativeClean'
12:33:02.801 [DEBUG] [org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter] Determining if task ':openssl64:nativeClean' is up-to-date
12:33:02.801 [INFO] [org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter] Executing task ':openssl64:nativeClean' (up-to-date check took 0.0 secs) due to:
Task has not declared any outputs.
12:33:02.801 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter] Executing actions for task ':openssl64:nativeClean'.
12:33:02.801 [INFO] [org.gradle.process.internal.DefaultExecHandle] Starting process 'command 'rm''. Working directory: /usr/local/openssl Command: rm -rfv *
12:33:02.801 [DEBUG] [org.gradle.process.internal.DefaultExecHandle] Environment for process 'command 'rm'': {... (edited)`
}, LS_COLORS=, HOME=/home/sc1478, SHLVL=1}
12:33:02.801 [DEBUG] [org.gradle.process.internal.DefaultExecHandle] Changing state to: STARTING
12:33:02.802 [DEBUG] [org.gradle.process.internal.DefaultExecHandle] Waiting until process started: command 'rm'.
12:33:02.804 [DEBUG] [org.gradle.process.internal.DefaultExecHandle] Changing state to: STARTED
12:33:02.806 [DEBUG] [org.gradle.process.internal.ExecHandleRunner] waiting until streams are handled...
12:33:02.806 [INFO] [org.gradle.process.internal.DefaultExecHandle] Successfully started process 'command 'rm''
12:33:02.808 [DEBUG] [org.gradle.process.internal.DefaultExecHandle] Changing state to: SUCCEEDED
12:33:02.808 [DEBUG] [org.gradle.process.internal.DefaultExecHandle] Process 'command 'rm'' finished with exit value 0 (state: SUCCEEDED)
12:33:02.808 [QUIET] [system.out] rm output:
12:33:02.808 [QUIET] [system.out] rm error output:
12:33:02.808 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Finished executing task ':openssl64:nativeClean'
It seems possible that the “*” is not being globbed, as I don’t think this is executing through through a command line shell. You could verify this by changing the argument to a single file name that you know will exist. If that “works”, I’m still not sure what the proper solution is.
Now what to do about it? That is the $64K question.
I’m pretty sure I could use the Delete task instead of Exec with a properly constructed collection of Files. But is it true that globs are not properly processible by Exec? Is there a way around this?
Task nativeClean = project.tasks.create('nativeClean', Exec) {
// does not depend on anything, must be manually invoked.
workingDir nativeDir
commandLine 'bash', '-c', "/bin/rm -rf *"
}