Gradle之任务(二)

版本

  1. gradle-4.8.1

GroovyDSL

  1. 属性访问器的自动转换

    {
        project.buildDir
        等价于:
        getProject().getBuildDir()
    
        project.group = "dianping.beauty"
        等价于:
        project.setGroup("dianping.beauty")
    }
    
  2. 方法调用,括号可选

    {
        project.setProperty("buildDir","/data")
        project.setProperty "buildDir","/data"
    }
    

任务

  1. 每个gradle构建都包含三个基本块project、task、property。每个构建包含至少一个project,进而包含一个或多个task。project和task的暴露的属性可以用来控制构建。

  2. 项目(Project):代表一个正在构建的组件(一个jar文件)或一个想要完成的目标,当构建启动时,gradle会根据build.gradle实例化一个org.gradle.api.Project类

  3. 任务动作(Task Action):定义了一个当任务执行时最小的工作单元。动作就是在task中合适的地方放置构建逻辑。Task接口提供了两个相关的方法来声明task动作:doFirst(Closure)和doLast(Closure)。当task被执行的时候,动作逻辑被定义为闭包参数被依次执行。

  4. 可以为每个task只添加一个动作或者多个动作。在内部,每个task都保持了一个动作列表,在运行时,它们按顺序执行。

    task printVersion{
      group="verion"
      description="打印版本号"
      doFirst { println "2.0" }
    
    }
    
    // –q 表示日志级别为error
    $ gradle –q printVersion
    2.0
    
  5. 一个构建至少包含一个项目、一个项目可包含多个任务,项目与项目,项目中任务与任务都可以建立依赖关系。

    img

  6. 任务名字的缩写:能够以驼峰式的缩写在命令行上执行任务。不如helloWorld任务,可以通过gradle hW(当你的任务名字比较长的时候可以使用缩写,但是必须保证缩写的名字唯一)

    task helloWorld(){
        println "HelloWorld"
    }
    
    $ gradle -q hW
    HelloWorld
    
    
  7. 排除任务可以使用-x选项

    // 这里排除了tH任务
    $ gradle -q third -x tH  
    
  8. 根据表达式跳过任务,调用task对应的onlyIf()方法,跳过task

    1. 语法,onlyif方法接收一个闭包作为参数,如果该闭包返回true则该任务执行,否则跳过
    taskname.onlyIf{expression == true}
    
    2. 案例
    
    

创建任务

  1. 第一种方式,本质是调用Project对象中的task(String name)方法

    def Task task = task(helloWorld1)
    helloWorld1.doLast{
        println "helloWorld1"
    }
    
  2. 第二种方式,name+Map(配置)

    //任务的分组就是对任务的分类
    def Task task2 = task(helloWorld2,group: BasePlugin.BUILD_GROUP)
    helloWorld2.doLast{
        println "helloWorld2"
    }
    

    image-20190918132451603

  3. 第三种方式,name+闭包,闭包里委托的对象是Task,所以可以使用Task的任何方法或者属性

    task helloWorld3{
        description 'helloWorld3'
        doLast {
            println "helloWorld3,任务描述${description}"
        }
    }
    

任务中调用方法

  1. 任务中调用方法

    task userMethod(){
        doLast {
            println getMsg("调用方法")
        }
    }
    
    String getMsg(msg){
        return msg
    }
    

添加动作

  1. 可以为现有的task动态添加动作。这在你想要为不是自己编写的task执行自定义逻辑时非常有用。比如为java插件compileJava的task上添加一个doFirst动作来检查项目中至少包含一个java源文件

    task printVersion{
      group="verion"
      description="打印版本号"
      doLast { println "2.0" }
    }
    // 可以使用<<代表doLast,a<<b 对应的方法是a.leftShift(b)
    task printVersion <<{
      group="verion"
      description="打印版本号"
      println "3.0"
    }
    

默认任务

  1. 默认任务

    // 运行gradle 运行时会默认执行这些task
    defaultTasks 'clean1', 'run1','other'  
    
    task clean1 << {
        println 'Default Cleaning!'
    }
    
    task run1 << {
        println 'Default Running!'
    }
    
    task otherss << {
        println "I'm not a default task!"
    }
    

任务顺序

  1. taskB.shoudRunAfter(taskA):表示taskB应该在taskA之后执行,这里是应该而不是必须,所以只是建议

  2. taskB.mustRunAfter(taskA):表示taskB必须在taskA之后执行

    task first << { println "first" }
    task second << { println "second" }
    second.mustRunAfter first
    
    $ gradle -q second first
    first
    second
    
    

