Skip to content

Commit

Permalink
Support source-removal logic in libbs
Browse files Browse the repository at this point in the history
Signed-off-by: Sambhav Kothari <[email protected]>
  • Loading branch information
sambhav committed Sep 4, 2022
1 parent 8dac763 commit a4fb625
Show file tree
Hide file tree
Showing 4 changed files with 3,505 additions and 9 deletions.
32 changes: 24 additions & 8 deletions application.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/paketo-buildpacks/libpak/crush"
"github.com/paketo-buildpacks/libpak/effect"
"github.com/paketo-buildpacks/libpak/sherpa"
"github.com/paketo-buildpacks/source-removal/logic"
)

type Application struct {
Expand Down Expand Up @@ -133,17 +134,32 @@ func (a Application) Contribute(layer libcnb.Layer) (libcnb.Layer, error) {

// Purge Workspace
a.Logger.Header("Removing source code")
cs, err := ioutil.ReadDir(a.ApplicationPath)
if err != nil {
return libcnb.Layer{}, fmt.Errorf("unable to list children of %s\n%w", a.ApplicationPath, err)
includeDirs, iset := a.ArtifactResolver.ConfigurationResolver.Resolve("BP_INCLUDE_FILES")
if includeDirs != "" {
if err := logic.Include(a.ApplicationPath, includeDirs); err != nil {
return libcnb.Layer{}, err
}
}
for _, c := range cs {
file := filepath.Join(a.ApplicationPath, c.Name())
if err := os.RemoveAll(file); err != nil {
return libcnb.Layer{}, fmt.Errorf("unable to remove %s\n%w", file, err)
excludeDirs, eset := a.ArtifactResolver.ConfigurationResolver.Resolve("BP_EXCLUDE_FILES")
if excludeDirs != "" {
if err := logic.Exclude(a.ApplicationPath, excludeDirs); err != nil {
return libcnb.Layer{}, err
}
}
// if the source remvoval env vars are all unset and the default values are all empty
// fall back to the legacy behavior
if excludeDirs == "" && includeDirs == "" && !iset && !eset {
cs, err := ioutil.ReadDir(a.ApplicationPath)
if err != nil {
return libcnb.Layer{}, fmt.Errorf("unable to list children of %s\n%w", a.ApplicationPath, err)
}
for _, c := range cs {
file := filepath.Join(a.ApplicationPath, c.Name())
if err := os.RemoveAll(file); err != nil {
return libcnb.Layer{}, fmt.Errorf("unable to remove %s\n%w", file, err)
}
}
}

// Restore compiled artifacts
file := filepath.Join(layer.Path, "application.zip")
if _, err := os.Stat(file); err == nil {
Expand Down
146 changes: 146 additions & 0 deletions application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ func testApplication(t *testing.T, context spec.G, it spec.S) {
Expect(in.Close()).To(Succeed())
Expect(out.Close()).To(Succeed())
}
Expect(os.WriteFile(filepath.Join(ctx.Application.Path, "random-file"), []byte(""), 0644)).To(BeNil())
Expect(os.Symlink(filepath.Join(ctx.Application.Path, "random-file"), filepath.Join(ctx.Application.Path, "random-link"))).To(BeNil())
})

it("matches multiple files", func() {
Expand Down Expand Up @@ -250,6 +252,8 @@ func testApplication(t *testing.T, context spec.G, it spec.S) {
Expect(filepath.Join(layer.Path, "application.zip")).NotTo(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "stub-application.jar")).To(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "stub-executable.jar")).To(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "random-file")).NotTo(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "random-link")).NotTo(BeAnExistingFile())
})

it("matches a folder", func() {
Expand Down Expand Up @@ -280,6 +284,148 @@ func testApplication(t *testing.T, context spec.G, it spec.S) {
Expect(filepath.Join(layer.Path, "application.zip")).NotTo(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "native-sources", "stub-application.jar")).To(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "native-sources", "stub-executable.jar")).To(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "random-file")).NotTo(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "random-link")).NotTo(BeAnExistingFile())
})

context("source-removal vars are set", func() {
it("does not remove the included files", func() {
artifactResolver := libbs.ArtifactResolver{
ConfigurationResolver: libpak.ConfigurationResolver{
Configurations: []libpak.BuildpackConfiguration{{Default: "target/native-sources"}, {Name: "BP_INCLUDE_FILES", Default: "random-*"}},
},
}
application.ArtifactResolver = artifactResolver

application.Logger = bard.NewLogger(ioutil.Discard)
executor.On("Execute", mock.Anything).Return(nil)

layer, err := ctx.Layers.Layer("test-layer")
Expect(err).NotTo(HaveOccurred())

layer, err = application.Contribute(layer)

Expect(err).NotTo(HaveOccurred())

e := executor.Calls[0].Arguments[0].(effect.Execution)
Expect(e.Command).To(Equal("test-command"))
Expect(e.Args).To(Equal([]string{"test-argument"}))
Expect(e.Dir).To(Equal(ctx.Application.Path))
Expect(e.Stdout).NotTo(BeNil())
Expect(e.Stderr).NotTo(BeNil())

Expect(filepath.Join(layer.Path, "application.zip")).NotTo(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "native-sources", "stub-application.jar")).To(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "native-sources", "stub-executable.jar")).To(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "random-file")).To(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "random-link")).To(BeAnExistingFile())
})

