Sto scrivendo un plugin gradle personalizzato per gestire un lavoro vagamente complicato e mi sono imbattuto in un problema frustrante mentre utilizzavo le proprietà per configurare alcune delle attività che il plugin applica.Le estensioni gradle possono gestire la valutazione lenta di una proprietà?
apply plugin: myPlugin
//Provide properties for the applied plugin
myPluginProps {
message = "Hello"
}
//Define a task that uses my custom task directly
task thisTaskWorksFine(type: MyTask) {
input = myPluginProps.message
}
//Define a plugin that will apply a task of my custom type
class MyPlugin implements Plugin<Project> {
void apply(Project project) {
project.extensions.create('myPluginProps', MyPluginExtension)
project.task(type: MyTask, 'thisTaskWorksIncorrectly') {
input = project.myPluginProps.message
}
}
}
//The extension used by my custom plugin to get input
class MyPluginExtension {
def String message
}
//The task used by both the standard build section and the plugin
class MyTask extends DefaultTask {
def String input
@TaskAction
def action() {
println "You gave me this: ${input}"
}
}
I risultati di utilizzare questo file sono i seguenti:
$ gradle thisTaskWorksFine thisTaskWorksIncorrectly
:thisTaskWorksFine
You gave me this: Hello
:thisTaskWorksIncorrectly
You gave me this: null
BUILD SUCCESSFUL
Ritengo che questo sia molto inaspettato. A mio avviso, l'applicazione di un task dal plug-in e la scrittura diretta di uno dovrebbe portare allo stesso output quando viene fornito lo stesso input. In questo caso, entrambe le attività vengono fornite come input, myPluginProps.message
, ma l'attività applicata dal plug-in è ingorda e viene valutata nulla all'inizio. (Durante la fase di applicazione?)
L'unica soluzione che ho trovato è quello di utilizzare le chiusure nel blocco di configurazione del task plug-in in questo modo:
//Define a plugin that will apply a task of my custom type
class MyPlugin implements Plugin<Project> {
void apply(Project project) {
project.extensions.create('myPluginProps', MyPluginExtension)
project.task(type: MyTask, 'thisTaskWorksIncorrectly') {
input = { project.myPluginProps.message }
}
}
}
che risolve il problema di valutazione avido abbastanza bene tranne che ora l'attività personalizzata deve essere modificata per prevedere e gestire una chiusura. Non è terribilmente difficile da fare, ma non penso che dovrebbe essere la responsabilità del compito di occuparsi della chiusura, dal momento che il plugin è "da incolpare".
Sto utilizzando le estensioni in modo errato qui? O semplicemente non sono adeguati? La posizione ufficiale sembra essere quella we should use extensions ma non ho ancora trovato alcun esempio in cui le estensioni potrebbero fare ciò di cui ho bisogno. Posso andare avanti con il mio uso di chiusure e scrivere un gruppo di getter di piastre di riscaldamento che fanno la chiusura di eval e setter in grado di gestire chiusure e tipi normali, ma sembra molto contrario alla filosofia di groovy e quindi gradle. Sarei molto felice se c'è un modo in cui posso usare le estensioni e ottenere automaticamente la valutazione pigra.
C'è differenza tra la convenzione e le convenzioni? La tua risposta sembra piuttosto chiara, quindi quasi sicuramente la userò, ma uno degli sviluppatori principali ha detto "In breve, usa solo le estensioni, non usare le convenzioni". Forse l'ho preso troppo alla lettera. –
Le [convenzioni] (http://www.gradle.org/docs/current/dsl/org.gradle.api.Project.html#org.gradle.api.Project:convention) che Peter sta citando sono il vecchio meccanismo per le estensioni. La differenza è che ottieni il dsl ('myPluginProps {message =" Hello "}') gratuitamente con le estensioni e non le hai con le convenzioni.Le convenzioni e le mappature delle convenzioni sono due cose diverse e le mappature delle convenzioni sono utilizzate internamente in [gradle code] (https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/groovy/org/gradle/ api/plugins/JavaPlugin.java # L131) molto. – erdi
Eccellente. Nella mia ricerca stavo schivando tutto ciò che menzionava la parola convenzione, ma era sbrigativo. Grazie per il consiglio! –