文章目录
Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming.
看官网图标就不简单,这门语言及其特殊,综合多门语言的语法特点,既能用编译型语言的语法书写,也能按脚本语言的语法书写,即有编程语言风格,也有脚本语言特色。使用脚本式风格属性,还可以用不同风格方式表达。继承了Java语言,理论上使用Java写的,Groovy也能正常编译通过。貌似编译是Java编译,先把Groovy转换成Java后再编译。
官网文档:Apache Groovy
使用 -D file.encoding
参数来设置脚本的默认编码
groovy -D file.encoding=UTF-8 .\test.groovy
脚本中获取编码:
println("Default encoding is: " + System.getProperty("file.encoding"))
怎么查看数据类型
def myVar = "Hello"
println(myVar.getClass())
1 注释和变量定义
注释分单行注释和多行注释
单行注释://
多行注释:/* ... */
使用 def 定义变量的时候,会自动转换为对应类型
引用变量不存在会报错:println(var)/println(“${var}”)
变量定义
自动识别:
def x = 5
def y = “hello world”
指定变量类型,如:Boolean, BigDecimal, Integer, Float, Double, String, ArrayList(List), LinkedHashMap(Map), 指定了变量类型不能把其他类型的值赋值给它 !!
数值:Integer/BigDecimal
示例:
Boolean a = "true"
BigDecimal b = 20
Integer c = 30
Integer c1 = 30.8 // 会自动转换为整形
Float d = 12.8
String e = "ok"
List f = [1,2,3]
Map g = ["name": "star", "age": 18]
Double h = 12.346
println(a)
println(b)
println(c)
println(c1)
println(d)
println(e)
println(f)
println(g)
println(h)
// true
// 20
// 30
// 30
// 12.8
// ok
// [1, 2, 3]
// [name:star, age:18]
// 12.346
2 数据类型及方法
Groovy 支持以下数据类型:
- 基本数据类型:byte、short、int、long、float、double、boolean、char
- 对象数据类型:String、BigDecimal、BigInteger、Date、Time、Timestamp、File、URL、Map、List、Set、Range、Pattern、Matcher、Closure、Class、Object 等
- 特殊数据类型:null、void
需要注意的是,Groovy 是一种动态类型语言,变量的数据类型可以在运行时动态改变。因此,Groovy 的数据类型比 Java 更加灵活。
类型:数值/字符串/列表/映射/范围(数组 def tup = (1…5))
定义布尔类型:boolean result = 3 > 5
2.1 运算符
算术运算符:加减乘除取模
赋值运算符:= += -= *= /=
自增自减运算符:++ –
关系运算符:大于/大于等于/小于/小于等于
等于运算符:等于== 不等于!= ,计算结果是布尔值. <=>
符号 "hello"<=>"hellq"
值为-1, 5<=>6
值为-1, 5<=>2
值为 1,也就是前面与后面比较,大于就是 1,小于就是-1,等于就是 0
逻辑运算符:
println(! (3 > 5)) // true
println( 3 > 2 && 3 > 5) // false
println( 3 > 2 || 3 >5) // true
三元运算符(条件运算符):
println( false?false:true)
println(3<2?false:3>5?true:false) // 3<2 是false,false取冒号后面的值,(冒号后面计算3>5?true:false,3>5是false,取fasle)
println(3<2?false:3<5?true:false)
// true
// false
// true
2.2 数值
整数:正数/零/负数
浮点数:正/负浮点数
整数运算符:加减乘除/取模
浮点数运算符:加减乘除
整数与浮点数:加减乘除
2.3 字符串-不可变对象
使用引号将字符串包裹起来,可以使用单引号/双引号/三引号,三引号可以包含多行文本
注意: 跟 shell 一样,使用$引用变量,单引号不会解释变量
字符串索引:
索引从 0 开始,var[3]/var[-1],var[1..3]是 1 到 3 包含 3,var[1..<3]不包含 3,var[4..2]反向,var[2,1,6]取第 2/1/6 个字符
基本操作:
数学符号:加减乘
比较字符串: 等于/不等于/<=>
基本函数:
.size() 字符个数
.length() 字符长度,2 个含义相同
.count(‘x’) 统计 x 的数量
.contains(“hello”) 返回布尔值,是否包含 hello
.center(字符串,填充符号)
.compareToIgnoreCase(字符串) 跟字符串比较大小,按词典顺序比较,返回整形
.endsWith(字符串)
.equalsIgnoreCase(字符串) 返回 bool 值
.matches(正则) 全部匹配才返回 true
.replaceAll(正则,闭包函数)
.reverse()反转
.split(正则)
.strim() 去除字符串前后空格
.substring(开始,结束)
.toCharacter
.toDouble
.toFloat
.toInteger
.toLong
.toLowerCase
.toUpperCase
.tokenize()空格作为字符串分隔符,或传参给定字符串
.readLines(字符串)
.eachLine(闭包函数) eachLine(字符串,闭包函数)
eachLine 示例:
def func = {v -> print v}
def s = """hello
world
nice\n"""
func "hello"
print(s)
s.eachLine(func)
2.4 列表
重要:列表可以是任意元素的集合,数值/字符串/列表/映射/函数/对象(变量/类对象),列表跟字符串一样,索引从 0 开始
列表索引跟字符串一样
列表可以使用加法/减法/<<追加新元素
列表方法:
.add(元素) .add(索引,元素)
.addAll(元素集合)
.contains(元素) 返回 bool 值
.flatten() 子元素展开形成新列表
.getAt(索引) .getAt(range 对象)返回多个元素的列表 .getAt(指定多个子元素索引)
.intersect(列表) 交集
.isEmpty() 返回 bool 值
.pop() 删除最后一个元素
.remove(索引/元素值) 整数默认是索引,字符串或者其他默认是元素值
.size() 元素个数
.sort() 排序
2.5 映射
示例:
["name":"star", "age":18]
[2:[1,2] , 3:["name", "age"]]
def x = 1
def y = 2
def m = [x:y,y:x] 键是变量不会解析,值是变量会解析变量
println(m) # [x:2, y:1]
引用方法:m.x,m["x"]
方法:
.containsKey(键) 返回 bool 值
.get(键) 键不存在返回空, .get(键,默认值)
.keySet() 获取所有键集合,列表类型
.put(键,值)添加元素
.size()返回键值对个数
.values() 所有的值集合,collection 类型(List 也是集合类型一种), values().asList()返回列表
列表和映射的联合应用:
def library = [
"Ken": ["Groovy", "UML"],
"John": ["Java"]
]
library["Sally"] = ["Basic"]
library["John"] = library["John"]<<"Golang"
println("library: $library")
println "Ken has borrowed UML? ${library['Ken'].contains('UML')}"
println "borrowers number: ${library.size()}"
println "borrowers:${library.keySet().sort()}"
println "Ken borrowed books:${library["Ken"]}"
println "library values: ${library.values()}"
// library: [Ken:[Groovy, UML], John:[Java, Golang], Sally:[Basic]]
// Ken has borrowed UML? true
// borrowers number: 3
// borrowers:[John, Ken, Sally]
// Ken borrowed books:[Groovy, UML]
// library values: [[Groovy, UML], [Java, Golang], [Basic]]
2.6 range-范围
示例:
1..100
1..<10
"a".."z"
10..1
"Z".."X"
1..5+3
def num = 1…10
举例:num.size()
方法:
.contains(元素) 返回 bool 值
.get(索引)
.getFrom() 获取第一个值
.getTo() 获取最后一个值
.isReverse() 是否逆序,bool 值
.size() 长度
.subList(from,to) 返回列表
3 正则表达式
定义正则:def reg =~ “hello”
部分匹配:=~
全部匹配:==~
元字符:
^ $ . * + ? {} []字符集 [^]非字符集
(ab)*,ab出现任意次数 (a|b)*,a或b出现任意次数
元字符匹配要转义两个反斜杠\\ ,如:def reg =~ "\\.txt"
斜杆/包裹正则只需要单个斜杆,如: def reg =~ /\.txt/,含义同上
转义: \w
单词字符, \d
数字, \s
空字符, \W
非单词字符, \D
非数字, \S
非空白字符
正则案例:
import java.io.*
def s = "--11star 10:20PM"
def pt = '(\\w+)\\s+((\\d{1,2}):(\\d{2})([AP]M))'
def matcher1 = s =~ pt
println(matcher1.matches()) // 要整行匹配才是true,不是整行匹配可以输出matcher1[0]
println(matcher1)
println(matcher1[0])
println(matcher1[0][5])
// false
// java.util.regex.Matcher[pattern=(\w+)\s+((\d{1,2}):(\d{2})([AP]M)) region=0,16 lastmatch=]
// [11star 10:10PM, 11star, 10:10PM, 10, 10, PM] // matcher1[0]是全部,1是第一个括号,2是后面的外边括号,3/4/5是里面的小括号
// PM
4 输入输出
print 输出不换号,print(“hello”) print “hello”,2 种写法,函数式和闭包式,可以输出任意类型的值
println 输出换行
print("hello world")
print("hello \n world")
格式化输出:printf
示例:
def a = "name"
def b = 18
def c = 60.8 // 在def定义的时候自动转换为对应类型,如果是60会报错
printf("name is %s,age is %d, weight is %.2f", [a,b,c])
name is name,age is 18, weight is 60.80
字符串格式化: %20s,%-20s(文字靠左)
基本输入:
def getString(){
return System.console().readLine("请输入名字:")
}
def getInteger(){
return System.console().readLine("your age:").toInteger()
}
def getWeight(){
return System.console().readLine("your weight:").toDouble()
}
def name = getString()
def age = getInteger()
def weight = getWeight()
println("your name:$name, age: $age, weight: $weight")
// PS D:\my_document\vscode-project> groovy -D file.encoding=UTF-8 .\test.groovy
// 请输入名字:star
// your age:18
// your weight:60
// your name:star, age: 18, weight: 60.0
5 自定义方法
简单输出:
def greeting(){
println "hello world"
}
greeting()
// 多行语句可以分号隔开 print "hello";print " ";print "world"
内置变量:
def info(){
def name = "star"
def age = 18
println("my name is $name, age is $age")
}
info()
外部传参:
def info(name, age){
println("my name is $name, age is $age")
}
info("star", 18)
默认参数:
def info(name, age=20){
println("my name is $name, age is $age")
}
info("star")
函数返回值:
def info(name, age=20){
return "my name is $name, age is $age"
}
def s = info("star", 25)
println(s)
6 内置方法
assert(3 == 5),如果 bool 值为 FALSE,则断言失败,抛出异常
upto 方法:数字序列迭代
def sum = 0
1.upto(10){n -> sum += n}
println(sum)
each 方法:集合/字符串/列表/映射
def s = ''
"hello".each(){it -> s += it;s += "-"}
println(s)
[1,2,3,4].each(){it -> println it}
def m = ["Ken":18, "Sally":20]
m.each(){it -> println it}
m.each(){it -> println("${it.key} age is ${it.value}")}
// h-e-l-l-o-
// 1
// 2
// 3
// 4
// Ken=18
// Sally=20
// Ken age is 18
// Sally age is 20
each 配合 if 条件语句:
[1,2,3,4].each(){it -> if(it%2 ==0)println it}
// 2
// 4
find 方法,只返回查到的第一个元素:闭包必须返回 bool 值,所有返回 true 的元素形成一个新的元素集合
def lst = [1,2,3,4]
lst = lst.find(){it -> it > 2}
println(lst)
def m = ["Ken":18, "John":22, "Sally":24]
println(m)
m = m.find(){it -> it.value > 20}
println(m)
println(m.key)
// 3
// [Ken:18, John:22, Sally:24]
// John=22
// John
findAll 方法,只返回查到的所有元素:闭包必须返回 bool 值,所有返回 true 的元素形成一个新的元素集合
def lst = [1,2,3,4]
lst = lst.findAll(){it -> it > 2}
println(lst)
def m = ["Ken":18, "John":22, "Sally":24]
println(m)
m = m.findAll(){it -> it.value > 20}
println(m)
println(m.key)
println(m.keySet())
// [3, 4]
// [Ken:18, John:22, Sally:24]
// [John:22, Sally:24]
// null
// [John, Sally]
any 方法:每个元素迭代使用闭包函数返回值,类型为 bool,任意一个返回 true 则表达式为真,否则为假
def lst = [1,2,3,4]
def b = 'hello'
println(b)
b = lst.any(){it -> it > 0} // b可以重新复制为布尔类型
println(b)
every 方法:每个元素迭代使用闭包函数返回值,类型为 bool,所有元素返回 true 则表达式为真,否则为假
def lst = [1,2,3,4]
def b = 'hello'
println(b)
b = lst.every(){it -> it > 0}
println(b)
b = lst.every(){it -> it > 3}
println(b)
collect 方法:所有元素经过闭包函数运算后,返回同样长度的新列表,类似于 Python 的 map 函数
def lst = [1,2,3,4]
lst = lst.collect(){it -> it * it}
println(lst)
// [1, 4, 9, 16]
inject 方法:把集合的第一个元素和第二个元素通过闭包计算,返回的结果再与第三个元素计算,以此类推,最后返回总的计算结果
def lst = [1,2,3,4]
def sum = lst.inject(){previous, element -> previous + element}
println(sum) // 10
7 流程控制
三种流程控制结构:
- 顺序
- 选择
- 迭代
7.1 while
基本结构:
while(condition){
statement 1
statement 2
}
def LIMIT = 5
def count = 1
while(count <= LIMIT){
println count
count++
}
7.2 for
循环可以是某个范围/集合(列表/映射/数组)
示例:
for(count in 1..3){
println count
}
for (var in ['hello', 'world']){
println var
}
def staff = ["Ken":20,"John":22, "Sally":18]
def total = 0
for(s in staff){
total += s.value
}
println("ages: ${total}")
对数组做循环:
def tup = (1..5)
println(tup)
for(i in tup){
println(i)
}
7.3 if
基本结构:
if(condition){
statement 1
}
if(condition){
statement 1
} else {
statement 2
}
if(condition1){
statement 1
}
else if (condition2) {
statement 2
}
else if (condition3) {
statement 3
}
else {
statement 4
}
7.4 switch
基本结构:
switch(value) {
case express 1:
statement 1
break
case express 2:
statement 2
break
case express 3:
statement 3
break
default:
statement 4
break
}
express 可以是范围(1..5)/字符串("hello")/列表([1,2,3])/正则(~[0-9]{3}
7.5 循环关键字:break/continue
break:可以用在 while/for/switch 语句中
continue:可以用在 while/for 循环中
8 闭包 closure
闭包函数可以直接使用外部变量,普通函数只能通过传参
闭包特性:
- 闭包可以当做函数使用
- 闭包可以作为其他函数的参数
- 闭包可以作为其他闭包的参数
- 闭包作为返回值
- 闭包作为列表元素
- 闭包可以定义在闭包函数中
def lst = [1,2,3,4]
def isEven = {param -> param%2 == 0}
def isOdd = {param -> param%2 != 0}
def elem = {num ->
if(num ==2){
return isEven // 闭包作为返回值
} else if(num == 1){
return isOdd
}
}
def elemEven = elem(2)
def elemOdd = elem(1)
lst = lst.findAll elemOdd
println(lst)
def clos_list = [isEven, isOdd] // 闭包作为列表参数
println(clos_list)
// [1, 3]
// [test$_run_closure1@47f4e407, test$_run_closure2@2d1dee39]
闭包调用方法:
def closx = {println "hello ${it}"}
closx.call("Groovy")
closx "Groovy"
closx("Groovy")
无参闭包示例:
def clos = {println "hello world"}
clos()
有参闭包示例:
def clos = {param -> println param}
def closx = {param -> println("hello $param")}
clos("world")
closx("world")
单个参数可以隐藏:
def clos = {println it}
def closx = {println "hello ${it}"}
clos("world")
closx("world")
变量名称必须是it
调用外部变量:
def var = "hello"
def clos = {param -> println "$var world"}
clos()
闭包作为函数参数,闭包不会读取函数内部变量:
def greeting = "hello"
def closx = {param -> println "$greeting world"}
def demo(clos){
def greeting = "nice"
clos.call("star")
}
demo(closx)
函数调用闭包几种方法:
def greeting = "hello"
def closx = {param -> println "$greeting $param"}
def demo(clos){
def greeting = "nice"
clos.call("star")
}
// 第一种方法:
demo(closx)
// 第二种方法:
demo closx
// 第三种方法:
demo(){param -> println("good $param")}
闭包高级用法:
def lst = [1,2,3,4]
def doubles = {param -> 2 * param}
def triples = {param -> 3 * param}
def map(clos, list){
return list.collect(clos)
}
println(map(doubles, lst))
println(map(triples, lst))
// [2, 4, 6, 8]
// [3, 6, 9, 12]
9 文件和命令行参数
获取命令行参数:
println "args: $args"
println "args num: ${args.size()}"
println "args 0: ${args[0]}"
// PS D:\my_document\vscode-project> groovy .\test.groovy hello world
// args: [hello, world]
// args num: 2
// args 0: hello
// PS D:\my_document\vscode-project> groovy .\test.groovy "hello world"
// args: [hello world]
// args num: 1
// args 0: hello world
// PS D:\my_document\vscode-project> groovy .\test.groovy "hello world" "love groovy"
// args: [hello world, love groovy]
// args num: 2
// args 0: hello world
文件处理方法:
append(字符串)将字符串追加到文件末尾
createNewFile() 创建一个新的空文档,当且仅当文件不存在时才能创建,返回布尔值,表示成功或失败
delete() 删除由路径表示的文件或目录,返回布尔值,不存在不会报错,目录不是空的无法删除,可以先用 eachFileRecurse 删除文件,再删除目录
eachFile(闭包函数)为指定目录的每个文件应用闭包函数
eachFileRecurse(闭包函数),功能同上,但是会递归去执行
eachLine(闭包函数)逐行遍历指定文档
exists() 判断指定路径是否存在文件或目录
getPath()将抽象路径转换为一个路径字符串,返回字符串
getText() 读取文本内容作为一个字符串返回
isDirectory()判断是否是一个目录,返回布尔值
mkdir()创建目录,返回布尔值
withPrintWriter(闭包函数)为文件创建一个新的 PrintWriter 方法,并传递给闭包,并在此确认文件是否被关闭
一行一行读取文件并显示:
import java.io.File
if(args.size() != 1){
println "Usage: script.groovy filename"
System.exit(1)
} else {
new File(args[0]).eachLine {line ->
println "Line: $line"
}
}
// PS D:\my_document\vscode-project> groovy .\test.groovy "utf8.txt"
// Line: 这里是utf-8编码
// Line: fille encoding type is utf-8
// Line: 结束
读取文件返回字符串:
def s = new File(args[0]).getText()
println(s)
统计文件字符数/单词数/行数:
import java.io.File
def chars = 0
def words = 0
def lines = 0
new File("utf8.txt").eachLine {line ->
chars += line.length()
words += line.tokenize().size()
lines++
}
println("chars:${chars},words:${words},lines:$lines")
// chars:40,words:7,lines:3
列出目录下所有文件:
import java.io.File
def listDir(dirFile, indent){
dirFile.eachFile {file ->
(0..<indent).each {print " "}
println "${file.getName()}"
if (file.isDirectory()){
listDir(file, 2+indent)
}
}
}
def printDir(dirName){
listDir(new File(dirName), 0)
}
if (args.size() != 1 || new File(args[0]).isDirectory() == false){
println("Usage: script.groovy directory")
System.exit(1)
} else {
printDir(args[0])
}
// PS D:\my_document\vscode-project> groovy -D file.encoding=UTF-8 .\test.groovy "test\\down"
// process.bat
// t-link.txt.lnk
// t.txt
// testdir
// test.txt
// testdir2
// test2-1.txt
// test2-2.txt
// 测试.txt
目录递归查找文件:
import java.io.File
def printDir(dirName, size){
new File(dirName).eachFileRecurse {file ->
if(file.length() > size){
println "${file.getName()}"
}
}
}
if (args.size() != 2 || new File(args[0]).isDirectory() == false){
println "Usage: script.groovy dirname"
} else {
printDir(args[0], args[1].toInteger())
}
// PS D:\my_document\vscode-project> groovy -D file.encoding=UTF-8 .\test.groovy "test\\down" 80
// process.bat
// t-link.txt.lnk
// test.txt
文件拷贝:
import java.io.*
if (args.size() != 2){
println "Usage: script.groovy filename1 filename2"
System.exit(1)
} else {
def outFile = new File(args[1])
if(outFile.exists()){
outFile.delete()
}
def printWriter = outFile.newPrintWriter()
new File(args[0]).eachLine {line ->
printWriter.println(line)
}
printWriter.flush()
printWriter.close()
}
文件拷贝方法 2:
import java.io.*
if (args.size() != 2){
println "Usage: script.groovy filename1 filename2"
System.exit(1)
} else {
new File(args[1]).withPrintWriter {printWriter ->
new File(args[0]).eachLine {line ->
printWriter.println(line)
}
}
}
10 解析 XML
使用正则匹配获取 project 属性:
import java.io.File
def file = "test.xml"
def re_pt = '\s*<project\\s+name="(\\S+)".*'
new File(file).eachLine {line ->
matcher = line =~ re_pt
if(matcher.matches()){
println "name: ${matcher[0][1]}"
}
}
示例 books.xml 文件:
<books>
<book isbn="1234567890">
<title>Java Programming</title>
<author>John Smith</author>
</book>
<book isbn="0987654321">
<title>Python Programming</title>
<author>Jane Doe</author>
</book>
</books>
Jenkins 中导入以下 4 个模块无报错:
import groovy.xml.MarkupBuilder
import groovy.json.JsonSlurper
import groovy.util.XmlSlurper
import groovy.util.XmlParser
解析 XML 文件
import groovy.util.XmlParser
def xml = new XmlParser().parse(new File('books.xml'))
xml.book.each { book ->
println "Title: ${book.title.text()}"
println "Author: ${book.author.text()}"
println "ISBN: ${book.@isbn}"
println "------------------------"
}
输出结果:
Title: Java Programming
Author: John Smith
ISBN: 1234567890
------------------------
Title: Python Programming
Author: Jane Doe
ISBN: 0987654321
------------------------
11 执行本地命令
import groovy.util.XmlParser
import java.io.File
def file = ".repo/manifest.xml"
file = "/home/build/jenkins/workspace/dynamic_gerrit_paramter_build_test/t.txt"
def prj_list = []
boolean b = new File(file).exists()
b = true
prj_list.add(b)
def command = ['pwd']
def processBuilder = new ProcessBuilder(command)
def process = processBuilder.start()
def reader = new BufferedReader(new InputStreamReader(process.inputStream))
def line
while ((line = reader.readLine()) != null) {
prj_list.add(line)
}
process.waitFor()
// return ['master', 'feature', 'hotfix', 'develop']
return prj_list
Windows 执行命令:
def command = ['C:\\Windows\\System32\\cmd.exe', '/c', 'dir']
def processBuilder = new ProcessBuilder(command)
def process = processBuilder.start()
def reader = new BufferedReader(new InputStreamReader(process.inputStream))
def line
while ((line = reader.readLine()) != null) {
println line
}
process.waitFor()
第二种方法:
def lst = []
def command = "ls -l"
def process = Runtime.getRuntime().exec(command)
process.waitFor()
reader = process.inputStream.text
reader.eachLine {line ->
lst.add(line)
}
第三种方法:
def command = "ls -l"
def output = command.execute().text
// println output
output.eachLine { line ->
if(line.size() > 0){
hash_list.add(line)
}
}
多次执行宿主机的命令:
def commands = [
['C:\\Windows\\System32\\cmd.exe', '/c', 'dir', 'ansi.txt', '/b'],
['C:\\Windows\\System32\\cmd.exe', '/c', 'type', 'ansi.txt'],
['C:\\Windows\\System32\\cmd.exe', '/c', 'dir', 'test.xml', '/b']
]
for (def command : commands) {
def processBuilder = new ProcessBuilder(command)
def process = processBuilder.start()
def inputStream = process.inputStream
def reader = new BufferedReader(new InputStreamReader(inputStream))
reader.eachLine { line ->
println(line)
}
process.waitFor()
}
获取当前服务器 IP:
import groovy.util.XmlParser
import java.io.File
def file = ".repo/manifest.xml"
file = "/home/build/jenkins/workspace/dynamic_gerrit_paramter_build_test/t.txt"
file = "/tmp"
def prj_list = []
boolean b = new File(file).exists()
prj_list.add(b)
def command = ['hostname', '-I']
def processBuilder = new ProcessBuilder(command)
def process = processBuilder.start()
def reader = new BufferedReader(new InputStreamReader(process.inputStream))
def line
while ((line = reader.readLine()) != null) {
prj_list.add(line)
}
process.waitFor()
使用 groovy 脚本多次执行宿主机的命令:
def command = ['ls', '-l']
def processBuilder = new ProcessBuilder(command)
// 执行命令10次
for (int i = 0; i < 10; i++) {
def process = processBuilder.start()
def inputStream = process.inputStream
def reader = new BufferedReader(new InputStreamReader(inputStream))
reader.eachLine { line ->
println(line)
}
process.waitFor()
}
获取当前年月日,时分秒,纳秒:
import java.time.LocalTime
import java.time.LocalDate
def now = LocalTime.now()
def hour = now.getHour()
def minute = now.getMinute()
def second = now.getSecond()
println("Current time is: ${hour}:${minute}:${second}")
def c_time = now.getHour().toString() + now.getMinute().toString() + now.getSecond().toString()
println("Current time is: ${c_time}")
now = LocalDate.now()
def year = now.getYear()
def month = now.getMonthValue()
def day = now.getDayOfMonth()
println("Current date is: ${year}-${month}-${day}")
def nanoTime = System.nanoTime()
println("Current nanoseconds is: ${nanoTime}")
println("nano to int: ${nanoTime.toInteger()}")
保存为 JSON 数据格式到文件:
import groovy.json.JsonBuilder
// 创建一个Map对象,用于存储数据
def data = [
name: "John",
age: 30,
email: "john@example.com"
]
// 创建JsonBuilder对象,并将Map对象转换为JSON格式
def json = new JsonBuilder(data).toPrettyString()
// 创建File对象,并将JSON字符串写入文件
def file = new File("data.json")
file.write(json)
def printWriter = file.newPrintWriter()
printWriter.flush()
printWriter.close()
读取文件中的 JSON 数据:
import groovy.json.JsonSlurper
// 创建File对象,并读取文件中的JSON字符串
def file = new File("data.json")
def json = file.text
// 创建JsonSlurper对象,并将JSON字符串转换为Map对象
def slurper = new JsonSlurper()
def data = slurper.parseText(json)
// 输出Map对象中的数据
println "Name: ${data.name}"
println "Age: ${data.age}"
println "Email: ${data.email}"
Jenkins 中 tag 参数写入并读取代码(样例):
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
import java.io.File
def tag_dict = [:]
for (key in 1..4){
key = "project/build/name" + key
def value_list = []
for (value in 1..5){
value = key + "-" + value
value_list.add(value)
}
tag_dict.put(key, value_list)
}
def json = new JsonBuilder(tag_dict).toPrettyString()
def file = new File("/tmp/data.json")
file.write(json)
def file_read = new File("/tmp/data.json")
boolean b = file_read.exists()
def json_read = file_read.text
def slurper = new JsonSlurper()
def data_read = slurper.parseText(json_read)
return data_read[project]
// return tag_dict[project]
groovy 读取 JSON 文件,指定文件编码为 utf-8:
import groovy.json.JsonSlurper
def file = new File("path/to/your/json/file.json")
def reader = new InputStreamReader(new FileInputStream(file), "UTF-8")
def json = new JsonSlurper().parse(reader)
// 处理读取到的JSON数据
12 获取Gerrit仓库分支
参考文档:设置java.net.URL请求方式post get
都是groovy内置模块,无需额外安装,代码如下:
package test
import java.net.URL
import java.net.HttpURLConnection
import groovy.json.JsonSlurper
List list = []
String username = "admin"
String password = "123456"
String responseCookie = ""
String gerritLoginURL = "http://192.168.72.55:8080/login"
String gerritHomeURL = "http://192.168.72.55:8080"
// 仓库名称
String prjName = "android/kernel"
// 设置默认cookie handler,新创建连接自动添加handler中cookie
CookieManager cookieManager = new CookieManager()
CookieHandler.setDefault(cookieManager)
// 创建连接,设置请求方法
URL url = new URL(gerritLoginURL)
HttpURLConnection connection = (HttpURLConnection) url.openConnection()
connection.setDoOutput(true)
connection.setRequestMethod("POST")
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)")
// 发送POST请求,写入请求数据账号密码
String auth = String.format("username=%s&password=%s", username, password)
OutputStream os = connection.getOutputStream()
os.write(auth.toString().getBytes())
os.close()
// 获取连接状态及cookie
if(connection.responseCode == 200) {
responseCookie = connection.getHeaderField("Set-Cookie")
} else {
list.add("error")
return list
}
//获取登录后的cookie
//println(connection.responseCode)
//List cookies = cookieManager.getCookieStore().getCookies();
//for (HttpCookie cookie : cookies) {
// System.out.println(cookie);
//}
// 获取仓库分支数据
String branchText = ""
String gerritBranchURL = gerritHomeURL + "/projects/" + prjName.replace("/", "%2F") + "/branches/"
url = new URL(gerritBranchURL)
connection = (HttpURLConnection) url.openConnection()
if(connection.responseCode == 200) {
branchText = connection.getInputStream().getText().replace(")]}'", "")
} else {
list.add("error")
return list
}
// 获取分支
JsonSlurper js = new JsonSlurper()
for (element in js.parseText(branchText)) {
s = element.ref.toString()
if(s.startsWith("refs/heads/")) {
list.add(s.replace("refs/heads/", ""))
}
}
println(list)