it("removes the excluded files", func() {
artifactResolver := libbs.ArtifactResolver{
ConfigurationResolver: libpak.ConfigurationResolver{
Configurations: []libpak.BuildpackConfiguration{
{Default: "target/native-sources"},
{Name: "BP_INCLUDE_FILES", Default: "random-*"},
{Name: "BP_EXCLUDE_FILES", Default: "random-link"},
},
},
}
application.ArtifactResolver = artifactResolver

application.Logger = bard.NewLogger(ioutil.Discard)
executor.On("Execute", mock.Anything).Return(nil)

layer, err := ctx.Layers.Layer("test-layer")
Expect(err).NotTo(HaveOccurred())

layer, err = application.Contribute(layer)

Expect(err).NotTo(HaveOccurred())

e := executor.Calls[0].Arguments[0].(effect.Execution)
Expect(e.Command).To(Equal("test-command"))
Expect(e.Args).To(Equal([]string{"test-argument"}))
Expect(e.Dir).To(Equal(ctx.Application.Path))
Expect(e.Stdout).NotTo(BeNil())
Expect(e.Stderr).NotTo(BeNil())

Expect(filepath.Join(layer.Path, "application.zip")).NotTo(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "native-sources", "stub-application.jar")).To(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "native-sources", "stub-executable.jar")).To(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "random-file")).To(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "random-link")).NotTo(BeAnExistingFile())
})

it("does not cause issues if all files are included", func() {
artifactResolver := libbs.ArtifactResolver{
ConfigurationResolver: libpak.ConfigurationResolver{
Configurations: []libpak.BuildpackConfiguration{
{Default: "target/native-sources"},
{Name: "BP_INCLUDE_FILES", Default: "*"},
},
},
}
application.ArtifactResolver = artifactResolver

application.Logger = bard.NewLogger(ioutil.Discard)
executor.On("Execute", mock.Anything).Return(nil)

layer, err := ctx.Layers.Layer("test-layer")
Expect(err).NotTo(HaveOccurred())

layer, err = application.Contribute(layer)

Expect(err).NotTo(HaveOccurred())

e := executor.Calls[0].Arguments[0].(effect.Execution)
Expect(e.Command).To(Equal("test-command"))
Expect(e.Args).To(Equal([]string{"test-argument"}))
Expect(e.Dir).To(Equal(ctx.Application.Path))
Expect(e.Stdout).NotTo(BeNil())
Expect(e.Stderr).NotTo(BeNil())

Expect(filepath.Join(layer.Path, "application.zip")).NotTo(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "native-sources", "stub-application.jar")).To(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "native-sources", "stub-executable.jar")).To(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "random-file")).To(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "random-link")).To(BeAnExistingFile())
})

it("keeps interesting files even if all files are excluded", func() {
artifactResolver := libbs.ArtifactResolver{
ConfigurationResolver: libpak.ConfigurationResolver{
Configurations: []libpak.BuildpackConfiguration{
{Default: "target/native-sources"},
{Name: "BP_EXCLUDE_FILES", Default: "*"},
},
},
}
application.ArtifactResolver = artifactResolver

application.Logger = bard.NewLogger(ioutil.Discard)
executor.On("Execute", mock.Anything).Return(nil)

layer, err := ctx.Layers.Layer("test-layer")
Expect(err).NotTo(HaveOccurred())

layer, err = application.Contribute(layer)

Expect(err).NotTo(HaveOccurred())

e := executor.Calls[0].Arguments[0].(effect.Execution)
Expect(e.Command).To(Equal("test-command"))
Expect(e.Args).To(Equal([]string{"test-argument"}))
Expect(e.Dir).To(Equal(ctx.Application.Path))
Expect(e.Stdout).NotTo(BeNil())
Expect(e.Stderr).NotTo(BeNil())

Expect(filepath.Join(layer.Path, "application.zip")).NotTo(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "native-sources", "stub-application.jar")).To(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "native-sources", "stub-executable.jar")).To(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "random-file")).NotTo(BeAnExistingFile())
Expect(filepath.Join(ctx.Application.Path, "random-link")).NotTo(BeAnExistingFile())
})
})
})

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/onsi/gomega v1.20.2
github.com/paketo-buildpacks/libjvm v1.40.0
github.com/paketo-buildpacks/libpak v1.62.0
github.com/paketo-buildpacks/source-removal v0.2.0
github.com/sclevine/spec v1.4.0
github.com/stretchr/testify v1.8.0
)
Expand Down
Loading

0 comments on commit a4fb625

Please sign in to comment.