Skip to content

Commit

Permalink
Merge pull request #1783 from buildpacks/enhancement/flatten-buildpac…
Browse files Browse the repository at this point in the history
…kage-experimental

Flatten buildpack package is move to be experimental
  • Loading branch information
jkutner authored Jun 20, 2023
2 parents 52902b0 + 37747ef commit 5a61950
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 11 deletions.
27 changes: 21 additions & 6 deletions internal/commands/buildpack_package.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func BuildpackPackage(logger logging.Logger, cfg config.Config, packager Buildpa
"and they can be included in the configs used in `pack builder create` and `pack buildpack package`. For more " +
"on how to package a buildpack, see: https://buildpacks.io/docs/buildpack-author-guide/package-a-buildpack/.",
RunE: logError(logger, func(cmd *cobra.Command, args []string) error {
if err := validateBuildpackPackageFlags(&flags); err != nil {
if err := validateBuildpackPackageFlags(cfg, &flags); err != nil {
return err
}

Expand Down Expand Up @@ -96,6 +96,10 @@ func BuildpackPackage(logger logging.Logger, cfg config.Config, packager Buildpa
logger.Warnf("%s is not a valid extension for a packaged buildpack. Packaged buildpacks must have a %s extension", style.Symbol(ext), style.Symbol(client.CNBExtension))
}
}
if flags.Flatten {
logger.Warn("Flattening a buildpack package could break the distribution specification. Please use it with caution.")
}

if err := packager.PackageBuildpack(cmd.Context(), client.PackageBuildpackOptions{
RelativeBaseDir: relativeBaseDir,
Name: name,
Expand Down Expand Up @@ -134,22 +138,33 @@ func BuildpackPackage(logger logging.Logger, cfg config.Config, packager Buildpa
cmd.Flags().BoolVar(&flags.Flatten, "flatten", false, "Flatten the buildpack into a single layer")
cmd.Flags().StringSliceVarP(&flags.FlattenExclude, "flatten-exclude", "e", nil, "Buildpacks to exclude from flattening, in the form of '<buildpack-id>@<buildpack-version>'")
cmd.Flags().IntVar(&flags.Depth, "depth", -1, "Max depth to flatten.\nOmission of this flag or values < 0 will flatten the entire tree.")
if !cfg.Experimental {
cmd.Flags().MarkHidden("flatten")
cmd.Flags().MarkHidden("depth")
cmd.Flags().MarkHidden("flatten-exclude")
}
AddHelpFlag(cmd, "package")
return cmd
}

func validateBuildpackPackageFlags(p *BuildpackPackageFlags) error {
func validateBuildpackPackageFlags(cfg config.Config, p *BuildpackPackageFlags) error {
if p.Publish && p.Policy == image.PullNever.String() {
return errors.Errorf("--publish and --pull-policy never cannot be used together. The --publish flag requires the use of remote images.")
}
if p.PackageTomlPath != "" && p.Path != "" {
return errors.Errorf("--config and --path cannot be used together. Please specify the relative path to the Buildpack directory in the package config file.")
}

if p.Flatten && len(p.FlattenExclude) > 0 {
for _, exclude := range p.FlattenExclude {
if strings.Count(exclude, "@") != 1 {
return errors.Errorf("invalid format %s; please use '<buildpack-id>@<buildpack-version>' to exclude buildpack from flattening", exclude)
if p.Flatten {
if !cfg.Experimental {
return client.NewExperimentError("Flattening a buildpack package is currently experimental.")
}

if len(p.FlattenExclude) > 0 {
for _, exclude := range p.FlattenExclude {
if strings.Count(exclude, "@") != 1 {
return errors.Errorf("invalid format %s; please use '<buildpack-id>@<buildpack-version>' to exclude buildpack from flattening", exclude)
}
}
}
}
Expand Down
37 changes: 33 additions & 4 deletions internal/commands/buildpack_package_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,42 @@ func testPackageCommand(t *testing.T, when spec.G, it spec.S) {
})
})
when("flatten is set to true", func() {
when("flatten exclude doesn't have format <buildpack>@<version>", func() {
when("experimental is true", func() {
when("flatten exclude doesn't have format <buildpack>@<version>", func() {
it("errors with a descriptive message", func() {
cmd := packageCommand(withClientConfig(config.Config{Experimental: true}), withBuildpackPackager(fakeBuildpackPackager))
cmd.SetArgs([]string{"test", "-f", "file", "--flatten", "--flatten-exclude", "some-buildpack"})

err := cmd.Execute()
h.AssertError(t, err, fmt.Sprintf("invalid format %s; please use '<buildpack-id>@<buildpack-version>' to exclude buildpack from flattening", "some-buildpack"))
})
})

when("no exclusions", func() {
it("creates package with correct image name and warns flatten is being used", func() {
cmd := packageCommand(
withClientConfig(config.Config{Experimental: true}),
withBuildpackPackager(fakeBuildpackPackager),
withLogger(logger),
)
cmd.SetArgs([]string{"my-flatten-image", "-f", "file", "--flatten"})
err := cmd.Execute()
h.AssertNil(t, err)

receivedOptions := fakeBuildpackPackager.CreateCalledWithOptions
h.AssertEq(t, receivedOptions.Name, "my-flatten-image.cnb")
h.AssertContains(t, outBuf.String(), "Flattening a buildpack package could break the distribution specification. Please use it with caution.")
})
})
})

when("experimental is false", func() {
it("errors with a descriptive message", func() {
cmd := packageCommand(withBuildpackPackager(fakeBuildpackPackager))
cmd.SetArgs([]string{"test", "-f", "file", "--flatten", "--flatten-exclude", "some-buildpack"})
cmd := packageCommand(withClientConfig(config.Config{Experimental: false}), withBuildpackPackager(fakeBuildpackPackager))
cmd.SetArgs([]string{"test", "-f", "file", "--flatten"})

err := cmd.Execute()
h.AssertError(t, err, fmt.Sprintf("invalid format %s; please use '<buildpack-id>@<buildpack-version>' to exclude buildpack from flattening", "some-buildpack"))
h.AssertError(t, err, "Flattening a buildpack package is currently experimental.")
})
})
})
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/package_buildpack.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func PackageBuildpack(logger logging.Logger, cfg config.Config, packager Buildpa
RunE: logError(logger, func(cmd *cobra.Command, args []string) error {
deprecationWarning(logger, "package-buildpack", "buildpack package")

if err := validateBuildpackPackageFlags(&flags); err != nil {
if err := validateBuildpackPackageFlags(cfg, &flags); err != nil {
return err
}

Expand Down

0 comments on commit 5a61950

Please sign in to comment.