From ad0e745e553e8cf8805b43b989004401d62a70e0 Mon Sep 17 00:00:00 2001 From: gcemaj Date: Tue, 5 Apr 2022 09:49:08 -0400 Subject: [PATCH] [action] add working-directory to launch.toml (API>=0.8) --- application.go | 3 + build.go | 13 ++++- build_test.go | 148 ++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 161 insertions(+), 3 deletions(-) diff --git a/application.go b/application.go index 1d11438..e8836bf 100644 --- a/application.go +++ b/application.go @@ -48,6 +48,9 @@ type Process struct { // Command is exec'd directly by the os (no profile.d scripts run) Direct bool `toml:"direct,omitempty"` + // WorkingDirectory is a directory to execute the command in, removes the need to use a shell environment to CD into working directory + WorkingDirectory string `toml:"working-directory,omitempty"` + // Default can be set to true to indicate that the process // type being defined should be the default process type for the app image. Default bool `toml:"default,omitempty"` diff --git a/build.go b/build.go index fb5199d..61eed5c 100644 --- a/build.go +++ b/build.go @@ -171,8 +171,8 @@ func Build(builder Builder, options ...Option) { logger.Debugf("Buildpack: %+v", ctx.Buildpack) API := strings.TrimSpace(ctx.Buildpack.API) - if API != "0.5" && API != "0.6" && API != "0.7" { - config.exitHandler.Error(errors.New("this version of libcnb is only compatible with buildpack APIs 0.5, 0.6, and 0.7")) + if API != "0.5" && API != "0.6" && API != "0.7" && API != "0.8" { + config.exitHandler.Error(errors.New("this version of libcnb is only compatible with buildpack APIs 0.5, 0.6, 0.7 and 0.8")) return } @@ -346,6 +346,15 @@ func Build(builder Builder, options ...Option) { } } + if API != "0.8" { + for i, process := range launch.Processes { + if process.WorkingDirectory != "" { + logger.Infof("WARNING: Launch layer is setting working-directory=%s, but that is not supported until API version 0.8. This setting will be ignored.", process.WorkingDirectory) + launch.Processes[i].WorkingDirectory = "" + } + } + } + if err = config.tomlWriter.Write(file, launch); err != nil { config.exitHandler.Error(fmt.Errorf("unable to write application metadata %s\n%w", file, err)) return diff --git a/build_test.go b/build_test.go index b4fd36b..8e7ac0f 100644 --- a/build_test.go +++ b/build_test.go @@ -204,7 +204,7 @@ version = "1.1.1" ) Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError( - "this version of libcnb is only compatible with buildpack APIs 0.5, 0.6, and 0.7", + "this version of libcnb is only compatible with buildpack APIs 0.5, 0.6, 0.7 and 0.8", )) }) }) @@ -549,6 +549,152 @@ version = "1.1.1" })) }) + it("ignore working-directory setting and writes launch.toml (API<0.8)", func() { + builder.On("Build", mock.Anything).Return(libcnb.BuildResult{ + BOM: &libcnb.BOM{Entries: []libcnb.BOMEntry{ + { + Name: "test-launch-bom-entry", + Metadata: map[string]interface{}{"test-key": "test-value"}, + Launch: true, + }, + { + Name: "test-build-bom-entry", + Metadata: map[string]interface{}{"test-key": "test-value"}, + }, + }}, + Labels: []libcnb.Label{ + { + Key: "test-key", + Value: "test-value", + }, + }, + Processes: []libcnb.Process{ + { + Type: "test-type", + Command: "test-command-in-dir", + Default: true, + WorkingDirectory: "/my/directory/", + }, + }, + Slices: []libcnb.Slice{ + { + Paths: []string{"test-path"}, + }, + }, + }, nil) + + libcnb.Build(builder, + libcnb.WithBOMLabel(true), + libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}), + libcnb.WithTOMLWriter(tomlWriter), + ) + + Expect(tomlWriter.Calls[0].Arguments[0]).To(Equal(filepath.Join(layersPath, "launch.toml"))) + Expect(tomlWriter.Calls[0].Arguments[1]).To(Equal(libcnb.LaunchTOML{ + Labels: []libcnb.Label{ + { + Key: "test-key", + Value: "test-value", + }, + }, + Processes: []libcnb.Process{ + { + Type: "test-type", + Command: "test-command-in-dir", + Default: true, + }, + }, + Slices: []libcnb.Slice{ + { + Paths: []string{"test-path"}, + }, + }, + BOM: []libcnb.BOMEntry{ + { + Name: "test-launch-bom-entry", + Metadata: map[string]interface{}{"test-key": "test-value"}, + Launch: true, + }, + }, + })) + }) + + it("writes launch.toml with working-directory setting(API>=0.8)", func() { + var b bytes.Buffer + err := buildpackTOML.Execute(&b, map[string]string{"APIVersion": "0.8"}) + Expect(err).ToNot(HaveOccurred()) + + Expect(ioutil.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"), b.Bytes(), 0600)).To(Succeed()) + builder.On("Build", mock.Anything).Return(libcnb.BuildResult{ + BOM: &libcnb.BOM{Entries: []libcnb.BOMEntry{ + { + Name: "test-launch-bom-entry", + Metadata: map[string]interface{}{"test-key": "test-value"}, + Launch: true, + }, + { + Name: "test-build-bom-entry", + Metadata: map[string]interface{}{"test-key": "test-value"}, + }, + }}, + Labels: []libcnb.Label{ + { + Key: "test-key", + Value: "test-value", + }, + }, + Processes: []libcnb.Process{ + { + Type: "test-type", + Command: "test-command-in-dir", + Default: true, + WorkingDirectory: "/my/directory/", + }, + }, + Slices: []libcnb.Slice{ + { + Paths: []string{"test-path"}, + }, + }, + }, nil) + + libcnb.Build(builder, + libcnb.WithBOMLabel(true), + libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}), + libcnb.WithTOMLWriter(tomlWriter), + ) + + Expect(tomlWriter.Calls[0].Arguments[0]).To(Equal(filepath.Join(layersPath, "launch.toml"))) + Expect(tomlWriter.Calls[0].Arguments[1]).To(Equal(libcnb.LaunchTOML{ + Labels: []libcnb.Label{ + { + Key: "test-key", + Value: "test-value", + }, + }, + Processes: []libcnb.Process{ + { + Type: "test-type", + Command: "test-command-in-dir", + Default: true, + WorkingDirectory: "/my/directory/", + }, + }, + Slices: []libcnb.Slice{ + { + Paths: []string{"test-path"}, + }, + }, + BOM: []libcnb.BOMEntry{ + { + Name: "test-launch-bom-entry", + Metadata: map[string]interface{}{"test-key": "test-value"}, + Launch: true, + }, + }, + })) + }) + it("writes persistent metadata", func() { m := map[string]interface{}{"test-key": "test-value"}