Skip to content

Commit

Permalink
Add support for supplying strip-components via buildpack.toml
Browse files Browse the repository at this point in the history
This PR adds a strip-components flag to postal’s service resolver. So that when it parses the buildpack tomls it can use artifacts that are tar’d in a slightly different manner. This would allow for customization of paketo forks that only have a different buildpack.toml.

For more details see https://paketobuildpacks.slack.com/archives/CULAS8ACD/p1619441959093300

Signed-off-by: Sambhav Kothari <skothari44@bloomberg.net>
  • Loading branch information
sambhav committed May 28, 2021
1 parent a7ecf09 commit 7eca5c1
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 11 deletions.
4 changes: 4 additions & 0 deletions postal/buildpack.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ type Dependency struct {

// Version is the specific version of the dependency.
Version string `toml:"version"`

// StripComponents behaves like the --strip-components flag on tar command
// removing the first n levels from the final decompression destination.
StripComponents int `toml:"strip-components"`
}

func parseBuildpack(path, name string) ([]Dependency, string, error) {
Expand Down
2 changes: 1 addition & 1 deletion postal/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ func (s Service) Deliver(dependency Dependency, cnbPath, layerPath, platformPath

validatedReader := cargo.NewValidatedReader(bundle, dependency.SHA256)

err = vacation.NewArchive(validatedReader).Decompress(layerPath)
err = vacation.NewArchive(validatedReader).StripComponents(dependency.StripComponents).Decompress(layerPath)
if err != nil {
return err
}
Expand Down
105 changes: 95 additions & 10 deletions postal/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ sha256 = "some-sha"
stacks = ["some-stack"]
uri = "some-uri"
version = "4.5.6"
strip-components = 1
`)
Expect(err).NotTo(HaveOccurred())

Expand Down Expand Up @@ -119,11 +120,12 @@ version = "4.5.6"
dependency, err := service.Resolve(path, "some-entry", "", "some-stack")
Expect(err).NotTo(HaveOccurred())
Expect(dependency).To(Equal(postal.Dependency{
ID: "some-entry",
Stacks: []string{"some-stack"},
URI: "some-uri",
SHA256: "some-sha",
Version: "4.5.6",
ID: "some-entry",
Stacks: []string{"some-stack"},
URI: "some-uri",
SHA256: "some-sha",
Version: "4.5.6",
StripComponents: 1,
}))
})
})
Expand All @@ -133,11 +135,12 @@ version = "4.5.6"
dependency, err := service.Resolve(path, "some-entry", "default", "some-stack")
Expect(err).NotTo(HaveOccurred())
Expect(dependency).To(Equal(postal.Dependency{
ID: "some-entry",
Stacks: []string{"some-stack"},
URI: "some-uri",
SHA256: "some-sha",
Version: "4.5.6",
ID: "some-entry",
Stacks: []string{"some-stack"},
URI: "some-uri",
SHA256: "some-sha",
Version: "4.5.6",
StripComponents: 1,
}))
})
})
Expand Down Expand Up @@ -401,6 +404,88 @@ version = "this is super not semver"
Expect(err).NotTo(HaveOccurred())
Expect(info.Mode()).To(Equal(os.FileMode(0755)))
})
context("when the dependency has a strip-components value set", func() {
it.Before(func() {
var err error
layerPath, err = os.MkdirTemp("", "path")
Expect(err).NotTo(HaveOccurred())

buffer := bytes.NewBuffer(nil)
zw := gzip.NewWriter(buffer)
tw := tar.NewWriter(zw)

Expect(tw.WriteHeader(&tar.Header{Name: "some-dir", Mode: 0755, Typeflag: tar.TypeDir})).To(Succeed())
_, err = tw.Write(nil)
Expect(err).NotTo(HaveOccurred())

nestedFile := "some-dir/some-file"
Expect(tw.WriteHeader(&tar.Header{Name: nestedFile, Mode: 0755, Size: int64(len(nestedFile))})).To(Succeed())
_, err = tw.Write([]byte(nestedFile))
Expect(err).NotTo(HaveOccurred())

for _, file := range []string{"some-dir/first", "some-dir/second", "some-dir/third"} {
Expect(tw.WriteHeader(&tar.Header{Name: file, Mode: 0755, Size: int64(len(file))})).To(Succeed())
_, err = tw.Write([]byte(file))
Expect(err).NotTo(HaveOccurred())
}

linkName := "some-dir/symlink"
linkDest := "./first"
Expect(tw.WriteHeader(&tar.Header{Name: linkName, Mode: 0777, Size: int64(0), Typeflag: tar.TypeSymlink, Linkname: linkDest})).To(Succeed())
_, err = tw.Write([]byte{})
Expect(err).NotTo(HaveOccurred())

Expect(tw.Close()).To(Succeed())
Expect(zw.Close()).To(Succeed())

sum := sha256.Sum256(buffer.Bytes())
dependencySHA = hex.EncodeToString(sum[:])

transport.DropCall.Returns.ReadCloser = io.NopCloser(buffer)

deliver = func() error {
return service.Deliver(postal.Dependency{
ID: "some-entry",
Stacks: []string{"some-stack"},
URI: "some-entry.tgz",
SHA256: dependencySHA,
Version: "1.2.3",
StripComponents: 1,
}, "some-cnb-path",
layerPath,
platformPath,
)
}
})

it.After(func() {
Expect(os.RemoveAll(layerPath)).To(Succeed())
})

it("downloads the dependency, strips given number of componenets and unpackages it into the path", func() {
err := deliver()

Expect(err).NotTo(HaveOccurred())

Expect(transport.DropCall.Receives.Root).To(Equal("some-cnb-path"))
Expect(transport.DropCall.Receives.Uri).To(Equal("some-entry.tgz"))

files, err := filepath.Glob(fmt.Sprintf("%s/*", layerPath))
Expect(err).NotTo(HaveOccurred())
Expect(files).To(ConsistOf([]string{
filepath.Join(layerPath, "first"),
filepath.Join(layerPath, "second"),
filepath.Join(layerPath, "third"),
filepath.Join(layerPath, "symlink"),
filepath.Join(layerPath, "some-file"),
}))

info, err := os.Stat(filepath.Join(layerPath, "first"))
Expect(err).NotTo(HaveOccurred())
Expect(info.Mode()).To(Equal(os.FileMode(0755)))
})

})

context("when there is a dependency mapping via binding", func() {
it.Before(func() {
Expand Down

0 comments on commit 7eca5c1

Please sign in to comment.