Skip to content

Commit 68677dd

Browse files
author
felix.phipps
committed
replace gopkg with goccy in order to preserve comments and newline
Signed-off-by: felix.phipps <felix.phipps@cyberark.com>
1 parent 1656c13 commit 68677dd

File tree

3 files changed

+147
-9
lines changed

3 files changed

+147
-9
lines changed

tools/helm-tool/baker/modify_values.go

Lines changed: 120 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@ import (
2121
"fmt"
2222
"io"
2323
"os"
24+
"strconv"
2425
"strings"
26+
"unicode"
2527

26-
"gopkg.in/yaml.v3"
28+
"github.com/goccy/go-yaml"
29+
"github.com/goccy/go-yaml/parser"
2730
)
2831

2932
// inplaceReadValuesYAML reads the provided chart tar file and returns the values
@@ -124,16 +127,126 @@ func modifyTarStreamValuesYAML(in io.Reader, out io.Writer, modFn modFunction) e
124127
}
125128

126129
func modifyStreamValuesYAML(in io.Reader, out io.Writer, modFn modFunction) error {
127-
// Parse YAML
130+
inputBytes, err := io.ReadAll(in)
131+
if err != nil {
132+
return err
133+
}
134+
// Parse YAML into Go values for modification logic.
128135
var data map[string]any
129-
if err := yaml.NewDecoder(in).Decode(&data); err != nil {
136+
if err := yaml.Unmarshal(inputBytes, &data); err != nil {
137+
return err
138+
}
139+
originalStrings := map[string]string{}
140+
collectStringValues(data, nil, originalStrings)
141+
// Modify YAML values via the existing callback.
142+
data, err = modFn(data)
143+
if err != nil {
130144
return err
131145
}
132-
// Modify YAML
133-
data, err := modFn(data)
146+
updatedStrings := map[string]string{}
147+
collectStringValues(data, nil, updatedStrings)
148+
// Parse YAML into an AST so we can update nodes without losing comments.
149+
astFile, err := parser.ParseBytes(inputBytes, parser.ParseComments)
134150
if err != nil {
135151
return err
136152
}
137-
// Marshal back to YAML
138-
return yaml.NewEncoder(out).Encode(data)
153+
for yamlPath, newValue := range updatedStrings {
154+
if originalValue, ok := originalStrings[yamlPath]; ok && originalValue == newValue {
155+
continue
156+
}
157+
path, err := yaml.PathString(yamlPath)
158+
if err != nil {
159+
return err
160+
}
161+
node, err := yaml.ValueToNode(newValue)
162+
if err != nil {
163+
return err
164+
}
165+
if err := path.ReplaceWithNode(astFile, node); err != nil {
166+
return err
167+
}
168+
}
169+
_, err = io.WriteString(out, astFile.String())
170+
return err
171+
}
172+
173+
type pathSegment struct {
174+
key string
175+
isIndex bool
176+
}
177+
178+
func collectStringValues(object any, path []pathSegment, out map[string]string) {
179+
switch t := object.(type) {
180+
case map[string]any:
181+
for key, value := range t {
182+
keyPath := append(path, pathSegment{key: key})
183+
if stringValue, ok := value.(string); ok {
184+
out[pathToYAMLPath(keyPath)] = stringValue
185+
continue
186+
}
187+
collectStringValues(value, keyPath, out)
188+
}
189+
case map[string]string:
190+
for key, value := range t {
191+
keyPath := append(path, pathSegment{key: key})
192+
out[pathToYAMLPath(keyPath)] = value
193+
}
194+
case []any:
195+
for i, value := range t {
196+
keyPath := append(path, pathSegment{key: strconv.Itoa(i), isIndex: true})
197+
if stringValue, ok := value.(string); ok {
198+
out[pathToYAMLPath(keyPath)] = stringValue
199+
continue
200+
}
201+
collectStringValues(value, keyPath, out)
202+
}
203+
case []string:
204+
for i, value := range t {
205+
keyPath := append(path, pathSegment{key: strconv.Itoa(i), isIndex: true})
206+
out[pathToYAMLPath(keyPath)] = value
207+
}
208+
default:
209+
// ignore object
210+
}
211+
}
212+
213+
func pathToYAMLPath(path []pathSegment) string {
214+
if len(path) == 0 {
215+
return "$"
216+
}
217+
var builder strings.Builder
218+
builder.WriteString("$")
219+
for _, segment := range path {
220+
if segment.isIndex {
221+
builder.WriteString("[")
222+
builder.WriteString(segment.key)
223+
builder.WriteString("]")
224+
continue
225+
}
226+
builder.WriteString(".")
227+
if isSimpleYAMLPathKey(segment.key) {
228+
builder.WriteString(segment.key)
229+
continue
230+
}
231+
builder.WriteString("'")
232+
builder.WriteString(strings.ReplaceAll(segment.key, "'", "\\'"))
233+
builder.WriteString("'")
234+
}
235+
return builder.String()
236+
}
237+
238+
func isSimpleYAMLPathKey(key string) bool {
239+
if key == "" {
240+
return false
241+
}
242+
for i, r := range key {
243+
if i == 0 && unicode.IsDigit(r) {
244+
return false
245+
}
246+
if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' || r == '-' {
247+
continue
248+
}
249+
return false
250+
}
251+
return true
139252
}

