From 1abf6aa0da66470bbf6092532951df6b3517bc49 Mon Sep 17 00:00:00 2001 From: Forest Eckhardt Date: Tue, 10 Sep 2024 17:27:31 +0000 Subject: [PATCH] Adds enviroment structure to allow for thread safe unit testing --- detect.go | 9 ++---- detect_test.go | 12 ++++--- environment.go | 7 +++++ generate_configuration_parser.go | 25 +++++++++------ generate_configuration_parser_test.go | 45 +++++++++++---------------- go.mod | 1 + go.sum | 2 ++ run/main.go | 13 ++++++-- 8 files changed, 65 insertions(+), 49 deletions(-) create mode 100644 environment.go diff --git a/detect.go b/detect.go index 1cba1ae..2565617 100644 --- a/detect.go +++ b/detect.go @@ -1,16 +1,13 @@ package gogenerate import ( - "os" - "github.com/paketo-buildpacks/packit/v2" ) -func Detect() packit.DetectFunc { +func Detect(generateEnvironement GenerateEnvironment) packit.DetectFunc { return func(context packit.DetectContext) (packit.DetectResult, error) { - run := os.Getenv("BP_GO_GENERATE") - if run != "true" { - return packit.DetectResult{}, packit.Fail.WithMessage("BP_GO_GENERATE is empty") + if !generateEnvironement.RunGoGenerate { + return packit.DetectResult{}, packit.Fail.WithMessage("BP_GO_GENERATE is not truthy") } return packit.DetectResult{}, nil diff --git a/detect_test.go b/detect_test.go index 4eec877..7300933 100644 --- a/detect_test.go +++ b/detect_test.go @@ -24,9 +24,9 @@ func testDetect(t *testing.T, context spec.G, it spec.S) { workingDir, err = os.MkdirTemp("", "working-dir") Expect(err).NotTo(HaveOccurred()) - os.Setenv("BP_GO_GENERATE", "true") - - detect = gogenerate.Detect() + detect = gogenerate.Detect(gogenerate.GenerateEnvironment{ + RunGoGenerate: true, + }) }) it.After(func() { @@ -43,14 +43,16 @@ func testDetect(t *testing.T, context spec.G, it spec.S) { context("when BP_GO_GENERATE is empty", func() { it.Before(func() { - os.Unsetenv("BP_GO_GENERATE") + detect = gogenerate.Detect(gogenerate.GenerateEnvironment{ + RunGoGenerate: false, + }) }) it("fails detection", func() { _, err := detect(packit.DetectContext{ WorkingDir: workingDir, }) - Expect(err).To(MatchError(packit.Fail.WithMessage("BP_GO_GENERATE is empty"))) + Expect(err).To(MatchError(packit.Fail.WithMessage("BP_GO_GENERATE is not truthy"))) }) }) } diff --git a/environment.go b/environment.go new file mode 100644 index 0000000..a369761 --- /dev/null +++ b/environment.go @@ -0,0 +1,7 @@ +package gogenerate + +type GenerateEnvironment struct { + RunGoGenerate bool `env:BP_GO_GENERATE` + GoGenerateArgs string `env:BP_GO_GENERATE_ARGS` + GoGenerateFlags string `env:BP_GO_GENERATE_FLAGS` +} diff --git a/generate_configuration_parser.go b/generate_configuration_parser.go index dd6602f..685ec5a 100644 --- a/generate_configuration_parser.go +++ b/generate_configuration_parser.go @@ -2,7 +2,6 @@ package gogenerate import ( "fmt" - "os" "github.com/mattn/go-shellwords" ) @@ -13,10 +12,18 @@ type GenerateConfiguration struct { } type GenerateConfigurationParser struct { + generateEnvironment GenerateEnvironment } -func NewGenerateConfigurationParser() GenerateConfigurationParser { - return GenerateConfigurationParser{} +func NewGenerateConfigurationParser(generateEnvironment GenerateEnvironment) GenerateConfigurationParser { + return GenerateConfigurationParser{ + generateEnvironment: generateEnvironment, + } +} + +func (p GenerateConfigurationParser) WithEnvironment(generateEnvironment GenerateEnvironment) GenerateConfigurationParser { + p.generateEnvironment = generateEnvironment + return p } func (p GenerateConfigurationParser) Parse() (GenerateConfiguration, error) { @@ -30,19 +37,19 @@ func (p GenerateConfigurationParser) Parse() (GenerateConfiguration, error) { shellwordsParser.ParseEnv = true generateConfiguration.Args = []string{"./..."} - if val, ok := os.LookupEnv("BP_GO_GENERATE_ARGS"); ok { - generateConfiguration.Args, err = shellwordsParser.Parse(val) + if p.generateEnvironment.GoGenerateArgs != "" { + generateConfiguration.Args, err = shellwordsParser.Parse(p.generateEnvironment.GoGenerateArgs) if err != nil { - return GenerateConfiguration{}, fmt.Errorf("BP_GO_GENERATE_ARGS=%q: %w", val, err) + return GenerateConfiguration{}, fmt.Errorf("BP_GO_GENERATE_ARGS=%q: %w", p.generateEnvironment.GoGenerateArgs, err) } } - if val, ok := os.LookupEnv("BP_GO_GENERATE_FLAGS"); ok { - generateConfiguration.Flags, err = shellwordsParser.Parse(val) + if p.generateEnvironment.GoGenerateFlags != "" { + generateConfiguration.Flags, err = shellwordsParser.Parse(p.generateEnvironment.GoGenerateFlags) if err != nil { - return GenerateConfiguration{}, fmt.Errorf("BP_GO_GENERATE_FLAGS=%q: %w", val, err) + return GenerateConfiguration{}, fmt.Errorf("BP_GO_GENERATE_FLAGS=%q: %w", p.generateEnvironment.GoGenerateFlags, err) } } return generateConfiguration, nil diff --git a/generate_configuration_parser_test.go b/generate_configuration_parser_test.go index 8bfdf2b..4f86340 100644 --- a/generate_configuration_parser_test.go +++ b/generate_configuration_parser_test.go @@ -1,7 +1,6 @@ package gogenerate_test import ( - "os" "testing" gogenerate "github.com/paketo-buildpacks/go-generate" @@ -18,16 +17,14 @@ func testGenerateConfigurationParser(t *testing.T, context spec.G, it spec.S) { ) it.Before(func() { - parser = gogenerate.NewGenerateConfigurationParser() + parser = gogenerate.NewGenerateConfigurationParser(gogenerate.GenerateEnvironment{}) }) context("BP_GO_GENERATE_ARGS is set", func() { it.Before(func() { - os.Setenv("BP_GO_GENERATE_ARGS", "somemodule othermodule") - }) - - it.After(func() { - os.Unsetenv("BP_GO_GENERATE_ARGS") + parser = parser.WithEnvironment(gogenerate.GenerateEnvironment{ + GoGenerateArgs: "somemodule othermodule", + }) }) it("uses the values in the env var", func() { @@ -37,7 +34,7 @@ func testGenerateConfigurationParser(t *testing.T, context spec.G, it spec.S) { Args: []string{"somemodule", "othermodule"}, })) }) - }, spec.Sequential()) + }) context("BP_GO_GENERATE_ARGS is NOT set", func() { it("uses the default value", func() { @@ -47,15 +44,13 @@ func testGenerateConfigurationParser(t *testing.T, context spec.G, it spec.S) { Args: []string{"./..."}, })) }) - }, spec.Sequential()) + }) context("BP_GO_GENERATE_FLAGS is set", func() { it.Before(func() { - os.Setenv("BP_GO_GENERATE_FLAGS", `-run="^//go:generate go get" -n`) - }) - - it.After(func() { - os.Unsetenv("BP_GO_GENERATE_FLAGS") + parser = parser.WithEnvironment(gogenerate.GenerateEnvironment{ + GoGenerateFlags: `-run="^//go:generate go get" -n`, + }) }) it("uses the values in the env var", func() { @@ -66,38 +61,34 @@ func testGenerateConfigurationParser(t *testing.T, context spec.G, it spec.S) { Flags: []string{`-run=^//go:generate go get`, "-n"}, })) }) - }, spec.Sequential()) + }) context("failure cases", func() { context("generate args fail to parse", func() { it.Before(func() { - os.Setenv("BP_GO_GENERATE_ARGS", "\"") + parser = parser.WithEnvironment(gogenerate.GenerateEnvironment{ + GoGenerateArgs: "\"", + }) }) it("returns an error", func() { _, err := parser.Parse() Expect(err).To(MatchError(ContainSubstring(`BP_GO_GENERATE_ARGS="\"": invalid command line string`))) }) - - it.After(func() { - os.Unsetenv("BP_GO_GENERATE_ARGS") - }) - }, spec.Sequential()) + }) context("generate flags fail to parse", func() { it.Before(func() { - os.Setenv("BP_GO_GENERATE_FLAGS", "\"") + parser = parser.WithEnvironment(gogenerate.GenerateEnvironment{ + GoGenerateFlags: "\"", + }) }) it("returns an error", func() { _, err := parser.Parse() Expect(err).To(MatchError(ContainSubstring(`BP_GO_GENERATE_FLAGS="\"": invalid command line string`))) }) - - it.After(func() { - os.Unsetenv("BP_GO_GENERATE_ARGS") - }) - }, spec.Sequential()) + }) }) } diff --git a/go.mod b/go.mod index 877d897..f3518ee 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( github.com/ForestEckhardt/freezer v0.1.0 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/caarlos0/env/v6 v6.10.1 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/containerd/log v0.1.0 // indirect github.com/containerd/platforms v0.2.1 // indirect diff --git a/go.sum b/go.sum index 5889c93..4ebcdb7 100644 --- a/go.sum +++ b/go.sum @@ -1021,6 +1021,8 @@ github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacM github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bytecodealliance/wasmtime-go v0.36.0/go.mod h1:q320gUxqyI8yB+ZqRuaJOEnGkAnHh6WtJjMaT2CW4wI= github.com/caarlos0/ctrlc v1.0.0/go.mod h1:CdXpj4rmq0q/1Eb44M9zi2nKB0QraNKuRGYGrrHhcQw= +github.com/caarlos0/env/v6 v6.10.1 h1:t1mPSxNpei6M5yAeu1qtRdPAK29Nbcf/n3G7x+b3/II= +github.com/caarlos0/env/v6 v6.10.1/go.mod h1:hvp/ryKXKipEkcuYjs9mI4bBCg+UI0Yhgm5Zu0ddvwc= github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMSc6E5ydlp5NIonxObaeu/Iub/X03EKPVYo= github.com/carolynvs/magex v0.9.0/go.mod h1:H1LW6RYJ/sNbisMmPe9E73aJZa8geKLKK9mBWLWz3ek= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= diff --git a/run/main.go b/run/main.go index c936752..8f3f5c0 100644 --- a/run/main.go +++ b/run/main.go @@ -1,8 +1,10 @@ package main import ( + "fmt" "os" + "github.com/caarlos0/env/v6" gogenerate "github.com/paketo-buildpacks/go-generate" "github.com/paketo-buildpacks/packit/v2" "github.com/paketo-buildpacks/packit/v2/chronos" @@ -13,10 +15,17 @@ import ( func main() { logger := scribe.NewLogger(os.Stdout) + var generateEnvironment gogenerate.GenerateEnvironment + err := env.Parse(&generateEnvironment) + if err != nil { + fmt.Fprintln(os.Stderr, fmt.Errorf("failed to parse build configuration: %w", err)) + os.Exit(1) + } + packit.Run( - gogenerate.Detect(), + gogenerate.Detect(generateEnvironment), gogenerate.Build( - gogenerate.NewGenerateConfigurationParser(), + gogenerate.NewGenerateConfigurationParser(generateEnvironment), gogenerate.NewGenerate( pexec.NewExecutable("go"), logger,