From 3e0d81291831914996a4c225b81cb36065e75553 Mon Sep 17 00:00:00 2001 From: Nicolas Bender Date: Wed, 15 May 2024 11:05:07 +0200 Subject: [PATCH 1/4] Add Deprecated comment to all stack related identifiers Co-authored-by: Ralf Pannemans Signed-off-by: Nicolas Bender --- build.go | 2 +- buildpack.go | 4 ++-- generate.go | 2 +- platform.go | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.go b/build.go index 5a5ab19..a0c9788 100644 --- a/build.go +++ b/build.go @@ -55,7 +55,7 @@ type BuildContext struct { // Platform is the contents of the platform. Platform Platform - // StackID is the ID of the stack. + // Deprecated: StackID is the ID of the stack. StackID string } diff --git a/buildpack.go b/buildpack.go index a81ba2c..a2d9261 100644 --- a/buildpack.go +++ b/buildpack.go @@ -76,7 +76,7 @@ type BuildpackOrder struct { Groups []BuildpackOrderBuildpack `toml:"group"` } -// BuildpackStack is a stack supported by the buildpack. +// Deprecated: BuildpackStack is a stack supported by the buildpack. type BuildpackStack struct { // ID is the id of the stack. ID string `toml:"id"` @@ -96,7 +96,7 @@ type Buildpack struct { // Path is the path to the buildpack. Path string `toml:"-"` - // Stacks is the collection of stacks supported by the buildpack. + // Deprecated: Stacks is the collection of stacks supported by the buildpack. Stacks []BuildpackStack `toml:"stacks"` // Metadata is arbitrary metadata attached to the buildpack. diff --git a/generate.go b/generate.go index 600b13c..407a554 100644 --- a/generate.go +++ b/generate.go @@ -50,7 +50,7 @@ type GenerateContext struct { // Platform is the contents of the platform. Platform Platform - // StackID is the ID of the stack. + // Deprecated: StackID is the ID of the stack. StackID string } diff --git a/platform.go b/platform.go index a9c09c5..e2ebf4f 100644 --- a/platform.go +++ b/platform.go @@ -65,7 +65,7 @@ const ( // EnvBuildPlanPath is the name of the environment variable that contains the path to the build plan EnvBuildPlanPath = "CNB_BP_PLAN_PATH" - // EnvStackID is the name of the environment variable that contains the stack id + // Deprecated: EnvStackID is the name of the environment variable that contains the stack id EnvStackID = "CNB_STACK_ID" // DefaultPlatformBindingsLocation is the typical location for bindings, which exists under the platform directory From 22da3d2eb0bfbe752eac54b6e7f99afdc1b657d8 Mon Sep 17 00:00:00 2001 From: Nicolas Bender Date: Wed, 15 May 2024 13:24:39 +0200 Subject: [PATCH 2/4] Add target structs Co-authored-by: Ralf Pannemans Signed-off-by: Nicolas Bender --- build.go | 2 +- build_test.go | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ buildpack.go | 27 +++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) diff --git a/build.go b/build.go index a0c9788..4ce43c8 100644 --- a/build.go +++ b/build.go @@ -87,7 +87,7 @@ const ( MinSupportedBPVersion = "0.8" // MaxSupportedBPVersion indicates the maximum supported version of the Buildpacks API - MaxSupportedBPVersion = "0.9" + MaxSupportedBPVersion = "0.10" ) // NewBuildResult creates a new BuildResult instance, initializing empty fields. diff --git a/build_test.go b/build_test.go index 7a951ca..18ff429 100644 --- a/build_test.go +++ b/build_test.go @@ -320,6 +320,61 @@ version = "1.1.1" }) }) + context("has a build environment specifying target metadata", func() { + var ctx libcnb.BuildContext + + it.Before(func() { + Expect(os.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"), + []byte(` + api = "0.10" + + [buildpack] + id = "test-id" + name = "test-name" + version = "1.1.1" + + [[targets]] + os = "linux" + arch = "amd64" + + [[targets.distros]] + name = "ubuntu" + version = "18.04" + + [[targets.distros]] + name = "debian" + + [[targets]] + os = "linux" + arch = "arm" + variant = "v6" + `), 0600), + ).To(Succeed()) + + buildFunc = func(context libcnb.BuildContext) (libcnb.BuildResult, error) { + ctx = context + return libcnb.NewBuildResult(), nil + } + }) + + it("provides target information", func() { + libcnb.Build(buildFunc, + libcnb.NewConfig( + libcnb.WithArguments([]string{commandPath})), + ) + + Expect(ctx.Buildpack.Targets).To(HaveLen(2)) + Expect(ctx.Buildpack.Targets[0].OS).To(Equal("linux")) + Expect(ctx.Buildpack.Targets[0].Arch).To(Equal("amd64")) + Expect(ctx.Buildpack.Targets[0].Distros).To(HaveLen(2)) + Expect(ctx.Buildpack.Targets[0].Distros[0].Name).To(Equal("ubuntu")) + Expect(ctx.Buildpack.Targets[0].Distros[0].Version).To(Equal("18.04")) + Expect(ctx.Buildpack.Targets[0].Distros[1].Name).To(Equal("debian")) + + Expect(ctx.Buildpack.Targets[1].Variant).To(Equal("v6")) + }) + }) + it("fails if CNB_BUILDPACK_DIR is not set", func() { Expect(os.Unsetenv("CNB_BUILDPACK_DIR")).To(Succeed()) diff --git a/buildpack.go b/buildpack.go index a2d9261..bc1f73f 100644 --- a/buildpack.go +++ b/buildpack.go @@ -85,6 +85,30 @@ type BuildpackStack struct { Mixins []string `toml:"mixins"` } +// BuildpackTargetDistro is the supported target distro +type BuildpackTargetDistro struct { + // Name is the name of the supported distro. + Name string `toml:"name"` + + // Version is the version of the supported distro. + Version string `toml:"version"` +} + +// BuildpackTarget is a target supported by the buildpack. +type BuildpackTarget struct { + // OS is the supported os. + OS string `toml:"os"` + + // Arch is the supported architecture. + Arch string `toml:"arch"` + + // Variant is the supported variant of the architecture. + Variant string `toml:"variant"` + + // Distros is the collection of distros associated with the target. + Distros []BuildpackTargetDistro `toml:"distros"` +} + // Buildpack is the contents of the buildpack.toml file. type Buildpack struct { // API is the api version expected by the buildpack. @@ -99,6 +123,9 @@ type Buildpack struct { // Deprecated: Stacks is the collection of stacks supported by the buildpack. Stacks []BuildpackStack `toml:"stacks"` + // Targets is the collection of targets supported by the buildpack. + Targets []BuildpackTarget `toml:"targets"` + // Metadata is arbitrary metadata attached to the buildpack. Metadata map[string]interface{} `toml:"metadata"` } From 385aa0e6b265bfae1097c3e2691fc74d11db5373 Mon Sep 17 00:00:00 2001 From: Nicolas Bender Date: Wed, 15 May 2024 15:03:04 +0200 Subject: [PATCH 3/4] Adapt extension related files Co-authored-by: Ralf Pannemans Signed-off-by: Nicolas Bender --- build.go | 19 ++++++++++++ build_test.go | 22 +++++++++++++- buildpack.go | 17 +++++++---- extension.go | 3 ++ generate.go | 19 ++++++++++++ generate_test.go | 79 ++++++++++++++++++++++++++++++++++++++++++++++-- platform.go | 15 +++++++++ 7 files changed, 165 insertions(+), 9 deletions(-) diff --git a/build.go b/build.go index 4ce43c8..fe54b3e 100644 --- a/build.go +++ b/build.go @@ -57,6 +57,12 @@ type BuildContext struct { // Deprecated: StackID is the ID of the stack. StackID string + + // TargetInfo contains info of the target (os, arch, ...). + TargetInfo TargetInfo + + // TargetDistro is the target distribution (name, version). + TargetDistro TargetDistro } // BuildResult contains the results of detection. @@ -231,6 +237,19 @@ func Build(build BuildFunc, config Config) { config.logger.Debugf("Stack: %s", ctx.StackID) } + if API.GreaterThan(semver.MustParse("0.9")) { + ctx.TargetInfo = TargetInfo{} + ctx.TargetInfo.OS, _ = os.LookupEnv(EnvTargetOS) + ctx.TargetInfo.Arch, _ = os.LookupEnv(EnvTargetArch) + ctx.TargetInfo.Variant, _ = os.LookupEnv(EnvTargetArchVariant) + config.logger.Debugf("System: %+v", ctx.TargetInfo) + + ctx.TargetDistro = TargetDistro{} + ctx.TargetDistro.Name, _ = os.LookupEnv(EnvTargetDistroName) + ctx.TargetDistro.Version, _ = os.LookupEnv(EnvTargetDistroVersion) + config.logger.Debugf("Distro: %+v", ctx.TargetDistro) + } + result, err := build(ctx) if err != nil { config.exitHandler.Error(err) diff --git a/build_test.go b/build_test.go index 18ff429..730ca5e 100644 --- a/build_test.go +++ b/build_test.go @@ -165,6 +165,12 @@ test-key = "test-value" Expect(os.Setenv("CNB_PLATFORM_DIR", platformPath)).To(Succeed()) Expect(os.Setenv("CNB_BP_PLAN_PATH", buildpackPlanPath)).To(Succeed()) + Expect(os.Setenv("CNB_TARGET_OS", "linux")).To(Succeed()) + Expect(os.Setenv("CNB_TARGET_ARCH", "arm")).To(Succeed()) + Expect(os.Setenv("CNB_TARGET_ARCH_VARIANT", "v6")).To(Succeed()) + Expect(os.Setenv("CNB_TARGET_DISTRO_NAME", "ubuntu")).To(Succeed()) + Expect(os.Setenv("CNB_TARGET_DISTRO_VERSION", "24.04")).To(Succeed()) + workingDir, err = os.Getwd() Expect(err).NotTo(HaveOccurred()) Expect(os.Chdir(applicationPath)).To(Succeed()) @@ -178,6 +184,12 @@ test-key = "test-value" Expect(os.Unsetenv("CNB_BP_PLAN_PATH")).To(Succeed()) Expect(os.Unsetenv("CNB_LAYERS_DIR")).To(Succeed()) + Expect(os.Unsetenv("CNB_TARGET_OS")) + Expect(os.Unsetenv("CNB_TARGET_ARCH")) + Expect(os.Unsetenv("CNB_TARGET_ARCH_VARIANT")) + Expect(os.Unsetenv("CNB_TARGET_DISTRO_NAME")) + Expect(os.Unsetenv("CNB_TARGET_DISTRO_VERSION")) + Expect(os.RemoveAll(applicationPath)).To(Succeed()) Expect(os.RemoveAll(buildpackPath)).To(Succeed()) Expect(os.RemoveAll(buildpackPlanPath)).To(Succeed()) @@ -360,7 +372,9 @@ version = "1.1.1" it("provides target information", func() { libcnb.Build(buildFunc, libcnb.NewConfig( - libcnb.WithArguments([]string{commandPath})), + libcnb.WithArguments([]string{commandPath}), + libcnb.WithLogger(log.New(os.Stdout)), + ), ) Expect(ctx.Buildpack.Targets).To(HaveLen(2)) @@ -372,6 +386,12 @@ version = "1.1.1" Expect(ctx.Buildpack.Targets[0].Distros[1].Name).To(Equal("debian")) Expect(ctx.Buildpack.Targets[1].Variant).To(Equal("v6")) + + Expect(ctx.TargetInfo.OS).To(Equal("linux")) + Expect(ctx.TargetInfo.Arch).To(Equal("arm")) + Expect(ctx.TargetInfo.Variant).To(Equal("v6")) + Expect(ctx.TargetDistro.Name).To(Equal("ubuntu")) + Expect(ctx.TargetDistro.Version).To(Equal("24.04")) }) }) diff --git a/buildpack.go b/buildpack.go index bc1f73f..d6195d9 100644 --- a/buildpack.go +++ b/buildpack.go @@ -85,8 +85,8 @@ type BuildpackStack struct { Mixins []string `toml:"mixins"` } -// BuildpackTargetDistro is the supported target distro -type BuildpackTargetDistro struct { +// TargetDistro is the supported target distro +type TargetDistro struct { // Name is the name of the supported distro. Name string `toml:"name"` @@ -94,8 +94,8 @@ type BuildpackTargetDistro struct { Version string `toml:"version"` } -// BuildpackTarget is a target supported by the buildpack. -type BuildpackTarget struct { +// TargetInfo is the supported target +type TargetInfo struct { // OS is the supported os. OS string `toml:"os"` @@ -104,9 +104,14 @@ type BuildpackTarget struct { // Variant is the supported variant of the architecture. Variant string `toml:"variant"` +} + +// Target is a target supported by the buildpack. +type Target struct { + TargetInfo // Distros is the collection of distros associated with the target. - Distros []BuildpackTargetDistro `toml:"distros"` + Distros []TargetDistro `toml:"distros"` } // Buildpack is the contents of the buildpack.toml file. @@ -124,7 +129,7 @@ type Buildpack struct { Stacks []BuildpackStack `toml:"stacks"` // Targets is the collection of targets supported by the buildpack. - Targets []BuildpackTarget `toml:"targets"` + Targets []Target `toml:"targets"` // Metadata is arbitrary metadata attached to the buildpack. Metadata map[string]interface{} `toml:"metadata"` diff --git a/extension.go b/extension.go index 763ede1..d100799 100644 --- a/extension.go +++ b/extension.go @@ -51,6 +51,9 @@ type Extension struct { // Path is the path to the extension. Path string `toml:"-"` + // Targets is the collection of targets supported by the buildpack. + Targets []Target `toml:"targets"` + // Metadata is arbitrary metadata attached to the extension. Metadata map[string]interface{} `toml:"metadata"` } diff --git a/generate.go b/generate.go index 407a554..635373e 100644 --- a/generate.go +++ b/generate.go @@ -50,6 +50,12 @@ type GenerateContext struct { // Platform is the contents of the platform. Platform Platform + // TargetInfo contains info of the target (os, arch, ...). + TargetInfo TargetInfo + + // TargetDistro is the target distribution (name, version). + TargetDistro TargetDistro + // Deprecated: StackID is the ID of the stack. StackID string } @@ -184,6 +190,19 @@ func Generate(generate GenerateFunc, config Config) { config.logger.Debugf("Stack: %s", ctx.StackID) } + if API.GreaterThan(semver.MustParse("0.9")) { + ctx.TargetInfo = TargetInfo{} + ctx.TargetInfo.OS, _ = os.LookupEnv(EnvTargetOS) + ctx.TargetInfo.Arch, _ = os.LookupEnv(EnvTargetArch) + ctx.TargetInfo.Variant, _ = os.LookupEnv(EnvTargetArchVariant) + config.logger.Debugf("System: %+v", ctx.TargetInfo) + + ctx.TargetDistro = TargetDistro{} + ctx.TargetDistro.Name, _ = os.LookupEnv(EnvTargetDistroName) + ctx.TargetDistro.Version, _ = os.LookupEnv(EnvTargetDistroVersion) + config.logger.Debugf("Distro: %+v", ctx.TargetDistro) + } + result, err := generate(ctx) if err != nil { config.exitHandler.Error(err) diff --git a/generate_test.go b/generate_test.go index 54a77d2..1ec6403 100644 --- a/generate_test.go +++ b/generate_test.go @@ -76,8 +76,8 @@ api = "{{.APIVersion}}" id = "test-id" name = "test-name" version = "1.1.1" -description = "A test buildpack" -keywords = ["test", "buildpack"] +description = "A test extension" +keywords = ["test", "extension"] [[extension.licenses]] type = "Apache-2.0" @@ -147,6 +147,12 @@ test-key = "test-value" Expect(os.Setenv("CNB_PLATFORM_DIR", platformPath)).To(Succeed()) Expect(os.Setenv("CNB_BP_PLAN_PATH", buildpackPlanPath)).To(Succeed()) + Expect(os.Setenv("CNB_TARGET_OS", "linux")).To(Succeed()) + Expect(os.Setenv("CNB_TARGET_ARCH", "arm")).To(Succeed()) + Expect(os.Setenv("CNB_TARGET_ARCH_VARIANT", "v6")).To(Succeed()) + Expect(os.Setenv("CNB_TARGET_DISTRO_NAME", "ubuntu")).To(Succeed()) + Expect(os.Setenv("CNB_TARGET_DISTRO_VERSION", "24.04")).To(Succeed()) + workingDir, err = os.Getwd() Expect(err).NotTo(HaveOccurred()) Expect(os.Chdir(applicationPath)).To(Succeed()) @@ -160,6 +166,12 @@ test-key = "test-value" Expect(os.Unsetenv("CNB_BP_PLAN_PATH")).To(Succeed()) Expect(os.Unsetenv("CNB_OUTPUT_DIR")).To(Succeed()) + Expect(os.Unsetenv("CNB_TARGET_OS")) + Expect(os.Unsetenv("CNB_TARGET_ARCH")) + Expect(os.Unsetenv("CNB_TARGET_ARCH_VARIANT")) + Expect(os.Unsetenv("CNB_TARGET_DISTRO_NAME")) + Expect(os.Unsetenv("CNB_TARGET_DISTRO_VERSION")) + Expect(os.RemoveAll(applicationPath)).To(Succeed()) Expect(os.RemoveAll(extensionPath)).To(Succeed()) Expect(os.RemoveAll(buildpackPlanPath)).To(Succeed()) @@ -300,6 +312,69 @@ version = "1.1.1" }) }) + context("has a build environment specifying target metadata", func() { + var ctx libcnb.GenerateContext + + it.Before(func() { + Expect(os.WriteFile(filepath.Join(extensionPath, "extension.toml"), + []byte(` + api = "0.10" + + [extension] + id = "test-id" + name = "test-name" + version = "1.1.1" + + [[targets]] + os = "linux" + arch = "amd64" + + [[targets.distros]] + name = "ubuntu" + version = "18.04" + + [[targets.distros]] + name = "debian" + + [[targets]] + os = "linux" + arch = "arm" + variant = "v6" + `), 0600), + ).To(Succeed()) + + generateFunc = func(context libcnb.GenerateContext) (libcnb.GenerateResult, error) { + ctx = context + return libcnb.NewGenerateResult(), nil + } + }) + + it("provides target information", func() { + libcnb.Generate(generateFunc, + libcnb.NewConfig( + libcnb.WithArguments([]string{commandPath}), + libcnb.WithLogger(log.New(os.Stdout)), + ), + ) + + Expect(ctx.Extension.Targets).To(HaveLen(2)) + Expect(ctx.Extension.Targets[0].OS).To(Equal("linux")) + Expect(ctx.Extension.Targets[0].Arch).To(Equal("amd64")) + Expect(ctx.Extension.Targets[0].Distros).To(HaveLen(2)) + Expect(ctx.Extension.Targets[0].Distros[0].Name).To(Equal("ubuntu")) + Expect(ctx.Extension.Targets[0].Distros[0].Version).To(Equal("18.04")) + Expect(ctx.Extension.Targets[0].Distros[1].Name).To(Equal("debian")) + + Expect(ctx.Extension.Targets[1].Variant).To(Equal("v6")) + + Expect(ctx.TargetInfo.OS).To(Equal("linux")) + Expect(ctx.TargetInfo.Arch).To(Equal("arm")) + Expect(ctx.TargetInfo.Variant).To(Equal("v6")) + Expect(ctx.TargetDistro.Name).To(Equal("ubuntu")) + Expect(ctx.TargetDistro.Version).To(Equal("24.04")) + }) + }) + it("fails if CNB_EXTENSION_DIR is not set", func() { Expect(os.Unsetenv("CNB_EXTENSION_DIR")).To(Succeed()) diff --git a/platform.go b/platform.go index e2ebf4f..e38d45b 100644 --- a/platform.go +++ b/platform.go @@ -68,6 +68,21 @@ const ( // Deprecated: EnvStackID is the name of the environment variable that contains the stack id EnvStackID = "CNB_STACK_ID" + // EnvTargetOS contains the name of the os + EnvTargetOS = "CNB_TARGET_OS" + + // EnvTargetArch contains the architecture + EnvTargetArch = "CNB_TARGET_ARCH" + + // EnvTargetOS contains the variant of the architecture + EnvTargetArchVariant = "CNB_TARGET_ARCH_VARIANT" + + // EnvTargetDistroName contains the name of the ditro + EnvTargetDistroName = "CNB_TARGET_DISTRO_NAME" + + // EnvTargetDistroVersion contains the version of the distro + EnvTargetDistroVersion = "CNB_TARGET_DISTRO_VERSION" + // DefaultPlatformBindingsLocation is the typical location for bindings, which exists under the platform directory // // Not guaranteed to exist, but often does. This should only be used as a fallback if EnvServiceBindings and EnvPlatformDirectory are not set From 85dc71dc95bdd0db8b1e303ab6897f18730941f5 Mon Sep 17 00:00:00 2001 From: Pavel Busko Date: Fri, 7 Jun 2024 11:35:40 +0200 Subject: [PATCH 4/4] add support for generated dockerfiles and extend config Signed-off-by: Pavel Busko --- generate.go | 55 +++++++++++++++++++++++++++++++++++++++++++++--- generate_test.go | 43 ++++++++++++++++++++++++++++++++++--- 2 files changed, 92 insertions(+), 6 deletions(-) diff --git a/generate.go b/generate.go index 635373e..701d2d8 100644 --- a/generate.go +++ b/generate.go @@ -64,10 +64,30 @@ type GenerateContext struct { type GenerateResult struct { // Unmet contains buildpack plan entries that were not satisfied by the buildpack and therefore should be // passed to subsequent providers. - Unmet []UnmetPlanEntry + Unmet []UnmetPlanEntry + RunDockerfile []byte + BuildDockerfile []byte + Config *ExtendConfig } -// NewBuildResult creates a new BuildResult instance, initializing empty fields. +// DockerfileArg is a Dockerfile argument +type DockerfileArg struct { + Name string `toml:"name"` + Value string `toml:"value"` +} + +// BuildConfig contains additional arguments passed to the generated Dockerfiles +type BuildConfig struct { + Args []DockerfileArg `toml:"args"` +} + +// ExtendConfig contains additional configuration for the Dockerfiles +type ExtendConfig struct { + Build BuildConfig `toml:"build"` + Run BuildConfig `toml:"run"` +} + +// NewGenerateResult creates a new BuildResult instance, initializing empty fields. func NewGenerateResult() GenerateResult { return GenerateResult{} } @@ -79,7 +99,7 @@ func (b GenerateResult) String() string { ) } -// BuildFunc takes a context and returns a result, performing extension generate behaviors. +// GenerateFunc takes a context and returns a result, performing extension generate behaviors. type GenerateFunc func(context GenerateContext) (GenerateResult, error) // Generate is called by the main function of a extension, for generate phase @@ -209,4 +229,33 @@ func Generate(generate GenerateFunc, config Config) { return } config.logger.Debugf("Result: %+v", result) + + if len(result.RunDockerfile) > 0 { + // #nosec + if err := os.WriteFile(filepath.Join(ctx.OutputDirectory, "run.Dockerfile"), result.RunDockerfile, 0644); err != nil { + config.exitHandler.Error(err) + return + } + } + + if len(result.BuildDockerfile) > 0 { + // #nosec + if err := os.WriteFile(filepath.Join(ctx.OutputDirectory, "build.Dockerfile"), result.BuildDockerfile, 0644); err != nil { + config.exitHandler.Error(err) + return + } + } + + if result.Config != nil { + configFile, err := os.Create(filepath.Join(ctx.OutputDirectory, "extend-config.toml")) + if err != nil { + config.exitHandler.Error(err) + return + } + + if err := toml.NewEncoder(configFile).Encode(result.Config); err != nil { + config.exitHandler.Error(err) + return + } + } } diff --git a/generate_test.go b/generate_test.go index 1ec6403..2f9be6a 100644 --- a/generate_test.go +++ b/generate_test.go @@ -403,10 +403,12 @@ version = "1.1.1" Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError("test-error")) }) - it("writes a Dockerfile", func() { + it("writes Dockerfiles", func() { generateFunc = func(ctx libcnb.GenerateContext) (libcnb.GenerateResult, error) { - os.WriteFile(filepath.Join(ctx.OutputDirectory, "build.Dockerfile"), []byte(""), 0600) - return libcnb.NewGenerateResult(), nil + result := libcnb.NewGenerateResult() + result.BuildDockerfile = []byte(`FROM foo:latest`) + result.RunDockerfile = []byte(`FROM bar:latest`) + return result, nil } libcnb.Generate(generateFunc, @@ -417,5 +419,40 @@ version = "1.1.1" ) Expect(filepath.Join(outputPath, "build.Dockerfile")).To(BeARegularFile()) + Expect(filepath.Join(outputPath, "run.Dockerfile")).To(BeARegularFile()) + }) + + it("writes extend-config.toml", func() { + generateFunc = func(ctx libcnb.GenerateContext) (libcnb.GenerateResult, error) { + result := libcnb.NewGenerateResult() + result.Config = &libcnb.ExtendConfig{ + Build: libcnb.BuildConfig{ + Args: []libcnb.DockerfileArg{ + { + Name: "foo", + Value: "bar", + }, + }, + }, + Run: libcnb.BuildConfig{ + Args: []libcnb.DockerfileArg{ + { + Name: "bar", + Value: "bazz", + }, + }, + }, + } + return result, nil + } + + libcnb.Generate(generateFunc, + libcnb.NewConfig( + libcnb.WithArguments([]string{commandPath, outputPath, platformPath, buildpackPlanPath}), + libcnb.WithTOMLWriter(tomlWriter), + libcnb.WithLogger(log.NewDiscard())), + ) + + Expect(filepath.Join(outputPath, "extend-config.toml")).To(BeARegularFile()) }) }