Pruning Pack CLI Commands

David Freilich
Buildpacks
Published in
3 min readJan 14, 2021

Pack CLI v0.16.0 introduces some startling UX changes. Users will see the list of available commands shrink from:

$ pack
Available Commands:
build Generate app image from source code
rebase Rebase app image with latest run image
inspect-image Show information about a built image
inspect-buildpack Show information about a buildpack
set-run-image-mirrors Set mirrors to other repositories ...
set-default-builder Set default builder used by other commands
inspect-builder Show information about a builder
suggest-builders Display list of recommended builders
trust-builder Trust builder
untrust-builder Stop trusting builder
list-trusted-builders List Trusted Builders
create-builder Create builder image
package-buildpack Package buildpack in OCI format.
version Show current 'pack' version
report Display useful information for reporting ...
add-registry (experimental) Add buildpack registry to
list-registries (experimental) List buildpack registries
register-buildpack (experimental) Register the buildpack to ...
set-default-registry (experimental) Set default registry
remove-registry (experimental) Remove registry
yank-buildpack (experimental) Yank the buildpack from ...
completion Outputs completion script location
stack Displays stack information
help Help about any command

to:

$ pack
Available Commands:
build Generate app image from source code
builder Interact with builders
buildpack Interact with buildpacks
config Interact with your local pack config file
stack Interact with stacks
rebase Rebase app image with latest run image
inspect-image Show information about a built image
inspect-buildpack Show information about a buildpack
inspect-builder Show information about a builder
completion Outputs completion script location
report Display useful information for reporting ...
version Show current 'pack' version
help Help about any command

Note: The previous commands were deprecated, but still work as they did. They are just no longer suggested to users, with intention to remove them entirely in one or two releases.

One question remains:

Why?!?!

Design

As the number of commands for pack grew (a whopping 24 in the last release), we realized that it was becoming more and more difficult to identify interworking subcommands with a glance. As such, we wanted to reorganize the commands by resource type, to simplify usage of pack.

Let’s show this with an example. We had a number of commands focused on manipulating buildpacks:

$ pack
...
package-buildpack Package buildpack in OCI format.
...
register-buildpack (experimental) Register the buildpack to a registry
...
yank-buildpack (experimental) Yank the buildpack from the registry

These commands, while they are linked, weren’t necessarily relevant to users who weren’t buildpack authors, and they could be hard to discover if you were a buildpack author. As such, we have now grouped them as subcommands under a single command, pack buildpack

$  pack buildpack
Interact with buildpacks
Usage:
pack buildpack [command]
Available Commands:
package Package buildpack in OCI format.
pull (experimental) Pull the buildpack from a registry and store it locally
register (experimental) Register the buildpack to a registry
yank (experimental) Yank the buildpack from the registry

This is a relatively common pattern, as CLIs grow more complex. For example, popular CLIs that have resource based subcommands include docker, gcloud, heroku, and kubectl.

This change also allowed us to make a significant improvement, with the addition of a single command, pack config . That command now wraps all of functionality for manipulating the configuration file (where we maintain users lists of default-builder, trusted-builders, run-image-mirrors, and more) in a uniform way.

Our Process

This change was a long time coming. The Cloud Native Buildpacks project follows an RFC (Request for Comments) process for substantial changes to the project (described here). As such, platform maintainer Javier Romero created an RFC proposal in July, suggesting that we switch to a resource-based subcommand structure, rather than keeping all commands top-level.

That proposal, after considerable discussion, was merged in September, and issues were created for the various changes required in October. The process was kicked off by a new contributor (thanks anshlykov!) submitting a PR to add a new stack resource subcommand, and the race was on. Over the past few weeks, we’ve converted most of the previous commands to subcommands of 4 main commands: pack builder, pack buildpack, pack config, and pack stack.

We think that this should make for a better CLI organization, but ultimately, that depends on you. Try it out, and let us know what you think of the experience by participating in the discussions on slack or Github. In particular, let us know whether you think we should add a new inspect subcommand to group the three inspect-X commands we have currently, by participating on Github.

As ever, thanks for contributing to and enjoying the project!

--

--