Skip to content

Commit b582e2e

Browse files
authored
Feature: 'semver get' (#27)
1 parent a9c4b3a commit b582e2e

11 files changed

Lines changed: 379 additions & 345 deletions

README.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,15 @@ Coming soon.
4040
semver decrement-major <version>
4141
semver decrement-minor <version>
4242
semver decrement-patch <version>
43-
semver get-major <version>
44-
semver get-minor <version>
45-
semver get-patch <version>
46-
semver get-prerelease <version>
47-
semver get-build <version>
43+
semver get [--major | --minor | --patch | --prerelease | --build] <version>
4844
semver grep -
4945
semver increment-major <version>
5046
semver increment-minor <version>
5147
semver increment-patch <version>
5248
semver init
53-
semver sort [-r | --reverse] -
49+
semver sort [-r] -
5450
semver validate <string>
55-
semver [-h | --help]
51+
semver [-h]
5652

5753
Man page:
5854

semver

Lines changed: 108 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
use strict;
44
use warnings;
5-
use feature qw(say);
5+
use feature qw(say switch);
66
use Scalar::Util qw(looks_like_number);
77
use List::Util qw(max);
8+
use Getopt::Long qw(GetOptionsFromArray);
9+
no if $] >= 5.018, warnings => qw(experimental::smartmatch);
810

911
# Regex from semver.org: https://github.com/semver/semver/pull/460
1012
my $semver_regex = '^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$';
@@ -25,19 +27,15 @@ sub usage() {
2527
say STDERR " $program decrement-major <version>";
2628
say STDERR " $program decrement-minor <version>";
2729
say STDERR " $program decrement-patch <version>";
28-
say STDERR " $program get-major <version>";
29-
say STDERR " $program get-minor <version>";
30-
say STDERR " $program get-patch <version>";
31-
say STDERR " $program get-prerelease <version>";
32-
say STDERR " $program get-build <version>";
30+
say STDERR " $program get [--major | --minor | --patch | --prerelease | --build] <version>";
3331
say STDERR " $program grep -";
3432
say STDERR " $program increment-major <version>";
3533
say STDERR " $program increment-minor <version>";
3634
say STDERR " $program increment-patch <version>";
3735
say STDERR " $program init";
38-
say STDERR " $program sort [-r | --reverse] -";
36+
say STDERR " $program sort [-r] -";
3937
say STDERR " $program validate <string>";
40-
say STDERR " $program [-h | --help]";
38+
say STDERR " $program [-h]";
4139
say STDERR "";
4240
say STDERR "Options:";
4341
say STDERR " -h --help Show this help screen.";
@@ -205,6 +203,28 @@ sub semver::decrement_patch {
205203
}
206204
}
207205

