Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract method for generating Config #151

Merged
merged 4 commits into from
Dec 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 5 additions & 15 deletions build.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (
"github.com/Masterminds/semver"

"github.com/buildpacks/libcnb/internal"
"github.com/buildpacks/libcnb/log"
)

// BuildContext contains the inputs to build.
Expand All @@ -43,6 +42,9 @@ type BuildContext struct {
// Layers is the layers available to the buildpack.
Layers Layers

// Logger is the way to write messages to the end user
Logger Logger

// PersistentMetadata is metadata that is persisted even across cache cleaning.
PersistentMetadata map[string]interface{}

Expand Down Expand Up @@ -110,25 +112,13 @@ func (b BuildResult) String() string {
type BuildFunc func(context BuildContext) (BuildResult, error)

// Build is called by the main function of a buildpack, for build.
func Build(build BuildFunc, options ...Option) {
config := Config{
arguments: os.Args,
environmentWriter: internal.EnvironmentWriter{},
exitHandler: internal.NewExitHandler(),
logger: log.New(os.Stdout),
tomlWriter: internal.TOMLWriter{},
}

for _, option := range options {
config = option(config)
}

func Build(build BuildFunc, config Config) {
var (
err error
file string
ok bool
)
ctx := BuildContext{}
ctx := BuildContext{Logger: config.logger}

ctx.ApplicationPath, err = os.Getwd()
if err != nil {
Expand Down
146 changes: 84 additions & 62 deletions build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,10 @@ version = "1.1.1"

it("fails", func() {
libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithExitHandler(exitHandler),
libcnb.WithLogger(log.NewDiscard()),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithExitHandler(exitHandler),
libcnb.WithLogger(log.NewDiscard())),
)

if libcnb.MinSupportedBPVersion == libcnb.MaxSupportedBPVersion {
Expand Down Expand Up @@ -241,8 +242,9 @@ version = "1.1.1"

it("fails", func() {
libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath}),
libcnb.WithExitHandler(exitHandler),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath}),
libcnb.WithExitHandler(exitHandler)),
)
Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError(
fmt.Sprintf("expected %s to be set", envVar),
Expand All @@ -256,9 +258,10 @@ version = "1.1.1"
Expect(os.Unsetenv("CNB_STACK_ID")).To(Succeed())

libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithExitHandler(exitHandler),
libcnb.WithLogger(log.NewDiscard()),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithExitHandler(exitHandler),
libcnb.WithLogger(log.NewDiscard())),
)

Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError("CNB_STACK_ID not set"))
Expand Down Expand Up @@ -288,7 +291,8 @@ version = "1.1.1"

it("creates context", func() {
libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath}),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath})),
)

Expect(ctx.ApplicationPath).To(Equal(applicationPath))
Expand Down Expand Up @@ -334,9 +338,10 @@ version = "1.1.1"
Expect(os.Unsetenv("CNB_BUILDPACK_DIR")).To(Succeed())

libcnb.Build(buildFunc,
libcnb.WithArguments([]string{filepath.Join(buildpackPath, commandPath), layersPath, platformPath, buildpackPlanPath}),
libcnb.WithExitHandler(exitHandler),
libcnb.WithLogger(log.NewDiscard()),
libcnb.NewConfig(
libcnb.WithArguments([]string{filepath.Join(buildpackPath, commandPath), layersPath, platformPath, buildpackPlanPath}),
libcnb.WithExitHandler(exitHandler),
libcnb.WithLogger(log.NewDiscard())),
)

Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError("unable to get CNB_BUILDPACK_DIR, not found"))
Expand All @@ -348,9 +353,10 @@ version = "1.1.1"
}

libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithExitHandler(exitHandler),
libcnb.WithLogger(log.NewDiscard()),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithExitHandler(exitHandler),
libcnb.WithLogger(log.NewDiscard())),
)

Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError("test-error"))
Expand All @@ -364,9 +370,10 @@ version = "1.1.1"
}

libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithEnvironmentWriter(environmentWriter),
libcnb.WithLogger(log.NewDiscard()),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithEnvironmentWriter(environmentWriter),
libcnb.WithLogger(log.NewDiscard())),
)

