Gradle - 实战笔记

第一章,项目自动化介绍

重点:构建工具Gradle关系图

Gradle - 实战笔记_第1张图片

第二章,下一代构建工具:Gradle

重点:

重要的Gradle特性集

1,Gradle 构建脚本<表达性的构建语言(Java/Groovy),底层的API,Gradle 的扩展机制,引入外部库的依赖>

2,强大的依赖管理

使用Gradle

-q 选项: quiet,高速Gradle只输出该task相关的信息。

-x 选项:排除执行任务。

左移符号<< 和doLast (Action)是等价的。

dependsOn 关键字来描述task之间的依赖,实际上,该关键字是task的一个方法。

Gradle 提供了任务组的概念,可以把它看作是多个tasks的集群,我们可以添加新的任务组。

第三章,Gradle 项目

重点:

使用Java插件:要组装一个可执行程序,需要编译源代码,之后将生成的class文件打包成Jar文件。这些都是构建项目的一个个任务(tasks)。Gradle 使用Java插件能够自动化这些任务。

执行gradle build命令,注意到某些tasks被标记为Up-to-date消息, 这意味着这个任务被跳过了。

项目被构建后,(1)可以通过classpath命令行选项 -cp build/ classes/ main 告诉java 运行时去哪里找到class。 (2)可以通过Jar文件启动,但是要在build清单文件MANIFEST.MF 中指定Main-Class 属性。

//通过classpath的方式执行程序
>java -cp build/classes/main com.manning.gia.todo.ToDoApp

//通过在Manifest文件中指定Main Class的方式
jar{
   manifest{
         attributes 'Main-Class': 'com.manning.gia.todo.ToDoApp'
}
} 

外部依赖:源代码(import external.jar)vs build 脚本 (repositories{}dependencies{}),事实上,两者是有关联的,源代码中需要外部JAR的依赖,通过Import导入,但是外部依赖的JAR无需手动下载和配置,只要在build脚本中添加依赖管理和库,项目会自动下载和配置所需要的JAR文件。

大部分工程都不太可能完全自给自足,一定你都会用到其他工程的文件。比如自己的工程需要Hibernate,就需要把它的类库加进来,这些文件就是工程的依赖。Gradle 需要你来告诉它工程的依赖是什么,它们在哪,然后帮你加入构建中。依赖可能需要远程库下载,也可能在本地,甚至可能是另一个工程。

大部分工程构建的主要目的是脱离工程使用。比如生成jar包,包含源代码,文档等,然后发布出去。

war插件是Java插件的扩展,适用与web应用,war插件引入了两个新的依赖配置(configuration)。Servlet 依赖使用到的配置是 providedCompile,它表示该以来在编译时候需要,但是由运行时环境提供,运行时环境就是Jetty,配置是runtime。

jetty插件可以帮助你告诉嵌入式Servlet容器你的web应用的classpath和端口,通过运行‘gradle jettyRun’ 命令,jetty可以在运行时自动访问war插件的信息,然后将url和端口反馈给你。

第四章,构建build脚本

重点:

project 和 task 属性方法问题,当访问属性和方法时,不需要使用project/ task变量(Project/ Task接口实例)。也就是说,println project.description 和 println description都是可以的。然而对于task来说,却只能使用println description。

添加task配置块,task配置块没有定义动作或者使用左移操作符(<<), Gradle 称之为task配置。task配置块永远在task动作执行之前被执行,即使不被调用的情况下,最先执行。

Gradle 构建生命周期阶段:初始化阶段 ---  配置阶段(定义扩展属性以及task配置块)---  执行阶段(task动作代码)。

Gradle build脚本中也是可以定义类的。

声明task规则:tasks.addRule(String, 闭包)。e.g. tasks.addRule("String"){def var -> var}

第五章,依赖管理

重点:

依赖配置,插件可以引入配置来定义依赖的配置。也可以声明自己的配置。例如Java插件,引入了6个现成的配置, compile(build task默认访问), runtime(build task默认访问), testCompile(test task默认访问), testRuntime(test task默认访问), archives, default。

