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

Gradle任务语法:如何从Groovy的角度解释它?,gradle,groovy,dsl,Gradle,Groovy,Dsl,我很难理解Gradle的Groovy DSL是如何工作的 不幸的是,Gradle是我在日常工作中遇到的Groovy的主要用例,我注意到对于许多开发人员来说,他们对Groovy的接触完全是通过Gradle进行的。因此,大多数Gradle用户对Groovy的掌握非常有限 在我对Groovy有限的理解中,下面的sintaxtokenA-tokenB{tokenC}如果所有的标记都不是语言关键字,tokenA将是我们使用参数tokenB调用的方法,最后一个参数是闭包。我想我是正确的,但我知道我错了,因为

我很难理解Gradle的Groovy DSL是如何工作的

不幸的是,Gradle是我在日常工作中遇到的Groovy的主要用例,我注意到对于许多开发人员来说,他们对Groovy的接触完全是通过Gradle进行的。因此,大多数Gradle用户对Groovy的掌握非常有限

在我对Groovy有限的理解中,下面的sintax
tokenA-tokenB{tokenC}
如果所有的标记都不是语言关键字,
tokenA
将是我们使用参数
tokenB
调用的方法,最后一个参数是闭包。我想我是正确的,但我知道我错了,因为可能需要在tokenB后面加一个逗号才能使分析正确

正如您已经知道的,我绝不是Groovy开发人员,我认为在不学习Groovy基础知识的情况下使用Gradle是一件坏事,因为它限制了我充分利用它的功能。但不幸的是,我唯一可行的选择是在不学习理论的情况下学习实例

我确实检查了一些类似的问题,如,但没有对我来说足够清楚或完整的答案

TL;DR

  • 在Groovy中如何解释标记
    task myTask{doLast{}
  • Gradle是否使用标准Groovy解释器
  • 当有
    task
    而不是
    def
    或其背后的类型时,如何将
    myTask
    解释为标识符
  • 如果稍后我在文件中添加了
    myTask{dependsOn myOtherTask}
    如何解释
  • (免责声明,我不是groovy开发人员)

    运行生成(例如,
    gradle clean
    )时,
    build.gradle
    的内容根据
    项目
    对象(由gradle运行程序创建)进行评估;参见Javadoc,网址为;还要阅读整个摘要,因为它包含很多信息。在该页中,他们澄清:

    一个项目有5个方法“作用域”,它在其中搜索方法:项目对象本身。。。生成文件。。。插件添加到项目中的扩展项目的任务。。将为每个任务添加一个方法,使用任务名称作为方法名称

    task myTask{}
    应等同于
    project.task('myTask')
    。它创建了一个名为“myTask”的新任务,并将该任务添加到当前项目中(参见Javadoc)。然后,一个属性被添加到项目对象中,以便可以作为
    project.myTask
    访问它
    doLast{..}
    调用该任务对象上的
    doLast
    方法;请参阅


    关于你的一些观点:

  • project.task('myTask').doLast(…)
    (这里可能有更多关于闭包的信息)
  • 确实如此(尝试从github构建);但还有额外的处理;运行生成之前,
    build.gradle
    文件被“注入”到项目实例中。再加上许多其他步骤
  • project.task('myTask')
  • project.myTask.dependsOn(project.myOtherTask)
    (可能需要额外的闭包或操作实例)。这是由于任务作为属性添加到项目中


  • 还要注意,显式语句,如
    project.myTask…
    是有效的,它们可以在
    build.gradle
    脚本中使用;但是,这些语言非常冗长,很少使用

    我相信这一切都很棒,对格拉德尔来说也没什么特别的。以下是您需要了解的groovy概念

  • 如果方法的最后一个参数是闭包,则可以将闭包放在方法参数的结束括号之后
  • 您可以在对象上实现。如果有人试图调用一个不存在的方法,你可以这样做
  • 你可以在一个结束的时候
  • groovy的这3个特性很好地解释了gradle脚本中的“神奇”行为,这让java开发人员摸不着头脑

    那么,让我们来分析一下您的代码片段

    task myTask(type:Foo) { 
       doLast {...} 
    }
    
    让我们添加一些括号,并添加隐式项目引用。我们还将闭包提取到一个变量中

    Closure c = { 
       doLast {...} 
    }
    project.task(project.myTask([type: Foo.class], c)) 
    
    project.myTask(…)
    方法不存在,该行为最终通过
    methodMissing
    功能实现。Gradle将在任务实例的闭包上设置委托。因此,闭包中的任何方法都将委托给新创建的任务

    归根结底,这就是所谓的逻辑

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

    行动感谢您提供了非常有用的答案。我不知道有代表,这可以解释很多魔术。不过我还有一个问题。
    task myTask{…}
    中考虑的
    task
    一词是什么,是像
    int
    MyClass
    这样的类型,是在委托中查找的方法吗?我们怎么可以不加引号地命名任务?我们怎么能有这样一个语法
    任务
    ?这样的构造是标准Groovy吗?我不知道如何只使用闭包和委托来实现这样的DSL。可能是我在问题中所链接的问题中缺少了链接?请重新阅读我的细分。它是对项目对象的方法调用<代码>项目.task(项目.myTask({…}))
    task myTask(type:Foo) { 
       doLast {...} 
    }
    
    Closure c = { 
       doLast {...} 
    }
    project.task(project.myTask([type: Foo.class], c)) 
    
    Action<? extends Task> action = { task ->
       task.doLast {...} 
    }
    project.tasks.create('myTask', Foo.class, action)