feat: Set values from local files (#3758)

Adds the `--set-file key=filepath` flag to `install`, `upgrade`, `template` and `lint` sub-commands so that the content of the file at the `filepath` is set to the value for the `key`.

Resolves #1754
pull/4385/head
KUOKA Yusuke 7 years ago committed by Matt Butcher
parent 3bd07d3e98
commit dc93908626

@ -50,8 +50,10 @@ The install argument must be a chart reference, a path to a packaged chart,
a path to an unpacked chart directory or a URL. a path to an unpacked chart directory or a URL.
To override values in a chart, use either the '--values' flag and pass in a file To override values in a chart, use either the '--values' flag and pass in a file
or use the '--set' flag and pass configuration from the command line, to force or use the '--set' flag and pass configuration from the command line. To force string
a string value use '--set-string'. values in '--set', use '--set-string' instead. In case a value is large and therefore
you want not to use neither '--values' nor '--set', use '--set-file' to read the
single large value from file.
$ helm install -f myvalues.yaml ./redis $ helm install -f myvalues.yaml ./redis
@ -63,6 +65,9 @@ or
$ helm install --set-string long_int=1234567890 ./redis $ helm install --set-string long_int=1234567890 ./redis
or
$ helm install --set-file multiline_text=path/to/textfile
You can specify the '--values'/'-f' flag multiple times. The priority will be given to the You can specify the '--values'/'-f' flag multiple times. The priority will be given to the
last (right-most) file specified. For example, if both myvalues.yaml and override.yaml last (right-most) file specified. For example, if both myvalues.yaml and override.yaml
contained a key called 'Test', the value set in override.yaml would take precedence: contained a key called 'Test', the value set in override.yaml would take precedence:
@ -120,6 +125,7 @@ type installCmd struct {
client helm.Interface client helm.Interface
values []string values []string
stringValues []string stringValues []string
fileValues []string
nameTemplate string nameTemplate string
version string version string
timeout int64 timeout int64
@ -196,6 +202,7 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command {
f.BoolVar(&inst.replace, "replace", false, "re-use the given name, even if that name is already used. This is unsafe in production") f.BoolVar(&inst.replace, "replace", false, "re-use the given name, even if that name is already used. This is unsafe in production")
f.StringArrayVar(&inst.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.StringArrayVar(&inst.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&inst.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.StringArrayVar(&inst.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&inst.fileValues, "set-file", []string{}, "set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)")
f.StringVar(&inst.nameTemplate, "name-template", "", "specify template used to name the release") f.StringVar(&inst.nameTemplate, "name-template", "", "specify template used to name the release")
f.BoolVar(&inst.verify, "verify", false, "verify the package before installing it") f.BoolVar(&inst.verify, "verify", false, "verify the package before installing it")
f.StringVar(&inst.keyring, "keyring", defaultKeyring(), "location of public keys used for verification") f.StringVar(&inst.keyring, "keyring", defaultKeyring(), "location of public keys used for verification")
@ -222,7 +229,7 @@ func (i *installCmd) run() error {
i.namespace = defaultNamespace() i.namespace = defaultNamespace()
} }
rawVals, err := vals(i.valueFiles, i.values, i.stringValues, i.certFile, i.keyFile, i.caFile) rawVals, err := vals(i.valueFiles, i.values, i.stringValues, i.fileValues, i.certFile, i.keyFile, i.caFile)
if err != nil { if err != nil {
return err return err
} }
@ -343,8 +350,8 @@ func mergeValues(dest map[string]interface{}, src map[string]interface{}) map[st
} }
// vals merges values from files specified via -f/--values and // vals merges values from files specified via -f/--values and
// directly via --set or --set-string, marshaling them to YAML // directly via --set or --set-string or --set-file, marshaling them to YAML
func vals(valueFiles valueFiles, values []string, stringValues []string, CertFile, KeyFile, CAFile string) ([]byte, error) { func vals(valueFiles valueFiles, values []string, stringValues []string, fileValues []string, CertFile, KeyFile, CAFile string) ([]byte, error) {
base := map[string]interface{}{} base := map[string]interface{}{}
// User specified a values files via -f/--values // User specified a values files via -f/--values
@ -384,6 +391,17 @@ func vals(valueFiles valueFiles, values []string, stringValues []string, CertFil
} }
} }
// User specified a value via --set-file
for _, value := range fileValues {
reader := func(rs []rune) (interface{}, error) {
bytes, err := readFile(string(rs), CertFile, KeyFile, CAFile)
return string(bytes), err
}
if err := strvals.ParseIntoFile(value, base, reader); err != nil {
return []byte{}, fmt.Errorf("failed parsing --set-file data: %s", err)
}
}
return yaml.Marshal(base) return yaml.Marshal(base)
} }

