After a year dealing with Gradle in different companies, I think it's high time to start collecting some patterns and suggestions.
1) Avoid redundant folder declaration.
Remember, apply plugin java already sets up some defaults folder, you don't need to declare them if you don't plan to change them.
Recommended |
---|
apply plugin: 'java' |
Redundant |
---|
apply plugin: 'java' sourceSets { main { java { srcDir 'src/main/java' } resources { srcDir 'src/main/resources' } } test { java { srcDir 'src/test/java' } resources { srcDir 'src/test/resources' } } } |
Groovy plugin and scala plugin also declares other folders, just read some documentation before start using them.
2) Choose your syntax for dependency management.
Gradle allows you two syntax for dependency declaration.
- Extended (group: 'ws.lazylogin', name: 'lazylogin-core', version: '1.0.0')
- Compact ('ws.lazylogin:lazylogin-core:1.0.0').
I prefer the compact one :)
3) Your users don't need to know project details to compile it.
Any project should be able to clean + build from the code and a JVM in place. Ideally nothing else should be required.
Although some projects will inevitably break this suggestion, try not to.
Some examples of build breaking customs.
- Usage of variables declared in ${user.home}/.gradle/gradle.properties that don't have default value in build.gradle or exist in project's gradle.properties.
- This would fail for anyone not owning / not knowing what variables to include / contaminate hi/er user gradle properties file. No no no no no.
- Remember, project variables are overridden by user projects, no risk in declaring default values in project's gradle.properties to, at least, allow building. (More info: https://discuss.gradle.org/t/order-of-precedence-for-defining-gradle-properties/7274/2)
- Assumption of executables in the PATH or some predefined location.
4) Prevent incorrect dependency versioning
Declare your dependencies and version in a single place (that was a good idea in Maven's universe) and reuse those dependencies by its variable name.
The risk of not following this advice is the likelihood you'll end up using different versions for the same library in different modules in the same project, and you don't want that, neither do I.
Solution would look like this:
Dependency declaration (they can be declared in a different file) |
---|
ext{ //VERSIONS v = [ spring: '3.2.0.RELEASE', jme3: '3.1.0-snapshot-github' ] deps = [ //SPRING spring_core: 'org.springframework:spring-core:'+v.spring, spring_beans: 'org.springframework:spring-beans:'+v.spring, spring_context: 'org.springframework:spring-context:'+v.spring, //JME3 jme3_core: 'com.jme3:jme3-core:' + v.jme3, jme3_effects: 'com.jme3:jme3-effects:' + v.jme3 ] } |
Dependency usage for any subproject |
---|
dependencies { compile ( project(':mod-api'), deps.jme3_core, deps.jme3_effects, deps.spring_beans, deps.spring_core ) } |
Instead of the more error prone way:
Dependency usage for a given subproject A |
---|
dependencies { compile ( project(':mod-api'), 'com.jme3:jme3-core:3.1.0-snapshot-github', 'com.jme3:jme3-effects:3.1.0-snapshot-github', 'org.springframework:spring-beans:3.2.0.RELEASE', 'org.springframework:spring-core:3.2.0.RELEASE' ) } |
Dependency usage for a given subproject B |
---|
dependencies { compile ( project(':mod-api'), 'com.jme3:jme3-core:3.1.0-snapshot-github', 'com.jme3:jme3-effects:3.1.0-snapshot-github', 'org.springframework:spring-beans:3.1.0.RELEASE', 'org.springframework:spring-core:3.2.0.RELEASE' ) } |
5) Group your dependency by dependency configuration.
It's nicer :)
Dependencies grouped by configurations |
---|
compile ( project(':mod-api'), libs.lazylogin_common_context, libs.nifty, libs.jme3_core, libs.jme3_effects, libs.spring_beans, libs.spring_core, libs.jackson_dataformat_yaml, libs.jackson_databind ) runtime ( libs.nifty_default_controls, libs.eventbus, libs.auto_value)) |
Dependencies ungrouped (and disorganized) |
---|
compile project(':mod-api') compile libs.lazylogin_common_context, compile libs.nifty, compile libs.jme3_core, compile libs.jme3_effects, compile libs.spring_beans, compile libs.spring_core, runtime libs.nifty_default_controls, compile libs.jackson_dataformat_yaml, compile libs.jackson_databind, runtime libs.eventbus, runtime libs.auto_value) |
(Not possible when you want to exclude dependencies from dependencies).