Expect(environmentWriter.Calls[0].Arguments[0]).To(Equal(filepath.Join(layersPath, "test-name", "env.build")))
Expand All @@ -381,9 +388,10 @@ version = "1.1.1"
}

libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithEnvironmentWriter(environmentWriter),
libcnb.WithLogger(log.NewDiscard()),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithEnvironmentWriter(environmentWriter),
libcnb.WithLogger(log.NewDiscard())),
)

Expect(environmentWriter.Calls[1].Arguments[0]).To(Equal(filepath.Join(layersPath, "test-name", "env.launch")))
Expand All @@ -398,9 +406,10 @@ version = "1.1.1"
}

libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithEnvironmentWriter(environmentWriter),
libcnb.WithLogger(log.NewDiscard()),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithEnvironmentWriter(environmentWriter),
libcnb.WithLogger(log.NewDiscard())),
)

Expect(environmentWriter.Calls[2].Arguments[0]).To(Equal(filepath.Join(layersPath, "test-name", "env")))
Expand All @@ -415,9 +424,10 @@ version = "1.1.1"
}

libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithEnvironmentWriter(environmentWriter),
libcnb.WithLogger(log.NewDiscard()),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithEnvironmentWriter(environmentWriter),
libcnb.WithLogger(log.NewDiscard())),
)

Expect(environmentWriter.Calls[3].Arguments[0]).To(Equal(filepath.Join(layersPath, "test-name", "profile.d")))
Expand All @@ -440,9 +450,10 @@ version = "1.1.1"
}

libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithTOMLWriter(tomlWriter),
libcnb.WithLogger(log.NewDiscard()),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithTOMLWriter(tomlWriter),
libcnb.WithLogger(log.NewDiscard())),
)

Expect(tomlWriter.Calls[0].Arguments[0]).To(Equal(filepath.Join(layersPath, "test-name.toml")))
Expand Down Expand Up @@ -477,8 +488,9 @@ version = "1.1.1"
}

libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithTOMLWriter(tomlWriter),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithTOMLWriter(tomlWriter)),
)

Expect(tomlWriter.Calls[0].Arguments[0]).To(Equal(filepath.Join(layersPath, "launch.toml")))
Expand Down Expand Up @@ -519,9 +531,10 @@ version = "1.1.1"
}

libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithTOMLWriter(tomlWriter),
libcnb.WithLogger(log.NewDiscard()),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithTOMLWriter(tomlWriter),
libcnb.WithLogger(log.NewDiscard())),
)

Expect(tomlWriter.Calls[0].Arguments[0]).To(Equal(filepath.Join(layersPath, "launch.toml")))
Expand Down Expand Up @@ -555,9 +568,10 @@ version = "1.1.1"
}

libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithTOMLWriter(tomlWriter),
libcnb.WithLogger(log.NewDiscard()),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithTOMLWriter(tomlWriter),
libcnb.WithLogger(log.NewDiscard())),
)

Expect(tomlWriter.Calls[0].Arguments[0]).To(Equal(filepath.Join(layersPath, "store.toml")))
Expand All @@ -566,9 +580,10 @@ version = "1.1.1"

it("does not write empty files", func() {
libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithTOMLWriter(tomlWriter),
libcnb.WithLogger(log.NewDiscard()),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithTOMLWriter(tomlWriter),
libcnb.WithLogger(log.NewDiscard())),
)

Expect(tomlWriter.Calls).To(HaveLen(0))
Expand All @@ -586,9 +601,10 @@ version = "1.1.1"
}

libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithTOMLWriter(tomlWriter),
libcnb.WithLogger(log.NewDiscard()),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithTOMLWriter(tomlWriter),
libcnb.WithLogger(log.NewDiscard())),
)

Expect(tomlWriter.Calls).To(HaveLen(1))
Expand All @@ -609,9 +625,10 @@ version = "1.1.1"
}

libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithTOMLWriter(tomlWriter),
libcnb.WithLogger(log.NewDiscard()),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithTOMLWriter(tomlWriter),
libcnb.WithLogger(log.NewDiscard())),
)

