Bumping packages is one of the most common tasks of a Gentoo developer. It shouldn’t then be surprising that it is the one most asking for some kind of automation, and that the pkgbump script would be one of the first scripts to become a part of the mgorny-dev-scripts package.
Today’s pkgbump have come a long way from the trivial script of its first iteration. The most recent versions finally feature the feature I desired for a long time: version manipulation. This also made it possible for the script to become a complete version bumping tool rather than just a part of a larger workflow. In this post, I’d like to shortly tell the story behind the changes, and demonstrate the new options.
The first iteration
The initial version of pkgbump was quite trivial. It took two paths: source and destination. It copied the ebuild file, lowered the keywords, bumped the copyright date, updated the Manifest and run the pkgdiff (now pkgdiff-mg) tool to compare the unpacked archives. So a typical workflow would look like:
cdpkg svglib
pkgbump svglib-2.0.{1,2}.ebuild
vim svglib-2.0.2.ebuild # if necessary
# test the package in another terminal
pkgcommit -sS . -m 'Bump to 2.0.2'
Obviously, there’s some duplication here, and a potential for improvement. And over time, some improvements would happen. I’ve added support for removing obsolete Python implementations from PYTHON_COMPAT, support for PKGBUMPING variable that would be used to skip unpacking crates when diffing and integration with pkgcommit, so instead of repeating the version number, you’d do:
pkgcommit -sS . --bump
Bumping groups of packages
If pkgbump was sometimes cumbersome to use, that would be especially felt in groups of packages such as dev-python/botocore, dev-python/boto3 and app-admin/awscli. These three packages are released simulaneously, usually 5 times as week, often with slightly different version numbers. So you’d end up doing something like:
pkgbump botocore-1.24.{0,1}.ebuild
pkgbump boto3-1.21.{0,1}.ebuild
pkgbump awscli-1.22.{55,56}.ebuild
Thus, bump-boto was born. In its initial incarnation, it would take the old and new patch versions, and compute all the remaining numbers. So you’d just invoke:
bump-boto 0 1>
In this initial version, I’d have to update the script whenever upstream changed the minor version number. The next incarnation would actually grab the minor version number from the repository, but would still require changes whenever the alignment between patch numbers changed.
Eventually, I would replace the patch version arguments with an “increment”. So you’d just specify:
bump-boto +1
And it would increment the patch version of all packages by one. Of course, whenever the minor version or alignment changed, I would still have to pkgbump them manually, but bump-boto would work just fine for the subsequent release, no modifications needed.
For a long time, this was a function unique to bump-boto, with a pretty dumb implementation. However, the period of frequent kernel updates, requiring me to keep retyping 7 version pairs, finally motivated me to make it more generic. Just imagine typing the equivalent of, twice a day:
bump-kernels 7.0.{12,13} 6.18.{35,36} 6.12.{93,94} 6.6.{142,143} 6.1.{175,176} 5.15.{209,210} 5.10.{258,259}
Generic increments in pkgbump
The latest versions of pkgbump still accept two positional arguments: source and destination. However, they do not have to be filenames anymore.
The destination can be a version number or an increment instead. So you could do either of:
pkgbump gentoo-kernel-7.0.12.ebuild 7.0.13 pkgbump gentoo-kernel-7.0.12.ebuild +1
What about the minor version changing? The increment can be followed by one or more version components, in which case the final components are set to the specified value, and the one preceding them is incremented. So you can do either of:
pkgbump gentoo-kernel-7.0.12.ebuild 7.1.0 pkgbump gentoo-kernel-7.0.12.ebuild +1.0
Or:
pkgbump gentoo-kernel-7.0.12.ebuild 7.1.2 pkgbump gentoo-kernel-7.0.12.ebuild +1.2
The source can be a pattern instead, in which case the script finds the ebuild with the highest version number matching it:
pkgbump 'gentoo-kernel-7.0.*.ebuild' +1 pkgbump 'gentoo-kernel-6.18.*.ebuild' +1
At this point, I could make the arguments optional. If source is omitted, '*.ebuild' is assumed. If destination is omitted, an increment of +1 is assumed. So the following are all valid:
pkgbump 'gentoo-kernel-6.18.*.ebuild' # dest.: +1 pkgbump +2 # source: '*.ebuild' pkgbump 1.2.3 # source: '*.ebuild' pkgbump # source: '*.ebuild', dest.: +1
More options for an integrated workflow
At the same time, I’ve added a few options to pkgbump to make it more suitable for an all-in-one tool. So effectively the process becomes, depending on options given:
- Copy the ebuild, copybump, clean it.
- Lower the keywords, unless -s / --stable is passed.
- Run the editor to edit the ebuild, if -E / --edit-early is passed.
- Update Manifest, unless -M / --no-manifest is passed.
- Diff the working directories, unless -D / --no-diff is passed.
- Run the editor to edit the ebuild, if -e / --edit is passed.
- Commit the changes, if -c / --commit is passed.
So it would now be possible to reduce the initial workflow to a single call:
pkgbump -e -c
And that’s it! It means “pick the latest ebuild, increment the final version component by one, manifest, diff, edit and commit.”
Bumping kernels the easy way
This meant that I could finally make bumping kernels easier. The scripts are still work-in-progress, but now I can specify the branches instead of version pairs, to increment them all by one:
bump-kernels 7.0 6.18 6.12 6.6 6.1
Or I can just run the script without arguments to have it determine the available branches and bump them all:
bump-kernels
Snippets for the future
One of the features of pkgbump is that it attempts to do some minimal cleanup / modernization of ebuilds. For example, quite early I’ve added the cleanup of old Python implementations from PYTHON_COMPAT; it’s something that’s not urgent enough to justify the noise of mass updating, but worth doing if you’re bumping the ebuild anyway.
Lately I wanted to add another similar function: updating the deprecated DISTUTILS_USE_PEP517 values. Again, this is nothing urgent; it will be required for EAPI 9 though. And similarly to PYTHON_COMPAT updates, it’s quite specific to Python. It felt that pkgbump would end up with a lot of Python-specific logic for a generic tool.
But why restrict yourself to Python? I’m definitely open to adding other kinds of cleanup functions that people submit; except that keeping all that different logic inline feels kinda ugly. So the most recent version of pkgbump features cleanup snippets!
The Python-specific code is gone from the tool (only the generic copyright bumping and keyword lowering logic remains in the core), and now lives in /usr/lib/pkgbump.d/python. New scripts can also be dropped into that directory, either as part of mgorny-dev-scripts, or separately packaged. And there’s /etc/pkgbump.d for user scripts, which can also be used to override system scripts. So if you don’t want pkgbump to be doing its Python magic, you can drop a replacement /etc/pkgbump.d/python.