commit
64511e0ebf
|
@ -28,7 +28,7 @@ func NewLex(escapeToken rune) *Lex {
|
||||||
// ProcessWord will use the 'env' list of environment variables,
|
// ProcessWord will use the 'env' list of environment variables,
|
||||||
// and replace any env var references in 'word'.
|
// and replace any env var references in 'word'.
|
||||||
func (s *Lex) ProcessWord(word string, env []string) (string, error) {
|
func (s *Lex) ProcessWord(word string, env []string) (string, error) {
|
||||||
word, _, err := s.process(word, env)
|
word, _, err := s.process(word, buildEnvs(env))
|
||||||
return word, err
|
return word, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,11 +40,18 @@ func (s *Lex) ProcessWord(word string, env []string) (string, error) {
|
||||||
// Note, each one is trimmed to remove leading and trailing spaces (unless
|
// Note, each one is trimmed to remove leading and trailing spaces (unless
|
||||||
// they are quoted", but ProcessWord retains spaces between words.
|
// they are quoted", but ProcessWord retains spaces between words.
|
||||||
func (s *Lex) ProcessWords(word string, env []string) ([]string, error) {
|
func (s *Lex) ProcessWords(word string, env []string) ([]string, error) {
|
||||||
_, words, err := s.process(word, env)
|
_, words, err := s.process(word, buildEnvs(env))
|
||||||
return words, err
|
return words, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Lex) process(word string, env []string) (string, []string, error) {
|
// ProcessWordWithMap will use the 'env' list of environment variables,
|
||||||
|
// and replace any env var references in 'word'.
|
||||||
|
func (s *Lex) ProcessWordWithMap(word string, env map[string]string) (string, error) {
|
||||||
|
word, _, err := s.process(word, env)
|
||||||
|
return word, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Lex) process(word string, env map[string]string) (string, []string, error) {
|
||||||
sw := &shellWord{
|
sw := &shellWord{
|
||||||
envs: env,
|
envs: env,
|
||||||
escapeToken: s.escapeToken,
|
escapeToken: s.escapeToken,
|
||||||
|
@ -55,7 +62,7 @@ func (s *Lex) process(word string, env []string) (string, []string, error) {
|
||||||
|
|
||||||
type shellWord struct {
|
type shellWord struct {
|
||||||
scanner scanner.Scanner
|
scanner scanner.Scanner
|
||||||
envs []string
|
envs map[string]string
|
||||||
escapeToken rune
|
escapeToken rune
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,21 +360,33 @@ func isSpecialParam(char rune) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sw *shellWord) getEnv(name string) string {
|
func (sw *shellWord) getEnv(name string) string {
|
||||||
for _, env := range sw.envs {
|
for key, value := range sw.envs {
|
||||||
i := strings.Index(env, "=")
|
if EqualEnvKeys(name, key) {
|
||||||
if i < 0 {
|
return value
|
||||||
if EqualEnvKeys(name, env) {
|
|
||||||
// Should probably never get here, but just in case treat
|
|
||||||
// it like "var" and "var=" are the same
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
compareName := env[:i]
|
|
||||||
if !EqualEnvKeys(name, compareName) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return env[i+1:]
|
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func buildEnvs(env []string) map[string]string {
|
||||||
|
envs := map[string]string{}
|
||||||
|
|
||||||
|
for _, e := range env {
|
||||||
|
i := strings.Index(e, "=")
|
||||||
|
|
||||||
|
if i < 0 {
|
||||||
|
envs[e] = ""
|
||||||
|
} else {
|
||||||
|
k := e[:i]
|
||||||
|
v := e[i+1:]
|
||||||
|
|
||||||
|
// If key already exists, keep previous value.
|
||||||
|
if _, ok := envs[k]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
envs[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return envs
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ func TestShellParser4EnvVars(t *testing.T) {
|
||||||
shlex := NewLex('\\')
|
shlex := NewLex('\\')
|
||||||
scanner := bufio.NewScanner(file)
|
scanner := bufio.NewScanner(file)
|
||||||
envs := []string{"PWD=/home", "SHELL=bash", "KOREAN=한국어"}
|
envs := []string{"PWD=/home", "SHELL=bash", "KOREAN=한국어"}
|
||||||
|
envsMap := buildEnvs(envs)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
lineCount++
|
lineCount++
|
||||||
|
@ -56,6 +57,14 @@ func TestShellParser4EnvVars(t *testing.T) {
|
||||||
assert.Check(t, err, "at line %d of %s", lineCount, fn)
|
assert.Check(t, err, "at line %d of %s", lineCount, fn)
|
||||||
assert.Check(t, is.Equal(newWord, expected), "at line %d of %s", lineCount, fn)
|
assert.Check(t, is.Equal(newWord, expected), "at line %d of %s", lineCount, fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newWord, err = shlex.ProcessWordWithMap(source, envsMap)
|
||||||
|
if expected == "error" {
|
||||||
|
assert.Check(t, is.ErrorContains(err, ""), "input: %q, result: %q", source, newWord)
|
||||||
|
} else {
|
||||||
|
assert.Check(t, err, "at line %d of %s", lineCount, fn)
|
||||||
|
assert.Check(t, is.Equal(newWord, expected), "at line %d of %s", lineCount, fn)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,27 +123,27 @@ func TestShellParser4Words(t *testing.T) {
|
||||||
func TestGetEnv(t *testing.T) {
|
func TestGetEnv(t *testing.T) {
|
||||||
sw := &shellWord{envs: nil}
|
sw := &shellWord{envs: nil}
|
||||||
|
|
||||||
sw.envs = []string{}
|
sw.envs = buildEnvs([]string{})
|
||||||
if sw.getEnv("foo") != "" {
|
if sw.getEnv("foo") != "" {
|
||||||
t.Fatal("2 - 'foo' should map to ''")
|
t.Fatal("2 - 'foo' should map to ''")
|
||||||
}
|
}
|
||||||
|
|
||||||
sw.envs = []string{"foo"}
|
sw.envs = buildEnvs([]string{"foo"})
|
||||||
if sw.getEnv("foo") != "" {
|
if sw.getEnv("foo") != "" {
|
||||||
t.Fatal("3 - 'foo' should map to ''")
|
t.Fatal("3 - 'foo' should map to ''")
|
||||||
}
|
}
|
||||||
|
|
||||||
sw.envs = []string{"foo="}
|
sw.envs = buildEnvs([]string{"foo="})
|
||||||
if sw.getEnv("foo") != "" {
|
if sw.getEnv("foo") != "" {
|
||||||
t.Fatal("4 - 'foo' should map to ''")
|
t.Fatal("4 - 'foo' should map to ''")
|
||||||
}
|
}
|
||||||
|
|
||||||
sw.envs = []string{"foo=bar"}
|
sw.envs = buildEnvs([]string{"foo=bar"})
|
||||||
if sw.getEnv("foo") != "bar" {
|
if sw.getEnv("foo") != "bar" {
|
||||||
t.Fatal("5 - 'foo' should map to 'bar'")
|
t.Fatal("5 - 'foo' should map to 'bar'")
|
||||||
}
|
}
|
||||||
|
|
||||||
sw.envs = []string{"foo=bar", "car=hat"}
|
sw.envs = buildEnvs([]string{"foo=bar", "car=hat"})
|
||||||
if sw.getEnv("foo") != "bar" {
|
if sw.getEnv("foo") != "bar" {
|
||||||
t.Fatal("6 - 'foo' should map to 'bar'")
|
t.Fatal("6 - 'foo' should map to 'bar'")
|
||||||
}
|
}
|
||||||
|
@ -143,7 +152,7 @@ func TestGetEnv(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure we grab the first 'car' in the list
|
// Make sure we grab the first 'car' in the list
|
||||||
sw.envs = []string{"foo=bar", "car=hat", "car=bike"}
|
sw.envs = buildEnvs([]string{"foo=bar", "car=hat", "car=bike"})
|
||||||
if sw.getEnv("car") != "hat" {
|
if sw.getEnv("car") != "hat" {
|
||||||
t.Fatal("8 - 'car' should map to 'hat'")
|
t.Fatal("8 - 'car' should map to 'hat'")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue