Skip to content

Commit 55a329c

Browse files
authored
Merge pull request kubernetes-sigs#1513 from DirectXMan12/bug/quote-envtest-tool-path
🐛 Quote path with -p env in envtest-setup
2 parents d63cfde + 066b7bb commit 55a329c

File tree

3 files changed

+132
-1
lines changed

3 files changed

+132
-1
lines changed

tools/setup-envtest/env/env.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"io/fs"
1212
"path/filepath"
1313
"sort"
14+
"strings"
1415
"text/tabwriter"
1516

1617
"github.com/go-logr/logr"
@@ -372,7 +373,14 @@ func (e *Env) PrintInfo(printFmt PrintFormat) {
372373
case PrintPath:
373374
fmt.Fprint(e.Out, path) // NB(directxman12): no newline -- want the bare path here
374375
case PrintEnv:
375-
fmt.Fprintf(e.Out, "export KUBEBUILDER_ASSETS=%s\n", path)
376+
// quote in case there are spaces, etc in the path
377+
// the weird string below works like this:
378+
// - you can't escape quotes in shell
379+
// - shell strings that are next to each other are concatenated (so "a""b""c" == "abc")
380+
// - you can intermix quote styles using the above
381+
// - so `'"'"'` --> CLOSE_QUOTE + "'" + OPEN_QUOTE
382+
shellQuoted := strings.ReplaceAll(path, "'", `'"'"'`)
383+
fmt.Fprintf(e.Out, "export KUBEBUILDER_ASSETS='%s'\n", shellQuoted)
376384
default:
377385
panic(fmt.Sprintf("unexpected print format %v", printFmt))
378386
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package env_test
2+
3+
import (
4+
"testing"
5+
6+
. "github.com/onsi/ginkgo"
7+
. "github.com/onsi/gomega"
8+
9+
"github.com/go-logr/logr"
10+
"github.com/go-logr/zapr"
11+
"go.uber.org/zap"
12+
"go.uber.org/zap/zapcore"
13+
)
14+
15+
var testLog logr.Logger
16+
17+
func zapLogger() logr.Logger {
18+
testOut := zapcore.AddSync(GinkgoWriter)
19+
enc := zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig())
20+
// bleh setting up logging to the ginkgo writer is annoying
21+
zapLog := zap.New(zapcore.NewCore(enc, testOut, zap.DebugLevel),
22+
zap.ErrorOutput(testOut), zap.Development(), zap.AddStacktrace(zap.WarnLevel))
23+
return zapr.NewLogger(zapLog)
24+
}
25+
26+
func TestEnv(t *testing.T) {
27+
testLog = zapLogger()
28+
29+
RegisterFailHandler(Fail)
30+
RunSpecs(t, "Env Suite")
31+
}

tools/setup-envtest/env/env_test.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package env_test
2+
3+
import (
4+
"bytes"
5+
6+
. "github.com/onsi/ginkgo"
7+
. "github.com/onsi/gomega"
8+
"github.com/spf13/afero"
9+
10+
. "sigs.k8s.io/controller-runtime/tools/setup-envtest/env"
11+
"sigs.k8s.io/controller-runtime/tools/setup-envtest/store"
12+
"sigs.k8s.io/controller-runtime/tools/setup-envtest/versions"
13+
)
14+
15+
var _ = Describe("Env", func() {
16+
// Most of the rest of this is tested e2e via the workflows test,
17+
// but there's a few things that are easier to test here. Eventually
18+
// we should maybe move some of the tests here.
19+
var (
20+
env *Env
21+
outBuffer *bytes.Buffer
22+
)
23+
BeforeEach(func() {
24+
outBuffer = new(bytes.Buffer)
25+
env = &Env{
26+
Out: outBuffer,
27+
Log: testLog,
28+
29+
Store: &store.Store{
30+
// use spaces and quotes to test our quote escaping below
31+
Root: afero.NewBasePathFs(afero.NewMemMapFs(), "/kb's test store"),
32+
},
33+
34+
// shouldn't use these, but just in case
35+
NoDownload: true,
36+
FS: afero.Afero{Fs: afero.NewMemMapFs()},
37+
}
38+
39+
env.Version.MakeConcrete(versions.Concrete{
40+
Major: 1, Minor: 21, Patch: 3,
41+
})
42+
env.Platform.Platform = versions.Platform{
43+
OS: "linux", Arch: "amd64",
44+
}
45+
})
46+
47+
Describe("printing", func() {
48+
It("should use a manual path if one is present", func() {
49+
By("using a manual path")
50+
Expect(env.PathMatches("/otherstore/1.21.4-linux-amd64")).To(BeTrue())
51+
52+
By("checking that that path is printed properly")
53+
env.PrintInfo(PrintPath)
54+
Expect(outBuffer.String()).To(Equal("/otherstore/1.21.4-linux-amd64"))
55+
})
56+
57+
Context("as human-readable info", func() {
58+
BeforeEach(func() {
59+
env.PrintInfo(PrintOverview)
60+
})
61+
62+
It("should contain the version", func() {
63+
Expect(outBuffer.String()).To(ContainSubstring("/kb's test store/k8s/1.21.3-linux-amd64"))
64+
})
65+
It("should contain the path", func() {
66+
Expect(outBuffer.String()).To(ContainSubstring("1.21.3"))
67+
})
68+
It("should contain the platform", func() {
69+
Expect(outBuffer.String()).To(ContainSubstring("linux/amd64"))
70+
})
71+
72+
})
73+
Context("as just a path", func() {
74+
It("should print out just the path", func() {
75+
env.PrintInfo(PrintPath)
76+
Expect(outBuffer.String()).To(Equal(`/kb's test store/k8s/1.21.3-linux-amd64`))
77+
})
78+
})
79+
80+
Context("as env vars", func() {
81+
BeforeEach(func() {
82+
env.PrintInfo(PrintEnv)
83+
})
84+
It("should set KUBEBUILDER_ASSETS", func() {
85+
Expect(outBuffer.String()).To(HavePrefix("export KUBEBUILDER_ASSETS="))
86+
})
87+
It("should quote the return path, escaping quotes to deal with spaces, etc", func() {
88+
Expect(outBuffer.String()).To(HaveSuffix(`='/kb'"'"'s test store/k8s/1.21.3-linux-amd64'` + "\n"))
89+
})
90+
})
91+
})
92+
})

0 commit comments

Comments
 (0)