mirror of https://github.com/helm/helm.git
repo: detect JSON and unmarshal efficiently
When an index is in a JSON format, the `sigs.k8s.io/yaml` package uses an inefficient approach to unmarshaling the data, as it does an unnecessary roundtrip on the data to transform the YAML to valid JSON. To prevent this from happening, detect if the bytes which we attempt to load contain valid JSON, and unmarshal them directly using `json.Unmarshal` instead. Signed-off-by: Hidde Beydals <hidde@hhh.computer>
This commit is contained in:
parent
a50206fed2
commit
e21c9cf7e2
|
|
@ -18,6 +18,7 @@ package repo
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
|
|
@ -336,7 +337,7 @@ func loadIndex(data []byte, source string) (*IndexFile, error) {
|
|||
return i, ErrEmptyIndexYaml
|
||||
}
|
||||
|
||||
if err := yaml.UnmarshalStrict(data, i); err != nil {
|
||||
if err := jsonOrYamlUnmarshal(data, i); err != nil {
|
||||
return i, err
|
||||
}
|
||||
|
||||
|
|
@ -361,3 +362,17 @@ func loadIndex(data []byte, source string) (*IndexFile, error) {
|
|||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// jsonOrYamlUnmarshal unmarshals the given byte slice containing JSON or YAML
|
||||
// into the provided interface.
|
||||
//
|
||||
// It automatically detects whether the data is in JSON or YAML format by
|
||||
// checking its validity as JSON. If the data is valid JSON, it will use the
|
||||
// `encoding/json` package to unmarshal it. Otherwise, it will use the
|
||||
// `sigs.k8s.io/yaml` package to unmarshal the YAML data.
|
||||
func jsonOrYamlUnmarshal(b []byte, i interface{}) error {
|
||||
if json.Valid(b) {
|
||||
return json.Unmarshal(b, i)
|
||||
}
|
||||
return yaml.UnmarshalStrict(b, i)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ const (
|
|||
annotationstestfile = "testdata/local-index-annotations.yaml"
|
||||
chartmuseumtestfile = "testdata/chartmuseum-index.yaml"
|
||||
unorderedTestfile = "testdata/local-index-unordered.yaml"
|
||||
jsonTestfile = "testdata/local-index.json"
|
||||
testRepo = "test-repo"
|
||||
indexWithDuplicates = `
|
||||
apiVersion: v1
|
||||
|
|
@ -145,6 +146,10 @@ func TestLoadIndex(t *testing.T) {
|
|||
Name: "chartmuseum index file",
|
||||
Filename: chartmuseumtestfile,
|
||||
},
|
||||
{
|
||||
Name: "JSON index file",
|
||||
Filename: jsonTestfile,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
{
|
||||
"apiVersion": "v1",
|
||||
"entries": {
|
||||
"nginx": [
|
||||
{
|
||||
"urls": ["https://charts.helm.sh/stable/nginx-0.2.0.tgz"],
|
||||
"name": "nginx",
|
||||
"description": "string",
|
||||
"version": "0.2.0",
|
||||
"home": "https://github.com/something/else",
|
||||
"digest": "sha256:1234567890abcdef",
|
||||
"keywords": ["popular", "web server", "proxy"],
|
||||
"apiVersion": "v2"
|
||||
},
|
||||
{
|
||||
"urls": ["https://charts.helm.sh/stable/nginx-0.1.0.tgz"],
|
||||
"name": "nginx",
|
||||
"description": "string",
|
||||
"version": "0.1.0",
|
||||
"home": "https://github.com/something",
|
||||
"digest": "sha256:1234567890abcdef",
|
||||
"keywords": ["popular", "web server", "proxy"],
|
||||
"apiVersion": "v2"
|
||||
}
|
||||
],
|
||||
"alpine": [
|
||||
{
|
||||
"urls": [
|
||||
"https://charts.helm.sh/stable/alpine-1.0.0.tgz",
|
||||
"http://storage2.googleapis.com/kubernetes-charts/alpine-1.0.0.tgz"
|
||||
],
|
||||
"name": "alpine",
|
||||
"description": "string",
|
||||
"version": "1.0.0",
|
||||
"home": "https://github.com/something",
|
||||
"keywords": ["linux", "alpine", "small", "sumtin"],
|
||||
"digest": "sha256:1234567890abcdef",
|
||||
"apiVersion": "v2"
|
||||
}
|
||||
],
|
||||
"chartWithNoURL": [
|
||||
{
|
||||
"name": "chartWithNoURL",
|
||||
"description": "string",
|
||||
"version": "1.0.0",
|
||||
"home": "https://github.com/something",
|
||||
"keywords": ["small", "sumtin"],
|
||||
"digest": "sha256:1234567890abcdef",
|
||||
"apiVersion": "v2"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue