Can I put my dependencies and repositories in another file? - gradle

I have a requirement that some of my dependencies are in a separate file. How can I accomplish this? One of the samples on docs.gradle.org is:
List groovy = ["org.codehaus.groovy:groovy-all:2.4.7#jar",
"commons-cli:commons-cli:1.0#jar",
"org.apache.ant:ant:1.9.6#jar"]
List hibernate = ['org.hibernate:hibernate:3.0.5#jar',
'somegroup:someorg:1.0#jar']
dependencies {
runtime groovy, hibernate
}
Something like this would work, but I'd also like to specify my repositories in the same file.
Edit:
The solution I came up with
stuff.gradle
repositories {
maven {
credentials {
username 'stuff'
password 'stuff'
}
url 'stuff'
}
}
dependencies {
compile 'things'
}
And in build.gradle
apply from: 'path/to/stuff.gradle'
After dependencies, though I'm not sure if it makes a difference. It was surprisingly simple. There were no changes to build.gradle apart from the apply statement, it still has the normal repositories and dependencies closures. Thanks to Opal for putting me on the right track.

Here you go:
lol.gradle:
ext.repos = { mavenCentral(); mavenLocal() }
ext.groovy = [
"org.codehaus.groovy:groovy-all:2.4.7#jar",
"commons-cli:commons-cli:1.0#jar",
"org.apache.ant:ant:1.9.6#jar",
]
ext.hibernate = [
'org.hibernate:hibernate:3.0.5#jar',
]
build.gradle
apply from: 'lol.gradle'
apply plugin: 'java'
repositories repos
dependencies {
runtime groovy, hibernate
}
Since repositories can be kept as a list, the simplest way of keeping repositories with no workarounds is to use a closure. If you use a list to keep repositories as well it will fail with with method resolution error for both mavenLocal and mavenCentral.
If you prefer to keep repositories as a list however then the following piece of code can be used:
lol.gradle
ext.repos = ['mavenCentral', 'mavenLocal',]
ext.groovy = [
"org.codehaus.groovy:groovy-all:2.4.7#jar",
"commons-cli:commons-cli:1.0#jar",
"org.apache.ant:ant:1.9.6#jar",
]
ext.hibernate = [
'org.hibernate:hibernate:3.0.5#jar',
]
build.gradle
apply from: 'lol.gradle'
apply plugin: 'java'
repositories { r ->
repos.each { n -> r."$n"() }
}
dependencies {
runtime groovy, hibernate
}

Related

new gradle format confusion and migrating causes Could not find method testCompile()

