Skip to content

Commit

Permalink
Add .cnb file support for package-buildpack dependencies
Browse files Browse the repository at this point in the history
* Close #586

Signed-off-by: David Freilich <[email protected]>
  • Loading branch information
dfreilich committed May 18, 2020
1 parent 7de5225 commit 37a31da
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 6 deletions.
28 changes: 22 additions & 6 deletions package_buildpack.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,31 +51,47 @@ func (c *Client) PackageBuildpack(ctx context.Context, opts PackageBuildpackOpti

packageBuilder.SetBuildpack(bp)

var bps []dist.Buildpack
for _, dep := range opts.Config.Dependencies {
if dep.URI != "" {
blob, err := c.downloader.Download(ctx, dep.URI)
if err != nil {
return errors.Wrapf(err, "downloading buildpack from %s", style.Symbol(dep.URI))
}

depBP, err := dist.BuildpackFromRootBlob(blob, archive.DefaultTarWriterFactory())
isOCILayout, err := buildpackage.IsOCILayoutBlob(blob)
if err != nil {
return errors.Wrapf(err, "creating buildpack from %s", style.Symbol(dep.URI))
return errors.Wrap(err, "inspecting buildpack blob")
}

packageBuilder.AddDependency(depBP)
if isOCILayout {
mainBP, depBPs, err := buildpackage.BuildpacksFromOCILayoutBlob(blob)
if err != nil {
return errors.Wrapf(err, "extracting buildpacks from %s", style.Symbol(dep.URI))
}

bps = append([]dist.Buildpack{mainBP}, depBPs...)
} else {
depBP, err := dist.BuildpackFromRootBlob(blob, archive.DefaultTarWriterFactory())
if err != nil {
return errors.Wrapf(err, "creating buildpack from %s", style.Symbol(dep.URI))
}
bps = []dist.Buildpack{depBP}
}
} else if dep.ImageName != "" {
mainBP, depBPs, err := extractPackagedBuildpacks(ctx, dep.ImageName, c.imageFetcher, opts.Publish, opts.NoPull)
if err != nil {
return err
}

for _, depBP := range append([]dist.Buildpack{mainBP}, depBPs...) {
packageBuilder.AddDependency(depBP)
}
bps = append([]dist.Buildpack{mainBP}, depBPs...)
}
}

for _, depBP := range bps {
packageBuilder.AddDependency(depBP)
}

switch opts.Format {
case FormatFile:
return packageBuilder.SaveAsFile(opts.Name)
Expand Down
73 changes: 73 additions & 0 deletions package_buildpack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,38 @@ func testPackageBuildpack(t *testing.T, when spec.G, it spec.S) {
})
})

when("dependencies have issues", func() {
when("dependencies include a flawed packaged buildpack file", func() {
it("should fail", func() {
dependencyPath := "fakePath.file"
mockDownloader.EXPECT().Download(gomock.Any(), dependencyPath).Return(blob.NewBlob("no-file.txt"), nil).AnyTimes()

packageDescriptor := dist.BuildpackDescriptor{
API: api.MustParse("0.2"),
Info: dist.BuildpackInfo{ID: "bp.1", Version: "1.2.3"},
Order: dist.Order{{
Group: []dist.BuildpackRef{{
BuildpackInfo: dist.BuildpackInfo{ID: "bp.nested", Version: "2.3.4"},
Optional: false,
}},
}},
}

err := subject.PackageBuildpack(context.TODO(), pack.PackageBuildpackOptions{
Name: "test",
Config: pubbldpkg.Config{
Buildpack: dist.BuildpackURI{URI: createBuildpack(packageDescriptor)},
Dependencies: []dist.ImageOrURI{{BuildpackURI: dist.BuildpackURI{URI: dependencyPath}}},
},
Publish: false,
NoPull: false,
})

h.AssertError(t, err, "inspecting buildpack blob")
})
})
})

when("FormatImage", func() {
when("nested package lives in registry", func() {
var nestedPackage *fakes.Image
Expand Down Expand Up @@ -428,6 +460,47 @@ func testPackageBuildpack(t *testing.T, when spec.G, it spec.S) {
})
})
})

when("dependencies include a packaged buildpack file", func() {
var (
dependencyPackagePath string
tmpDir string
err error
)
it.Before(func() {
tmpDir, err = ioutil.TempDir("", "package-buildpack")
h.AssertNil(t, err)

dependencyPackagePath = filepath.Join(tmpDir, "dep.cnb")

h.AssertNil(t, subject.PackageBuildpack(context.TODO(), pack.PackageBuildpackOptions{
Name: dependencyPackagePath,
Config: pubbldpkg.Config{
Buildpack: dist.BuildpackURI{URI: createBuildpack(childDescriptor)},
},
Format: pack.FormatFile,
}))

mockDownloader.EXPECT().Download(gomock.Any(), dependencyPackagePath).Return(blob.NewBlob(dependencyPackagePath), nil).AnyTimes()
})

it("should open file and correctly add buildpacks", func() {
packagePath := filepath.Join(tmpDir, "test.cnb")

h.AssertNil(t, subject.PackageBuildpack(context.TODO(), pack.PackageBuildpackOptions{
Name: packagePath,
Config: pubbldpkg.Config{
Buildpack: dist.BuildpackURI{URI: createBuildpack(packageDescriptor)},
Dependencies: []dist.ImageOrURI{{BuildpackURI: dist.BuildpackURI{URI: dependencyPackagePath}}},
},
Publish: false,
NoPull: false,
Format: pack.FormatFile,
}))

assertPackageBPFileHasBuildpacks(packagePath, packageDescriptor, childDescriptor)
})
})
})

when("unknown format is provided", func() {
Expand Down

0 comments on commit 37a31da

Please sign in to comment.