tools/helm-tool/go.mod

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,21 @@ module github.com/jetstack/preflight/tools/helm-tool
33
go 1.25.0
44

55
require (
6+
github.com/goccy/go-yaml v1.12.0
67
github.com/google/go-containerregistry v0.20.7
78
github.com/spf13/cobra v1.10.2
8-
gopkg.in/yaml.v3 v3.0.1
99
)
1010

1111
require (
1212
github.com/containerd/stargz-snapshotter/estargz v0.18.1 // indirect
1313
github.com/docker/cli v29.0.3+incompatible // indirect
1414
github.com/docker/distribution v2.8.3+incompatible // indirect
1515
github.com/docker/docker-credential-helpers v0.9.3 // indirect
16+
github.com/fatih/color v1.15.0 // indirect
1617
github.com/inconshreveable/mousetrap v1.1.0 // indirect
1718
github.com/klauspost/compress v1.18.1 // indirect
19+
github.com/mattn/go-colorable v0.1.13 // indirect
20+
github.com/mattn/go-isatty v0.0.17 // indirect
1821
github.com/mitchellh/go-homedir v1.1.0 // indirect
1922
github.com/opencontainers/go-digest v1.0.0 // indirect
2023
github.com/opencontainers/image-spec v1.1.1 // indirect
@@ -23,4 +26,5 @@ require (
2326
github.com/vbatts/tar-split v0.12.2 // indirect
2427
golang.org/x/sync v0.18.0 // indirect
2528
golang.org/x/sys v0.38.0 // indirect
29+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
2630
)

tools/helm-tool/go.sum

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@ github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBi
1010
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
1111
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
1212
github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
13+
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
14+
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
15+
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
16+
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
17+
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
18+
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
19+
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
20+
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
21+
github.com/goccy/go-yaml v1.12.0 h1:/1WHjnMsI1dlIBQutrvSMGZRQufVO3asrHfTwfACoPM=
22+
github.com/goccy/go-yaml v1.12.0/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU=
1323
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
1424
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
1525
github.com/google/go-containerregistry v0.20.7 h1:24VGNpS0IwrOZ2ms2P1QE3Xa5X9p4phx0aUgzYzHW6I=
@@ -18,6 +28,13 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
1828
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
1929
github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co=
2030
github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0=
31+
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
32+
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
33+
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
34+
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
35+
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
36+
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
37+
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
2138
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
2239
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
2340
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
@@ -42,12 +59,16 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8
4259
github.com/vbatts/tar-split v0.12.2 h1:w/Y6tjxpeiFMR47yzZPlPj/FcPLpXbTUi/9H7d3CPa4=
4360
github.com/vbatts/tar-split v0.12.2/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA=
4461
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
62+
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
63+
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
4564
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
4665
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
4766
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
67+
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
4868
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
4969
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
50-
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
70+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
71+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
5172
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
5273
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
5374
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

0 commit comments

Comments
 (0)