To prephrase this suggestion a bit, let’s paint up some context. In most enterprise situations I would suspect that there is one centralized maven/ivy/artifactory/nexus server which serves all the artifacts for the project. I believe creating one single ‘virtual repository’ which mirrors all repositories needed for a project has even been mentioned as a best practice for gradle projects. This makes the life of the project maintainer simpler and probably makes the gradle build executions faster as there is a single point of truth when it comes to artifacts.
So far all is well. In most scenarios like this I would further suspect that the repository is password protected since it is probably also hosting the output of proprietary in-house projects. In most larger long-lived projects the enterprise would probably also be using a custom plugin to encapsulate and hide some of the build logic and leave the interface to the guy writing the code as clean as possible.
So where does this leave us with regards to configuration for repositories and dependencies? Well here is an example from my current project settings.gradle file:
buildscript {
repositories {
maven {
credentials.username artifactoryReader
credentials.password artifactoryReaderPwd
url "$artifactoryReaderUrl/repo"
}
}
configurations.classpath {
resolutionStrategy.cacheDynamicVersionsFor 5, 'minutes'
resolutionStrategy.cacheChangingModulesFor 5, 'minutes'
}
dependencies {
classpath('my.custom.build:plugin:1.0') { changing=true }
}
//ugly hack, but 10x faster than doing the gradle.allprojects { buildscript {} } below
//configurations.classpath.each { file -> settings.classLoader.addURL(file.toURI().toURL()) }
}
gradle.allprojects {
repositories {
maven {
credentials.username artifactoryReader
credentials.password artifactoryReaderPwd
url "$artifactoryReaderUrl/repo"
}
}
buildscript {
repositories {
maven {
credentials.username artifactoryReader
credentials.password artifactoryReaderPwd
url "$artifactoryReaderUrl/repo"
}
}
configurations.classpath {
resolutionStrategy.cacheDynamicVersionsFor 5, 'minutes'
resolutionStrategy.cacheChangingModulesFor 5, 'minutes'
}
dependencies {
classpath('my.custom.build:plugin:1.0') { changing=true }
}
}
}
In this specific case I need the custom build logic plugin classes to also be available in the settings.gradle file. So we need the root level buildscript block.
I then further want the plugin code to be available in all project build files. For this there is a non-supported hack which is commented out in the code above. I get the feeling that gradle.allprojects loops through the projects and we end up with a build log which flickers through the project list for a number of seconds. The hack runs more or less instantaneously, but I was told that those APIs might change and it is therefore not a recommended practice.
As an additional and final requirement for this particular case I want to centralize the artifactory username/password usage to this one file. For this reason I need the gradle.allprojects { repositories { } } block.
Now all the individual pieces of the DSL in the snippet above make sense when taken individually. But taken together it makes me wish for a more concise way of expressing this. The code above has a lot of duplication and we all hate duplication.
Perhaps something along the lines of:
repositories.default {
maven {
credentials.username artifactoryReader
credentials.password artifactoryReaderPwd
url "$artifactoryReaderUrl/repo"
}
}
buildscripts {
//with an S at the end
configurations.classpath {
resolutionStrategy.cacheDynamicVersionsFor 5, 'minutes'
resolutionStrategy.cacheChangingModulesFor 5, 'minutes'
}
dependencies {
classpath('my.custom.build:plugin:1.0') { changing=true }
}
}
could be an alternative?
repositories.default would be global for both buildscript and normal dependencies. i.e. if you don’t specify a repositories block in your project, we use the .default setting.
The ‘buildscripts’ closure would configure the classpath for all Script files in the project, both the settings.gradle file and the normal build files.
If there is an existing clean way of doing this I would very much appreciate the pointer. If not, perhaps it might be worth considering some additions to the DSL?