From fa5fe315f85333e5e7dc0b2147cbe3aae3e4afce Mon Sep 17 00:00:00 2001 From: Illia Volochii Date: Tue, 1 May 2018 12:02:44 +0300 Subject: [PATCH] Change format from JSON to CSV --- README.md | 5 ++--- parse.go | 16 +++++----------- parse_test.go | 19 +++++-------------- 3 files changed, 12 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 362f455..8980ba1 100644 --- a/README.md +++ b/README.md @@ -94,8 +94,7 @@ $ NUM_WORKERS=4 ./example Workers: 4 ``` -You should use a JSON array of strings (value will be converted if -necessary) in the case of multiple values: +You can provide multiple values using the CSV (RFC 4180) format: ```go var args struct { @@ -106,7 +105,7 @@ fmt.Println("Workers:", args.Workers) ``` ``` -$ WORKERS='["1", "99"]' ./example +$ WORKERS='1,99' ./example Workers: [1 99] ``` diff --git a/parse.go b/parse.go index 03b6c07..1b534fd 100644 --- a/parse.go +++ b/parse.go @@ -2,7 +2,7 @@ package arg import ( "encoding" - "encoding/json" + "encoding/csv" "errors" "fmt" "os" @@ -278,18 +278,12 @@ func process(specs []*spec, args []string) error { if value, found := os.LookupEnv(spec.env); found { var err error if spec.multiple { - // expect a JSON array of strings in an environment + // expect a CSV string 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, - ) + values, err := csv.NewReader(strings.NewReader(value)).Read() + if err == nil { + err = setSlice(spec.dest, values, !spec.separate) } - err = setSlice(spec.dest, values, !spec.separate) } else { err = scalar.ParseValue(spec.dest, value) } diff --git a/parse_test.go b/parse_test.go index f263df5..56b2b45 100644 --- a/parse_test.go +++ b/parse_test.go @@ -584,16 +584,16 @@ func TestEnvironmentVariableSliceArgumentString(t *testing.T) { var args struct { Foo []string `arg:"env"` } - setenv(t, "FOO", "[\"bar\", \"baz\"]") + setenv(t, "FOO", "bar,\"baz, qux\"") MustParse(&args) - assert.Equal(t, []string{"bar", "baz"}, args.Foo) + assert.Equal(t, []string{"bar", "baz, qux"}, args.Foo) } func TestEnvironmentVariableSliceArgumentInteger(t *testing.T) { var args struct { Foo []int `arg:"env"` } - setenv(t, "FOO", "[\"1\", \"99\"]") + setenv(t, "FOO", "1,99") MustParse(&args) assert.Equal(t, []int{1, 99}, args.Foo) } @@ -602,7 +602,7 @@ func TestEnvironmentVariableSliceArgumentFloat(t *testing.T) { var args struct { Foo []float32 `arg:"env"` } - setenv(t, "FOO", "[\"1.1\", \"99.9\"]") + setenv(t, "FOO", "1.1,99.9") MustParse(&args) assert.Equal(t, []float32{1.1, 99.9}, args.Foo) } @@ -611,20 +611,11 @@ func TestEnvironmentVariableSliceArgumentBool(t *testing.T) { var args struct { Foo []bool `arg:"env"` } - setenv(t, "FOO", "[\"true\", \"false\", \"0\", \"1\"]") + setenv(t, "FOO", "true,false,0,1") MustParse(&args) assert.Equal(t, []bool{true, false, false, true}, args.Foo) } -func TestEnvironmentVariableSliceArgumentError(t *testing.T) { - var args struct { - Foo []int `arg:"env"` - } - setenv(t, "FOO", "[1, 99]") - err := Parse(&args) - assert.Error(t, err) -} - type textUnmarshaler struct { val int }