~mclehman/app-ryov

2f1c130c20b29306b16952fc67e97bde9335b77d — 0xFORDCOMMA 3 years ago 9ca18a0
Refactor into a CLI tool only.
6 files changed, 11 insertions(+), 168 deletions(-)

M META6.json
M bin/ryov
D lib/Version/Chronological/Ryov.rakumod
D t/test-bump.t
D t/test-malformed.t
D t/test-roundtrip.t
M META6.json => META6.json +9 -5
@@ 1,18 1,22 @@
{
  "api": 3,
  "api": 0,
  "authors": [
    "0xford"
  ],
  "depends": [
    "JSON::Fast",
    "Version::Chronologic"
  ],
  "description": "",
  "license": "https://opensource.org/licenses/GPL-3.0",
  "name": "ryov",
  "perl": "v6.*",
  "name": "App::ryov",
  "perl": "v6.d",
  "production": false,
  "provides": {
    "Version::Chronological::Ryov": "lib/Version/Chronological/Ryov.rakumod"
    
  },
  "scripts": {
    "test": "zef test ."
  },
  "version": "2020.01.05"
  "version": "2020.01.06"
}
\ No newline at end of file

M bin/ryov => bin/ryov +2 -2
@@ 1,7 1,7 @@
#!/usr/bin/env raku

use JSON::Fast;
use Version::Chronological::Ryov;
use Version::Chronologic;

