Groovy 基础入门:语法、数据类型、流程控制与常用 DSL

来自AI助手的总结
文章介绍了Groovy基础语法、数据类型及常用操作,帮助理解Jenkins Pipeline脚本。
Groovy 基础入门:语法、数据类型、流程控制与常用 DSL

一、Groovy简明教程

1.1 Groovy简明教程

无论是声明式还是脚本式的 Pipeline 都依赖了 Groovy 脚本,所以如果要很好的掌握 Pipeline 脚本的用法,我们非常有必要去了解下 Groovy 语言。

1.2 什么是Groovy

Groovy 是跑在 JVM 中的另外一种语言,我们可以用 Groovy 在 Java 平台上进行编程,使用方式基本与使用 Java 代码的方式相同,所以如果你熟悉 Java 代码的话基本上不用花很多精力就可以掌握 Groovy 了,它的语法与 Java 语言的语法很相似,而且完成同样的功能基本上所需要的 Groovy 代码量会比 Java 的代码量少。

官方网站:https://groovy.apache.org

1.3 环境搭建

要安装 Groovy 环境非常简单,前往官网网站下载对应的平台安装包一键安装即可:https://groovy.apache.org/download.html,我这里使用的是 Mac,当然也可以使用比较方便的 Homebrew 工具来进行一键安装:

$ brew install groovy

可以使用下面的命令查看 groovy 是否安装成功:

$ groovy -v
Groovy Version: 3.0.4 JVM: 13.0.2 Vendor: Oracle Corporation OS: Mac OS X

1.4 基本语法

1.4 运行方法

使用编辑器(vscode)新建一个 Groovy 文件 hello.groovy,文件内容如下:

class Example {
   static void main(String[] args) {
        // 使用 println 打印信息到 stdout
        /*除了上面的注释方法外,这里没也是注释信息哦*/
        println 'Hello World'
        println "Hello World";
   }
}

如果你对 Java 代码较熟悉的话,可以看到上面的 Groovy 是非常类似的。

然后可以使用 groovy 命令运行上面的程序:

$ groovy 1hello.groovy
Hello World
Hello World
  • 从输出结果可以看出了 Groovy 里面支持单引号和双引号两种方式,
  • 注释支持//和/**/两种方式,
  • 而且不以分号“;”结尾也可以,
  • 但是我们还是推荐都带上分号保持代码的一致性。

1.4 标识符

标识符被用来定义变量,函数或其他用户定义的变量。标识符以字母、美元或下划线开头,不能以数字开头。

以下是有效标识符的一些例子 :

def employeename 
def student1 
def student_name

其中,def是在 Groovy 中用来定义标识符的关键字。

如下代码:2datatype.groovy

class Example{
    static void main(String[] agrs){
        String x ="Happy";
        println(x);

        def _Holiday = "Mother's Day";
        println(_Holiday);
        println(x + " "+_Holiday);
    }
}

运行结果如下:

$ groovy 1hello.groovy
Happy
Mother's Day
Happy Mother's Day

1.4 数据类型

上述例子中我们定义了一个字符串 x 和一个标识符 _Name。当然除了字符串之外,Groovy 也支持有符号整数、浮点数、字符等:

class Example {
    static void main(String[] args) {
        String str = "Hello";  // 字符串
        int x = 5;  // 整数
        long y = 100L;  // 长整型
        float a = 10.56f;  // 32位浮点数 
        double b = 10.5e40;  // 64位浮点数
        char c = 'A';  // 字符
        Boolean l = true;  // 布尔值,可以是true或false。
        println(str);
        println(x);
        println(y);
        println(a);
        println(b);
        println(c);
        println(l);
    }
}

运行结果如下:

$ groovy 2datatype.groovy
Hello
5
100
10.56
1.05E41
A
true
  • String => 字符串
  • int => 整数
  • long => 长整型
  • float => 32位浮点数
  • double => 64位浮点数
  • char => 字符
  • Boolean => 布尔值,可以是true或false。

1.4 打印变量

上面用 def 关键字来定义变量,当然也可以用一个确定的数据类型来声明一个变量,我们可以用下面的几种方式来打印变量:

class Example {
    static void main(String[] args) {
        // 初始化两个变量
        int x = 5; 
        int X = 6; 

        // 打印变量值
        println("x = " + x + " and X = " + X);  
        println("x = ${x} and X = ${X}");
        println('x = ${x} and X = ${X}');
    }
}

