You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 the python-iniparse package). Install it with pip install iniparse, then run:
    in2json example.ini > example.json
    
    Then just use readJSON in 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:18:35