From 133fdc1f0ae5761e634d052689e92e26326cdc18 Mon Sep 17 00:00:00 2001 From: Alex Quick Date: Mon, 1 May 2017 01:48:02 -0400 Subject: [PATCH] [config] support for old export-style config files --- plugins/config/src/configenv/configenv_test.go | 11 +++++++---- plugins/config/src/configenv/parsing.go | 16 ++++++++++++---- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/plugins/config/src/configenv/configenv_test.go b/plugins/config/src/configenv/configenv_test.go index 16b3e3db0..56033f81c 100644 --- a/plugins/config/src/configenv/configenv_test.go +++ b/plugins/config/src/configenv/configenv_test.go @@ -13,11 +13,16 @@ func TestExportfileRoundtrip(t *testing.T) { Expect(env.Map()).To(Equal(pairs("Baz", "BOFF", "Foo", "Bar", "HI", "ho"))) Expect(env.String()).To(Equal("Baz='BOFF'\nFoo='Bar'\nHI='ho'")) - env, err = NewFromString("\n export HI='h\\\no\\'\n") + env, err = NewFromString("\n export HI='h\\\no\\' \n") Expect(err).NotTo(HaveOccurred()) Expect(env.Map()).To(Equal(pairs("HI", "h\\\no\\"))) Expect(env.String()).To(Equal("HI='h\\\no\\'")) + env, err = NewFromString("\n export HI=ho\n") + Expect(err).NotTo(HaveOccurred()) + Expect(env.Map()).To(Equal(pairs("HI", "ho"))) + Expect(env.String()).To(Equal("HI='ho'")) + env, err = NewFromString("HI='ho'\nFOO=''\\''\nBAR='\\'''\\'''") Expect(err).NotTo(HaveOccurred()) Expect(env.Map()).To(Equal(pairs("HI", "ho", "FOO", "'\nBAR=''"))) @@ -31,10 +36,8 @@ func TestExportfileRoundtrip(t *testing.T) { func TestExportfileErrors(t *testing.T) { RegisterTestingT(t) - _, err := NewFromString("FOO=bar") //values must be quoted - Expect(err).To(HaveOccurred()) - _, err = NewFromString("FOO='bar\\''") //single quotes are not escaped this way + _, err := NewFromString("FOO='bar\\''") //single quotes are not escaped this way Expect(err).To(HaveOccurred()) _, err = NewFromString("F\nOO='bar'") //keys cannot have embedded newlines diff --git a/plugins/config/src/configenv/parsing.go b/plugins/config/src/configenv/parsing.go index 1c8feda37..762a65358 100644 --- a/plugins/config/src/configenv/parsing.go +++ b/plugins/config/src/configenv/parsing.go @@ -6,6 +6,7 @@ import ( "errors" "io" "os" + "strings" ) func parseEnv(name string, filename string) (*Env, error) { @@ -24,7 +25,7 @@ func parseEnv(name string, filename string) (*Env, error) { } func parseEnvFromReader(name string, filename string, reader io.Reader) (*Env, error) { - //The file format looks like: `KEY='VALUE'`. Eait pair is terminated with a newline. + //The file format looks like: `KEY='VALUE'`. Each pair is terminated with a newline. //All characters are valid for VALUE without escaping but one: the single quote. //A single quote literal is represented by ending the quoting //emitting a \' and resuming the quoting. So for VALUE to be "don't care": @@ -40,6 +41,7 @@ func parseEnvFromReader(name string, filename string, reader io.Reader) (*Env, e var buffer bytes.Buffer var state = StateKey var quoted = false + var exportStyle = false var escaped = false var key = "" for char, _, err := buffered.ReadRune(); err == nil; char, _, err = buffered.ReadRune() { @@ -48,6 +50,7 @@ func parseEnvFromReader(name string, filename string, reader io.Reader) (*Env, e switch char { case ' ': if buffer.String() == "export" { + exportStyle = true buffer.Truncate(0) //so we can read exportfiles as well as envfiles } else if buffer.Len() == 0 { continue //leading spaced are allowed but not encouraged @@ -79,11 +82,16 @@ func parseEnvFromReader(name string, filename string, reader io.Reader) (*Env, e buffer.WriteRune(char) } else { state = StateKey - env.Set(key, buffer.String()) + value := buffer.String() + if exportStyle { + value = strings.TrimSpace(value) + } + env.Set(key, value) buffer.Truncate(0) key = "" escaped = false quoted = false + exportStyle = false } case '\\': if quoted { @@ -93,8 +101,8 @@ func parseEnvFromReader(name string, filename string, reader io.Reader) (*Env, e escaped = true } default: - if !quoted { - return nil, errors.New("unquoted or unbalanced value for " + key) + if !quoted && !exportStyle { + return nil, errors.New("trailing content for value of " + key) } if escaped { return nil, errors.New("invalid escape for " + key)