版本
- gradle-4.8.1
GroovyDSL
-
属性访问器的自动转换
{ project.buildDir 等价于: getProject().getBuildDir() project.group = "dianping.beauty" 等价于: project.setGroup("dianping.beauty") }
-
方法调用,括号可选
{ project.setProperty("buildDir","/data") project.setProperty "buildDir","/data" }
任务
-
每个gradle构建都包含三个基本块project、task、property。每个构建包含至少一个project,进而包含一个或多个task。project和task的暴露的属性可以用来控制构建。
-
项目(Project):代表一个正在构建的组件(一个jar文件)或一个想要完成的目标,当构建启动时,gradle会根据build.gradle实例化一个org.gradle.api.Project类
-
任务动作(Task Action):定义了一个当任务执行时最小的工作单元。动作就是在task中合适的地方放置构建逻辑。Task接口提供了两个相关的方法来声明task动作:doFirst(Closure)和doLast(Closure)。当task被执行的时候,动作逻辑被定义为闭包参数被依次执行。
-
可以为每个task只添加一个动作或者多个动作。在内部,每个task都保持了一个动作列表,在运行时,它们按顺序执行。
task printVersion{ group="verion" description="打印版本号" doFirst { println "2.0" } } // –q 表示日志级别为error $ gradle –q printVersion 2.0
-
一个构建至少包含一个项目、一个项目可包含多个任务,项目与项目,项目中任务与任务都可以建立依赖关系。
-
任务名字的缩写:能够以驼峰式的缩写在命令行上执行任务。不如
helloWorld
任务,可以通过gradle hW
(当你的任务名字比较长的时候可以使用缩写,但是必须保证缩写的名字唯一)task helloWorld(){ println "HelloWorld" } $ gradle -q hW HelloWorld
-
排除任务可以使用-x选项
// 这里排除了tH任务 $ gradle -q third -x tH
-
根据表达式跳过任务,调用task对应的onlyIf()方法,跳过task
1. 语法,onlyif方法接收一个闭包作为参数,如果该闭包返回true则该任务执行,否则跳过 taskname.onlyIf{expression == true} 2. 案例
创建任务
-
第一种方式,本质是调用Project对象中的task(String name)方法
def Task task = task(helloWorld1) helloWorld1.doLast{ println "helloWorld1" }
-
第二种方式,name+Map(配置)
//任务的分组就是对任务的分类 def Task task2 = task(helloWorld2,group: BasePlugin.BUILD_GROUP) helloWorld2.doLast{ println "helloWorld2" }
-
第三种方式,name+闭包,闭包里委托的对象是Task,所以可以使用Task的任何方法或者属性
task helloWorld3{ description 'helloWorld3' doLast { println "helloWorld3,任务描述${description}" } }
任务中调用方法
-
任务中调用方法
task userMethod(){ doLast { println getMsg("调用方法") } } String getMsg(msg){ return msg }
添加动作
-
可以为现有的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" }
默认任务
-
默认任务
// 运行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!" }
任务顺序
-
taskB.shoudRunAfter(taskA):表示taskB应该在taskA之后执行,这里是应该而不是必须,所以只是建议
-
taskB.mustRunAfter(taskA):表示taskB必须在taskA之后执行
task first << { println "first" } task second << { println "second" } second.mustRunAfter first $ gradle -q second first first second
任务依赖
-
dependsOn
方法允许声明依赖一个或多个task1. 定义四个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
-
在gradle中task执行顺序是不确定的。dependsOn方法只是定义了所依赖的task需要先执行。在gradle中执行顺序是由task的输入输出规范自动确定的。这样的好处:第一不需要知道整合task依赖链上的关系是否发生改变,第二因为构建没有严格顺序,也就是支持并行执行,可以极大的节约构建执行时间
任务禁用与启用
-
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.
任务断言
-
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
剔除任务
-
Gradle每次构建时都执行了许多的task,其中或许有一些task是我们不需要的,可以都屏蔽掉
tasks.whenTaskAdded { task -> if (task.name.contains('helloWorld') ) { task.enabled = false } }
跳过任务
- 任务后面有时会标注 up-to-date. 代表这个任务已经运行过了或者说是最新的状态, 不再需要产生一次相同的输出
- 如果一个任务有指定的输出目录, 自从该任务上次执行以来被加入到该目录的任务文件都会被忽略, 并且不会引起任务过时 (out of date). 这是因为不相关任务也许会共用同一个输出目录. 如果这并不是你所想要的情况, 可以考虑使用 TaskOutputs.upToDateWhen()
常用任务
-
复制运行时包到具体目录
task copyJars(type: Copy) { from configurations.runtime into 'dist' // 目标位置 }
-
创建java项目结构
task mkdirs { doLast { sourceSets*.java.srcDirs*.each { it.mkdirs() } sourceSets*.resources.srcDirs*.each { it.mkdirs() } } }
-
校验编译版本
task checkCompatibility { doLast { assert JavaVersion.current().java8Compatible } }
发布私服
-
发布私服
// 上传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信息
-
打印构建信息
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) } }