簡體   English   中英

Groovy/Jenkins:如何美化 json 字符串?

[英]Groovy/Jenkins: how to prettify json string?

如何使用 Jenkins 聲明性語法管道將 JSON object 捕獲為美化字符串?

pipeline {
  agent any

  stages {

    stage( "Set up" ) {
      steps {
        script {
          hostname    = "bld-machine"
          reply_email = "jenkins@${hostname}.company.com"
          actor_email = "user@company.com"
          status_json = initStatusJson()
        }
      }
    }

    /** Try figure out the difference between "global" and "env." variables. */
    stage( "Capture variables" ) {
      steps {
        script {
          status_json.env["var"]  = "${env.var}" as String
          status_json.env["var2"] = "${var}" as String
        }
      }
    }
  }

  post {
    always {
      script {
        def pretty_json = writeJSON( returnText: true, json: status_json )
      }
      emailext( subject: "CI/CD | ${currentBuild.currentResult}",
                from: "${reply_email}",
                to: "${actor_email}",
                mimeType: "text/plain",
                body: "${pretty_json}" )
    }
  }
}

def initStatusJson() {
  def json_obj = readJSON text: '{}'
  json_obj.job = readJSON text: '{}'
  json_obj.env = [:]
  json_obj.job.name = "${JOB_BASE_NAME}" as String
  json_obj.job.number = "${BUILD_ID}" as String
  json_obj.job.server = "${JENKINS_URL}" as String
  json_obj.job.visualization = "${JENKINS_URL}/blue/organizations/jenkins/${JOB_BASE_NAME}/detail/${JOB_BASE_NAME}/${BUILD_ID}/pipeline" as String

  return json_obj
}

上述 Jenkinsfile 中的def pretty_json =...語句會觸發如下錯誤:

WARNING: Unknown parameter(s) found for class type WARNING: Unknown parameter(s) found for class type 'org.jenkinsci.plugins.pipeline.utility.steps.json.WriteJSONStep': returnText
[Pipeline] }
[Pipeline] // script
Error when executing always post condition:
java.lang.IllegalArgumentException: You have to provided a file for writeJSON.
    at org.jenkinsci.plugins.pipeline.utility.steps.json.WriteJSONStepExecution.run(WriteJSONStepExecution.java:61)
    at org.jenkinsci.plugins.pipeline.utility.steps.json.WriteJSONStepExecution.run(WriteJSONStepExecution.java:43)
    at org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution.lambda$start$0(SynchronousNonBlockingStepExecution.java:47)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

我試過的:

  1. def pretty_json = writeJSON( returnText: true, json: status_json )語句受到以下資源的啟發:
    Jenkinsfile 管道構造 JSON object 並寫入文件
    https://www.jenkins.io/doc/pipeline/steps/pipeline-utility-steps/#writejson-write-json-to-a-file-in-the-workspace

  2. 我還嘗試def pretty_json = writeJSON returnText: true, json: status_json導致了相同的錯誤。

  3. status_json.toString()返回一個有效但未修飾的 JSON 字符串。

  4. 我嘗試def pretty_json = JsonOutput.toJson(status_json)基於Create JSON strings from Jenkins Pipeline 中的 Groovy 變量,它會生成此錯誤:

Error when executing always post condition:
groovy.lang.MissingPropertyException: No such property: JsonOutput for class: groovy.lang.Binding
  1. Tried def pretty_json = groovy.json.JsonOutput.prettyPrint(status_json) based on https://gist.github.com/osima/1161966 , and it generated this error:
Error when executing always post condition:
groovy.lang.MissingMethodException: No signature of method: java.lang.Class.prettyPrint() is applicable for argument types: (net.sf.json.JSONObject)

更新:嘗試@daggett的解決方案如下:

  post {
    always {
      script {
        def pretty_json = status_json.toString(2)
      }
      emailext( subject: "CI/CD | ${currentBuild.currentResult}",
                from: "${reply_email}",
                to: "${actor_email}",
                mimeType: "text/plain",
                body: "${pretty_json}" )
    }
  }

...並且還嘗試了一些變體,例如pretty_json =... (而不是def pretty_json =... )並且還將pretty_json分配移到script{...} scope ...但沒有一個工作。

script{...}上下文中, .toString(2)產生了這個錯誤:

Scripts not permitted to use method net.sf.json.JSON toString int.

script{...}上下文之外,它生成了我解釋為“語法錯誤”的內容:

WorkflowScript: 79: Expected a step @ line 79, column 7.
         pretty_json = status_json.toString(2)

根據最后的錯誤信息

groovy.lang.MissingMethodException: 
No signature of method: java.lang.Class.prettyPrint() 
is applicable for argument types: (net.sf.json.JSONObject)

您在status_json變量中有net.sf.json.JSONObject

這真的很奇怪 - 似乎你得到的status_json不是 jenkins 的標准方式

但是根據此 class 的文檔

http://json-lib.sourceforge.net/apidocs/jdk15/net/sf/json/JSONObject.html#toString(int)

只需按照以下步驟制作漂亮的 json:

def pretty_json = status_json.toString(2)

如果您的Scripts not permitted to use method XYZ異常:

出於安全原因,jenkins 中禁用了許多非標准方法。

請參閱此答案以解決此類問題: https://stackoverflow.com/a/39412951/1276664


最后 - 您問題中的幾乎所有案例都應該有效:

  1. writeJSON( returnText: true, json: status_json ) : 更新pipeline-utility-steps jenkins 插件到最新版本以支持returnText參數

  2. 和上面一樣

...

  1. JsonOutput.toJson(status_json)JsonOutput class 位於groovy.json ZEFE70A8E604A67C68. you could import this package at t he beginning of the script import groovy.json or call it like this: groovy.json.JsonOutput.toJson(status_json) . 請注意,此方法返回未格式化的 json。

  2. groovy.json.JsonOutput.prettyPrint(status_json) :檢查JsonOutput.prettyPrint的文檔 - 它可以被稱為字符串而不是 ZA8CFDE6331BD59EB2AC966F8911C466 so this could work: groovy.json.JsonOutput.prettyPrint(status_json.toString()) but only in case when status_json.toString() returns a valid json and JsonOutput.prettyPrint allowed to be called in jenkins admin.

我剛剛做了一個測試,它給出了結果:
def pretty_json = writeJSON( returnText: true, json: status_json, pretty: 4)
注意:確保您已安裝插件Pipeline Utility Steps 或者重新安裝。
下面是腳本示例:

#!groovy
import hudson.model.Result
import groovy.json.*
pipeline 
{
    agent any 
    stages 
    {
        stage ('Set up')
        {
            steps
            {
                script
                {
                    hostname    = "bld-machine"
                    reply_email = "jenkins@${hostname}.company.com"
                    actor_email = "user@company.com"
                    status_json = initStatusJson()
                    println (status_json)
                }
            }
        }
        stage ('Capture variables')
        {
            steps
            {
                script
                {
                    // Added just for test
                    status_json.env["var"]  = "Alt" as String
                    status_json.env["var2"]  = "su" as String
                    println (status_json)
                }
            }
        }
    }
    
    post {
    always {
      script {
        def pretty_json = writeJSON( returnText: true, json: status_json , pretty: 4)
        println (pretty_json)
         emailext( subject: "CI/CD | ${currentBuild.currentResult}",
                from: "${reply_email}",
                to: "${actor_email}",
                mimeType: "text/plain",
                body: "${pretty_json}" )
       }
     }
    }
} 
def initStatusJson() {
  def json_obj = readJSON text: '{}'
  json_obj.job = readJSON text: '{}'
  json_obj.env = [:]
  json_obj.job.name = "${JOB_BASE_NAME}" as String
  json_obj.job.number = "${BUILD_ID}" as String
  json_obj.job.server = "${JENKINS_URL}" as String
  json_obj.job.visualization = "${JENKINS_URL}/blue/organizations/jenkins/${JOB_BASE_NAME}/detail/${JOB_BASE_NAME}/${BUILD_ID}/pipeline" as String

  return json_obj
}

Output 日志: 在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM