Automatically pass unparsed arguments to JavaExec-type task in Gradle? - gradle

I'm trying to pass a lot of arguments to a JavaExec task in Gradle. Right now I'm doing something like:
task foo(type: JavaExec) {
if (project.hasProperty('prop1')) {
args += ["--prop1"]
}
if (project.hasProperty('foo2')) {
args += ["--foo3"]
}
...
if (project.hasProperty('flagn')) {
args += ["--flagn"]
}
}
And then when I execute this I do something like ./gradlew :foo -Pprop1 -Pfoo2 ... -Pflagn. This works but is really tedious since I need to literally pass the same string arguments from Gradle to JVM. Is there an easier way - like automatically pass all the unparsed arguments or something simpler?

You can access the project properties from the command line via the StartParameter object.
So, for your example, you could use:
task foo(type: JavaExec) {
args gradle.startParameter.projectProperties.keySet().collect { "--$it" }
}
However, this will add any command line project property to the JavaExec args. Maybe you could think about filtering for properties with a specific prefix.

Related

Gradle task lines always getting executed

I have the following Gradle task:
task deploy(type: Exec) {
doFirst {
println 'Performing deployment'
}
final Map properties = project.getProperties()
if (!properties['tag']) {
throw new StopExecutionException("Need to pass a tag parameter")
}
commandLine "command", tag
}
If I run another task I get an error because properties['tag'] is undefined, I guess because Gradle is executing everything in the task except commandLine. Is there a better way to do this or a way to stop Gradle from executing parts of the task even when I'm running another task?
Using Gradle 6.6.1
I use this pattern:
// Groovy DSL
tasks.register("exec1", Exec) {
def tag = project.findProperty("tag") ?: ""
commandLine "echo", tag
doFirst {
if (!tag) {
throw new GradleException("Need to pass a tag parameter")
}
}
}
It adds the tag property if it exists.
If it does not exist, it adds an empty string but checks for this before it actually runs.
It would be great if the Exec task accepted providers as arguments so you could just give it providers.gradleProperty("tag"), but unfortunately it doesn't.

Executing registered task in kotlin build file

I need to convert a gradle build script, which is written in Groovy, into Kotlin. The problem is, that in the Groovy build file in one task another task, which was defined before, is executed. However, it appears that in Kotlin there is no support for that, at least I could not find any in the API.
I have studied the API and searched for similar problems, but I could not find anything useful.
The Groovy code looks like this:
task doSomething () {
...
}
task anotherTask () {
...
doSomething.execute()
...
}
How would this call be translated into Kotlin?
doSomething.execute()
You should never call execute() on a task. Instead set the inputs, outputs and dependencies correctly, and Gradle will call the task for you if it needs to.
something like:
tasks {
val doSomething by registering {
doLast {
println("running doSomething")
}
}
val anotherTask by registering {
dependsOn(doSomething)
doLast {
println("Running anotherTask")
}
}
}
Then:
$ gradle anotherTask
> Task :doSomething
running doSomething
> Task :anotherTask
Running anotherTask
BUILD SUCCESSFUL in 746ms
Kotlin is statically typed. So you must know the type of the task of doSomething and anotherTask if Kotlin not able to infer it for you. execute leads me to believe it some sort of execute task. So for your example:
val doSomething = tasks.register("doSomething", JavaExec::class.java) {
main = "com.example.Example"
}
val anotherTask = tasks.register("anotherTask") {
doSomething.get().exec()
}
However, it looks you just want to execute doSomething before anotherTask, so you'd want:
val doSomething = tasks.register("doSomething", JavaExec::class.java) {
main = "com.example.Example"
}
val anotherTask = tasks.register("anotherTask") {
dependsOn(doSomething)
}
Without knowing the types of your task it's difficult to give you the right answer.

Run executable jar with parameters from gradle

