pull/32675/merge
Arjun Vijay Prakash 3 days ago committed by GitHub
commit 40432a893f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -19,6 +19,7 @@ package loader
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -206,7 +207,12 @@ func LoadValues(data io.Reader) (map[string]any, error) {
} }
return nil, fmt.Errorf("error reading yaml document: %w", err) return nil, fmt.Errorf("error reading yaml document: %w", err)
} }
if err := yaml.Unmarshal(raw, &currentMap); err != nil { // Decode numbers as json.Number so integers stay integers through
// toYaml/toToml. v2 charts keep float64 for compatibility; see #30884.
if err := yaml.Unmarshal(raw, &currentMap, func(d *json.Decoder) *json.Decoder {
d.UseNumber()
return d
}); err != nil {
return nil, fmt.Errorf("cannot unmarshal yaml document: %w", err) return nil, fmt.Errorf("cannot unmarshal yaml document: %w", err)
} }
values = MergeMaps(values, currentMap) values = MergeMaps(values, currentMap)

@ -20,6 +20,7 @@ import (
"archive/tar" "archive/tar"
"bytes" "bytes"
"compress/gzip" "compress/gzip"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -31,8 +32,10 @@ import (
"testing" "testing"
"time" "time"
"github.com/BurntSushi/toml"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"sigs.k8s.io/yaml"
chart "helm.sh/helm/v4/internal/chart/v3" chart "helm.sh/helm/v4/internal/chart/v3"
"helm.sh/helm/v4/pkg/chart/common" "helm.sh/helm/v4/pkg/chart/common"
@ -420,6 +423,43 @@ foo:
}, },
}, },
}, },
"It should load integers as json.Number": {
data: []byte(`
key: 13
`),
expctedValues: map[string]any{
"key": json.Number("13"),
},
},
"It should load floats as json.Number": {
data: []byte(`
pi: 3.14
`),
expctedValues: map[string]any{
"pi": json.Number("3.14"),
},
},
"It should keep integers larger than float64 mantissa as json.Number": {
data: []byte(`
key: 9007199254740993
`),
expctedValues: map[string]any{
"key": json.Number("9007199254740993"),
},
},
"It should load nested numbers as json.Number": {
data: []byte(`
global:
key: 13
ratio: 1.5
`),
expctedValues: map[string]any{
"global": map[string]any{
"key": json.Number("13"),
"ratio": json.Number("1.5"),
},
},
},
} }
for testName, testCase := range testCases { for testName, testCase := range testCases {
t.Run(testName, func(tt *testing.T) { t.Run(testName, func(tt *testing.T) {
@ -430,6 +470,33 @@ foo:
} }
} }
func TestLoadValuesNumberEncoding(t *testing.T) {
values, err := LoadValues(bytes.NewReader([]byte(`
global:
key: 13
large: 9007199254740993
pi: 3.14
`)))
require.NoError(t, err)
yamlOut, err := yaml.Marshal(values)
require.NoError(t, err)
assert.Contains(t, string(yamlOut), "key: 13")
assert.Contains(t, string(yamlOut), "large: 9007199254740993")
assert.Contains(t, string(yamlOut), "pi: 3.14")
assert.NotContains(t, string(yamlOut), "13.0")
assert.NotContains(t, string(yamlOut), "1.048576e+")
var tomlBuf bytes.Buffer
require.NoError(t, toml.NewEncoder(&tomlBuf).Encode(values))
tomlOut := tomlBuf.String()
assert.Contains(t, tomlOut, "key = 13")
assert.Contains(t, tomlOut, "large = 9007199254740993")
assert.Contains(t, tomlOut, "pi = 3.14")
assert.NotContains(t, tomlOut, "13.0")
assert.NotContains(t, tomlOut, "key = \"13\"")
}
func TestLoadValuesEOFBoundary(t *testing.T) { func TestLoadValuesEOFBoundary(t *testing.T) {
// Reproduces #32506: a single logical line whose length is a multiple of // Reproduces #32506: a single logical line whose length is a multiple of
// bufio's default buffer (4096) and has no trailing newline used to be // bufio's default buffer (4096) and has no trailing newline used to be

@ -15,6 +15,7 @@ limitations under the License.
package util package util
import ( import (
"encoding/json"
"os" "os"
"path/filepath" "path/filepath"
"sort" "sort"
@ -219,6 +220,8 @@ func TestProcessDependencyImportValues(t *testing.T) {
case bool: case bool:
b := strconv.FormatBool(pv) b := strconv.FormatBool(pv)
assert.Equalf(t, vv, b, "failed to match imported bool value %v with expected %v for key %q", b, vv, kk) assert.Equalf(t, vv, b, "failed to match imported bool value %v with expected %v for key %q", b, vv, kk)
case json.Number:
assert.Equalf(t, vv, pv.String(), "failed to match imported number value %q with expected %q for key %q", pv, vv, kk)
default: default:
assert.Equalf(t, vv, pv, "failed to match imported string value %q with expected %q for key %q", pv, vv, kk) assert.Equalf(t, vv, pv, "failed to match imported string value %q with expected %q for key %q", pv, vv, kk)
} }
@ -296,6 +299,8 @@ func TestProcessDependencyImportValuesMultiLevelPrecedence(t *testing.T) {
case float64: case float64:
s := strconv.FormatFloat(pv, 'f', -1, 64) s := strconv.FormatFloat(pv, 'f', -1, 64)
assert.Equalf(t, vv, s, "failed to match imported float value %v with expected %v", s, vv) assert.Equalf(t, vv, s, "failed to match imported float value %v with expected %v", s, vv)
case json.Number:
assert.Equalf(t, vv, pv.String(), "failed to match imported number value %q with expected %q", pv, vv)
default: default:
assert.Equalf(t, vv, pv, "failed to match imported string value %q with expected %q", pv, vv) assert.Equalf(t, vv, pv, "failed to match imported string value %q with expected %q", pv, vv)
} }

@ -17,6 +17,7 @@ limitations under the License.
package engine package engine
import ( import (
"encoding/json"
"math" "math"
"strings" "strings"
"testing" "testing"
@ -36,6 +37,22 @@ func TestFuncs(t *testing.T) {
tpl: `{{ toYaml . }}`, tpl: `{{ toYaml . }}`,
expect: `foo: bar`, expect: `foo: bar`,
vars: map[string]any{"foo": "bar"}, vars: map[string]any{"foo": "bar"},
}, {
tpl: `{{ toYaml . }}`,
expect: "key: 13",
vars: map[string]any{"key": json.Number("13")},
}, {
tpl: `{{ toYaml . }}`,
expect: "large: 9007199254740993",
vars: map[string]any{"large": json.Number("9007199254740993")},
}, {
tpl: `{{ toYaml . }}`,
expect: "pi: 3.14",
vars: map[string]any{"pi": json.Number("3.14")},
}, {
tpl: `{{ toToml . }}`,
expect: "key = 13\n",
vars: map[string]any{"key": json.Number("13")},
}, { }, {
tpl: `{{ toYamlPretty . }}`, tpl: `{{ toYamlPretty . }}`,
expect: "baz:\n - 1\n - 2\n - 3", expect: "baz:\n - 1\n - 2\n - 3",

Loading…
Cancel
Save