i am a newbie of both gradle and groovy, now i am try to setup a tag on my subversion repository. Below is my gradle script:
task svnrev {
// use ant to retrieve revision.
ant.taskdef(resource: 'org/tigris/subversion/svnant/svnantlib.xml') {
classpath {
fileset(dir: 'lib/DEV/svnant', includes: '*.jar')
}
}
ant.svn(javahl: 'false', svnkit: 'true', username: "${_svn_user}", password: "${_svn_password}", failonerror: 'false') {
ant.info(target: "${_svn_source_url}", propPrefix: 'svninfo')
}
// retrieve property of ant project and assign it to a task's property, refer to:
// http://gradle.1045684.n5.nabble.com/can-t-find-or-extract-properties-from-svnant-info-function-in-gradle-td3335388.html
ext.lastRev = ant.getProject().properties['svninfo.lastRev']
// retrieve property of gradle project
//getProject().properties['buildFile']
}
task svntag << {
ant.svn(javahl: 'false', svnkit: 'true', username: "${_svn_user}", password: "${_svn_password}", failonerror: 'false') {
copy(srcurl: "${_svn_source_url}", desturl="${_svn_tag_url}", message="Create tag: ${_svn_tag_url}")
}
}
The task 'svnrev' works normally, however when run 'gradle svntag', i constantly got a error message:
* What went wrong:
A problem occurred evaluating root project 'AFM-IGPE-v2.0.0'.
> Could not find method copy() for arguments [{srcurl=svn://192.168.2.9/IGPE/trunk_dev}, svn://192.168.2.9/IGPE/tag/AFM, Create tag: svn://192.168.2.9/IGPE/tag/AFM] on root project 'AFM-IGPE-v2.0.0'.
Also I tried
ant.copy(srcurl: "${_svn_source_url}", desturl="${_svn_tag_url}", message="Create tag: ${_svn_tag_url}")
And this time a different error message shown:
* What went wrong:
A problem occurred evaluating root project 'AFM-IGPE-v2.0.0'.
> No signature of method: org.gradle.api.internal.project.DefaultAntBuilder.copy() is applicable for argument types: (java.util.LinkedHashMap, org.codehaus.groovy.runtime.GStringImpl, org.codehaus.groovy.runtime.GStringImpl) values: [[srcurl:svn://192.168.2.9/IGPE/trunk_dev], ...]
Possible solutions: any(), notify(), wait(), grep(), every(), find()
In fact I just simple translate my ant build.xml to gradle, and my ant build.xml works well. I have googled a period time, however no results found. Pls help and thanks in advance for your kindly help.
At first sight, I can spot two problems:
It has to be task svnrev << {, not task svnrev {.
Groovy named parameters are written with a :, not a =. (The latter instead assigns a default value to a positional parameter.) That's probably why you get the error for ant.copy (you mix and match between : and =).
Related
I'm trying to find the best way to pass a gradle task arguments from the command line.
I have this task. I want to unpack solutions from student exercises and copy them into the right place in the project to evaulate them. I call this task like this:
> gradle swapSolution -Pstudent=MyStudent -Pexercise=ex05
One Problem i have with this while doing this in IntelliJ while having the Gradle plugin enabled is that i get this error message when build the project. What could be a solution to this?
A problem occurred evaluating root project 'kprog-2020-ws'.
> Could not get unknown property 'student' for root project 'kprog-2020-ws' of type org.gradle.api.Project.
This is the gradle task:
task swapSolution(type: Copy) {
new File("${rootDir}/Abgaben").eachDir { file ->
if (file.name.toString().matches("(.*)" + project.property("student") + "(.*)")) {
def exDir = new File("/src/main/java/prog/" + project.property("exercise"))
if (!exDir.exists()) {
delete exDir
}
new File(file.path).eachFile { zipSolution ->
//def zipFile = new File("./Abgaben/" + file.name.toString() + "/" + project.property("exercise") + "Solution.zip")
from zipTree(zipSolution)
into "/src/main/java/"
}
}
}
}
Do you have any suggestions to optimize this process?
-P denotes the Gradle Project Property. If you need to use project properties you can specify it as a system property in gradle.properties file in project root directory.
If your task is of type JavaExec you can use --args switch and pass it in Arguments text field of the Gradle Task Run Configuration togenther with the task name like swapSolution -args="-student=MyStudent -exercise=ex05". See also
https://stackoverflow.com/a/48370451/2000323
I've got a Java project build with Gradle and a property file that contains custom configuration for my testing framework (amount of thread to use, test environment url, custom username & password for those environments, etc...).
I'm facing an issue related to using properties from that file that I can't figure out:
if my Test task include '**/*Test.class', all tests are running as expected.
if my Test task include '**/MyTest.class', only that test is running as expected.
if my Test task include readProperty(), the task is skipped as NO-SOURCE. <- this is the part I can't understand - as the readProperty return the correct value.
Let's get into details:
This is how the property is defined in a my.property file:
testng.class.includes='**/MyTest.class'
This is what the build.gradle file looks like:
Properties props = new Properties()
props.load(new FileInputStream(projectDir.toString() + '/common.properties'))
def testsToRunWorking(p) {
String t = 'MyTest.class'
println "Tests = $t"
return t ? t : '**/*Test.class'
}
def testsToRunNotWorking(p) {
String t = getProperty(p, "testng.class.includes")
println "Tests = $t"
return t ? t : '**/*Test.class'
}
task testCustom(type: Test) {
outputs.upToDateWhen { false }
testLogging.showStandardStreams = true
classpath = configurations.customTest + sourceSets.customTest.output
include testsToRunNotWorking(props) ///< Does not work!
// include testsToRunWorking(props) ///< Works!
useTestNG()
}
In terms of debugging:
The println properly return the value I expect, even when the testCustom task doesn't do what I would expect.
I tried adding a dependsOn task just to print the content of testCustom.configure { println $includes } which looks correct as well.
--info
Tests = '**/MyTest.class'
:clean
:compileCustomTestJava - is not incremental (e.g. outputs have changed, no previous execution, etc.).
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
:processCustomTestResources
:customTestClasses
:testCustom NO-SOURCE
The core of the issue seems to be coming from the fact that I'm reading that value from property. I hard coded inside the build.gradle everything works as expected. If read from a property file - build stops with a NO-SOURCE statement.
Any idea?
Thanks!
You are using quotation marks in the values of your property files. Everything that comes after the assignment sign in a property file is used as value, so the quotation marks remain in the string. They are printed in your output Tests = '**/MyTest.class'. On the other hand, if you define a string in your (Groovy) code with quotation marks, they are not included in the string. Therefor, the passed strings are not the same.
Remove the quotation marks from your property file(s) and everything should work, since the class files will match your string without the quotation marks.
My setup:
buildToolsVersion "25.0.3"
com.android.tools.build:gradle:2.3.0
Code:
apply plugin: 'com.android.application'
android {
// ...
signingConfigs {
release {
storeFile getReleaseKeyStoreFile()
// ...
File getReleaseKeyStoreFile() {
String keyStoreFile = System.getenv("KEYSTORE_FILE")
if (keyStoreFile == null || keyStoreFile == "") {
println 'ERROR: Failed getting release keyStoreFile'
return null
}
return file(keyStoreFile)
}
When I run the gradle task assembleDebug I'm getting this in the Gradle build messages:
Failed getting releaseKeyStoreFile
Why is this function evaluated even though the build variant is debug and not release?
Is there a simple work-around to avoid this unwanted behavior?
You need to distinguish between the configuration phase and the execution phase.
In the configuration phase, the whole build script is evaluated and executed.
Only task actions (defined by task types), doFirst and doLast closures are executed in the execution phase.
Whether a task is executed (explicit or as dependency) only affects the execution phase, but nevertheless it will always be configured.
You can call each task, the configuration code in your android closure will always be executed.
To answer your second question: Your method must be fail-safe (as it is right now). There is no problem in returning null to the storeFile property, since only the task (which is not executed) will fail.
An additional hint: You can simplify your method. There is no need to check for null and an empty string, you can simply check for Groovy truth. You can use a ternary expression, too.
return keyStoreFile ? file(keyStoreFile) : null
I'm trying to sync specific files from a dir with Gradle. But I get a odd error that I can't seem to solve. If there is a better (working) way to filter files while syncing that would also be welcome.
Implementation 1
def updateAbstractsContentSpec = copySpec {
from('../../base') {
includes "../../base/shared/**/*_abstract.*"
}
}
task updateAbstracts(type: Sync) {
group 'build'
with updateAbstractsContentSpec
}
Error 1
Error:(24, 0) Could not find method includes() for arguments [../../base/shared/**/*_abstract.*] on object of type org.gradle.api.internal.file.copy.CopySpecWrapper_Decorated.
Implementation 2 (Preferable)
task updateAbstracts(type: Sync) {
group 'build'
from '../../base'
includes '../../base/shared/**/*_abstract.*'
}
Error 2
Error:(23, 0) Could not find method includes() for arguments [../../base/shared/**/*_abstract.*] on task ':apps:TestApp1:updateAbstracts' of type org.gradle.api.tasks.Sync.
I assume that its clear what I try to do. I hope that somebody can help me with this.
As of Gradle 3.0 CopySpec documentation, CopySpec does not contain includes method.
You should use include instead:
task updateAbstracts(type: Sync) {
group 'build'
from '../../base'
include '../../base/shared/**/*_abstract.*'
}
I'm trying to configure the following custom task:
task antecedeRelease(type: AntecedeReleaseTask) {
antecedeWithVersion = project.'antecede-with-version'
antecedeToVersion = project.'antecede-to-version'
}
The problem is that the properties antecede-with-version and antecede-to-version are to be set through the command line with a -P option. If they're not set and antecedeRelease isn't being called, that shouldn't be a cause for an error:
$ ./gradlew tasks
org.gradle.api.GradleScriptException: A problem occurred evaluating project ...
Caused by: groovy.lang.MissingPropertyException: Could not find property 'antecede-with-version' on project ...
I could conditionally define the antecedeRelease task such that it's defined only if those properties are defined but I'd like to keep the build.gradle file as clean as possible.
If you need the antecedeRelease task to run "lazily" as-in, at the end of the configuration phase, or at the beginning of the execution phase, your best bet is to use doFirst
task antecedeRelease(type: AntecedeReleaseTask) {
doFirst {
antecedeWithVersion = project.'antecede-with-version'
antecedeToVersion = project.'antecede-to-version'
}
}
One option might be to use Groovy's elvis operator like so:
task antecedeRelease(type: AntecedeReleaseTask) {
antecedeWithVersion = project.ext.get('antecede-with-version') ?: 'unused'
antecedeToVersion = project.ext.get('antecede-with-version') ?: 'unused'
}
If this fails still, you can consider project.ext.has('property') when setting the value.