Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: semver increment #54

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 8 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ make install
## Usage

```bash
semver [-hqstw]
semver [-hiqstw]
```

Options:

- `-h --help`
Show the help screen.
- `-i --increment <major|minor|patch>`
Increment the specified component of the matched versions.
- `-q --quiet`
Quiet - suppress normal output.
- `-s --sort`
Expand All @@ -54,7 +56,7 @@ Options:
- `-w --word-match`
Select words that match the semver pattern. (Equivalent to the *grep(1)* `--word-regexp` option.)

Most options can be combined. For example, `semver -stw` will word-match occurrences of semvers, sort them, and print them in tabulated form.
Options can be combined. For example, `semver -stw` will word-match occurrences of semvers, sort them, and print them in tabulated form.

## Manual

Expand All @@ -73,14 +75,11 @@ semver < example.txt
**Calculate** the next Git tag:

```bash
# ++major
git tag | semver -st | tail -n 1 | awk -F '\t' '{ print ++$1 "." 0 "." 0 }'
git tag | semver -s | tail -n 1 | semver -i major

# ++minor
git tag | semver -st | tail -n 1 | awk -F '\t' '{ print $1 "." ++$2 "." 0 }'
git tag | semver -s | tail -n 1 | semver -i minor

# ++patch
git tag | semver -st | tail -n 1 | awk -F '\t' '{ print $1 "." $2 "." ++$3 }'
git tag | semver -s | tail -n 1 | semver -i patch
```

**Cut** out the major, minor, and patch components of a version:
Expand All @@ -94,7 +93,7 @@ semver -t <<< '1.2.3-alpha+1' | cut -f 1-3
```bash
v='0.0.1'
while curl -fs "https://example.com/artifact/$v.tar.gz" > "$v.tar.gz"; do
v=$(semver -t <<< "$v" | awk -F '\t' '{ print $1 "." $2 "." ++$3 }')
v=$(semver -i patch <<< "$v")
done
```

Expand All @@ -115,31 +114,3 @@ semver -tw < example.txt | tr '\t' ','
```bash
semver -q <<< '1.2.3' && echo 'ok'
```

## Functions

These Bash helper functions can make complex versioning operations easier.

```bash
#!/usr/bin/env bash

function ++major {
semver -t <<< "$1" | awk -F '\t' '{ print ++$1 "." 0 "." 0 }'
}

function ++minor {
semver -t <<< "$1" | awk -F '\t' '{ print $1 "." ++$2 "." 0 }'
}

function ++patch {
semver -t <<< "$1" | awk -F '\t' '{ print $1 "." $2 "." ++$3 }'
}
```

Examples:

```bash
++major '1.2.3' #=> 2.0.0
++minor '1.2.3' #=> 1.3.0
++patch '1.2.3' #=> 1.2.4
```
56 changes: 38 additions & 18 deletions semver
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use strict;
use warnings;
use feature qw(say);
use feature qw(say switch);
use Scalar::Util qw(looks_like_number);
use List::Util qw(max);
use Getopt::Long qw(GetOptionsFromArray :config bundling);
Expand All @@ -25,14 +25,15 @@ sub semver::usage() {
say STDERR "Semantic Versioning utility.";
say STDERR "";
say STDERR "Usage:";
say STDERR " $program [-hqstw]";
say STDERR " $program [-hiqstw]";
say STDERR "";
say STDERR "Options:";
say STDERR " -h --help Show the help screen.";
say STDERR " -q --quiet Quiet - suppress normal output.";
say STDERR " -s --sort Sort the matched versions in precedence order (low-to-high).";
say STDERR " -t --tabulate Tabulate the matched versions (separator: '\\t').";
say STDERR " -w --word-match Select words that match the semver pattern.";
say STDERR " -h --help Show the help screen.";
say STDERR " -i --increment <major|minor|patch> Increment the specified component of the matched versions.";
say STDERR " -q --quiet Quiet - suppress normal output.";
say STDERR " -s --sort Sort the matched versions in precedence order (low-to-high).";
say STDERR " -t --tabulate Tabulate the matched versions (separator: '\\t').";
say STDERR " -w --word-match Select words that match the semver pattern.";

exit 1;
}
Expand Down Expand Up @@ -143,7 +144,7 @@ sub semver::compare {
}

