且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Gradle任务语法:如何从Groovy角度解释它?

更新时间:2023-12-05 15:01:34

我相信它的所有功能都是通用的,没有什么特别的。这是您需要了解的常规概念。

I believe its all groovy and nothing special to gradle. Here's the groovy concepts you need to know.


  1. 如果方法的最后一个参数是闭包,则可以将闭包放在方法参数的右括号之后。



class MyClass {
   void doStuff(String name, Closure c) {
      c.call()
   } 
} 

def o = new MyClass() 
o.doStuff('x') {
   println "hello" 
} 




  1. 您可以实施您的对象上缺少方法 。如果有人尝试调用一个不存在的方法,您可以做

  1. You can implement method missing on your object. If someone tries to call a method that doesn't exist you can do stuff



class MyClass {
    def methodMissing(String name, args) {
        println "You invoked ${name}(${args})" 
    }
} 
def o = new MyClass() {
   o.thisMethodDoesNotExist('foo')
}




  1. 您可以将委托设置设置为关闭

  1. You can set the delegate on a closure



class MyBean {
   void include(String pattern) {...} 
   void exclude(String pattern) {...} 
} 
class MyClass {
   private MyBean myBean = new MyBean() 
   void doStuff(Closure c) {
      c.setDelegate(myBean)
      c.call()
   } 
} 

def o = new MyClass() 
o.doStuff {
   include 'foo' 
   exclude 'bar' 
} 

这3个时髦特性在很大程度上解释了gradle脚本中发生的魔术行为,使得Java开发人员抓狂了。

These 3 groovy features pretty much explain the "magic" behaviour going on in a gradle script that have java developers scratching their heads.

task myTask(type:Foo) { 
   doLast {...} 
}

让我们添加一些括号并添加隐式项目引用。让我们还将闭包提取到变量中

Let's add some brackets and also add the implicit project references. Let's also extract the closure into a variable

Closure c = { 
   doLast {...} 
}
project.task(project.myTask([type: Foo.class], c)) 

project.myTask(...)方法不存在,该行为最终通过 methodMissing 实现>功能。 Gradle会将关闭对象上的委托设置为任务实例。因此,闭包中的任何方法都将委派给新创建的任务。

The project.myTask(...) method doesn't exist and the behavior is ultimately implemented via methodMissing functionality. Gradle will set the delegate on the closure to the task instance. So any methods in the closure will delegate to the newly created task.

最终,这在逻辑上是

Action<? extends Task> action = { task ->
   task.doLast {...} 
}
project.tasks.create('myTask', Foo.class, action)

请参见 TaskContainer.create(String,Class,Action)