Bump Your Semantic Version
While looking at some old bash script that bumps my semantic versions I almost puked looking at my old ham handed way of bumping the version. That led me to see how I could do it "better". Why? I dunno know...bored on a Saturday morning and not motivated enough to do the NY Times crossword... So you want to bump a semantic version string like 1.2.3 major, minor, or patch - and you don’t want ceremony. You want one line, no dependencies, and enough arcane flair to scare off coworkers. Here's a single-line Bash–Perl spell that does exactly that: v=$(cat VERSION | p=$1 perl -a -F[.] -pe \ '$i=$ENV{p};$F[$i]++;$j=$i+1;$F[$_]=0 for $j..2;$"=".";$_="@F"') What It Does Reads the current version from a VERSION file (1.2.3) Increments the part you pass (0 for major, 1 for minor, 2 for patch) Resets all lower parts to zero Writes the result to v Scriptlet Form Wrap it like this in a shell function: bump() { v=$(cat VERSION | p=$1 perl -a -F[.] -pe \ '$i=$ENV{p};$F[$i]++;$j=$i+1;$F[$_]=0 for $j..2;$"=".";$_="@F"') echo "$v" > VERSION } Then run: bump 2 # bump patch (1.2.3 => 1.2.4) bump 1 # bump minor (1.2.3 => 1.3.0) bump 0 # bump major (1.2.3 => 2.0.0) Makefile Integration Want to bump right from make? bump-major: @v=$$(cat VERSION | p=0 perl -a -F[.] -pe '$$i=$$ENV{p};$$F[$$i]++;$$j=$$i+1;$$F[$$_]=0 for $$j..2;$$"=".";$_="$$F"') && \ echo $$v > VERSION && echo "New version: $$v" bump-minor: @$(MAKE) bump-major p=1 bump-patch: @$(MAKE) bump-major p=2 Or break it out into a .bump-version script and source it from your build tooling. How It Works (or ...Why I Love Perl) -a # autosplit into @F -F[.] # split on literal dot $i=$ENV{p} # get part index from environment (e.g., 1 for minor) $F[$i]++ # bump it $j=$i+1 # start index for resetting $F[$_]=0 ... # zero the rest $"="."; # join array with dots $_="@F" # set output If you have to explain this to some junior dev, just say RTFM skippy perldoc perlrun. Use the force Luke. And if the senior dev wags his finger and say UUOC, tell him Ego malum edo.

While looking at some old bash
script that bumps my semantic
versions I almost puked looking at my old ham handed way of bumping
the version. That led me to see how I could do it "better". Why? I
dunno know...bored on a Saturday morning and not motivated enough to
do the NY Times crossword...
So you want to bump a semantic version string like 1.2.3
- major, minor, or patch - and you don’t want ceremony. You want one line, no dependencies, and enough arcane flair to scare off coworkers.
Here's a single-line Bash–Perl spell that does exactly that:
v=$(cat VERSION | p=$1 perl -a -F[.] -pe \
'$i=$ENV{p};$F[$i]++;$j=$i+1;$F[$_]=0 for $j..2;$"=".";$_="@F"')
What It Does
- Reads the current version from a
VERSION
file (1.2.3
) - Increments the part you pass (
0
for major,1
for minor,2
for patch) - Resets all lower parts to zero
- Writes the result to
v
Scriptlet Form
Wrap it like this in a shell function:
bump() {
v=$(cat VERSION | p=$1 perl -a -F[.] -pe \
'$i=$ENV{p};$F[$i]++;$j=$i+1;$F[$_]=0 for $j..2;$"=".";$_="@F"')
echo "$v" > VERSION
}
Then run:
bump 2 # bump patch (1.2.3 => 1.2.4)
bump 1 # bump minor (1.2.3 => 1.3.0)
bump 0 # bump major (1.2.3 => 2.0.0)
Makefile Integration
Want to bump right from make
?
bump-major:
@v=$$(cat VERSION | p=0 perl -a -F[.] -pe '$$i=$$ENV{p};$$F[$$i]++;$$j=$$i+1;$$F[$$_]=0 for $$j..2;$$"=".";$_="$$F"') && \
echo $$v > VERSION && echo "New version: $$v"
bump-minor:
@$(MAKE) bump-major p=1
bump-patch:
@$(MAKE) bump-major p=2
Or break it out into a .bump-version
script and source it from your build tooling.
How It Works (or ...Why I Love Perl)
-a # autosplit into @F
-F[.] # split on literal dot
$i=$ENV{p} # get part index from environment (e.g., 1 for minor)
$F[$i]++ # bump it
$j=$i+1 # start index for resetting
$F[$_]=0 ... # zero the rest
$"="."; # join array with dots
$_="@F" # set output
If you have to explain this to some junior dev, just say RTFM skippy
perldoc perlrun
. Use the force Luke.
And if the senior dev wags his finger and say UUOC, tell him Ego
malum edo.