运行结果如下:

$ groovy 3Variable.groovy
x = 5 and X = 6
x = 5 and X = 6
x = ${x} and X = ${X}

从这里我们可以看出 Groovy 在单引号的字符串里面是不支持插值的,这点非常重要,很多同学在使用 Pipeline 脚本的时候经常会混淆。

除此之外,还支持三引号:

class Example {
    static void main(String[] args) {
        // 初始化两个变量
        int x = 5; 
        int X = 6; 

println """
x = ${x}
X = ${X}
"""

println '''
x = ${x}
X = ${X}
'''
    }
}

运行结果如下:

$ groovy 3Variable.groovy
x = 5
X = 6

x = ${x}
X = ${X}

可以看出 Groovy 里面三引号支持双引号和单引号两种方式,但是单引号同样不支持插值,要记住。

1.4 函数

Groovy 中的函数是使用返回类型或使用 def 关键字定义的,函数可以接收任意数量的参数,定义参数时,不必显式定义类型,

可以添加修饰符,如 public,private 和 protected,默认情况下,如果未提供可见性修饰符,则该方法为 public,如下所示:

class Example {
   static def PrintHello() {
      println("This is a print hello function in groovy");
   } 

   static int sum(int a, int b, int c = 10) {
      int d = a+b+c;
      return d;
   }  

   static void main(String[] args) {
      PrintHello();
      println(sum(5, 50));
   } 
}
  • static def PrintHello(){}
  • static int sum(int a, int b, int c = 10) {}
  • static void main(String[] args) {}

运行结果如下:

$ groovy 4func.groovy
This is a print hello function in groovy
65

1.4 条件语句

在我们日常工作中条件判断语句是必不可少的,即使在 Jenkins Pipeline 脚本中也会经常遇到,Groovy 里面的条件语句和其他语言基本一致,使用 if/else 判断:

class Example { 
   static void main(String[] args) { 
      // 初始化变量值
      int a = 2

      // 条件判断
      if (a < 100) { 
         // 如果a<100打印下面这句话
         println("The value is less than 100"); 
      } else { 
         // 如果a>=100打印下面这句话
         println("The value is greater than 100"); 
      } 
   } 
}

运行结果如下:

$ groovy 5cond.groovy
The value is less than 100

1.4 循环语句

除了条件判断语句之外,循环语句也是非常重要的,Groovy 中可以使用三种方式来进行循环:while、for语句、for-in语句,如下:

class Example {
   static void main(String[] args) {
      int count = 0;
      println("while循环语句:");
      while(count<5) {
         println(count);
         count++;
      }

      println("for循环语句:");
      for(int i=0;i<5;i++) {
         println(i);
      }

      println("for-in循环语句:");
      int[] array = [0,1,2,3]; 
      for(int i in array) { 
         println(i); 
      } 

      println("for-in循环范围:");
      for(int i in 1..5) {
         println(i);
      }
   }
}

运行结果如下:

$ groovy 6loop.groovy
while循环语句:
0
1
2
3
4
for循环语句:
0
1
2
3
4
for-in循环语句:
0
1
2
3
for-in循环范围:
1
2
3
4
5

上面是常用的三种循环方式,其中一个比较特殊的地方是我们可以用..来定义一个数据范围,比如1:5表示1到5的数组。

另外我们还可以使用for-in来循环 Map,Map(字典)是我们在编写程序的过程中会镜像使用到的数据结构,大部分的编程语言都是使用{}来定义 Map,而在 Groovy 中有点不一样的地方,是使用[]来定义的 Map,如下所示:

class Example {
   static void main(String[] args) {
       // 定义一个Map
      def ageMap = ["Ken" : 21, "John" : 25, "Sally" : 22];

      for(am in ageMap) {
         println(am);
      }
   }
}

运行结果如下:

$ groovy 7map.groovy
Ken=21
John=25
Sally=22

除了上面这些最基本的特性外,Groovy 还支持很多其他的特性,比如异常处理、面向对象设计、正则表达式、泛型、闭包等等,由于我们这里只是为了让大家对 Jenkins Pipeline 的脚本有一个基本的认识,更深层次的用法很少会涉及到.

二、Groovy基础

2.1 字符串与列表

2.1 Groovy – 简介

  • Groovy是一种功能强大,可选类型和动态语言,支持Java平台
  • 旨在提高开发人员的生产力得益于简洁,熟悉且简单易学的语法。
  • 可以与任何Java程序顺利集成,并立即为您的应用程序提供强大的功能, 包括脚本编写功能,特定领域语言编写,运行时和编译时元编程以及函数式编程