Expect(tomlWriter.Calls[0].Arguments[0]).To(Equal(filepath.Join(layersPath, "build.toml")))
Expand Down Expand Up @@ -646,9 +663,10 @@ sbom-formats = ["application/vnd.cyclonedx+json"]

it("has SBOM files", func() {
libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithExitHandler(exitHandler),
libcnb.WithLogger(log.NewDiscard()),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithExitHandler(exitHandler),
libcnb.WithLogger(log.NewDiscard())),
)

Expect(exitHandler.Calls).To(BeEmpty())
Expand All @@ -671,9 +689,10 @@ sbom-formats = []
Expect(os.WriteFile(filepath.Join(layersPath, "launch.sbom.spdx.json"), []byte{}, 0600)).To(Succeed())

libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithExitHandler(exitHandler),
libcnb.WithLogger(log.NewDiscard()),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithExitHandler(exitHandler),
libcnb.WithLogger(log.NewDiscard())),
)

Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError("unable to validate SBOM\nunable to find actual SBOM Type application/spdx+json in list of supported SBOM types []"))
Expand All @@ -683,9 +702,10 @@ sbom-formats = []
Expect(os.WriteFile(filepath.Join(layersPath, "launch.sbom.spdx.json"), []byte{}, 0600)).To(Succeed())

libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithExitHandler(exitHandler),
libcnb.WithLogger(log.NewDiscard()),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithExitHandler(exitHandler),
libcnb.WithLogger(log.NewDiscard())),
)

Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError("unable to validate SBOM\nunable to find actual SBOM Type application/spdx+json in list of supported SBOM types [application/vnd.cyclonedx+json]"))
Expand All @@ -695,9 +715,10 @@ sbom-formats = []
Expect(os.WriteFile(filepath.Join(layersPath, "launch.sbom.cdx.json"), []byte{}, 0600)).To(Succeed())
Expect(os.WriteFile(filepath.Join(layersPath, "layer.sbom.cdx.json"), []byte{}, 0600)).To(Succeed())
libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithExitHandler(exitHandler),
libcnb.WithLogger(log.NewDiscard()),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithExitHandler(exitHandler),
libcnb.WithLogger(log.NewDiscard())),
)

Expect(exitHandler.Calls).To(BeEmpty())
Expand All @@ -707,9 +728,10 @@ sbom-formats = []
Expect(os.WriteFile(filepath.Join(layersPath, "launch.sbom.random.json"), []byte{}, 0600)).To(Succeed())
Expect(os.WriteFile(filepath.Join(layersPath, "layer.sbom.cdx.json"), []byte{}, 0600)).To(Succeed())
libcnb.Build(buildFunc,
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithExitHandler(exitHandler),
libcnb.WithLogger(log.NewDiscard()),
libcnb.NewConfig(
libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}),
libcnb.WithExitHandler(exitHandler),
libcnb.WithLogger(log.NewDiscard())),
)

Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError("unable to validate SBOM\nunable to parse SBOM unknown\nunable to translate from random.json to SBOMFormat"))
Expand Down
27 changes: 27 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@

package libcnb

import (
"os"

"github.com/buildpacks/libcnb/internal"
"github.com/buildpacks/libcnb/log"
)

//go:generate mockery --name EnvironmentWriter --case=underscore

// EnvironmentWriter is the interface implemented by a type that wants to serialize a map of environment variables to
Expand Down Expand Up @@ -89,6 +96,26 @@ type Config struct {
// Option is a function for configuring a Config instance.
type Option func(config Config) Config

// NewConfig will generate a config from the given set of options
func NewConfig(options ...Option) Config {
config := Config{}

// apply defaults
options = append([]Option{
WithArguments(os.Args),
WithEnvironmentWriter(internal.EnvironmentWriter{}),
WithExitHandler(internal.NewExitHandler()),
WithLogger(log.New(os.Stdout)),
WithTOMLWriter(internal.TOMLWriter{}),
}, options...)

for _, opt := range options {
config = opt(config)
}

return config
}

// WithArguments creates an Option that sets a collection of arguments.
func WithArguments(arguments []string) Option {
return func(config Config) Config {
Expand Down
Loading