I want to edit the value of certain keys in a YAML file while keeping the rest unchanged. I have written a snippet to insert some values for these keys, but the resulting new file does not maintain single quotes ('
). How can I avoid this situation?
my code:
func updateVariables(nameValue, nameCluster string) error {
yamlFile, err := os.ReadFile("path")
if err != nil {
return fmt.Errorf("Error reading YAML file: %v", err)
}
var config PipelineConfig
err = yaml.Unmarshal(yamlFile, &config)
if err != nil {
return fmt.Errorf("Error parsing YAML file: %v", err)
}
for i := range config.Variables {
switch config.Variables[i].Name {
case "app_name":
config.Variables[i].Value = nameValue
case "cluster_name":
config.Variables[i].Value = nameCluster
}
}
modifiedYAML, err := yaml.Marshal(&config,)
if err != nil {
return fmt.Errorf("Error converting structure to YAML: %v", err)
}
err = os.WriteFile("path", modifiedYAML, 0644)
if err != nil {
return fmt.Errorf("Error writing modified YAML file: %v", err)
}
fmt.Println("File YAML modified.")
return nil
}
my struct:
type PipelineConfig struct {
Trigger string `yaml:"trigger"`
Variables []struct {
Name string `yaml:"name"`
Value string `yaml:"value"`
} `yaml:"variables"`
Stages []struct {
Template string `yaml:"template"`
Parameters struct {
AppName string `yaml:"app_name"`
AppRepoBranch string `yaml:"app_repo_branch"`
LocationEnv string `yaml:"location_env"`
ComponentName string `yaml:"component_name"`
ClusterName string `yaml:"cluster_name"`
} `yaml:"parameters"`
} `yaml:"stages"`
}
file yaml before edit
trigger: none
variables:
- name: app_name
value: '<name>'
- name: cluster_name
value: '<cluster>'
- name: component_name
value: '<component>'
- name: location_env
value: 'dev'
stages:
- template: 'tem'
parameters:
app_name: '${{ variables.app_name }}'
app_repo_branch: 'dev'
location_env: '${{ variables.location_env }}'
component_name: '${{ variables.component_name }}'
cluster_name: '${{ variables.cluster_name }}'
file yaml after edit
trigger: none
variables:
- name: app_name
value: test
- name: cluster_name
value: test
- name: component_name
value: <component>
- name: location_env
value: dev
stages:
- template: tem
parameters:
app_name: ${{ variables.app_name }}
app_repo_branch: develop
location_env: ${{ variables.location_env }}
component_name: ${{ variables.component_name }}
cluster_name: ${{ variables.cluster_name }}
As you can see, the single quotes disappear. Any suggestions?
yaml.Unmarshal
function unmarshal yaml value to a custom struct without metadata (style, kind, etc.).
yaml.Marshal
function under processing on a custom struct set metadata values as default. To get access metadata's fields, need to use yaml.Node
.
In your case Value
field has yaml.Style
equal yaml.SingleQuotedStyle
To get access to it (don't lose after unmarshalling), change Value
field type to yaml.Node
.
Variables []struct {
Name string `yaml:"name"`
Value yaml.Node `yaml:"value"`
} `yaml:"variables"`
for i := range config.Variables {
switch config.Variables[i].Name.Value {
case "app_name":
config.Variables[i].Value.Value = nameValue
case "cluster_name":
config.Variables[i].Value.Value = nameCluster
}
}