Is it possible to pass a parameter to settings.gradle - gradle

I would like to add a command line parameter to completetly skip some subprojects for performance reasons. My settings.gradle looks like this:
rootProject.name='MyProject'
if (!rootProject.hasProperty('NO_LIBRARY_BUILD')) {
print "=== BUILDING OF LIBRARY PROJECTS. Pass -PNO_LIBRARY_BUILD to gradle to skip building ==="
include('Lib1')
project(':Lib1').projectDir=file('Path/to/Lib1')
include('Lib2')
project(':Lib2').projectDir=file('Path/to/Lib2')
}
else {
print "=== SKIPPING BUILD OF LIBRARY PROJECTS ==="
}
However, this does not work - passing -PNO_LIBRARY_BUILD still enters the "building" part of the if. I assume that these properties are not passed to rootProject, but somewhere else.
How can I access (more so, how can I check for the existence of) the NO_LIBRARY_BUILD command line parameter from the settings gradle?

I found that what worked was using simply
hasProperty('NO_BUILD_LIBRARIES') without specifying the project.

Tested on Gradle 7.1.1. Just using hasProperty does not work. Using settings.hasProperty('abc') works with -Pabc=true.
Reference: https://docs.gradle.org/current/dsl/org.gradle.api.initialization.Settings.html

Related

Gradle: Project dependencies from file

I'm fairly new to Gradle, and am enamored by its task-driven approach and customizability. So I have a question that hopefully helps me understand how to do something beyond the basics.
Suppose I have a simple text file that contains information about a project's dependencies. For example, something like
- dependency1
from: 'foobar'
version: '1'
- dependency2
from: 'foobaz'
version: '1'
Note that these are not I have some code that would, from this file, generate a file along the lines as follows:
compile 'commons-lang:commons-lang 2.6'
testCompile 'org.spockframework:spock-core:1.1-groovy-2.4'
Is there a way to configure my project so that my project's dependencies are taken from this file (not exclusively)?
Do note that the text file is also used to generate other artifacts that are used by other tasks (for example, a file to be added to a Docker container), so while it may be possible to, say, declare the dependencies normally and generate the text file instead, it is not a trivial process to do so at this time.
Yes, you can write your own groovy function that parses the file and creates a List. Then you can pass this map to the dependencies closures:
List<String> compileLibraries() {
// ... parse yaml and return list
}
dependencies {
compile compileLibraries()
}
Also, to use a yaml-parsing library, consider setting up a custom gradle subproject in the special buildSrc subfolder and writing your helper function there.
See this old post for more details: https://discuss.gradle.org/t/programmatically-adding-dependencies/7575/12
And here for buildSrc projects:
https://docs.gradle.org/current/userguide/organizing_build_logic.html#sec:build_sources

How to pass system properties to the tests in gradle in the smart way?

build.gradle
tasks.withType(Test){
systemProperties=System.properties
println systemProperties['param']
}
Now I can either pass parameters in the command line:
gradle test -Dparam=10
or put them in gradle.properties:
systemProp.param=15
Ideally I would like to put the defaults in the gradle.properties, and be able to overwrite them from the command line. Unfortunately if I do that, the gradle.properties has precedence, and -Dparam=10 is ignored.
Could you offer any solutions on that?
https://issues.gradle.org/browse/GRADLE-2122
It works since 2.12 or 2.13 "the smart way" already!
The example above is working, the command line -D option overdrives the defaults in gradle.properties
I am using gradle 2.12 and sharing how I used it:
test {
// support passing -Dsystem.property=value to bootRun task
systemProperties = System.properties
}
I have JUnit tests that I wanted to skip unless a property was used to include such tests. Using JUnit Assume for including the tests conditionally:
//first line of test
assumeThat(Boolean.parseBoolean(System.getProperty("deep.test.run","false"),true)
Doing this with gradle required that the system property provided at the time of running gradle build, shown here,
gradle build -Ddeep.test.run=true
was indeed passed through to the tests.
Hope this helps others trying out this approach for running tests conditionally.

Gradle file rename causes circular dependency error - Why?

I want to store an input file in a JAR created with a subclass of the Jar task in Gradle. The input file shall be stored under a different name.
Here is my build.gradle (complete working example; just create dir1/file1.txt first):
task myjar(type: MyJarTask);
class MyJarTask extends Jar {
#InputFile
File file1 = new File('dir1/file1.txt');
public MyJarTask() {
configure {
baseName 'foo'
from {
file1;
// comment out the next line to eliminate the error:
rename { String fileName -> fileName.replace('file1.txt', 'file2.txt'); }
}
}
}
}
Running this via gradle myjar gives the following error:
* What went wrong:
Circular dependency between the following tasks:
:myjar
\--- :myjar (*)
(*) - details omitted (listed previously)
When I comment out the line with the rename, everything works! (Of course the file is not renamed.)
What is the reason for this surprising behavior? Are we witnessing a Gradle bug?
Please do not suggest alternative solutions; I solved the original problem by avoiding the need for the rename. But I would like to learn; I feel I am missing something important.
I got an answer on the Gradle forum by Sterling Greene of Gradleware. Basically, the cause of the circular dependency is this (in my own words):
Closures always return the last value, so the from {} closure returns the value of rename. Incidentally, rename returns a reference to the task itself (why it would do that, I don't know, but that's what its docs say). So the task itself is added to its list of things to copy, and we have a circular dependency.
The solution would be to modify the closure slightly:
from(file1) {
//file1;
rename { String fileName -> fileName.replace('file1.txt', 'file2.txt'); }
}
This runs with no problems, because it uses an overloaded variant of the from() method which always adds the given file to the list of things to copy, not the result of the closure. All in all, that's not exactly intuitive, but there it is.
Well i also got same error I thought error was due to renaming of files but in my case error was due to dual dependency on module(:backend)and java library dependency on android module(:app) I got it sorted by following steps:
Press Ctrl+Shift+Alt+S or Go to File->Project Structure this will open project Structure Dialog box.
On left side PANEL ,under modules section choose java library (e.g jjLibrary) there was two compile dependency :app and :backend just have to remove both of these dependencies.As :backend already have compile dependency on java library and :app is android module which cannot have dependency on java library.Press Ok.
Save and Sync gradle files ..
And the error has gone..Hope this helps!!!Cheers

How to check java version when running gradle?

One of my project requires Java 1.8, but sometimes we didn't notice we are using older java so that we will get some strange errors.
I want to add the checking in build.gradle, so that when we run any task, it will firstly check the version, and prints error and quit immediately.
I tried to add the checking directly in build.gradle on the first line, but it still do some others tasks e.g. (clean, compileJava) before the checking happens, when I run:
$ ./gradlew
How to do it correctly?
If you put the check very early in your build lifecycle (plain check in the beginning of your build.gradle file or in the apply method of a plugin) you shouldn't see any tasks executed.
you can use JavaVersion enum for that which is part of the gradle api:
if(JavaVersion.current() != JavaVersion.VERSION_1_8){
throw new GradleException("This build must be run with java 8")
}
The accepted answer is nice however it could be improved a little bit by making it more generic. Indeed instead of comparing the current version with an explicit version, we could rely on the value of targetCompatibility instead (assuming it has been set properly) as next:
if (JavaVersion.current() != project.targetCompatibility) {
throw new GradleException("The java version used ${JavaVersion.current()} is not the expected version ${project.targetCompatibility}.")
}

How to override Gradle `rootProject.name` from the command line?

I'm writing a test that does a build and publish to Artifactory. Since I don't want the test to fail if it's run concurrently (eg by separate build jobs or developers), I'd like to override rootProject.name. Can this be done from the command line? I've tried -ProotProject.name=${module} and -Pproject.archivesBaseName=${module} but they're not working (the latter does have some effect, but the artifact is still published with the rootProject.name setting in settings.gradle).
You'll have to script settings.gradle. For example:
rootProject.name = System.getProperty("rootProjectName")
Now you can run with gradle build -DrootProjectName=foo.
The following is a slightly simpler version when you need the default behavior that just passes through the default when it's not being overwritten.
rootProject.name = System.getProperty('rootProjectName') ?: rootProject.name

Resources