206+
sub semver::get {
207+
my ($version) = @_;
208+
209+
my @matches = semver_get($version);
210+
211+
my $major = $matches[0];
212+
my $minor = $matches[1];
213+
my $patch = $matches[2];
214+
my $prerelease = $matches[3];
215+
my $build = $matches[4];
216+
217+
print $major . "\t" . $minor . "\t" . $patch;
218+
219+
if ($build) {
220+
print "\t" . ($prerelease // '') . "\t" . $build;
221+
} elsif ($prerelease) {
222+
print "\t" . $prerelease;
223+
}
224+
225+
print "\n";
226+
}
227+
208228
sub semver::get_major {
209229
my ($version) = @_;
210230

@@ -336,55 +356,91 @@ sub semver::validate {
336356
($str =~ /$semver_regex/) ? exit 0 : exit 1;
337357
}
338358

359+
sub num_trues(@) {
360+
my $trues = 0;
361+
foreach (@_) {
362+
$trues++ if ($_)
363+
}
364+
return $trues
365+
}
366+
339367
sub main {
340368
my @args = @_;
341369

342-
if (scalar(@args) < 1) {
343-
usage();
344-
}
370+
my $subcommand = shift @args // '';
345371

346-
my $subcommand = $args[0];
347-
348-
if ($subcommand eq "grep") {
349-
semver::grep();
350-
} elsif ($subcommand eq "init") {
351-
semver::init();
352-
} elsif ($subcommand eq "decrement-major") {
353-
semver::decrement_major($args[1]);
354-
} elsif ($subcommand eq "decrement-minor") {
355-
semver::decrement_minor($args[1]);
356-
} elsif ($subcommand eq "decrement-patch") {
357-
semver::decrement_patch($args[1]);
358-
} elsif ($subcommand eq "get-major") {
359-
semver::get_major($args[1]);
360-
} elsif ($subcommand eq "get-minor") {
361-
semver::get_minor($args[1]);
362-
} elsif ($subcommand eq "get-patch") {
363-
semver::get_patch($args[1]);
364-
} elsif ($subcommand eq "get-prerelease") {
365-
semver::get_prerelease($args[1]);
366-
} elsif ($subcommand eq "get-build") {
367-
semver::get_build($args[1]);
368-
} elsif (($subcommand eq "-h") || ($subcommand eq "--help")) {
369-
usage();
370-
} elsif ($subcommand eq "increment-major") {
371-
semver::increment_major($args[1]);
372-
} elsif ($subcommand eq "increment-minor") {
373-
semver::increment_minor($args[1]);
374-
} elsif ($subcommand eq "increment-patch") {
375-
semver::increment_patch($args[1]);
376-
} elsif ($subcommand eq "sort") {
377-
if (grep { $_ eq "-r" || $_ eq "--reverse" } @args) {
378-
semver::sort { semver::sort_pair($b, $a) };
379-
} else {
380-
semver::sort { semver::sort_pair($a, $b) };
372+
for ($subcommand) {
373+
when (/grep/) {
374+
semver::grep();
375+
}
376+
when (/init/) {
377+
semver::init();
378+
}
379+
when (/decrement-major/) {
380+
semver::decrement_major($args[0]);
381+
}
382+
when (/decrement-minor/) {
383+
semver::decrement_minor($args[0]);
384+
}
385+
when (/decrement-patch/) {
386+
semver::decrement_patch($args[0]);
387+
}
388+
when (/get/) {
389+
my $major, my $minor, my $patch, my $prerelease, my $build;
390+
391+
GetOptionsFromArray(
392+
\@args,
393+
"major" => \$major,
394+
"minor" => \$minor,
395+
"patch" => \$patch,
396+
"prerelease" => \$prerelease,
397+
"build" => \$build,
398+
) or exit 1;
399+
400+
usage() if (num_trues($major, $minor, $patch, $prerelease, $build) > 1);
401+
402+
if ($major) {
403+
semver::get_major($args[0]);
404+
} elsif ($minor) {
405+
semver::get_minor($args[0]);
406+
} elsif ($patch) {
407+
semver::get_patch($args[0]);
408+
} elsif ($prerelease) {
409+
semver::get_prerelease($args[0]);
410+
} elsif ($build) {
411+
semver::get_build($args[0]);
412+
} else {
413+
semver::get($args[0]);
414+
}
415+
}
416+
when (/increment-major/) {
417+
semver::increment_major($args[0]);
418+
}
419+
when (/increment-minor/) {
420+
semver::increment_minor($args[0]);
421+
}
422+
when (/increment-patch/) {
423+
semver::increment_patch($args[0]);
424+
}
425+
when (/sort/) {
426+
my $reverse;
427+
GetOptionsFromArray(\@args, "reverse|r" => \$reverse) or exit 1;
428+
429+
if ($reverse) {
430+
semver::sort { semver::sort_pair($b, $a) };
431+
} else {
432+
semver::sort { semver::sort_pair($a, $b) };
433+
}
434+
}
435+
when (/validate/) {
436+
semver::validate($args[0]);
437+
}
438+
when (/compare/) {
439+
say semver::compare($args[0], $args[1]);
440+
}
441+
default {
442+
usage();
381443
}
382-
} elsif ($subcommand eq "validate") {
383-
semver::validate($args[1]);
384-
} elsif ($subcommand eq "compare") {
385-
say semver::compare($args[1], $args[2]);
386-
} else {
387-
usage();
388444
}
389445
}
390446

semver.1

Lines changed: 46 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,8 @@ decrement-minor
1919
decrement-patch
2020
.Ar version
2121
.Nm
22-
get-major
23-
.Ar version
24-
.Nm
25-
get-minor
26-
.Ar version
27-
.Nm
28-
get-patch
29-
.Ar version
30-
.Nm
31-
get-prerelease
32-
.Ar version
33-
.Nm
34-
get-build
22+
get
23+
.Op Fl -major | Fl -minor | Fl -patch | Fl -prerelease | Fl -build
3524
.Ar version
3625
.Nm
3726
grep
@@ -49,13 +38,13 @@ increment-patch
4938
init
5039
.Nm
5140
sort
52-
.Op Fl r | Fl -reverse
41+
.Op Fl r
5342
.Fl
5443
.Nm
5544
validate
5645
.Ar string
5746
.Nm
58-
.Op Fl h | Fl -help
47+
.Op Fl h
5948
.Sh DESCRIPTION
6049
The
6150
.Nm
@@ -157,62 +146,53 @@ If
157146
.Ar version
158147
is invalid.
159148
.El
160-
.Ss get-major
149+
.Ss get
161150
.Nm
162-
can get the MAJOR component of a
151+
can get the components of a
163152
.Ar version
164-
string.
153+
string, and print them in tab-separated format to STDOUT. The output is suitable for post-processing by standard *nix tools like 'cut'.
165154
.Pp
166-
The operation will fail if
167-
.Ar version
168-
is invalid.
169-
.Ss get-minor
170-
.Nm
171-
can get the MINOR component of a
172-
.Ar version
173-
string.
155+
The format looks like this:
174156
.Pp
175-
The operation will fail if
176-
.Ar version
177-
is invalid.
178-
.Ss get-patch
179-
.Nm
180-
can get the PATCH component of a
181-
.Ar version
182-
string.
157+
.Dl $ semver get MAJOR.MINOR.PATCH
158+
.Dl MAJOR\tMINOR\tPATCH
183159
.Pp
184-
The operation will fail if
160+
.Dl $ semver get MAJOR.MINOR.PATCH-PRERELEASE
161+
.Dl MAJOR\tMINOR\tPATCH\tPRERELEASE
162+
.Pp
163+
.Dl $ semver get MAJOR.MINOR.PATCH+BUILD
164+
.Dl MAJOR\tMINOR\tPATCH\t\tBUILD
165+
.Pp
166+
.Dl $ semver get MAJOR.MINOR.PATCH-PRERELEASE+BUILD
167+
.Dl MAJOR\tMINOR\tPATCH\tPRERELEASE\tBUILD
168+
.Pp
169+
The get subcommand understands the following (mutually exclusive) options:
170+
.Bl -tag -width indent
171+
.It Fl -major
172+
Get only the MAJOR component of
185173
.Ar version
186-
is invalid.
187-
.Ss get-prerelease
188-
.Nm
189-
can get the PRERELEASE component of a
174+
.It Fl -minor
175+
Get only the MINOR component of
190176
.Ar version
191-
string.
192-
.Pp
193-
The operation will fail:
194-
.Bl -bullet -compact
195-
.It
196-
If
177+
.It Fl -patch
178+
Get only the PATCH component of
197179
.Ar version
198-
does not contain a PRERELEASE.
199-
.It
200-
If
180+
.It Fl -prerelease
181+
Get only the PRERELEASE component of
201182
.Ar version
202-
is invalid.
203-
.El
204-
.Ss get-build
205-
.Nm
206-
can get the BUILD component of a
183+
.It Fl -build
184+
Get only the BUILD component of
207185
.Ar version
208-
string.
186+
.El
209187
.Pp
210188
The operation will fail:
211189
.Bl -bullet -compact
212190
.It
191+
If more than one mutually exclusive option is given.
192+
.It
213193
If
214194
.Ar version
215-
does not contain a BUILD.
195+
does not contain the specified component.
216196
.It
217197
If
218198
.Ar version
@@ -358,19 +338,25 @@ To get components of the version string
358338
.Sq 1.2.3-SNAPSHOT+2019
359339
:
360340
.Pp
361-
.Dl $ semver get-major '1.2.3-SNAPSHOT+2019'
341+
.Dl $ semver get '1.2.3-SNAPSHOT+2019'
342+
.Dl 1\t2\t3\tSNAPSHOT\t2019
343+
.Pp
344+
.Dl $ semver get '1.2.3-SNAPSHOT+2019' | cut -f 1-3
345+
.Dl 1\t2\t3
346+
.Pp
347+
.Dl $ semver get --major '1.2.3-SNAPSHOT+2019'
362348
.Dl 1
363349
.Pp
364-
.Dl $ semver get-minor '1.2.3-SNAPSHOT+2019'
350+
.Dl $ semver get --minor '1.2.3-SNAPSHOT+2019'
365351
.Dl 2
366352
.Pp
367-
.Dl $ semver get-patch '1.2.3-SNAPSHOT+2019'
353+
.Dl $ semver get --patch '1.2.3-SNAPSHOT+2019'
368354
.Dl 3
369355
.Pp
370-
.Dl $ semver get-prerelease '1.2.3-SNAPSHOT+2019'
356+
.Dl $ semver get --prerelease '1.2.3-SNAPSHOT+2019'
371357
.Dl SNAPSHOT
372358
.Pp
373-
.Dl $ semver get-build '1.2.3-SNAPSHOT+2019'
359+
.Dl $ semver get --build '1.2.3-SNAPSHOT+2019'
374360
.Dl 2019
375361
.Ss Increment
376362
To increment components of the version string

0 commit comments

Comments
 (0)