Fix providing multiple values via environment variables
This commit is contained in:
parent
074ee5f759
commit
75bf1a1525
16
README.md
16
README.md
|
@ -94,6 +94,22 @@ $ NUM_WORKERS=4 ./example
|
||||||
Workers: 4
|
Workers: 4
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You should use a JSON array of strings (value will be converted if
|
||||||
|
necessary) in the case of multiple values:
|
||||||
|
|
||||||
|
```go
|
||||||
|
var args struct {
|
||||||
|
Workers []int `arg:"env"`
|
||||||
|
}
|
||||||
|
arg.MustParse(&args)
|
||||||
|
fmt.Println("Workers:", args.Workers)
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
$ WORKERS='["1", "99"]' ./example
|
||||||
|
Workers: [1 99]
|
||||||
|
```
|
||||||
|
|
||||||
### Usage strings
|
### Usage strings
|
||||||
```go
|
```go
|
||||||
var args struct {
|
var args struct {
|
||||||
|
|
19
parse.go
19
parse.go
|
@ -2,6 +2,7 @@ package arg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding"
|
"encoding"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
@ -275,7 +276,23 @@ func process(specs []*spec, args []string) error {
|
||||||
}
|
}
|
||||||
if spec.env != "" {
|
if spec.env != "" {
|
||||||
if value, found := os.LookupEnv(spec.env); found {
|
if value, found := os.LookupEnv(spec.env); found {
|
||||||
err := scalar.ParseValue(spec.dest, value)
|
var err error
|
||||||
|
if spec.multiple {
|
||||||
|
// expect a JSON array of strings in an environment
|
||||||
|
// variable in the case of multiple values
|
||||||
|
var values []string
|
||||||
|
err = json.Unmarshal([]byte(value), &values)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf(
|
||||||
|
"error processing environment variable %s (it should be a JSON array of strings):\n%v",
|
||||||
|
spec.env,
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
err = setSlice(spec.dest, values, !spec.separate)
|
||||||
|
} else {
|
||||||
|
err = scalar.ParseValue(spec.dest, value)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error processing environment variable %s: %v", spec.env, err)
|
return fmt.Errorf("error processing environment variable %s: %v", spec.env, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -580,6 +580,42 @@ func TestEnvironmentVariableRequired(t *testing.T) {
|
||||||
assert.Equal(t, "bar", args.Foo)
|
assert.Equal(t, "bar", args.Foo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEnvironmentVariableSliceArgumentString(t *testing.T) {
|
||||||
|
var args struct {
|
||||||
|
Foo []string `arg:"env"`
|
||||||
|
}
|
||||||
|
setenv(t, "FOO", "[\"bar\", \"baz\"]")
|
||||||
|
MustParse(&args)
|
||||||
|
assert.Equal(t, []string{"bar", "baz"}, args.Foo)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnvironmentVariableSliceArgumentInteger(t *testing.T) {
|
||||||
|
var args struct {
|
||||||
|
Foo []int `arg:"env"`
|
||||||
|
}
|
||||||
|
setenv(t, "FOO", "[\"1\", \"99\"]")
|
||||||
|
MustParse(&args)
|
||||||
|
assert.Equal(t, []int{1, 99}, args.Foo)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnvironmentVariableSliceArgumentFloat(t *testing.T) {
|
||||||
|
var args struct {
|
||||||
|
Foo []float32 `arg:"env"`
|
||||||
|
}
|
||||||
|
setenv(t, "FOO", "[\"1.1\", \"99.9\"]")
|
||||||
|
MustParse(&args)
|
||||||
|
assert.Equal(t, []float32{1.1, 99.9}, args.Foo)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnvironmentVariableSliceArgumentBool(t *testing.T) {
|
||||||
|
var args struct {
|
||||||
|
Foo []bool `arg:"env"`
|
||||||
|
}
|
||||||
|
setenv(t, "FOO", "[\"true\", \"false\", \"0\", \"1\"]")
|
||||||
|
MustParse(&args)
|
||||||
|
assert.Equal(t, []bool{true, false, false, true}, args.Foo)
|
||||||
|
}
|
||||||
|
|
||||||
type textUnmarshaler struct {
|
type textUnmarshaler struct {
|
||||||
val int
|
val int
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue