I'm using a gradle task which executes the command-line inside a file collection loop:
...
collection.each { file ->
exec {
workingDir = file(props['WORKING_DIR']).getAbsolutePath()
commandLine "java", "-jar", file(props['SIGN_TOOL']).getAbsoluteFile(), file
}
}
...
Unfortunately, the gradle task ends up with this error:
Execution failed for task ':signFiles'.
No signature of method: java.io.File.call() is applicable for argument types: (java.lang.String) values: Possible
solutions: wait(), any(), wait(long), each(groovy.lang.Closure),
any(groovy.lang.Closure), list()
How can i fix this issue?
Thx MVM
You've called your loop var file and then it's trying to use that for the call to file()...
Try renaming your closure variable:
collection.each { aFile ->
exec {
workingDir = file(props['WORKING_DIR']).getAbsolutePath()
commandLine "java", "-jar", file(props['SIGN_TOOL']).getAbsoluteFile(), aFile
}
}
Related
I want to run
./gradlew extractMyDeps
instead of
./gradlew :app:dependencies --configuration productionDebugRuntimeClasspath
but I can't pass args to this task via dependOn
How to achieve my goal?
task("extractMyDeps") {
dependsOn(":app:dependencies") // how pass --configuration
}
I think you can't pass the command line arguments to another task. But if you want to make an alias for a task you can use Exec Tasks like this:
task('extractMyDeps', type: Exec) {
workingDir '..'
def arguments = ['cmd', '/c', 'gradlew', ':app:dependencies', '--configuration', 'testCompileClasspath']
commandLine arguments
}
By using this task, you can run:
> gradlew extractMyDeps
Also you can make it more dynamic by passing the configuration name like this:
task('extractMyDeps', type: Exec) {
workingDir '..'
def arguments = ['cmd', '/c', 'gradlew', ':app:dependencies']
if (project.hasProperty("conf")) {
def conf = project.property("conf")
arguments.add('--configuration')
arguments.add(conf.toString())
}
commandLine arguments
}
This way these commands are valid:
> gradlew extractMyDeps
> gradlew extractMyDeps -Pconf=testCompileClasspath
I hope it will help you.
I am facing an issue when I try to stop gradle when a condition is not met.
I want when I execute a specific task and a file is not present to throw a GradleException but instead it fails to sync with Android Studio.
My code:
def mapFile = project.rootProject.file('../../maps.json')
buildConfigField "error", "BUILD_ERROR", '"maps.json is missing"'
if(!mapFile.exists()) throw new GradleException("File does not exist")
I have found this solution(don't really like it) with code:
buildConfigField "error", "BUILD_ERROR", '"maps.json is missing"'
so the BuildConfig will generate an error variable and the gradle will stop. Any other options of actually throwing an exception and the sync does not fail?
To let the task fail and not the whole build, you must raise the exception at task execution:
task myTask(type: MyType) {
def mapFile = project.rootProject.file('../../maps.json')
// do some configuration ...
doFirst {
if(!mapFile.exists()) throw new GradleException("File does not exist")
}
}
I am writing a gradle task. The task it invokes returns 3 for successful run instead of 3. How do I go about doing this ?
task copyToBuildShare(){
def robocopySourceDir = "build\\outputs\\apk"
def cmd = "robocopy "+ robocopySourceDir + " C:\\TEST *.* /MIR /R:5 2>&1"
exec {
ignoreExitValue = true
workingDir '.'
commandLine "cmd", "/c", cmd
if (execResult.exitValue == 3) {
println("It probably succeeded")
}
}
}
It gives the error:
Could not find property 'execResult' on task
I don't want to create a separate task. I want it to be in the exec block. What am I doing wrong?
project.exec() has a return value typed ExecResult.
def result = exec {
ignoreExitValue true
executable "cmd"
args = ["/c", "exit", "1"]
}
println "exit value:"+result.getExitValue()
Reference here:
https://docs.gradle.org/current/dsl/org.gradle.api.Project.html#org.gradle.api.Project:exec(groovy.lang.Closure)
You're going to need to specify that this task is of type Exec. This is done by specifying the task type like so
task testExec(type: Exec) {
}
In your specific case, You'll also want to make sure you don't try to get the execResult until the exec has finished this can be done by wrapping the check in a doLast.
task testExec(type: Exec) {
doLast {
if (execResult.exitValue == 3) {
println("It probably succeeded")
}
}
}
Here's an example of executing ls and checking its return value
task printDirectoryContents(type: Exec) {
workingDir '.'
commandLine "sh", "-c", "ls"
doLast{
if (execResult.exitValue == 0) {
println("It probably succeeded")
}
}
}
In the code provided below I can print each of the file names in the directory, but when it reaches the Exec command it only performs an Exec on the last file.
task frmf2xml(type:Exec) {
new File('src/orca/').eachFile {file ->
if(file.name.endsWith(".fmb")){
println file
commandLine 'cmd', '/c', 'frmf2xml.bat', file, 'OVERWRITE=YES'
}
}
}
I would like it to run the tool on every file
Actually i found a Solution, using execute().
task frmf2xml() {
new File('src/orca/').eachFile {file ->
if(file.name.endsWith(".fmb")){
def cmd = "cmd /c frmf2xml.bat ${file} OVERWRITE=YES"
def result = cmd.execute();
result.waitFor();
}
}
}
I'm new in gradle. How can I run exec one task after another? I've got a problem that task test1 runs before android.applicationVariants.all, and property test is empty,how to change it?
project A
String test = ''
android {
android.applicationVariants.all.doFirst {
test = 'vasya'
}
task test1.doLast{
println "$test"
}
But I've got the following output:
* Where:
Build file '/home/build.gradle' line: 57
* What went wrong:
A problem occurred evaluating project ':ProjectA'.
> No signature of method: java.util.ArrayList.doFirst() is applicable for argument types: (build_6g09fl113rl613 iaq870b0hod0$_run_closure1_closure12_closure18) values: [build_6g09fl113rl613iaq870b0hod0$_run_closure1_closure12_closure18#5f81a4ab]
Possible solutions: first(), toList(), asList(), sort(), sort(groovy.lang.Closure), sort(boolean)
1) Use dependsOn to handle hierarchy:
task helloTask1 << {
println "hello task 1"
}
task helloTask2(dependsOn: helloTask1) {
println "hello task 2"
}
then, calling helloTask2 execustion will trigger helloTask1 first
2) Use mustRunAfter() if needed (this method is in incubating mode):
task helloTask1 {
println "hello task 1"
}
task helloTask2 {
mustRunAfter helloTask1
println "hello task 2"
}
Given two tasks defined:
task mainTask {
println "main"
}
task nextTask {
println "next task"
}
the following code
mainTask << {
nextTask.execute()
}
executes nextTask after mainTask is run:
> gradle mainTask
main
next task
Have a look at task's mustRunAfter method.