@ -47,6 +47,7 @@ type lintCmd struct {
valueFiles valueFiles valueFiles valueFiles
values []string values []string
sValues []string sValues []string
fValues []string
namespace string namespace string
strict bool strict bool
paths []string paths []string
@ -73,6 +74,7 @@ func newLintCmd(out io.Writer) *cobra.Command {
cmd.Flags().VarP(&l.valueFiles, "values", "f", "specify values in a YAML file (can specify multiple)") cmd.Flags().VarP(&l.valueFiles, "values", "f", "specify values in a YAML file (can specify multiple)")
cmd.Flags().StringArrayVar(&l.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") cmd.Flags().StringArrayVar(&l.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
cmd.Flags().StringArrayVar(&l.sValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") cmd.Flags().StringArrayVar(&l.sValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
cmd.Flags().StringArrayVar(&l.fValues, "set-file", []string{}, "set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)")
cmd.Flags().StringVar(&l.namespace, "namespace", "default", "namespace to put the release into") cmd.Flags().StringVar(&l.namespace, "namespace", "default", "namespace to put the release into")
cmd.Flags().BoolVar(&l.strict, "strict", false, "fail on lint warnings") cmd.Flags().BoolVar(&l.strict, "strict", false, "fail on lint warnings")
@ -172,6 +174,12 @@ func lintChart(path string, vals []byte, namespace string, strict bool) (support
return lint.All(chartPath, vals, namespace, strict), nil return lint.All(chartPath, vals, namespace, strict), nil
} }
// vals merges values from files specified via -f/--values and
// directly via --set or --set-string or --set-file, marshaling them to YAML
//
// This func is implemented intentionally and separately from the `vals` func for the `install` and `upgrade` comammdsn.
// Compared to the alternative func, this func lacks the parameters for tls opts - ca key, cert, and ca cert.
// That's because this command, `lint`, is explicitly forbidden from making server connections.
func (l *lintCmd) vals() ([]byte, error) { func (l *lintCmd) vals() ([]byte, error) {
base := map[string]interface{}{} base := map[string]interface{}{}
@ -204,5 +212,16 @@ func (l *lintCmd) vals() ([]byte, error) {
} }
} }
// User specified a value via --set-file
for _, value := range l.fValues {
reader := func(rs []rune) (interface{}, error) {
bytes, err := ioutil.ReadFile(string(rs))
return string(bytes), err
}
if err := strvals.ParseIntoFile(value, base, reader); err != nil {
return []byte{}, fmt.Errorf("failed parsing --set-file data: %s", err)
}
}
return yaml.Marshal(base) return yaml.Marshal(base)
} }