I wish to run executable jar from my gradle file. I have tied:
task runJar(dependsOn:jar) << {
javaexec {
main="-jar"; args "C:/Development/AndroidStudioProjects/AndroidDev/Test.jar"
}
}
But I get "Could not find property 'jar' on project ':MyProj"
I also tried:
task runScheduleReader << {
javaexec {
main = "MainClass"
classpath = "C:/Development/AndroidStudioProjects/AndroidDev/Test.jar"
args('1')
}
}
I am relatively new to groovy, can you please help me with that?
P.S... I put those function outside of android {}
In your first code snippet dependsOn in task declaration means, that task runJar should be executed only after the jar task. Exception you get, says, that your current project doesn't have such a task. So, if you really don't need to execute jar task just before, you can simply not declere this task dependency:
task runJar() << {
javaexec {
main="-jar"; args "C:/Development/AndroidStudioProjects/AndroidDev/Test.jar"
}
}
Though, this is a little bit strange case, when you have to execute some jar without relative path, this solution should work.
The second snippet should pass the jar as the argument too, but this time, it should be an arguments array, something like this:
task runScheduleReader() << {
javaexec {
main="-jar";
args = [
"C:/Development/AndroidStudioProjects/AndroidDev/Test.jar",
"1"
]
}
}

Gradle task should not execute automatically

I'm defining a task in gradle:
task releaseCandidate(type: Exec) {
commandLine 'git', 'checkout', 'develop'
// Increment version code in Manifest
String manifest = new File('AndroidManifest.xml').getText('UTF-8')
Pattern pattern = Pattern.compile('android:versionCode="([0-9]+)"')
Matcher matcher = pattern.matcher(manifest)
matcher.find()
int newVersionCode = Integer.parseInt(matcher.group(1)) + 1
manifest = manifest.replaceAll(
"android:versionCode=\"([0-9]+)\"", "android:versionCode=\"$newVersionCode\""
)
new File('AndroidManifest.xml').write(manifest, 'UTF-8')
commandLine 'git', 'diff'
}
Which I want to execute only when I explicitly call it as gradle releaseCandidate. However, when I run any other task, such as gradle assembleDebug, it also runs task releaseCandidate. I don't want that behaviour to happen. There is no task depending on releaseCandidate or vice-versa.
My project is an Android app, so I am using android gradle plugin.
A common pitfall. Add an action to the task otherwise code will run at configuration phase. Sample task with action:
task sample << {
}
As I see You'd rather need to write a custom task than using Exec type. I suppose it's not valid to define commandLine twice.
EDIT
You can read this post to get the general idea how it all works.
You are mixing Task configuration and groovy code. Everything that is part of the main body of a task definition will be executed in the configuration phase. The task task1 << { code } is a shorthand for
task task1 {
doLast {
code
}
}
commandLine is part of the Exec Task but your other code is not and should be wrapped into a doLast this will execute the commandline first and then execute your additional code. If you need another exec commandLine then you'll need another task.
task releaseCandidate(type: Exec) {
commandLine 'git', 'checkout', 'develop'
doLast {
// Increment version code in Manifest
String manifest = new File('AndroidManifest.xml').getText('UTF-8')
Pattern pattern = Pattern.compile('android:versionCode="([0-9]+)"')
Matcher matcher = pattern.matcher(manifest)
matcher.find()
int newVersionCode = Integer.parseInt(matcher.group(1)) + 1
manifest = manifest.replaceAll(
"android:versionCode=\"([0-9]+)\"", "android:versionCode=\"$newVersionCode\""
)
new File('AndroidManifest.xml').write(manifest, 'UTF-8')
}
}
Just to complete #Opal answer for cases when Exec is really used (for example CommandLine reference) :
task task1 << {
exec {
List<String> arguments = new ArrayList<String>()
//..
commandLine arguments
}
}

Gradle javaexec task is ignoring jvmargs

I am trying to run my app using a Gradle javaexec task. However, jvmargs and args are not passed to the command execution. Why?
task runArgoDev(type: JavaExec) {
main = "org.app.ArgoDevRunner"
classpath = configurations.testRuntime
project.ext.jvmargs = ['-Xdock:name=Argo', '-Xmx512m', '-Dfile.encoding=UTF-8', '-Dapple.awt.textantialiasing=on', '-ea']
project.ext.args = ['-initParameter', 'implicit-scrollpane-support=true']
}
Above code doesn't have the desired effect because it sets extra properties on the project object, instead of configuring the task. Correct is jvmArgs = ... and args = .... (It's also possible to omit =, [, and ].)
Here is example, to pass program args and jvmargs to run task in gradle.
run {
args 'server', 'test.yml'
jvmArgs '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005'
}

Resources