Skip to content

Commit aa49ae6

Browse files
authored
Merge pull request #1109 from samj1912/cnb-extension
Add a .cnb extension by default on buildpackage creation Signed-off-by: David Freilich <freilich.david@gmail.com>
2 parents e00ee4a + 626fc5c commit aa49ae6

5 files changed

Lines changed: 97 additions & 13 deletions

File tree

acceptance/acceptance_test.go

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -338,16 +338,47 @@ func testWithoutSpecificBuilderRequirement(
338338
})
339339

340340
when("--format file", func() {
341-
it("creates the package", func() {
342-
packageTomlPath := generatePackageTomlWithOS(t, assert, pack, tmpDir, simplePackageConfigFixtureName, imageManager.HostOS())
343-
destinationFile := filepath.Join(tmpDir, "package.cnb")
344-
output := pack.RunSuccessfully(
345-
"buildpack", "package", destinationFile,
346-
"--format", "file",
347-
"-c", packageTomlPath,
348-
)
349-
assertions.NewOutputAssertionManager(t, output).ReportsPackageCreation(destinationFile)
350-
h.AssertTarball(t, destinationFile)
341+
when("the file extension is .cnb", func() {
342+
it("creates the package with the same extension", func() {
343+
packageTomlPath := generatePackageTomlWithOS(t, assert, pack, tmpDir, simplePackageConfigFixtureName, imageManager.HostOS())
344+
destinationFile := filepath.Join(tmpDir, "package.cnb")
345+
output := pack.RunSuccessfully(
346+
"buildpack", "package", destinationFile,
347+
"--format", "file",
348+
"-c", packageTomlPath,
349+
)
350+
assertions.NewOutputAssertionManager(t, output).ReportsPackageCreation(destinationFile)
351+
h.AssertTarball(t, destinationFile)
352+
})
353+
})
354+
when("the file extension is empty", func() {
355+
it("creates the package with a .cnb extension", func() {
356+
packageTomlPath := generatePackageTomlWithOS(t, assert, pack, tmpDir, simplePackageConfigFixtureName, imageManager.HostOS())
357+
destinationFile := filepath.Join(tmpDir, "package")
358+
expectedFile := filepath.Join(tmpDir, "package.cnb")
359+
output := pack.RunSuccessfully(
360+
"buildpack", "package", destinationFile,
361+
"--format", "file",
362+
"-c", packageTomlPath,
363+
)
364+
assertions.NewOutputAssertionManager(t, output).ReportsPackageCreation(expectedFile)
365+
h.AssertTarball(t, expectedFile)
366+
})
367+
})
368+
when("the file extension is not .cnb", func() {
369+
it("creates the package with the given extension but shows a warning", func() {
370+
packageTomlPath := generatePackageTomlWithOS(t, assert, pack, tmpDir, simplePackageConfigFixtureName, imageManager.HostOS())
371+
destinationFile := filepath.Join(tmpDir, "package.tar.gz")
372+
output := pack.RunSuccessfully(
373+
"buildpack", "package", destinationFile,
374+
"--format", "file",
375+
"-c", packageTomlPath,
376+
)
377+
assertOutput := assertions.NewOutputAssertionManager(t, output)
378+
assertOutput.ReportsPackageCreation(destinationFile)
379+
assertOutput.ReportsInvalidExtension(".gz")
380+
h.AssertTarball(t, destinationFile)
381+
})
351382
})
352383
})
353384

acceptance/assertions/output.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,12 @@ func (o OutputAssertionManager) ReportsPackageCreation(name string) {
112112
o.assert.ContainsF(o.output, "Successfully created package '%s'", name)
113113
}
114114

115+
func (o OutputAssertionManager) ReportsInvalidExtension(extension string) {
116+
o.testObject.Helper()
117+
118+
o.assert.ContainsF(o.output, "'%s' is not a valid extension for a packaged buildpack. Packaged buildpacks must have a '.cnb' extension", extension)
119+
}
120+
115121
func (o OutputAssertionManager) ReportsPackagePublished(name string) {
116122
o.testObject.Helper()
117123

internal/commands/buildpack_package.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,11 @@ func BuildpackPackage(logger logging.Logger, cfg config.Config, client Buildpack
4242
Use: "package <name> --config <config-path>",
4343
Short: "Package a buildpack in OCI format.",
4444
Args: cobra.ExactValidArgs(1),
45-
Example: "pack buildpack package my-buildpack --config ./package.toml",
45+
Example: "pack buildpack package my-buildpack --config ./package.toml\npack buildpack package my-buildpack.cnb --config ./package.toml --f file",
4646
Long: "buildpack package allows users to package (a) buildpack(s) into OCI format, which can then to be hosted in " +
47-
"image repositories. You can also package a number of buildpacks together, to enable easier distribution of " +
48-
"a set of buildpacks. Packaged buildpacks can be used as inputs to `pack build` (using the `--buildpack` flag), " +
47+
"image repositories or persisted on disk as a '.cnb' file. You can also package a number of buildpacks " +
48+
"together, to enable easier distribution of a set of buildpacks. " +
49+
"Packaged buildpacks can be used as inputs to `pack build` (using the `--buildpack` flag), " +
4950
"and they can be included in the configs used in `pack builder create` and `pack buildpack package`. For more " +
5051
"on how to package a buildpack, see: https://buildpacks.io/docs/buildpack-author-guide/package-a-buildpack/.",
5152
RunE: logError(logger, func(cmd *cobra.Command, args []string) error {
@@ -82,6 +83,15 @@ func BuildpackPackage(logger logging.Logger, cfg config.Config, client Buildpack
8283
}
8384
}
8485
name := args[0]
86+
if flags.Format == pack.FormatFile {
87+
switch ext := filepath.Ext(name); ext {
88+
case pack.CNBExtension:
89+
case "":
90+
name += pack.CNBExtension
91+
default:
92+
logger.Warnf("%s is not a valid extension for a packaged buildpack. Packaged buildpacks must have a %s extension", style.Symbol(ext), style.Symbol(pack.CNBExtension))
93+
}
94+
}
8595
if err := client.PackageBuildpack(cmd.Context(), pack.PackageBuildpackOptions{
8696
RelativeBaseDir: relativeBaseDir,
8797
Name: name,

internal/commands/buildpack_package_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,40 @@ func testPackageCommand(t *testing.T, when spec.G, it spec.S) {
8888
h.AssertEq(t, receivedOptions.Config, myConfig)
8989
})
9090

91+
when("file format", func() {
92+
when("extension is .cnb", func() {
93+
it("does not modify the name", func() {
94+
cmd := packageCommand(withBuildpackPackager(fakeBuildpackPackager))
95+
cmd.SetArgs([]string{"test.cnb", "-f", "file"})
96+
h.AssertNil(t, cmd.Execute())
97+
98+
receivedOptions := fakeBuildpackPackager.CreateCalledWithOptions
99+
h.AssertEq(t, receivedOptions.Name, "test.cnb")
100+
})
101+
})
102+
when("extension is empty", func() {
103+
it("appends .cnb to the name", func() {
104+
cmd := packageCommand(withBuildpackPackager(fakeBuildpackPackager))
105+
cmd.SetArgs([]string{"test", "-f", "file"})
106+
h.AssertNil(t, cmd.Execute())
107+
108+
receivedOptions := fakeBuildpackPackager.CreateCalledWithOptions
109+
h.AssertEq(t, receivedOptions.Name, "test.cnb")
110+
})
111+
})
112+
when("extension is something other than .cnb", func() {
113+
it("does not modify the name but shows a warning", func() {
114+
cmd := packageCommand(withBuildpackPackager(fakeBuildpackPackager), withLogger(logger))
115+
cmd.SetArgs([]string{"test.tar.gz", "-f", "file"})
116+
h.AssertNil(t, cmd.Execute())
117+
118+
receivedOptions := fakeBuildpackPackager.CreateCalledWithOptions
119+
h.AssertEq(t, receivedOptions.Name, "test.tar.gz")
120+
h.AssertContains(t, outBuf.String(), "'.gz' is not a valid extension for a packaged buildpack. Packaged buildpacks must have a '.cnb' extension")
121+
})
122+
})
123+
})
124+
91125
when("there is a path flag", func() {
92126
it("returns an error saying that it cannot be used with the config flag", func() {
93127
myConfig := pubbldpkg.Config{

package_buildpack.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ const (
2222

2323
// Packaging indicator that format of output will be a file on the host filesystem.
2424
FormatFile = "file"
25+
26+
// CNBExtension is the file extension for a cloud native buildpack tar archive
27+
CNBExtension = ".cnb"
2528
)
2629

2730
// PackageBuildpackOptions is a configuration object used to define

0 commit comments

Comments
 (0)