Alt Image Text

2.1 Install Groovy

https://groovy-lang.org/install.html

You should now have Groovy installed properly. You can test this by typing the following in a command shell:

groovysh
$ groovysh
Groovy Shell (3.0.4, JVM: 13.0.2)
Type ':help' or ':h' for help.
--------------------------------------------------------------------------------------------------------------------------------------------------------
groovy:000> println("hello world");
hello world
===> null

Which should create an interactive groovy shell where you can type Groovy statements.

groovyConsole

Alt Image Text

To run a specific Groovy script type:

groovy SomeScript

2.1 Groovy数据类型

  • 字符串表示:单引号、双引号、三引号
  • 常用方法:
    • contains()工是否包含特定内容返回true false
    • size() length()字符串数量大小长度
    • toString() 转换成string类型 indexOf()
    • 元素的索引 endsWith() 是否指定字符结尾
    • minus() plus() 去掉、增加字符串
    • reverse() 反向排序
    • substring(1,2)字符串的指定索引开始的子字符串
    • toUpperCase() toLowerCase()字符串大小写转换
    • split()字符串分割默认空格分割返回列表
groovy:000> "devsecurityops".contains("ops")
===> true
groovy:000> "devsecurityops".contains("users")
===> false
groovy:000> "devsecurityops".endsWith("ops")
===> true
groovy:000> "devsecurityops".endsWith("abc")
===> false
groovy:000> "devsecurityops".length()
===> 14
groovy:000> "devsecurityops".size()
===> 14
groovy:000> "dev"+"ops"
===> devops
groovy:000> "devops" - "dev"
===> ops
groovy:000> "devops".toUpperCase()
===> DEVOPS
groovy:000> "DEVOPS".toLowerCase()
===> devops
 "dev1,dev2,dev3"
===> dev1,dev2,dev3

groovy:000>  "host1,host2,host3".split(',')
===> [host1, host2, host3]

groovy:000> hosts = "host1,host2,host3".split(',')
===> [host1, host2, host3]

groovy:000> for( i in hosts){
groovy:001>   println(i)
groovy:002> }
host1
host2
host3
===> null

groovy:000> result = [1,2,3,4].add(5)
===> true

2.1 Groovy数据类型一list

  • 列表符号:[]
  • 常用方法
    • + - + -= 元素增加减少
    • add() << 添加元素
    • isEmpty()判断是否为空
    • intersect([2,3]) disjoint([1]) 取交集、判断是否有交集
    • flatten() 合并嵌套的列表
    • unique()去重
    • reverse() sort()反转升序
    • count() 元素个数
    • join() 将元素按照参数链接
    • sum() min() max() 求和最小值最大值
    • contains() 包含特定元素
    • remove(2) removeAll()
    • each{}遍历
groovy:000> []
===> []
groovy:000> [1,2,3,4] + 4
===> [1, 2, 3, 4, 4]
groovy:000> [1,2,3,4] + 46
===> [1, 2, 3, 4, 46]
groovy:000> [1,2,3,4] << 14
===> [1, 2, 3, 4, 14]
groovy:000> result = [1,2,3,4].add(5)
===> true
groovy:000> print(result)
true===> null
groovy:000> [2,3,4,5,6,6,6].unique()
===> [2, 3, 4, 5, 6]
groovy:000> [2,3,4,5,6,6,6].join("-")
===> 2-3-4-5-6-6-6
groovy:000> [2,3,4,5,6,6,6].each{
groovy:001> println it}
2
3
4
5
6
6
6
===> [2, 3, 4, 5, 6, 6, 6]

2.2 字典条件语句与循环

本节介绍 Groovy 基础语法中的字典条件语句循环语句。

