公共脚本
公共脚本
Gradle 中公共脚本抽取与共享
要解决冗余代码和通用配置的问题,最简单的做法就是抽取出共同部分,作为其它所有项目的 parent/common 项目。
使用 git submodule
将所有系统中公共的类库和通用的配置,放到独立的仓库 Common 中。因为我们用 git 来管理代码,而 git 本身提倡多 branch,多仓库,所以采用 git submodule 方式,其它项目需要添加 Common 这个 submodule:
git submodule add yourGitRepo deps/Common
最后的”deps/Common”是自定义的,意思就是在当前的 deps 目录下用 Common 名字来当作 submodule 的 clone。
如果你 clone 别的带有 submodule 的项目时,默认情况下,当前的 project 并不会把 submodule 的代码都 clone 下来,可以执行:
git submodule foreach git pull
以下这段一般大家经常会遇到:当你 clone 项目时,submodule 会以最新的 master 分支上的 commit id 作为本次的 tag 下载,类似一个副本,因为一般大家都是用 submodule,而不是修改它。所以当你的 submodule 需要更新的时候,需要先执行这段代码:
git submodule foreach git checkout master
让 submodule 切换到 master 分支了,然后就可以用上面的 submodule pull 来更新了。
Gradle 构建
鉴于上文对 gradle 优点的描述,我们采用 gradle 来构建。我们的项目最初都是基于 maven 来构建的,从 maven 切换到 gradle 很简单,在项目根目录下,先执行(假设你的机器已经安装了 gradle 环境,一般负责构建的人首次需要安装,开发人员可以不安装):
gradle init wrapper
这样,就会自动生成相关的 gradlew,build.gradle,settings.gradle 等文件和相关目录,并会自动下载对应版本的 gradle binary 包(所以以后不需要安装)。Gradle 会自动识别 Maven 里的配置,并相应的导入进来,有少量部分配置可能需要修改。
注:在已有的 gradle 项目里,尽量使用生成的 gradlew 这个 wrapper,因为它会自动下载对应版本的 Gradle,也就是说团队合作的其他人开发机上是不需要手动安装 Gradle 的,并且 wrapper 也让大家的 Gradle 版本一致,避免问题。
Gradle 脚本修改
上面执行完之后,环境已经准备好了,现在要做的就是修改构建脚本:因为已经通过 git submodule 把公共项目放到独立目录(deps/Common)了,并且它本身也是独立可构建的项目,那么也就是说当前有两个项目了,一个是当前 project,一个是 Common 项目,要做的就是告诉 gradle,要多项目构建,编辑 settings.gradle,增加项目配置:
include "deps:Common"
以上就是把 Common 引入到当前项目了。根据项目的不同,然后对应修改 build.gradle,就大功告成了。看一个例子:
// 这一段主要是把公共库Common的构建脚本引入,因为一般会有通用的配置在里面
def userGradleScript = file("deps/Common/build.gradle")
if (userGradleScript.exists()) {
apply from: userGradleScript
}
// 使用war插件,这样就默认引入了java插件
apply plugin: 'war'
// for jetty
apply plugin: 'jetty'
stopKey = 'yourStopKey' // 自定义的stopkey
stopPort = xxxx // 停止端口
httpPort = xxxx // 启动http端口
// 项目属性
group = 'yourApp'
version = '1.0.0'
description = """这里描述你的项目"""
// checkstyle config文件地址
checkstyle {
configFile = file("deps/Common/config/checkstyle/checkstyle.xml")
}
// lib依赖
dependencies {
// 依赖公共库Common,compile是和maven里的compile scope一样
compile project(':deps:Common')
compile 'commons-validator:commons-validator:1.4.0'
compile('javax.servlet.jsp.jstl:jstl-api:1.2') {
exclude(module: 'servlet-api') // 防止版本冲突
}
compile 'javax.persistence:persistence-api:1.0.2'
runtime 'mysql:mysql-connector-java:5.1.26'
providedCompile 'org.apache.tomcat:tomcat-servlet-api:7.0.30'
// providedCompile 这个conf在java插件里是报错的,war里是正确的
providedCompile 'javax.servlet.jsp:jsp-api:2.1'
...
}
我们再来简单看下公共项目 Common 的构建脚本:
// 定义一堆基础插件
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: "jacoco"
apply plugin: 'checkstyle'
apply plugin: 'pmd'
apply plugin: 'findbugs'
apply plugin: 'eclipse'
apply plugin: 'idea'
// 定义项目属性
group = 'Common'
version = '1.0.0'
description = """Giant common library"""
// 定义依赖仓库
repositories {
mavenCentral()
}
// project的额外属性,这里用于定义profile属性,模拟maven的profile
ext {
if (project.hasProperty('profile')) {
profile = project['profile']
} else {
profile = "dev"
}
println "profile:" + profile
}
// 额外增加source path
sourceSets {
main {
resources {
srcDir "src/main/profiles/${profile}"
}
}
}
// project依赖
dependencies {
compile 'ch.qos.logback:logback-core:1.0.13'
compile 'ch.qos.logback:logback-classic:1.0.13'
compile 'ch.qos.logback:logback-access:1.0.13'
compile 'commons-io:commons-io:2.0.1'
compile 'commons-lang:commons-lang:2.6'
compile 'joda-time:joda-time:1.6.2'
compile 'org.testng:testng:6.8.7'
compile 'com.googlecode.jmockit:jmockit:1.5'
...
}
// task 配置
checkstyle {
ignoreFailures = true
sourceSets = [sourceSets.main]
}
findbugs {
ignoreFailures = true
sourceSets = [sourceSets.main]
}
pmd {
ruleSets = ["basic", "braces", "design"]
ignoreFailures = true
sourceSets = [sourceSets.main]
}
jacocoTestReport {
reports {
xml.enabled true
html.enabled true
csv.enabled false
}
sourceSets sourceSets.main
}
tasks.withType(Compile) {
options.encoding = "UTF-8"
}
test {
useTestNG()
jacoco {
excludes = ["org.*"]
}
}
这样,就可以在公共项目里配置好一堆基础的 task,dependencies 等等,而使用这个公共项目的其它项目则可以直接使用,无需再额外配置。脚本修改完了,就可以开始构建了(不需要安装 gradle,直接使用生成的 gradlew 就行):
./gradlew build
// 基于profile构建
./gradlew -Pprofile=dev build
常用构建命令:clean:清除之前的构建 test:执行测试 compileJava:编译 java check:在 test 之后做一个 check,一般代码检查插件,都是在这个阶段做的 build:构建打包