任务依赖

  1. dependsOn方法允许声明依赖一个或多个task

    1. 定义四个task,printVersion依赖first和second,third依赖printVersion
    task first << { println "first" }
    task second << { println "second" }
    
    task printVersion(dependsOn: [second, first]) << {
        logger.quiet "version:1.0-SNAPSHOT"
    }
    task third << { println "third" }
    third.dependsOn { 'printVersion' }
    
    2. 执行third任务
    $ gradle third
    
    > Task :first
    first
    
    > Task :second
    second
    
    > Task :printVersion
    version:1.0-SNAPSHOT
    
    > Task :third
    third
    
    3. 日志级别 
    $ gradle -q third
    
    first
    second
    version:1.0-SNAPSHOT
    third
    
    
  2. 在gradle中task执行顺序是不确定的。dependsOn方法只是定义了所依赖的task需要先执行。在gradle中执行顺序是由task的输入输出规范自动确定的。这样的好处:第一不需要知道整合task依赖链上的关系是否发生改变,第二因为构建没有严格顺序,也就是支持并行执行,可以极大的节约构建执行时间

任务禁用与启用

  1. Task中有一个enabled属性,用于启用和禁用任务,默认为true,表示启用,设为false,表示禁止任务执行。

    1. //默认是true,false表示禁用
    taskname.enabled=false
    
    2. 示例
    task helloWorld3{
        description 'helloWorld3'
        doLast {
            println "helloWorld3,任务描述${description}"
        }
    }
    
    helloWorld3.enabled = false
    
    $ gradle -i helloWorld3 
    
    输出任务被跳过
    > Task :helloWorld3 SKIPPED
    Skipping task ':helloWorld3' as task onlyIf is false.
    :helloWorld3 (Thread[Task worker for ':',5,main]) completed. Took 0.0 secs.
    
    

任务断言

  1. Task有一个onlyIf方法,接受一个闭包,如果闭包返回true,则该任务执行,否则跳过。但是我这里居然不生效,不知道为什么?

    task helloWorld() {
        println "HelloWorld"
    }
    helloWorld.onlyIf {
        if (project.hasProperty('env') && project.getProperty('env') == "local") {
            println "execute onlyIf true"
            return true
        }
        println "execute onlyIf false"
        return false
    }
    
    
    $ gradle  -q helloWorld
    HelloWorld
    execute onlyIf false
    
    返回true应该不执行才对,但是任务居然执行了??
    $ gradle -Penv=local -q helloWorld
    HelloWorld
    execute onlyIf true
    
    

剔除任务

  1. Gradle每次构建时都执行了许多的task,其中或许有一些task是我们不需要的,可以都屏蔽掉

    tasks.whenTaskAdded { task ->
        if (task.name.contains('helloWorld') ) {
            task.enabled = false
        }
    }
    

跳过任务

  1. 任务后面有时会标注 up-to-date. 代表这个任务已经运行过了或者说是最新的状态, 不再需要产生一次相同的输出
  2. 如果一个任务有指定的输出目录, 自从该任务上次执行以来被加入到该目录的任务文件都会被忽略, 并且不会引起任务过时 (out of date). 这是因为不相关任务也许会共用同一个输出目录. 如果这并不是你所想要的情况, 可以考虑使用 TaskOutputs.upToDateWhen()

常用任务

  1. 复制运行时包到具体目录

        task copyJars(type: Copy) {
            from configurations.runtime
            into 'dist' // 目标位置
        }
    
    
  2. 创建java项目结构

    
        task mkdirs {
            doLast {
                sourceSets*.java.srcDirs*.each { it.mkdirs() }
                sourceSets*.resources.srcDirs*.each { it.mkdirs() }
            }
    
        }
    
    
  3. 校验编译版本

    task checkCompatibility {
        doLast {
            assert JavaVersion.current().java8Compatible
        }
    }
    

发布私服

  1. 发布私服

    // 上传source
    task sourcesJar(type: Jar) {
        from sourceSets.main.allJava
        classifier = 'sources'
    }
    
    task javadocJar(type: Jar) {
        from javadoc
        classifier = 'javadoc'
    }
    
    
    publishing {
    
        publications {
            mavenJava(MavenPublication) {
                from components.java
            }
        }
    
        repositories {
            maven {
                credentials {
                    username "admin"
                    password "admin123"
                }
    
                if (project.version.endsWith('-SNAPSHOT')) {
                    url "http://xxxxx/nexus/content/repositories/snapshots/"
                } else {
                    url "http://xxxx/nexus/content/repositories/releases/"
                }
            }
        }
    }
    

获取git信息

  1. 打印构建信息

    def buildTime() {
        return new Date().format("yyyy-MM-dd HH:mm:ss")
    }
    
    def hostName() {
        return System.getProperty("user.name") + "@" + InetAddress.localHost.hostName
    }
    
    task printVersion {
        try{
            def cmd = 'git rev-list HEAD --first-parent --count'
            def gitVersion = cmd.execute().text.trim().toInteger()
            println "============打印构建信息start=========="
            println 'git版本:' + gitVersion
            println buildTime()
            println hostName()
            println 'git rev-parse --short HEAD'.execute().text.trim()
            println "============打印构建信息end============"
        }catch(e){
            println(e)
        }
    }
    
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值