Search code examples
jsonjenkinsgroovyjenkins-groovyjsonbuilder

Groovy unable to generate json output as needed


I'm trying to generate the following JSON output in Groovy for one of my Jenkins Job.

Expected JSON

 {
    "svc-a": {
        "type": "object",
        "properties": {
            "svcVersion": {
                "type": "string",
                "propertyOrder": 1,
                "enum": ["No build", "1.0.0.59", "1.0.0.58"]
            },
            "skipConfigs": {
                "type": "boolean",
                "format": "checkbox"
            }
        }
    },
    "svc-b": {
        "type": "object",
        "properties": {
            "svcVersion": {
                "type": "string",
                "propertyOrder": 1,
                "enum": ["No build", "1.0.0.177", "1.0.0.176", "1.0.0.175"]
            },
            "skipConfigs": {
                "type": "boolean",
                "format": "checkbox"
            }
        }
    }
 }

I am looping through each service and getting the build number from Jenkins. For each service I am trying to generate the json along with the some additional header and appending it to map. Finally when build the json object from map exisiting json is treated as string.

MyCode.

#!/usr/bin/env groovy
import org.boon.Boon;
import groovy.json.JsonSlurper;
import groovy.transform.Field;
import groovy.json.JsonBuilder;
import groovy.json.*

def serviceList = [
"svc-a",
"svc-b"
]

def getBuildVersions(serviceName) {

  def resultList = []
  resultList.add(0,"No build")
       def job = jenkins.model.Jenkins.instance.getAllItems().findAll { it.name.contains(serviceName) }

  job.each { s ->
    if (s.toString().contains("")) {
      print s
       def builds = s.getBuilds()
       builds.each { t->
         if((t.result).toString() == "SUCCESS" && !t.displayName.contains("SNAPSHOT") && !t.displayName.contains("config")){
              resultList.add(t.displayName)
         }
      }
    }
  }

  return resultList
}

def retVal = new HashMap<String, Map>()

for (svc in serviceList) {

  def myBuilds = getBuildVersions(svc)

  List ver = myBuilds.collect{ "'" + it + "'"}

  def header = """
{"type": "object", "properties": { "svcVersion": { "type": "string", "propertyOrder": 1, "enum": $ver }, "skipConfigs": { "type": "boolean", "format": "checkbox" } } }
"""

def json = JsonOutput.toJson(header)
def result = new JsonSlurper().parseText(json)
  // s =  "'" + svc + "'"
  retVal.put(svc, result)

}


def builder = new JsonBuilder()

sjson =  JsonOutput.toJson(retVal)

return sjson

Received Output

{"svc-a":"\n{\"type\": \"object\", \"properties\": { \"svcVersion\": { \"type\": \"string\", \"propertyOrder\": 1, \"enum\": ['No build', '1.0.0.59', '1.0.0.58', '1.0.0.57', '1.0.0.56', '1.0.0.55', '1.0.0.54', '1.0.0.53', '1.0.0.52', '1.0.0.51', '1.0.0.49', '1.0.0.48', '1.0.0.47', '1.0.0.46', '1.0.0.45', '1.0.0.38', '1.0.0.37', '1.0.0.36', '1.0.0.35', '1.0.0.33', '1.0.0.31', '1.0.0.30', '1.0.0.29', '1.0.0.28', '1.0.0.27', '1.0.0.26', '1.0.0.25', '1.0.0.24', '1.0.0.22', '1.0.0.20', '1.0.0.19', '1.0.0.18', '1.0.0.17', '1.0.0.16', '1.0.0.13', '1.0.0.11', '1.0.0.8', '1.0.0.6', '1.0.0.5'] }, \"skipConfigs\": { \"type\": \"boolean\", \"format\": \"checkbox\" } } }\n","svc-b":"\n{\"type\": \"object\", \"properties\": { \"svcVersion\": { \"type\": \"string\", \"propertyOrder\": 1, \"enum\": ['No build', '1.0.0.177', '1.0.0.176', '1.0.0.175', '1.0.0.173', '1.0.0.172', '1.0.0.171', '1.0.0.170', '1.0.0.169', '1.0.0.167', '1.0.0.166', '1.0.0.165', '1.0.0.164', '1.0.0.163', '1.0.0.162', '1.0.0.158', '1.0.0.156', '1.0.0.38', '1.0.0.37', '1.0.0.36', '1.0.0.35', '1.0.0.33', '1.0.0.31', '1.0.0.29', '1.0.0.27'] }, \"skipConfigs\": { \"type\": \"boolean\", \"format\": \"checkbox\" } } }\n"}

When the Groovy Map is converted to JSON, json object in the values treated as one string.

How can get the properly formatted json output. I come from python background dont have mcuh idea on Groovy.


Solution

  • Found the solution by just using string manipulation

    for (svc in serviceList) {
    
      def myBuilds = getBuildVersions(svc)
    
      List ver = myBuilds.collect{ '"' + it + '"'}
    
      def header = """
    "$svc": {"type": "object", "properties": { "svcVersion": { "type": "string", "propertyOrder": 1, "enum": $ver }, "skipConfigs": { "type": "boolean", "format": "checkbox" } } }
    """
      if (firstRun == "true"){
        retVal =  header
      } else {
        retVal = retVal + "," + header
      }
       firstRun = "false"
    }