sub semver::match {
my ($quiet, $sort, $tabulate, $word_match) = @_;
my ($increment, $quiet, $sort, $tabulate, $word_match) = @_;

my $num_matches = 0;

Expand All @@ -166,12 +167,18 @@ sub semver::match {
exit 0;
}

my @ver = ($1, $2, $3, $4, $5);

if ($increment) {
@ver = inc($increment, $1, $2, $3);
}

if ($sort) {
push(@lines, plain($1, $2, $3, $4, $5));
push(@lines, plain(@ver));
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is happening the wrong way round. Versions should be sorted first, then incremented.

} elsif ($tabulate) {
say tabulate($1, $2, $3, $4, $5);
say tabulate(@ver);
} else {
say plain($1, $2, $3, $4, $5);
say plain(@ver);
}
}
}
Expand Down Expand Up @@ -213,6 +220,18 @@ sub semver::tabulate {
return $str;
}

sub semver::inc {
my ($increment, $major, $minor, $patch) = @_;

no warnings 'experimental';
for ($increment) {
when ("major") { return (++$major, 0, 0) }
when ("minor") { return ($major, ++$minor, 0) }
when ("patch") { return ($major, $minor, ++$patch) }
default { say STDERR "Error: unrecognised value for -i|--increment option. Allowed values are 'major', 'minor', or 'patch'."; exit 1; }
}
}

sub semver::plain {
my ($major, $minor, $patch, $pre, $build) = @_;

Expand All @@ -239,22 +258,23 @@ sub semver::sort_pair {
sub main {
my @args = @_;

my ($help, $quiet, $sort, $tabulate, $word_match);
my ($help, $increment, $quiet, $sort, $tabulate, $word_match);

main::GetOptionsFromArray(
\@args,
"help|h" => \$help,
"quiet|q" => \$quiet,
"sort|s" => \$sort,
"tabulate|t" => \$tabulate,
"word-match|w" => \$word_match
"help|h" => \$help,
"quiet|q" => \$quiet,
"increment|i=s" => \$increment,
"sort|s" => \$sort,
"tabulate|t" => \$tabulate,
"word-match|w" => \$word_match
) or exit 1;

if ($help || (scalar(@args) > 0)) {
usage();
}

match($quiet, $sort, $tabulate, $word_match);
match($increment, $quiet, $sort, $tabulate, $word_match);
}

main(@ARGV);
48 changes: 48 additions & 0 deletions test/options/increment.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env bats

semver() {
./semver "$@"
}

@test 'semver -i major: should increment the major version' {
[[ $(semver -i major <<< '1.2.3') = '2.0.0' ]]
}

@test 'semver -i minor: should increment the minor version' {
[[ $(semver -i minor <<< '1.2.3') = '1.3.0' ]]
}

@test 'semver -i patch: should increment the patch version' {
[[ $(semver -i patch <<< '1.2.3') = '1.2.4' ]]
}

@test 'semver -i patch: should increment a build modifier correctly' {
# TODO: is this the correct behaviour?
[[ $(semver -i patch <<< '1.2.3-alpha.1') = '1.2.3' ]]
}

@test 'semver -i: should reject unknown version component arguments' {
run semver -i foobar <<< '1.2.3'

[[ "$status" -eq 1 ]] && [[ "${lines[0]}" = "Error: unrecognised value for -i|--increment option. Allowed values are 'major', 'minor', or 'patch'." ]]
}

@test 'semver -i: should increment all matched versions' {
input=$(cat <<EOF
1.0.0
2.0.0
EOF
)

expected=$(cat <<EOF
2.0.0
3.0.0
EOF
)

[[ "$(semver -i major <<< "$input")" = "$expected" ]]
}

@test "semver -i: should alias to --increment" {
[[ "$(semver --increment major <<< "1.0.0")" = "2.0.0" ]]
}