Reputation: 906
I am new to gradle. So let straight to the point. I want to implement the block as below. Note that the libraries is dynamic, and available for other developers to add on for the needed libraries.
libraries {
slf4j 'org.slf4j:slf4j-api:1.7.21'
junit 'junit:junit:4.12'
}
So that I can call them out like this.
dependencies {
compile libraries.slf4j
testCompile libraries.junit
}
I am not sure how to make it. But I found some related solution from here. As shown below:
apply plugin: GreetingPlugin
greeting {
message 'Hi'
greeter 'Gradle'
}
class GreetingPlugin implements Plugin<Project> {
void apply(Project project) {
project.extensions.create("greeting", GreetingPluginExtension)
project.task('hello') {
doLast {
println "${project.greeting.message} from ${project.greeting.greeter}"
}
}
}
}
class GreetingPluginExtension {
String message
String greeter
}
The problem is as I add on to the greeting
block, I need to declare them in GreetingPluginExtension
as well. Any idea how to make it such that only update on greeting
block?
Upvotes: 1
Views: 110
Reputation: 84854
What you need to do is to utilize groovy meta programming. Below you can find just a sample, however fully functional.
apply plugin: LibrariesPlugin
libraries {
slf4j 'org.slf4j:slf4j-api:1.7.21'
junit 'junit:junit:4.12'
}
class LibrariesPlugin implements Plugin<Project> {
void apply(Project project) {
project.extensions.create("libraries", LibrariesPluginExtension)
project.task('printLib') {
doLast {
println "$project.libraries.slf4j"
println "$project.libraries.junit"
project.libraries.each {
println "$it.key -> $it.value"
}
}
}
}
}
class LibrariesPluginExtension {
Map libraries = [:]
def methodMissing(String name, args) {
// TODO you need to do some arg checking here
libraries[name] = args[0]
}
def propertyMissing(String name) {
// TODO same here
libraries[name]
}
Iterator iterator() {
libraries.iterator()
}
}
Upvotes: 5