I have a build.gradle with
plugins {
id {some plugin for all projects}
id "com.diffplug.spotless" version "5.1.1"
}
AND THEN I have an allprojects {} section that defines ONE apply plugin: 'jacoco' and a subprojects {} section that declares apply plugin: 'java' with a few others
Immediately adding spotless messed with stuff and errors out that it cannot find the java plugin so then I modify ALL plugins to be in the plugins section like so
plugins {
id "java"
id "checkstyle"
id "eclipse"
id "idea"
id "jacoco"
id "com.diffplug.spotless" version "5.1.1"
id "com.dorongold.task-tree" version "1.5" //This prints out a task tree (pretty print)
}
This then results in this error
Could not find method testCompile() for arguments [junit:junit:4.11] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
So for some reason the java plugin is lost. I can't figure out the right combination here to migrate everything to this new plugins section format.
How do I do that? I randomly tried putting a plugins section in allprojects and subprojects but that results in this new error
Could not find method plugins() for arguments [build_d8c2jgy4ua1m0vkv9kmvgefmc$_run_closure2$_closure5#62337fda] on root project 'providersvc-all' of type org.gradle.api.Project
How does this new plugins section work? I can't seem to migrate without it breaking everything. I just want java plugin, testCompile, and spotless to play nicely together right now
EDIT(forgot to attach the full trimmed down file that does not work):
plugins {
id "java"
id "com.diffplug.spotless" version "5.1.1"
}
ext {
//dependency versions every project usees so we version in one location all jars(less jar hell this way)
deps = [
'junit': 'junit:junit:4.11'
]
}
allprojects {
repositories {
jcenter()
mavenCentral()
maven {
//webpieces VERSIONED snapshots so you can lock on a snapshot
url "https://dl.bintray.com/deanhiller/maven"
}
//For testing locally
maven {
url uri('/tmp/myRepo/')
}
}
}
subprojects {
dependencies {
testCompile deps['junit']
}
}
thanks,
Dean
You are only applying the plugins to the root project - not the sub-projects. However, if you like to configure plugins through the subprojects configuration, you have to use the apply plugin syntax. But you don't have to use the old buildscript block for configuring the classpath and repositories if you a combination of the two.
Here is an example. I am assuming the root project is not a Java project. I have also removed your comments and inserted mine instead for the sole reason to make them easier to spot.
plugins {
id "com.diffplug.spotless" version "5.1.1" apply false // <-- Set "apply false" here
// This makes it configure which version to use on the classpath for the entire build, but without applying it.
// Notice that the Java plugin is not specified here anymore.
// This is because it is a core plugin so you can't set the version (and I am assuming you don't want it on in the root project).
}
ext {
deps = [
'junit': 'junit:junit:4.11'
]
}
allprojects {
repositories {
jcenter()
mavenCentral() // <-- You can remove this if you want as it is already present as a proxy in jcenter().
maven {
url "https://dl.bintray.com/deanhiller/maven"
}
maven {
url uri('/tmp/myRepo/')
}
}
}
subprojects {
// Here are the two plugins
apply plugin: "java"
apply plugin: "com.diffplug.spotless"
dependencies {
testImplementation deps['junit'] // <-- testCompile renamed to testImplementation as the former has been deprecated for a long time
}
}

ScalaStyle using grade return an error

I'm looking for scalaStyle using gradle. Can you explain how to do it?
I've tried this link, but I get an error:
Error:(110, 0) Could not find method scalaStyle() for arguments
[build_5ig236mubh10t6rxyt8apdkfi$_run_closure4#46b9e954] on root
project .....
Here's is a sample build.gradle that uses scalaStyle plugin:
buildscript {
repositories {
maven {
url 'http://jcenter.bintray.com/'
}
}
dependencies {
classpath 'org.github.ngbinh.scalastyle:gradle-scalastyle-plugin_2.11:0.9.0' //version 1.0.0 is not published yet.
}
}
apply plugin: 'scalaStyle'
scalaStyle {
configLocation = '/path/to/scalaStyle.xml'
includeTestSourceDirectory = true
source = 'src/main/scala'
testSource = 'src/test/scala'
}
You need to define buildscript block to declare dependencies for the script itself. When it's done a plugin needs to be applied. Finally you can use scalaStyle block to configure the plugin's behaviour.

Apply external Plugin to a subset of subprojects

I am using the Gradle SSH Plugin to deploy some, but not all subprojects to two different remote machines. I want to configure these remotes in the main build script to avoid duplication, but cannot apply the plugin as per this:
configure([
project(':Subproject1'), project(':Subproject5'), project(':Subproject7')
])
{
buildscript {
dependencies {
classpath 'org.hidetake:gradle-ssh-plugin:2.4.2'
}
}
apply plugin: "org.hidetake.ssh"
ssh.settings {
user = getProperty('ssh.username')
identity = file(getProperty('ssh.identity'))
knownHosts = allowAnyHosts
}
remotes {
tomcat {
host = getProperty('ssh.hosts.tomcat')
}
jboss {
host = getProperty('ssh.hosts.jboss')
}
}
}
Gradle fails with > Plugin with id 'org.hidetake.ssh' not found.
Everything is fine when the contents of the configuration closure are applied per project. How can I elegantly solve this issue?
Guessing here as I haven't reproduced your issue, but the buildscript block is special as it is pre-parsed before normal groovy parsing of the build files and I suspect that having it inside a project block like you have will not work.
Have you tried moving the buildscript block to the root level in the script above?
edit 1: old gradle forums post discussion this can be found here
edit 2: adding a snippet of code in response to a comment.
To remove duplication and only define say the repository references in one place, you could use the following pattern:
buildscript {
ext.RepositoryConfigurator = {
maven {
credentials.username artifactoryReader
credentials.password artifactoryReaderPwd
url artifactoryReaderUrl
}
jcenter()
mavenCentral()
}
ext.DependencyConfigurator = {
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:1.2"
}
ext.ResolutionConfigurator = {
resolutionStrategy.cacheChangingModulesFor 60, 'minutes'
}
repositories RepositoryConfigurator
dependencies DependencyConfigurator
configurations.classpath ResolutionConfigurator
}
apply plugin: "some.plugin.requiring.above.classpath"
gradle.rootProject {
buildscript {
repositories RepositoryConfigurator
dependencies DependencyConfigurator
configurations.classpath ResolutionConfigurator
}
}
gradle.allprojects {
buildscript {
repositories RepositoryConfigurator
dependencies DependencyConfigurator
configurations.classpath ResolutionConfigurator
}
}
In other words: since the buildscript block is special and pre-parsed, you can not use things defined elsewhere in the buildscript block. Going in the other direction is ok though, i.e. you can define things in the buildscript block which are then visible elsewhere. We can use this to define the repository references once inside the buildscript block and then use that reference in other places in the build file.
The above is from a settings.gradle file so might or might not be a perfect fit, but should demonstrate the idea.

Gradle Custom buildScriptRepository methods

I would like to make a custom buildScript repository method so I can easily reference our internal maven repo. Right now I'm required to declare a maven block everywhere we use our plugin.
Here is the current setup
buildscript {
repositories {
jcenter()
maven { url 'http://myNexus:8081/nexus/content/repositories/My-Release' }
}
dependencies {
classpath 'com.example.plugin:my-plugin:1+'
}
}
What I would like to do is something like this
buildscript {
repositories {
jcenter()
myReleaseRepo()
}
dependencies {
classpath 'com.example.plugin:my-plugin:1+'
}
}
How can I make a method available to create a repository anywhere we may use the plugin in the future?
Another solution is to add custom methods on RepositoryHandler using some Groovy goodness. Just chuck this in ~/.gradle/init.gradle
RepositoryHandler.metaClass.myReleaseRepo = {
delegate.maven {
name 'myReleaseRepo'
url 'http://myNexus:8081/nexus/content/repositories/My-Release'
}
}
After that, you can use it just as you described:
buildscript {
repositories {
myReleaseRepo()
}
}
Metaclasses in Groovy are just great. The delegate in this case is pretty much like the javascript this. This code is essentially using the RepositoryHandler instance (delegate keyword) and just calling repositoryHandlerInstance.maven(name, url).
It is possible to add a repo to an init script which would then apply to all gradle invocations that use the init script - without having to individually declare your maven repo in each build.gradle.
Solution 1:
Partial solution, does not do exactly what you're asking for. In init.gradle:
allprojects{
buildscript{
repositories{
maven{ url 'http://myNexus:8081/nexus/content/repositories/My-Release' }
}
}
}
Then your build.gradle can skip buildscript repo declaration entirely:
buildscript {
dependencies {
classpath 'com.example.plugin:my-plugin:1+'
}
}
Solution 2:
In fact, you can even move your buildscript classpath declaration to init and have the plugin apply to all projects that use the init script:
beefier init.gradle
allprojects{
buildscript{
repositories{
maven{ url 'http://myNexus:8081/nexus/content/repositories/My-Release' }
}
dependencies {
classpath 'com.example.plugin:my-plugin:1+'
}
}
}
gives you a lighter build.gradle
apply plugin: 'my-plugin'
I tried to, but apparently you cannot move the apply line to init.gradle as well. see this defect.
Solution 3:
I retract what I said in the comment above, I figured out how to do exactly what you're asking for. Apparently you can create extensions for the buildscript block using the initscript. However I still prefer solution2, because it gives you a cleaner build.gradle.
To create a buildscript extension, in your init.gradle:
class customRepos {
def buildscript
customRepos(buildscript) {
this.buildscript = buildscript
}
void addMyRepo() {
buildscript.repositories {
maven{ url 'http://myNexus:8081/nexus/content/repositories/My-Release' }
}
}
}
allprojects {
extensions.create('myRepo', customRepos, buildscript)
}
which then allows you to do this in your build.gradle
buildscript{
myRepo.addMyRepo()
dependencies {
classpath 'com.example.plugin:my-plugin:1+'
}
}
apply plugin: 'my-plugin'

Why do we need repositories/dependencies in buildscript task for gradle

In the post Using gradle/clojuresq to build clojure, and the answer https://stackoverflow.com/a/29018574/260127, there are (or seems) duplication of repositories and dependencies.
Why is this? Why do we need another set with the same setup?
buildscript { <- first
repositories {
maven { url "http://clojars.org/repo" }
mavenCentral()
}
dependencies {
classpath "clojuresque:clojuresque:1.7.0"
}
}
...
-> Same set again!
repositories {
maven { url "http://clojars.org/repo" }
mavenCentral()
}
dependencies {
compile "org.clojure:clojure:1.6.0"
}
...
The first is a dependency required for the build script itself. The dependency you are declaring in this case is clojuresque, which contains the Clojure Gradle plugin (apply plugin: 'clojure'). The second is the dependencies for you project, in this case, the Clojure library itself.
Simply, the first is needed by Gradle, the second by your code.

Resources