sub meta-dispatch($action, *@args, *%named) {
    given 'META6.json'.IO -> $path {


@@ 49,7 49,7 @@ sub bump-meta6($path, Bool :$breaking) {
    my $res = update-meta6 $path,
                           'version',
                           transform => {
                               Version::Chronological::Ryov.new($_).bump(:$breaking).Str
                               Version::Chronologic.new($_).bump(:$breaking).Str
                           };
    say "Bumped to $res";
}

D lib/Version/Chronological/Ryov.rakumod => lib/Version/Chronological/Ryov.rakumod +0 -90
@@ 1,90 0,0 @@
# unit module Version::Chronological::Ryov;

my regex           year { \d+ }
my regex          month { ['0' <[1..9]>] | ['1' <[012]>] }
my regex            day { ['0' <[1..9]>] | ['1' <[1..9]>] | ['2' <[1..9]>] | ['3' <[01]>] }
my regex       patchset { \d+ }
my regex padded-segment { \d ** 2 }
my regex abridged-chrono-ver { <year> '.' <month> '.' <day> }
my regex          chrono-ver { <abridged-chrono-ver> '.' <patchset> }

subset               NonNeg of Int where * >= 0;
subset         ChronoVerStr of Str where * ~~ / ^ <chrono-ver> $ /;
subset AbridgedChronoVerStr of Str where * ~~ / ^ <abridged-chrono-ver> $ /;
subset BreakingChronoVerStr of Str where * ~~ / ^ [<chrono-ver> | <abridged-chrono-ver>] '-break' $ /;

class X::Version::Chronological::Ryov::Malformed is Exception {
    method message() {
        "Malformed Chronological Version";
    }
}

sub zero-pad($d, $width) { sprintf "\%0{$width}d", $d }

class Version::Chronological::Ryov {
    has Int  $.year     is rw;
    has Int  $.month    is rw;
    has Int  $.day      is rw;
    has Int  $.patchset is rw;
    has Bool $.breaking is rw;

    multi method new(BreakingChronoVerStr $breaking-ver-str) {
        samewith $breaking-ver-str.split('-').head, :breaking;
    }

    multi method new(AbridgedChronoVerStr $abridged-ver-str, Bool :$breaking = False) {
        samewith |$abridged-ver-str.split('.')>>.Int, 0, :$breaking
    }

    multi method new(ChronoVerStr $ver-str, Bool :$breaking = False) {
        samewith |$ver-str.split('.')>>.Int, :$breaking
    }

    multi method new(NonNeg $year,
                     NonNeg $month,
                     NonNeg $day,
                     NonNeg $patchset,
                     Bool   :$breaking = False) {
        return self.bless(:$year, :$month, :$day, :$patchset, :$breaking)
    }

    multi method new() {
        my ($year, $month, $day) = {.year, .month, .day}(DateTime.new: now);
        return &.new($year, $month, $day, 0);
    }

    multi method new(*@args) {
        X::Version::Chronological::Ryov::Malformed.new.throw;
    }

    method bump(Bool :$breaking = False) {
        my ($year, $month, $day) = {.year, .month, .day}(DateTime.new: now);
        if all(($year, $month, $day) Z== ($.year, $.month, $.day)) {
            # Increment patchset
            $.patchset++;
        } else {
            $.year     = $year;
            $.month    = $month;
            $.day      = $day;
            $.patchset = 0;
        }
        $.breaking = $breaking;
        return self
    }

    method Str() {
        ($.year,
         zero-pad($.month, 2),
         zero-pad($.day, 2),
         $.patchset > 0 ?? $.patchset !! |(),
        ).join('.') ~ ($.breaking ?? "-break" !! '');
    }

    method gist() {
        "Version::Chronological::Ryov.new($.year, $.month, $.day, $.patchset, :breaking($.breaking))"
    }

    method perl() {
        "Version::Chronological::Ryov.new(\"{self.Str}\")"
    }
}

D t/test-bump.t => t/test-bump.t +0 -26
@@ 1,26 0,0 @@
#!/usr/bin/env raku
use Test;
use lib 'lib';
use Version::Chronological::Ryov;

plan 4;

my $base-ver-str = Version::Chronological::Ryov.new.Str;

is $base-ver-str ~ '.1',
   Version::Chronological::Ryov.new($base-ver-str).bump.Str,
   'Bump omitted patchset.';

is $base-ver-str ~ '.2',
   Version::Chronological::Ryov.new($base-ver-str).bump.bump.Str,
   'Bump non-omitted patchset.';

is $base-ver-str ~ '.1-break',
   Version::Chronological::Ryov.new($base-ver-str).bump(:breaking).Str,
   'Bump omitted patchset with breaking change.';

is $base-ver-str ~ '.2-break',
   Version::Chronological::Ryov.new($base-ver-str).bump.bump(:breaking).Str,
   'Bump non-omitted patchset with breaking change';

done-testing;

D t/test-malformed.t => t/test-malformed.t +0 -33
@@ 1,33 0,0 @@
#!/usr/bin/env raku
use Test;
use lib 'lib';
use Version::Chronological::Ryov;

plan 12;

sub is-malformed($ver-str, $desc = '') {
    throws-like { Version::Chronological::Ryov.new($ver-str) },
                X::Version::Chronological::Ryov::Malformed,
                'Check malformed: ' ~ $desc ;
}

sub is-well-formed($ver-str, $desc = '') {
    lives-ok { Version::Chronological::Ryov.new($ver-str) },
             'Check well-formed: ' ~ $desc;
}

is-malformed '2020.01.0',       'invalid day value';
is-malformed '2020.12.32.0',    'invalid day value';
is-malformed '2020.13.01.0',    'invalid month value';
is-malformed '2020.1.1.0',      'unpadded month/day values';
is-malformed '2020.01.1.0',     'unpadded day value';
is-malformed '2020.1.01.0',     'unpadded month value';
is-malformed 'v2020.1.01.0',    'leading "v"';
is-malformed '2020.1.01.0-tag', 'improper label';

is-well-formed '2020.01.01',         'omitted patchset';
is-well-formed '2020.01.01-break',   'omitted patchset with break label';
is-well-formed '2020.01.01.0',       'included 0 patchset';
is-well-formed '2020.01.01.0-break', 'included 0 patchset with break label';

done-testing;

D t/test-roundtrip.t => t/test-roundtrip.t +0 -12
@@ 1,12 0,0 @@
#!/usr/bin/env raku
use Test;
use lib 'lib';

use Version::Chronological::Ryov;

plan 1;

my $ver-str = '2020.01.01.4-break';
is $ver-str, Version::Chronological::Ryov.new($ver-str).Str;

done-testing;