自定义配置,直接在项目的根级别声明添加自定义配置,声明自定义配置后,可以在依赖中添加该配置的依赖,并通过指定该依赖的classpath给task来访问该配置。

configurations{
       cargo{//通过名称定义新的配置
           description=''
           visible=false //设置配置的描述信息
}
}
排除传递性依赖,使用exclude方法来排除传递性依赖。

dependencies{
       cargo('group:name:version'){
              exclude group: 'group_name', model:'model_name'
}
}
通过transitive=false属性来排除说有传递性依赖。

仓库的各种形式,<1> Maven 仓库,预配置的Maven仓库,本地Maven仓库,自定义Maven仓库

//预配置的Maven仓库
repositories{
      mavenCentral ()
}
//本地Maven仓库
repositories{
      mavenLocal()
}
//自定义的Maven仓库
repositories{
      maven{
           name 'Custom maven repos'
           url 'http://repository-gradle-in-action...'
}
}
<2> Ivy 仓库: 和Maven不同的是,Maven仓库中的工件必须以一种固定的布局存储,Ivy仓库可以完全自定义布局。

repositories{
        ivy{
          url 'http://repositories.myenterprise.com/ivy/..'
          layout 'pattern',{
               artifact '[organization]/[module]/[revision]/[artifact]-[revision].[ext]'
                ivy '[organization]/[module]/[revision]/ivy-[revision].xml'
}
}
}
<3>扁平的目录仓库

repositories{
      flatDir(dir:"[path]",
      name:'Local libs directory')
}
//dependencies{}中声明的依赖只能使用name和version
--offset 命令行选项高速Gradle在离线模式下不要检查远程仓库。

第六章,多项目构建

重点:

调用子项目的命令 gradle :[sub-project-name]:[task-name]。

-a 命令行选项可以起到部分都建的作用。gradle :repository:build -a。

第七章,Gradle测试

重点:

如何让Gradle使用一个特定的测试框架,需要声明依赖外部的类库。dependencise{testCompile 'junit:junit:4.11'}//依赖Junit框架

使用JUnit来进行单元测试,测试<代码片段>是否成功实现。在测试类代码中,@Before:使用这个注解标记的方法总会在每个类的测试方法之前执行;@Test:使用这个注解标记的方法将作为测试用例运行。在build中,添加testCompile配置,声明依赖JUnit。

使用TestNG来进行单元测试,测试类代码和JUnit相同,在build中,首先需要声明TestNG的依赖,testCompile 'org.testing:testing:6.8',其次,需要指定TestNG用来执行测试。可以通过test.useTestNG()// test 测试task调用useTestNG方法。也可以通过test{useTestNG()}闭包方法声明。

在build中指定默认的测试任务域(test task),默认包含所有的测试类,可以使用exclude来排除部分不愿意在默认模块中执行的类。在默认的测试域中可以设置控制测试的配置。

test{
    testLogging {//testLogging 是一个接口类
            showStandardStreams=true//把日志标准流输出到终端
            exceptionFormat 'full'//显示全部的异常信息
            events 'started', 'passed', 'skipped', 'failed'//记录特定测试事件
            exclude '**.class'//排除不愿默认执行的类
}
}
可以自定义test task,task testOne(type:Test){}

验证task:check。check task是java插件提供的生命周期task,它依赖于任何测试task,如test。如果你想自动执行整个测试task链,这个task是最便捷的。

集成测试,测试类中可以将集成测试的类名约定为**IntegrateTest 结尾的文件(单元测试类和集成测试类都放置在src/test/java中),在build中可以定义一个test task,e.g. 

task IntegratedTest (type: Test){
      include '**/*IntegrateTest.class'
}
假如想分离集成测试类到src/IntegrateTest/java, 需要使用sourceSets{},并在其中指定classpath。
功能测试和以上过程类似。

第八章,扩展Gradle

编写定制的task类,Gradle 标准插件的task都是继承DefaultTask 类的。如果想定制task类,可以<1> 在build中构建一个task类,例如,

class MyTask extends DefaultTask{
       @TaskAction
       public void start(){

}
}

task obj_task(type: MyTask){}

<2> 将定制的task类放到项目根目录下的 buildSrc/ src/ main/ java目录下。 Gradle 将该目录当作默认的源代码目录,自动可用。在buildSrc目录中也需要创建一个build脚本用来引入定制task类中依赖的类。

<3>还可以将定制的task类打包成jar,在build中依赖它的classpath配置项。

@TaskAction: task的行为封装在task 的action中。要指定哪个action执行,需要在执行方法上加上注解@TaskAction。执行方法是可以任意取的,只要不覆盖父类的void execute()方法就可以。

buildSrc 目录(主要用于存放自定义task类的目录)和src目录(源代码目录)可以同时存在在根目录下,同时可以在根目录下直接添加BuildSrc路径。如果在build脚本中使用该类型的task,只需要import该类的path,Gradle 就可以识别到该类。

在build脚本中创建指定type的task不能定义动作或者使用左移操作符(<<)。

Gradle 中含有插件库类,可以称为内部插件,包括Java,Eclipse,Jetty等,这些插件可以通过apply'plugin: 'plugin-name' 直接引用。还有一些插件不在Gradle插件库中,称为外部插件,包括Tomcat,JS等,对于这些插件需要通过buildscript 块来引用。

buildscript{
    repositories{
         mavenCentral()
}
    dependencies{
         classpath 'org.gradle.api.plugins:gradle-tomcat-plugin:0.9.7'
}
}

apply plugin: 'tomcat'
第九章,集成与迁移

重点:

构建工具Ant不支持增量构建,而Gradle可以帮助Ant实现增量构建,Gradle 会意识到源文件没有改变,输出文件已经存在,这么做节省了大量时间,特别是在有许多依赖和源文件的企业级构建。

Gradle 可以通过AntBuilder对象ant来定义一个Ant任务,对于Ant来说,所谓的Ant任务就是Ant任务标签,不是通过标签定义的任务,而是直接的任务标签,例如Ant中获取任务标签。

如果将Ant target定义的任务迁移到Gradle 的task,需要用Gradle的方式去实现target的逻辑。


   ***

//迁移到Gradle task
task target_name{
   ***
}
//在Gradle中使用该target
target_name{
   ***
}
Gradle 有依赖管理,而Ant是没有依赖管理的,除非结合使用Ivy。

Gradle 并不支持在运行时对POM中Maven目标的导入,Gradle 提供了maven2Gradle 转换task,可以根据有效的POM生成build.gradle文件。maven2Gradle task只有在当前目录中包含一个pom.xml 文件的时候才可见。执行这个maven2Gradle task后,根据pom.xml, Gradle 可以转化成相应的build.gradle 和 settings.gradle 文件。

第十章,IDE支持和工具

重点:

Eclipse插件:eclipse 和 eclipse-wtp (负责生成Eclipse的web工具平台)。

这两个插件提供了一些task来生成Eclipse项目。eclipse task负责生成所有的Eclipse项目文件,包括.project,classpath,.settings 目录下的设置文件。cleaneclipes task负责清除所有已经存在Eclipse项目文件。

Gradle ——> 构建脚本(apply plugin: 'eclipse')——> IDE项目文件 ——> Eclipse IDE

         <执行task>                                                          <生成>                      <导入>

//通过eclipse.project.name来设置Eclipse的项目名,默认的项目名和Gradle Project Name相同
eclipse{
     project{
           name='***'
}
}
//subproject
project(':web'){
     eclipse{
           project{
                comment ='***'
}
}
}
事实上,Eclipse有一个安装包可以导入现成的Gradle项目结构,无需在构建脚本中添加Eclipse插件:SpringSource Tool Suite(STS)

第十一章,构建多语言项目

重点:

Groovy 自定义项目结构(事实上和Java自定义项目结构是一样的,但是在Java自定义项目结构时没有说明,在这里一并说明。)

//通过sourceSets来自定义项目结构
sourceSets{
      main{
          groovy{
              srcDirs=['src/groovy']//编译路径
}
}
      test{
         groovy{
              srcDirs=['test/groovy']//测试路径
}
}
}
sourceSets.main.java 或者 sourceSets{ main{ java{  } } }可以被认为是java编译器,sourceSets.test.java 或者 sourceSets{ test{ java{  } } }可以被认为是java测试编辑器。

Groovy和上面相同。

Groovy可以依赖Java,但是Java 无法依赖Groovy。为了解决这一个问题,需要联合编辑,配置Groovy编译器,让groovy编译Java和Groovy的源码。

sourceSets.main.java.srcDirs=[]
sourceSets.main.groovy.srcDirs=['src/main/java','src/main/groovy']
第十二章,代码质量管理和监测
重点:
衡量代码覆盖率工具:它将代码中没有被测试到的执行分支暴露出来:JaCoCo (构建JaCoCo脚本插件,在root下mkdir一个gradle路径,里面添加JaCoCo脚本插件。在build脚本中通过路径应用插件,例如apply plugin: "$rootDir/gradle/jacoco.gradle")

静态代码分析工具:仅仅分析源代码,而没有必要真正的执行软件得到质量结构:checkstyle

集中监控,可视化和整合报告信息:Sonar,它可以和JaCoCo,checkstyle 很好的集成。Sonnar Runner插件被用来分析源代码,结合JaCoCo来发布代码覆盖率报告。所有信息都发布到Sonar,Sonar Dashboard中可见。

第十三章,持续集成

重点:

CI:Continuous Integration 持续集成,频繁的集成代码,对于每个变化,源代码都会通过自动化构建被编译和测试。持续集成就是通过定义的构建项目的时间间隔(如,每5分钟构建一次)或者每次VCS中的变化来触发构建。Hudson/Jenkins 是比较流行的CI server

VCS:将不同开发人员的代码集成到一个中央VCS中,GitHub 后端使用的是免费的开源的 VCS 叫做Git。

//搭Git环境:

安装Git,创建SSH key,将Key添加到GitHub Setting中,可以安装一个GitHub应用在windows上。将源代码上传到Git中,安装Hudson来构建项目。创建一个Hudson Job,配置代码仓库,也就是告诉Hudson到什么地方去获得源代码(Git)。Repository URL: [email protected]:/todo.git。每次每一个Dev修改代码并提交到Git后,都会触发这个Hudson Job。Job来调用Gradle build中的命令。Hudson会把结构发布到Dashboard中。当构建失败时会有Email通知。点击job名字,可以看到输出结构。

事实上,在本地执行可以直接执行Gradle命令执行各个Task,Hudson是用来多次的,频繁的,自动化构建项目。

第十四章,打包和发布

重点:

artifact:工件

在默认情况下,所有应用了Java插件的项目在执行assemble task的时候都会生成一个单独的JAR文件(包含项目的类文件和基本数据的标准JAR文件),path:/build/libs。有些时候,你想要在组建过程中创建额外的工件,换句话说,为项目添加自定义的包。

如果你的项目交付的非标准工件(自定义的包)需要被其他用户或项目使用,那么需要将他们包含在组建过程中。

对于Java插件的项目都有一个archives配置项,该配置定义了一个项目的输出包。这个配置默认是标准JAR文件,也就是项目构建生成的工件。我们可以通过这个配置项来添加更多的输出包来丰富插件项目。

当执行gradle assemble 时,项目会创建标准JAR文件到libs目录下,通过指定archives配置来注册你所定义的自定义的包,再次执行assemble,标准Jar和附加Jar都会在libs目录中创建。

使用distribution插件创建自定义包:

apply plugin: 'distribution'
distributions{
       main{
          baseName = "***"
          contents{
              from {libsDir}//打包build/libs 目录下的所有文件
      }
  }
}
通过执行gradle assemble distZip/ distTar 命令创建包,包默认地址放置到build/ distributions目录下。
发布工件:可以发布到Maven仓库中,有三种类型的Maven仓库,1 位于/.m2/repository目录下的本地缓存,2 本地文件系统中任意目录下的仓库,3 通过HTTP(S)可访问的远程二进制仓库。通过 Maven-publish插件可以发布工件。

publishing{
	publications{
		plugin(MavenPublication){
			from components.java//添加JAR组件到发布包列表中。
			artifactId 'artifactTodo-plugin'//必须定义工件id
			groupId 'com.manning'//必须定义组id
		}
	}
}


你可能感兴趣的:(Gradle)