1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Vendor mattn/go-shellwords

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
This commit is contained in:
Vincent Demeester 2015-10-05 00:17:44 +02:00
parent 1eafc7264c
commit b09a452c1f
6 changed files with 227 additions and 0 deletions

View file

@ -13,6 +13,7 @@ clone git github.com/go-check/check 11d3bc7aa68e238947792f30573146a3231fc0f1
clone git github.com/gorilla/context 14f550f51a
clone git github.com/gorilla/mux e444e69cbd
clone git github.com/kr/pty 5cf931ef8f
clone git github.com/mattn/go-shellwords v1.0.0
clone git github.com/mattn/go-sqlite3 v1.1.0
clone git github.com/microsoft/hcsshim de43b42b5ce14dfdcbeedb0628b0032174d89caa
clone git github.com/mistifyio/go-zfs v2.1.1

View file

@ -0,0 +1,9 @@
language: go
go:
- tip
before_install:
- go get github.com/axw/gocov/gocov
- go get github.com/mattn/goveralls
- go get golang.org/x/tools/cmd/cover
script:
- $HOME/gopath/bin/goveralls -repotoken 2FMhp57u8LcstKL9B190fLTcEnBtAAiEL

View file

@ -0,0 +1,47 @@
# go-shellwords
[![Coverage Status](https://coveralls.io/repos/mattn/go-shellwords/badge.png?branch=master)](https://coveralls.io/r/mattn/go-shellwords?branch=master)
[![Build Status](https://travis-ci.org/mattn/go-shellwords.svg?branch=master)](https://travis-ci.org/mattn/go-shellwords)
Parse line as shell words.
## Usage
```go
args, err := shellwords.Parse("./foo --bar=baz")
// args should be ["./foo", "--bar=baz"]
```
```go
os.Setenv("FOO", "bar")
p := shellwords.NewParser()
p.ParseEnv = true
args, err := p.Parse("./foo $FOO")
// args should be ["./foo", "bar"]
```
```go
p := shellwords.NewParser()
p.ParseBacktick = true
args, err := p.Parse("./foo `echo $SHELL`")
// args should be ["./foo", "/bin/bash"]
```
```go
shellwords.ParseBacktick = true
p := shellwords.NewParser()
args, err := p.Parse("./foo `echo $SHELL`")
// args should be ["./foo", "/bin/bash"]
```
# Thanks
This is based on cpan module [Parse::CommandLine](https://metacpan.org/pod/Parse::CommandLine).
# License
under the MIT License: http://mattn.mit-license.org/2014
# Author
Yasuhiro Matsumoto (a.k.a mattn)

View file

@ -0,0 +1,134 @@
package shellwords
import (
"errors"
"os"
"regexp"
"strings"
)
var (
ParseEnv bool = false
ParseBacktick bool = false
)
var envRe = regexp.MustCompile(`\$({[a-zA-Z0-9_]+}|[a-zA-Z0-9_]+)`)
func isSpace(r rune) bool {
switch r {
case ' ', '\t', '\r', '\n':
return true
}
return false
}
func replaceEnv(s string) string {
return envRe.ReplaceAllStringFunc(s, func(s string) string {
s = s[1:]
if s[0] == '{' {
s = s[1 : len(s)-1]
}
return os.Getenv(s)
})
}
type Parser struct {
ParseEnv bool
ParseBacktick bool
}
func NewParser() *Parser {
return &Parser{ParseEnv, ParseBacktick}
}
func (p *Parser) Parse(line string) ([]string, error) {
line = strings.TrimSpace(line)
args := []string{}
buf := ""
var escaped, doubleQuoted, singleQuoted, backQuote bool
backtick := ""
for _, r := range line {
if escaped {
buf += string(r)
escaped = false
continue
}
if r == '\\' {
if singleQuoted {
buf += string(r)
} else {
escaped = true
}
continue
}
if isSpace(r) {
if singleQuoted || doubleQuoted || backQuote {
buf += string(r)
backtick += string(r)
} else if buf != "" {
if p.ParseEnv {
buf = replaceEnv(buf)
}
args = append(args, buf)
buf = ""
}
continue
}
switch r {
case '`':
if !singleQuoted && !doubleQuoted {
if p.ParseBacktick {
if backQuote {
out, err := shellRun(backtick)
if err != nil {
return nil, err
}
buf = out
}
backtick = ""
backQuote = !backQuote
continue
}
backtick = ""
backQuote = !backQuote
}
case '"':
if !singleQuoted {
doubleQuoted = !doubleQuoted
continue
}
case '\'':
if !doubleQuoted {
singleQuoted = !singleQuoted
continue
}
}
buf += string(r)
if backQuote {
backtick += string(r)
}
}
if buf != "" {
if p.ParseEnv {
buf = replaceEnv(buf)
}
args = append(args, buf)
}
if escaped || singleQuoted || doubleQuoted || backQuote {
return nil, errors.New("invalid command line string")
}
return args, nil
}
func Parse(line string) ([]string, error) {
return NewParser().Parse(line)
}

View file

@ -0,0 +1,19 @@
// +build !windows
package shellwords
import (
"errors"
"os"
"os/exec"
"strings"
)
func shellRun(line string) (string, error) {
shell := os.Getenv("SHELL")
b, err := exec.Command(shell, "-c", line).Output()
if err != nil {
return "", errors.New(err.Error() + ":" + string(b))
}
return strings.TrimSpace(string(b)), nil
}

View file

@ -0,0 +1,17 @@
package shellwords
import (
"errors"
"os"
"os/exec"
"strings"
)
func shellRun(line string) (string, error) {
shell := os.Getenv("COMSPEC")
b, err := exec.Command(shell, "/c", line).Output()
if err != nil {
return "", errors.New(err.Error() + ":" + string(b))
}
return strings.TrimSpace(string(b)), nil
}