@ -69,6 +69,7 @@ type templateCmd struct {
out io.Writer out io.Writer
values []string values []string
stringValues []string stringValues []string
fileValues []string
nameTemplate string nameTemplate string
showNotes bool showNotes bool
releaseName string releaseName string
@ -100,6 +101,7 @@ func newTemplateCmd(out io.Writer) *cobra.Command {
f.StringVar(&t.namespace, "namespace", "", "namespace to install the release into") f.StringVar(&t.namespace, "namespace", "", "namespace to install the release into")
f.StringArrayVar(&t.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.StringArrayVar(&t.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&t.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.StringArrayVar(&t.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&t.fileValues, "set-file", []string{}, "set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)")
f.StringVar(&t.nameTemplate, "name-template", "", "specify template used to name the release") f.StringVar(&t.nameTemplate, "name-template", "", "specify template used to name the release")
f.StringVar(&t.kubeVersion, "kube-version", defaultKubeVersion, "kubernetes version used as Capabilities.KubeVersion.Major/Minor") f.StringVar(&t.kubeVersion, "kube-version", defaultKubeVersion, "kubernetes version used as Capabilities.KubeVersion.Major/Minor")
f.StringVar(&t.outputDir, "output-dir", "", "writes the executed templates to files in output-dir instead of stdout") f.StringVar(&t.outputDir, "output-dir", "", "writes the executed templates to files in output-dir instead of stdout")
@ -132,7 +134,7 @@ func (t *templateCmd) run(cmd *cobra.Command, args []string) error {
t.namespace = defaultNamespace() t.namespace = defaultNamespace()
} }
// get combined values and create config // get combined values and create config
rawVals, err := vals(t.valueFiles, t.values, t.stringValues, "", "", "") rawVals, err := vals(t.valueFiles, t.values, t.stringValues, t.fileValues, "", "", "")
if err != nil { if err != nil {
return err return err
} }

@ -37,8 +37,10 @@ a packaged chart, or a fully qualified URL. For chart references, the latest
version will be specified unless the '--version' flag is set. version will be specified unless the '--version' flag is set.
To override values in a chart, use either the '--values' flag and pass in a file To override values in a chart, use either the '--values' flag and pass in a file
or use the '--set' flag and pass configuration from the command line, to force string or use the '--set' flag and pass configuration from the command line. To force string
values, use '--set-string'. values in '--set', use '--set-string' instead. In case a value is large and therefore
you want not to use neither '--values' nor '--set', use '--set-file' to read the
single large value from file.
You can specify the '--values'/'-f' flag multiple times. The priority will be given to the You can specify the '--values'/'-f' flag multiple times. The priority will be given to the
last (right-most) file specified. For example, if both myvalues.yaml and override.yaml last (right-most) file specified. For example, if both myvalues.yaml and override.yaml
@ -65,6 +67,7 @@ type upgradeCmd struct {
valueFiles valueFiles valueFiles valueFiles
values []string values []string
stringValues []string stringValues []string
fileValues []string
verify bool verify bool
keyring string keyring string
install bool install bool
@ -122,6 +125,7 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
f.BoolVar(&upgrade.force, "force", false, "force resource update through delete/recreate if needed") f.BoolVar(&upgrade.force, "force", false, "force resource update through delete/recreate if needed")
f.StringArrayVar(&upgrade.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.StringArrayVar(&upgrade.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&upgrade.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") f.StringArrayVar(&upgrade.stringValues, "set-string", []string{}, "set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.StringArrayVar(&upgrade.fileValues, "set-file", []string{}, "set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)")
f.BoolVar(&upgrade.disableHooks, "disable-hooks", false, "disable pre/post upgrade hooks. DEPRECATED. Use no-hooks") f.BoolVar(&upgrade.disableHooks, "disable-hooks", false, "disable pre/post upgrade hooks. DEPRECATED. Use no-hooks")
f.BoolVar(&upgrade.disableHooks, "no-hooks", false, "disable pre/post upgrade hooks") f.BoolVar(&upgrade.disableHooks, "no-hooks", false, "disable pre/post upgrade hooks")
f.BoolVar(&upgrade.verify, "verify", false, "verify the provenance of the chart before upgrading") f.BoolVar(&upgrade.verify, "verify", false, "verify the provenance of the chart before upgrading")
@ -189,6 +193,7 @@ func (u *upgradeCmd) run() error {
keyring: u.keyring, keyring: u.keyring,
values: u.values, values: u.values,
stringValues: u.stringValues, stringValues: u.stringValues,
fileValues: u.fileValues,
namespace: u.namespace, namespace: u.namespace,
timeout: u.timeout, timeout: u.timeout,
wait: u.wait, wait: u.wait,
@ -198,7 +203,7 @@ func (u *upgradeCmd) run() error {
} }
} }
rawVals, err := vals(u.valueFiles, u.values, u.stringValues, u.certFile, u.keyFile, u.caFile) rawVals, err := vals(u.valueFiles, u.values, u.stringValues, u.fileValues, u.certFile, u.keyFile, u.caFile)
if err != nil { if err != nil {
return err return err
} }

@ -93,6 +93,7 @@ There are three potential sources of values:
- A chart's `values.yaml` file - A chart's `values.yaml` file
- A values file supplied by `helm install -f` or `helm upgrade -f` - A values file supplied by `helm install -f` or `helm upgrade -f`
- The values passed to a `--set` or `--set-string` flag on `helm install` or `helm upgrade` - The values passed to a `--set` or `--set-string` flag on `helm install` or `helm upgrade`
- The content of a file passed to `--set-file` flag on `helm install` or `helm upgrade`
When designing the structure of your values, keep in mind that users of your When designing the structure of your values, keep in mind that users of your
chart may want to override them via either the `-f` flag or with the `--set` chart may want to override them via either the `-f` flag or with the `--set`

@ -12,8 +12,10 @@ The install argument must be a chart reference, a path to a packaged chart,
a path to an unpacked chart directory or a URL. a path to an unpacked chart directory or a URL.
To override values in a chart, use either the '--values' flag and pass in a file To override values in a chart, use either the '--values' flag and pass in a file
or use the '--set' flag and pass configuration from the command line, to force or use the '--set' flag and pass configuration from the command line. To force string
a string value use '--set-string'. values in '--set', use '--set-string' instead. In case a value is large and therefore
you want not to use neither '--values' nor '--set', use '--set-file' to read the
single large value from file.
$ helm install -f myvalues.yaml ./redis $ helm install -f myvalues.yaml ./redis
@ -25,6 +27,9 @@ or
$ helm install --set-string long_int=1234567890 ./redis $ helm install --set-string long_int=1234567890 ./redis
or
$ helm install --set-file multiline_text=path/to/textfile
You can specify the '--values'/'-f' flag multiple times. The priority will be given to the You can specify the '--values'/'-f' flag multiple times. The priority will be given to the
last (right-most) file specified. For example, if both myvalues.yaml and override.yaml last (right-most) file specified. For example, if both myvalues.yaml and override.yaml
contained a key called 'Test', the value set in override.yaml would take precedence: contained a key called 'Test', the value set in override.yaml would take precedence:
@ -91,6 +96,7 @@ helm install [CHART]
--replace re-use the given name, even if that name is already used. This is unsafe in production --replace re-use the given name, even if that name is already used. This is unsafe in production
--repo string chart repository url where to locate the requested chart --repo string chart repository url where to locate the requested chart
--set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
--set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--timeout int time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300) --timeout int time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300)
--tls enable TLS for request --tls enable TLS for request
@ -120,4 +126,4 @@ helm install [CHART]
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 17-Jun-2018 ###### Auto generated by spf13/cobra on 17-Jul-2018

@ -23,6 +23,7 @@ helm lint [flags] PATH
``` ```
--namespace string namespace to put the release into (default "default") --namespace string namespace to put the release into (default "default")
--set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
--set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--strict fail on lint warnings --strict fail on lint warnings
-f, --values valueFiles specify values in a YAML file (can specify multiple) (default []) -f, --values valueFiles specify values in a YAML file (can specify multiple) (default [])
@ -43,4 +44,4 @@ helm lint [flags] PATH
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 17-Jun-2018 ###### Auto generated by spf13/cobra on 25-Jul-2018

@ -34,6 +34,7 @@ helm template [flags] CHART
--notes show the computed NOTES.txt file as well --notes show the computed NOTES.txt file as well
--output-dir string writes the executed templates to files in output-dir instead of stdout --output-dir string writes the executed templates to files in output-dir instead of stdout
--set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
--set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
-f, --values valueFiles specify values in a YAML file (can specify multiple) (default []) -f, --values valueFiles specify values in a YAML file (can specify multiple) (default [])
``` ```
@ -53,4 +54,4 @@ helm template [flags] CHART
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 17-Jun-2018 ###### Auto generated by spf13/cobra on 17-Jul-2018

@ -14,8 +14,10 @@ a packaged chart, or a fully qualified URL. For chart references, the latest
version will be specified unless the '--version' flag is set. version will be specified unless the '--version' flag is set.
To override values in a chart, use either the '--values' flag and pass in a file To override values in a chart, use either the '--values' flag and pass in a file
or use the '--set' flag and pass configuration from the command line, to force string or use the '--set' flag and pass configuration from the command line. To force string
values, use '--set-string'. values in '--set', use '--set-string' instead. In case a value is large and therefore
you want not to use neither '--values' nor '--set', use '--set-file' to read the
single large value from file.
You can specify the '--values'/'-f' flag multiple times. The priority will be given to the You can specify the '--values'/'-f' flag multiple times. The priority will be given to the
last (right-most) file specified. For example, if both myvalues.yaml and override.yaml last (right-most) file specified. For example, if both myvalues.yaml and override.yaml
@ -54,6 +56,7 @@ helm upgrade [RELEASE] [CHART]
--reset-values when upgrading, reset the values to the ones built into the chart --reset-values when upgrading, reset the values to the ones built into the chart
--reuse-values when upgrading, reuse the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' is specified, this is ignored. --reuse-values when upgrading, reuse the last release's values and merge in any overrides from the command line via --set and -f. If '--reset-values' is specified, this is ignored.
--set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
--set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--timeout int time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300) --timeout int time in seconds to wait for any individual Kubernetes operation (like Jobs for hooks) (default 300)
--tls enable TLS for request --tls enable TLS for request
@ -83,4 +86,4 @@ helm upgrade [RELEASE] [CHART]
### SEE ALSO ### SEE ALSO
* [helm](helm.md) - The Helm package manager for Kubernetes. * [helm](helm.md) - The Helm package manager for Kubernetes.
###### Auto generated by spf13/cobra on 17-Jun-2018 ###### Auto generated by spf13/cobra on 17-May-2018

@ -227,7 +227,7 @@ There are two ways to pass configuration data during install:
- `--values` (or `-f`): Specify a YAML file with overrides. This can be specified multiple times - `--values` (or `-f`): Specify a YAML file with overrides. This can be specified multiple times
and the rightmost file will take precedence and the rightmost file will take precedence
- `--set`: Specify overrides on the command line. - `--set` (and its variants `--set-string` and `--set-file`): Specify overrides on the command line.
If both are used, `--set` values are merged into `--values` with higher precedence. If both are used, `--set` values are merged into `--values` with higher precedence.
Overrides specified with `--set` are persisted in a configmap. Values that have been Overrides specified with `--set` are persisted in a configmap. Values that have been
@ -304,6 +304,35 @@ Deeply nested data structures can be difficult to express using `--set`. Chart
designers are encouraged to consider the `--set` usage when designing the format designers are encouraged to consider the `--set` usage when designing the format
of a `values.yaml` file. of a `values.yaml` file.
Helm will cast certain values specified with `--set` to integers.
For example, `--set foo=true` results Helm to cast `true` into an int64 value.
In case you want a string, use a `--set`'s variant named `--set-string`. `--set-string foo=true` results in a string value of `"true"`.
`--set-file key=filepath` is another variant of `--set`.
It reads the file and use its content as a value.
An example use case of it is to inject a multi-line text into values without dealing with indentation in YAML.
Say you want to create a [brigade](https://github.com/Azure/brigade) project with certain value containing 5 lines JavaScript code, you might write a `values.yaml` like:
```yaml
defaultScript: |
const { events, Job } = require("brigadier")
function run(e, project) {
console.log("hello default script")
}
events.on("run", run)
```
Being embedded in a YAML, this makes it harder for you to use IDE features and testing framework and so on that supports writing code.
Instead, you can use `--set-file defaultScript=brigade.js` with `brigade.js` containing:
```javascript
const { events, Job } = require("brigadier")
function run(e, project) {
console.log("hello default script")
}
events.on("run", run)
```
### More Installation Methods ### More Installation Methods
The `helm install` command can install from several sources: The `helm install` command can install from several sources:

@ -50,6 +50,20 @@ func Parse(s string) (map[string]interface{}, error) {
return vals, err return vals, err
} }
// ParseFile parses a set line, but its final value is loaded from the file at the path specified by the original value.
//
// A set line is of the form name1=path1,name2=path2
//
// When the files at path1 and path2 contained "val1" and "val2" respectively, the set line is consumed as
// name1=val1,name2=val2
func ParseFile(s string, runesToVal runesToVal) (map[string]interface{}, error) {
vals := map[string]interface{}{}
scanner := bytes.NewBufferString(s)
t := newFileParser(scanner, vals, runesToVal)
err := t.parse()
return vals, err
}
// ParseString parses a set line and forces a string value. // ParseString parses a set line and forces a string value.
// //
// A set line is of the form name1=value1,name2=value2 // A set line is of the form name1=value1,name2=value2
@ -71,6 +85,15 @@ func ParseInto(s string, dest map[string]interface{}) error {
return t.parse() return t.parse()
} }
// ParseIntoFile parses a filevals line and merges the result into dest.
//
// This method always returns a string as the value.
func ParseIntoFile(s string, dest map[string]interface{}, runesToVal runesToVal) error {
scanner := bytes.NewBufferString(s)
t := newFileParser(scanner, dest, runesToVal)
return t.parse()
}
// ParseIntoString parses a strvals line nad merges the result into dest. // ParseIntoString parses a strvals line nad merges the result into dest.
// //
// This method always returns a string as the value. // This method always returns a string as the value.
@ -89,11 +112,20 @@ func ParseIntoString(s string, dest map[string]interface{}) error {
type parser struct { type parser struct {
sc *bytes.Buffer sc *bytes.Buffer
data map[string]interface{} data map[string]interface{}
st bool runesToVal runesToVal
} }
type runesToVal func([]rune) (interface{}, error)
func newParser(sc *bytes.Buffer, data map[string]interface{}, stringBool bool) *parser { func newParser(sc *bytes.Buffer, data map[string]interface{}, stringBool bool) *parser {
return &parser{sc: sc, data: data, st: stringBool} rs2v := func(rs []rune) (interface{}, error) {
return typedVal(rs, stringBool), nil
}
return &parser{sc: sc, data: data, runesToVal: rs2v}
}
func newFileParser(sc *bytes.Buffer, data map[string]interface{}, runesToVal runesToVal) *parser {
return &parser{sc: sc, data: data, runesToVal: runesToVal}
} }
func (t *parser) parse() error { func (t *parser) parse() error {
@ -157,8 +189,12 @@ func (t *parser) key(data map[string]interface{}) error {
set(data, string(k), "") set(data, string(k), "")
return e return e
case ErrNotList: case ErrNotList:
v, e := t.val() rs, e := t.val()
set(data, string(k), typedVal(v, t.st)) if e != nil && e != io.EOF {
return e
}
v, e := t.runesToVal(rs)
set(data, string(k), v)
return e return e
default: default:
return e return e
@ -230,8 +266,12 @@ func (t *parser) listItem(list []interface{}, i int) ([]interface{}, error) {
case io.EOF: case io.EOF:
return setIndex(list, i, ""), err return setIndex(list, i, ""), err
case ErrNotList: case ErrNotList:
v, e := t.val() rs, e := t.val()
return setIndex(list, i, typedVal(v, t.st)), e if e != nil && e != io.EOF {
return list, e
}
v, e := t.runesToVal(rs)
return setIndex(list, i, v), e
default: default:
return list, e return list, e
} }
@ -279,7 +319,7 @@ func (t *parser) valList() ([]interface{}, error) {
list := []interface{}{} list := []interface{}{}
stop := runeSet([]rune{',', '}'}) stop := runeSet([]rune{',', '}'})
for { for {
switch v, last, err := runesUntil(t.sc, stop); { switch rs, last, err := runesUntil(t.sc, stop); {
case err != nil: case err != nil:
if err == io.EOF { if err == io.EOF {
err = errors.New("list must terminate with '}'") err = errors.New("list must terminate with '}'")
@ -290,10 +330,15 @@ func (t *parser) valList() ([]interface{}, error) {
if r, _, e := t.sc.ReadRune(); e == nil && r != ',' { if r, _, e := t.sc.ReadRune(); e == nil && r != ',' {
t.sc.UnreadRune() t.sc.UnreadRune()
} }
list = append(list, typedVal(v, t.st)) v, e := t.runesToVal(rs)
return list, nil list = append(list, v)
return list, e
case last == ',': case last == ',':
list = append(list, typedVal(v, t.st)) v, e := t.runesToVal(rs)
if e != nil {
return list, e
}
list = append(list, v)
} }
} }
} }

@ -416,6 +416,39 @@ func TestParseIntoString(t *testing.T) {
} }
} }
func TestParseIntoFile(t *testing.T) {
got := map[string]interface{}{}
input := "name1=path1"
expect := map[string]interface{}{
"name1": "value1",
}
rs2v := func(rs []rune) (interface{}, error) {
v := string(rs)
if v != "path1" {
t.Errorf("%s: runesToVal: Expected value path1, got %s", input, v)
return "", nil
}
return "value1", nil
}
if err := ParseIntoFile(input, got, rs2v); err != nil {
t.Fatal(err)
}
y1, err := yaml.Marshal(expect)
if err != nil {
t.Fatal(err)
}
y2, err := yaml.Marshal(got)
if err != nil {
t.Fatalf("Error serializing parsed value: %s", err)
}
if string(y1) != string(y2) {
t.Errorf("%s: Expected:\n%s\nGot:\n%s", input, y1, y2)
}
}
func TestToYAML(t *testing.T) { func TestToYAML(t *testing.T) {
// The TestParse does the hard part. We just verify that YAML formatting is // The TestParse does the hard part. We just verify that YAML formatting is
// happening. // happening.

Loading…
Cancel
Save