A large project with many developers and gradle projects uses a private maven repository for plugins, dependencies, and publication.
I would like to define a privateMaven()
method, just like the built-in jcenter()
, mavenCentral()
, and google()
methods. Currently we write a maven
block anywhere we need to use the repository - repositories
, publishing.repositories
, pluginManagement.repositories
, ...
repositories {
maven {
url "..."
credentials { ... }
}
}
which I would rather be
repositories {
private()
}
This answer explains how to extend repositories
and buildscript.repositories
but it doesn't work for publishing.repositories
because publishing
is provided by a plugin and doesn't work for pluginManagement.repositories
. Also I would also have to enumerate every repositories configuration and developers can't use privateMaven()
in any block we don't extend.
Is there a way for an init script to add a method to every repositories
block, or every RepositoryHandler?
Assuming you're using the maven-publish plugin, you can define an extension like so:
private.gradle
apply plugin: 'maven-publish'
publishing.repositories.ext.privateRepo = {
publishing.repositories.maven {
url "https://artifactory.website.com/private-repo"
credentials {...}
}
}
build.gradle
apply from: 'private.gradle' // or you can just include the script in here
afterEvaluate {
publishing {
publications {...}
repositories {
privateRepo()
}
}
}
You can also create a plugin if you'd like to distribute the script, the usage would remain exactly the same. https://guides.gradle.org/implementing-gradle-plugins/
PrivatePlugin.groovy
class PrivatePlugin implements Plugin<Project> {
@Override
void apply(Project project) {
// check if the publishing extension exists first
final publishing = project.extensions.findByType(PublishingExtension.class)
if (publishing != null) {
publishing.repositories.ext.privateRepo = {
publishing.repositories.maven {
url "https://artifactory.website.com/private-repo"
credentials {...}
}
}
}
}
}
Just be sure that if you distribute it as a plugin that you don't ship it with the credentials hardcoded.
My goal is that any repositories block can use privateMaven
. I don't want to explicitly extend publishing.repositories.ext
, repositories.ext
, buildscript.repositories.ext
. In addition to being tedious, if I miss one repositories
or gradle adds a new repositories
then privateMaven
will not be available.
One solution which is close, but not perfect, was to create an extension on with a method that takes a reference to RepositoryHandler.
Any repository block and now use the extension as so
repositories {
custom.privateMaven(it)
}
beforeSettings {
extensions.create("custom", PrivateMavenExtension::class)
}
allprojects {
extensions.create("custom", PrivateMavenExtension::class)
}
open class PrivateMavenExtension {
fun privateMaven(handler: RepositoryHandler): MavenArtifactRepository {
return handler.maven {
// implementation
}
}
}
One major hurdle I haven't solved is that classes defined in an init.d script cannot be loaded in build.gradle. If PrivateMavenExtensions
is defined in an init.d script I can't reference the extension in a type-safe way from a build.gradle.kts because the<PrivateMavenExtension>()
cannot be resolved.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With