Skip to content

Commit

Permalink
Add a new function to parse a line containing environment variables
Browse files Browse the repository at this point in the history
  • Loading branch information
johejo committed Dec 4, 2020
1 parent 2c8720d commit e976e98
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 0 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ args, err := shellwords.Parse("./foo --bar=baz")
// args should be ["./foo", "--bar=baz"]
```

```go
envs, args, err := shellwords.ParseWithEnvs("FOO=foo BAR=baz ./foo --bar=baz")
// envs should be ["FOO=foo", "BAR=baz"]
// args should be ["./foo", "--bar=baz"]
```

```go
os.Setenv("FOO", "bar")
p := shellwords.NewParser()
Expand Down
29 changes: 29 additions & 0 deletions shellwords.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,35 @@ loop:
return args, nil
}

func (p *Parser) ParseWithEnvs(line string) (envs []string, args []string, err error) {
_args, err := p.Parse(line)
if err != nil {
return nil, nil, err
}
envs = []string{}
args = []string{}
parsingEnv := true
for _, arg := range _args {
if parsingEnv && isEnv(arg) {
envs = append(envs, arg)
} else {
if parsingEnv {
parsingEnv = false
}
args = append(args, arg)
}
}
return envs, args, nil
}

func isEnv(arg string) bool {
return len(strings.Split(arg, "=")) == 2
}

func Parse(line string) ([]string, error) {
return NewParser().Parse(line)
}

func ParseWithEnvs(line string) (envs []string, args []string, err error) {
return NewParser().ParseWithEnvs(line)
}
42 changes: 42 additions & 0 deletions shellwords_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -407,3 +407,45 @@ func TestEnvInQuoted(t *testing.T) {
t.Fatalf("Expected %#v, but %#v:", expected, args)
}
}

func TestParseWithEnvs(t *testing.T) {
tests := []struct {
line string
wantEnvs, wantArgs []string
}{
{
line: "FOO=foo cmd --args=A=B",
wantEnvs: []string{"FOO=foo"},
wantArgs: []string{"cmd", "--args=A=B"},
},
{
line: "FOO=foo BAR=bar cmd --args=A=B -A=B",
wantEnvs: []string{"FOO=foo", "BAR=bar"},
wantArgs: []string{"cmd", "--args=A=B", "-A=B"},
},
{
line: `sh -c "FOO=foo BAR=bar cmd --args=A=B -A=B"`,
wantEnvs: []string{},
wantArgs: []string{"sh", "-c", "FOO=foo BAR=bar cmd --args=A=B -A=B"},
},
{
line: "cmd --args=A=B -A=B",
wantEnvs: []string{},
wantArgs: []string{"cmd", "--args=A=B", "-A=B"},
},
}
for _, tt := range tests {
t.Run(tt.line, func(t *testing.T) {
envs, args, err := ParseWithEnvs(tt.line)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(envs, tt.wantEnvs) {
t.Errorf("Expected %#v, but %#v", tt.wantEnvs, envs)
}
if !reflect.DeepEqual(args, tt.wantArgs) {
t.Errorf("Expected %#v, but %#v", tt.wantArgs, args)
}
})
}
}

0 comments on commit e976e98

Please sign in to comment.