2.2 Groovy数据类型一Map

  • 表示: [:]
  • 常用方法:
    • size() map 大小
    • ['key'].key get() 获取value
    • isEmpty () 是否为空 containKey () 是否包含key
    • containValue ()是否包含指定的value
    • keySet () 生成key的列表
    • each{}遍历map
    • remove( '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].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]-[1:2]
===> [3:4, 5:6]

2.2 Groovy条件语句一if

if(表达式){ 
    //xxxx 
    } else if(表达式2) {
    //xxxxx 
    } else { 
    // 
    } 
groovy:000> buildType = "maven"
===> maven
groovy:000> if (buildType == "maven"){
groovy:001>   println("This is a maven project");
groovy:002> } else if(buildType == "gradle"){
groovy:003>   println("project type error");
groovy:004> }
This is a maven project
===> null

2.2 Groovy条件语句一switch

switch(" ${buildType}")
{ 
    case: "maven":
    //xxxx 
    break;
    case "ant": 
    //xxxx 
    break; 
    default:
    //xxxx 
}
buildType = "maven";
switch("${buildType}"){ 
case 'maven': 
    println("This is a maven project !"); 
    break;
    ;;
    case 'gradle': 
    println("This is a gradle projects !"); 
    break;
    ;; 
    default: 
    println("Project Type Error");
    ;;
}
$ groovy switch.groovy 
This is a maven project !
groovy:000> langs = ["java","python","ruby"]
===> [java, python, ruby]

$ groovy for.groovy 
lang is java
lang is python
lang is ruby

2.3 函数使用

2.3 def定义函数语法

 def PrintMes(Value){ 
    printin(Value) 
    //xxxx 
    return value 
 } 
def PrintMes(info){ 
    println (info) 
    return info 
} 

response = PrintMes("DevOps") 
println(response) 

2.3 Groovy正则表达式

@NonCPS 
String getBranch(String branchName){ 
    def matcher = (branchName =~ "RELEASE-[0-9]{4}") 
    if (matcher.find()) { 
        newBranchName = matcher[0] 
        } else { 
        newBranchName = branchName 
        ) 
    newBranchName 
} 

newBranchName = getBranch(branchName) 
println("New branch Name" ----> ${newBranchName}") 

2.4 常用的Pipeline DSL方法

2.4 常用DSL- readJSON– JSON数据格式化

def response = readJSON text: "${scanResult}" 
println(scanResult) 
//原生方法
import groovy.json.* 
@NonCPS 
def GetJson(text) {
    def prettyJson = JsonOutput.prettyPrint(text) 
    new JsonSlurperClassic().parseText(prettyJson) 
}

2.4 常用DSL-withCredentials

withCredentias([string(credentialsId: "xxxxx", variable: "sonarToken")])
{ 
    printin(sonarToken) 
} 

2.4 常用DSL一checkout

//Git 
checkout([$class: 'GitSCM', branches:  [[name: "branchName"]],          
            doGenerateSubmoduleConfigurations: false, 
            extensions: [], submoduleCfg: [], 
            userRemoteConfigs: [[credentialsId: "${credentialsId}", 
            url: "${srcUrl}"]]])

//Svn 
checkout([$class: 'SubversionSCM', additionalCredentials: [], 
            filterChangelog: false, ignoreDirPropChanges: false, 
            locations: [[credentialsId: "${credentialsId}", 
            depthOption: 'infinity', ignoreExternalsOption: true, 
            remote: "${svnUrl}"]], workspaceUpdater: [$class: 'CheckoutUpdater']] 
) 

2.4 常用DSL一publishHTML

publishHTML([allowMissing: false, 
    alwaysLinkToLastBuild: false, 
    keepAll: true, 
    reportDir: './report/', 
    reportFiles: "a.html, b.html", 
    reportName: 'InterfaceTestReport', 
    reportTitles: 'HTML'
])

2.4 常用DSL一input

def result = input message: '选择xxxxx’, 
                ok: '提交',
                parameters: [extendedChoice( 
                        description: 'xxxxx', 
                        descriptionPropertyValue:'', 
                        multiSelectDelimiter: ',', 
                        name: 'failePositiveCases', 
                        quoteValue: false, 
                        saveJSONParameterToFile: false, 
                        type: 'PT_CHECKBOX', 
                        value: "1,2,3", 
                        visibleltemCount: 99)] 
println(result) 

2.4 常用DSL-BuildUser

wrap([$class: 'BuildUser']) {
    echo "full name is $BUILD_USER" 
    echo "user id is $BUILD_USER_ID" 
    echo "user email is $BUILD_USER_EMAIL"  
}

2.4 常用DSL一httpRequest

ApiUrl = "http://xxxxxx/api/project_branches/list?project=${projectName}" 
Result = httpRequest authentication: 'xxxxxxxxx', 
    quiet: true, 
    contentType: 'APPLICATION_JSON' , 
    url: "${ApiUrl}" 

2.4 常用DSL一email

Alt Image Text

© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容