Jenkins共享库的应用 - 掘金 (juejin.cn)
上一篇文章我们了解了jenkins 共享库的应用,在里面也用到了groov的语法,这可能是jenkins门槛稍微高一点的应用,不过不要紧,我会慢慢带你们熟悉这门语言,后面的文章会逐步用共享库的方式,完成构建安卓,node,java等代码的编译,最后也会给你一套可以自动化识别,项目语言然后进行不同语言项目构建的方法。
首先我们来部署一下groovy的环境。
访问Groovy的官网
http://www.groovy-lang.org/
我们可以看到,它是又Apache基金会管理的一个项目,和它的一些优点。点击Download,我们会看到很多版本
因为jenkins是运行的2.X的版本,所以我们也下载2.x的版本,可以直接下载windows的版本。连接如下:
https://groovy.jfrog.io/artifactory/dist-release-local/groovy-windows-installer/groovy-2.5.15/
下载后完成安装,就会发现桌面上有一个Groovy Console的 图标。我们就可以用这个作为开发工具,来运行我们的groovy程序。
老规矩,先输出一下Hello World.
println("Hello World")
然后ctrl + r 运行
我会从数据类型,条件判断,循环控制,和函数来简述一下Grovvy的简单应用。
01 数据类型
字符串string
字符串表示我们可以使用,单引号、双引号、三引号三种方式。这里一定要注意,如果要引用变量,那么一定要用双引号,单引号会原样输出。
在写Jenkins的构建过程中,对字符串的操作用的最多的还是split的方法,有的时候我们会将url传过来的信息,分割一下取出我们想要的内容,拼写路径或者文件名称一类的。
比如,类似如下的操作
def srcName = srcUrl.split("/")[-1]
srcDir = "${workspace}/${srcTmp}"
这里还用def这个关键字。那么除了split的方法,操作字符串还有没有其他的方法呢,当然是有。
contains(): 是否包含特定内容 返回true falsesize(): length() 字符串数量大小长度toString(): 转换成string类型indexOf(): 元素的索引endsWith(): 是否指定字符结尾minus() plus(): 去掉、增加字符串reverse(): 反向排序substring(1,2): 字符串的指定索引开始的子字符串toUpperCase() toLowerCase(): 字符串大小写转换split(): 字符串分割 默认空格分割 返回列表
让我们来举几个例子,首先要定义两个变量,一个数字,一个字符串,然后对其进行操作
def str = "test"
def num = 1
println(str.contains("te"))
println(str.contains("le"))
println(str.size())
println(num.toString())
println(str.reverse())
println(str.toUpperCase())
我们在编译器中试一下,效果如下
列表list
+ - += -=: 元素增加减少isEmpty(): 是否为空判断add(): 添加元素intersect([2,3]) disjoint([1]): 取交集、判断是否有交集flatten(): 合并嵌套的列表unique(): 去重reverse() sort(): 反转 升序count(): 元素个数join(): 将元素按照参数链接sum() min() max(): 求和 最小值 最大值contains(): 包含特定元素remove(2): removeAll()each{}: 遍历trim: 去除字符串前后的空格
def list1 = ["a", "b", "c"]
def list2 = ["d", "e", "f"]
def list3 = []
def list4 = ["a", "b", "c", "d", "e", "f"]
def list5 = ["a", "b", "c",["d", "e", "f"]]
def list6 = ["a", "b", "c", "a"]
println(list1 + list2)
println(list1.isEmpty())
println(list3.isEmpty())
println(list1.intersect(list2))
println(list4.intersect(list2))
println(list5.flatten())
println(list6.unique())
输出
[a, b, c, d, e, f]
false
true
[]
[d, e, f]
[a, b, c, d, e, f]
[a, b, c]
映射map
在Jenkins构建中,map是使用的相当频繁的一种数据架构。我们经常拿来定义变量,比如
def args = [
env: env.Environment,
workspace: "/var/lib/jenkins/workspace/cicd-projects",
groupName: env.GroupName,
projectName: null,
gitBranch: env.Branch,
gitUrl: env.RepositoryURL,
extra: null,
envType: env.EnvType
];
使用的时候可以如下写法
stage('Pre') {
if (args.projectName == null) {
echo "projectName 为空"
}
echo "git地址:$args.gitUrl"
echo "git分支:$args.gitBranch"
echo "项目组:$args.groupName"
echo "项目名:$args.projectName"
echo "环境:$args.env"
echo "a,b环境: $args.envType"
echo "附加参数:$args.extra"
}
对于map也有一些操作的方法
size(): map大小[’key’]: .key get() 获取valueisEmpty(): 是否为空containKey(): 是否包含keycontainValue(): 是否包含指定的valuekeySet(): 生成key的列表each{}: 遍历mapremove(‘a‘): 删除元素(k-v)
比如:
groovy:000> [:]
===> [:]
groovy:000> [1:2]
===> [1:2]
groovy:000> [1:2][1]
===> 2
groovy:000> [1:2,3:4,5:6]
===> [1:2, 3:4, 5:6]
groovy:000> [1:2,3:4,5:6].keySet()
===> [1, 3, 5]
groovy:000> [1:2,3:4,5:6].values()
===> [2, 4, 6]
groovy:000> [1:2,3:4,5:6] + [7:8]
===> [1:2, 3:4, 5:6, 7:8]
groovy:000> [1:2,3:4,5:6] - [7:8]
===> [1:2, 3:4, 5:6]
02 条件语句
if语句
在Jenkinsfile中可用于条件判断。他的基本结构如下:
if (表达式) {
//xxxx
} else if(表达式2) {
//xxxxx
} else {
//
}
我们可以用来判断项目,什么想用引用相应的工具。
if (buildType == 'maven'){
Home = tool '/usr/local/apache-maven'
buildHome = "${Home}/bin/mvn"
} else if (buildType == 'ant'){
Home = tool 'ANT'
buildHome = "${Home}/bin/ant"
} else if (buildType == 'gradle'){
buildHome = '/usr/local/bin/gradle'
} else{
error 'buildType Error [maven|ant|gradle]'
}
switch语句
switch语句的结构如下:
switch("${buildType}"){
case ”maven":
//xxxx
break;
case ”ant":
//xxxx
break;
default:
//xxxx
}
下面我来举个例子,我们可以用另外的一个方式判断项目,返回响应的构建
switch (projectType){
case "java-gradle":
return new JavaGradleBuild(steps, args);
case "java-maven":
return new JavaMavenBuild(steps, args);
case "android":
return new AndroidBuild(steps, args);
case "web":
return new WebBuild(steps, args);
case "node":
return new NodeBuild(steps, args);
default:
return new Build(steps,args);
}
我们可以将每一种构建写成一个groovy文件,然后判断响应的类型,返回一个new出来的实例,这部分内容。我会在后面的文章详细说明。
03 循环语句
for循环语句
test = [1,2,3]
for ( i in test){
///xxxxxx
break;
}
比如,我们有一个列表,要遍历列表中内容来进行操作
langs = ['java','python','groovy']
for ( lang in langs ){
if (lang == "java"){
println("lang error in java")
}else {
println("lang is ${lang}")
}
}
while循环语句
while(true){
//xxxx
}
04 函数和类
我们可以用def来定义一个函数
def PrintMes(info){
println(info)
return info
}
response = PrintMes("DevOps")
println(response)
我们可以用def来定义一个类中的方法。具体改怎么写呢
比如,我们有一个文件build.groovy我们想让他作为一个入口文件判断项目的类型,然后运行响应的构建。我们又创建了一个JavaMavenBuild.groovy的文件来存放,构建用Maven工具来编译的Java程序。那我们需要怎么做呢
比如,我们将这两个文件放于/src/com/devops/pipeline/build的路径下。我们在JavaMavenBuild.groovy文件的第一行用package关键字声明一下package com.devops.pipeline.build,然后我们创建一个class,如下:
class JavaGradleBuild extends Build {
JavaGradleBuild(steps, args) {
super(steps, args);
if (args.env == 'prod') {
...
}
}
}
这样我们在build.groovy文件中,就可以用new JavaMavenBuild(steps, args);的方式来引用它了。
最后我来总结一下,今天主要介绍了数据类型,条件判断,循环控制,和函数。Groovy作为脚本语言大部分内容还是比较简单,可能在类的地方有一些麻烦。这里要注意一些写法,比如字符串'''和''三引号和双引号的区别。当我们在构建中,调用一个dockerfile进行容器构建的时候,我们会传一些变量到进去,在java -jar ...的命令中用,就需要注意这些写法。