Jenkins Pipeline如何读取带分段的INI文件?求参考方案
Got it, let's break down how to handle this nested INI file in Jenkins Pipeline—whether you want to parse it directly for that clean dot-notation access, or convert it to a more Jenkins-friendly format first.
1. Directly Parse Nested INI for Dot-Notation Access
Jenkins doesn't have a built-in parser for nested INIs (with [[ sub-section ]] syntax), but we can build a simple Groovy function in your Pipeline to handle this. This will let you access values exactly like x.section1."section 1a".key as you wanted.
Here's a reusable parsing function and usage example:
def parseNestedIni(String iniContent) { def config = [:] def currentSection = null def currentSubSection = null iniContent.eachLine { line -> line = line.trim() // Skip comments and empty lines if (line.isEmpty() || line.startsWith(';') || line.startsWith('#')) { return } // Match main sections like [section1] if (line.matches(/^\[.*\]$/) && !line.matches(/^\[\[.*\]\]$/)) { def sectionName = line.replaceAll(/^\[|\]$/, '').trim() currentSection = [:] config[sectionName] = currentSection currentSubSection = null return } // Match sub-sections like [[section 1a]] if (line.matches(/^\[\[.*\]\]$/)) { def subSectionName = line.replaceAll(/^\[\[|\]\]$/, '').trim() if (!currentSection) { throw new IllegalArgumentException("Sub-section '${subSectionName}' found without a parent section") } currentSubSection = [:] currentSection[subSectionName] = currentSubSection return } // Parse key=value pairs def keyValueSplit = line.split('=', 2) if (keyValueSplit.size() == 2) { def key = keyValueSplit[0].trim() def value = keyValueSplit[1].trim() if (currentSubSection) { currentSubSection[key] = value } else if (currentSection) { currentSection[key] = value } else { throw new IllegalArgumentException("Key-value pair '${line}' exists outside any section") } } } return config } // Use it in your Pipeline def iniContent = readFile "example.ini" def config = parseNestedIni(iniContent) // Access values with dot notation (note the quotes for sub-section names with spaces) echo config.section1."section 1a".key // Outputs: value1 echo config.section2."section 2a".key // Outputs: value2
This function handles:
- Main sections (
[section]) - Nested sub-sections (
[[sub-section]]) - Comments/empty lines
- Key-value pairs under both main and sub-sections
2. Convert Nested INI to JSON/Properties First
If you'd rather avoid writing custom parsing logic, converting the INI to JSON or Properties (formats Jenkins has built-in readers for) is a great alternative.
Convert to JSON
You can either do this directly in your Pipeline or with a free offline tool:
- In-Pipeline Conversion: Use the same parsing function above, then convert the resulting Groovy Map to JSON with Groovy's built-in
JsonBuilder:import groovy.json.JsonBuilder def iniContent = readFile "example.ini" def configMap = parseNestedIni(iniContent) // Convert to pretty-printed JSON def jsonContent = new JsonBuilder(configMap).toPrettyString() writeFile file: "config.json", text: jsonContent // Read and access with Jenkins' readJSON step def jsonConfig = readJSON file: "config.json" echo jsonConfig.section1."section 1a".key - Offline Command-Line Tool: Use
in2json(a free, open-source Python tool part of thepython-iniparsepackage). Install it withpip install iniparse, then run:
Then just usein2json example.ini > example.jsonreadJSONin your Pipeline to load the JSON file.
Convert to Properties
Since Properties files use flat key-value pairs, we'll flatten the nested structure into keys like section1.section 1a.key. Here's how to do it in Pipeline:
def flattenNestedConfig(Map config, String parentKey = "") { def flatProps = [:] config.each { key, value -> def fullKey = parentKey ? "${parentKey}.${key}" : key if (value instanceof Map) { flatProps.putAll(flattenNestedConfig(value, fullKey)) } else { flatProps[fullKey] = value } } return flatProps } def iniContent = readFile "example.ini" def configMap = parseNestedIni(iniContent) def flatProperties = flattenNestedConfig(configMap) // Write to properties file def propsText = flatProperties.collect { k, v -> "${k}=${v}" }.join('\n') writeFile file: "config.properties", text: propsText // Read with Jenkins' readProperties step def propsConfig = readProperties file: "config.properties" echo propsConfig['section1.section 1a.key']
Alternatively, you can write a simple Python script with configparser to flatten the INI offline if you prefer.
内容的提问来源于stack exchange,提问作者justanothercoder

