~mclehman/version-chronologic

32d9867e48fa8bc17be03a5b0ae98fbea7c37dff — 0xFORDCOMMA 3 years ago 9ca18a0 master
Refactor into a library only, using the version reset to clean up breaking things like patchset -> changeset.
6 files changed, 49 insertions(+), 106 deletions(-)

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

D bin/ryov => bin/ryov +0 -55
@@ 1,55 0,0 @@
#!/usr/bin/env raku

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

sub meta-dispatch($action, *@args, *%named) {
    given 'META6.json'.IO -> $path {
        when $path.e {
            ::('&' ~ $action ~ '-meta6')($path, |@args, |%named)
        }
    }
}

multi MAIN('break') {
    meta-dispatch 'break';
    samewith 'bump', :breaking;
}
multi MAIN('bump', Bool :$breaking = False) {
    meta-dispatch 'bump', :$breaking;
}

class X::Ryov::BadUpdate is Exception {
    method message() {
        "Bad update, both transform and value provided";
    }
}

sub update-meta6($path, $key, :$transform, :$value) {
    my %meta6 = $path.slurp.&from-json;
    if $transform.defined and $value.defined {
        X::Ryov::BadUpdate.new.throw;
    }
    if $transform.defined {
        %meta6{$key} = $transform(%meta6{$key});
    }
    if $value.defined {
        %meta6{$key} = $value;
    }
    $path.spurt: to-json %meta6, :sorted-keys;
    return %meta6{$key};
}

sub break-meta6($path) {
    my $res = update-meta6 $path, 'api', transform => { $_ + 1 };
    say "API version bumped to $res";
}

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

R lib/Version/Chronological/Ryov.rakumod => lib/Version/Chronologic.rakumod +23 -25
@@ 1,32 1,30 @@
# 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                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           changeset { \d+ }
my regex      padded-segment { \d ** 2 }
my regex abridged-chrono-ver { <year> '.' <month> '.' <day> }
my regex          chrono-ver { <abridged-chrono-ver> '.' <patchset> }
my regex          chrono-ver { <abridged-chrono-ver> '.' <changeset> }

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 {
class X::Version::Chronologic::Malformed is Exception {
    method message() {
        "Malformed Chronological Version";
        "Malformed Chronologic 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;
class Version::Chronologic {
    has Int  $.year      is rw;
    has Int  $.month     is rw;
    has Int  $.day       is rw;
    has Int  $.changeset is rw;
    has Bool $.breaking  is rw;

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


@@ 43,9 41,9 @@ class Version::Chronological::Ryov {
    multi method new(NonNeg $year,
                     NonNeg $month,
                     NonNeg $day,
                     NonNeg $patchset,
                     NonNeg $changeset,
                     Bool   :$breaking = False) {
        return self.bless(:$year, :$month, :$day, :$patchset, :$breaking)
        return self.bless(:$year, :$month, :$day, :$changeset, :$breaking)
    }

    multi method new() {


@@ 54,19 52,19 @@ class Version::Chronological::Ryov {
    }

    multi method new(*@args) {
        X::Version::Chronological::Ryov::Malformed.new.throw;
        X::Version::Chronologic::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++;
            # Increment changeset
            $.changeset++;
        } else {
            $.year     = $year;
            $.month    = $month;
            $.day      = $day;
            $.patchset = 0;
            $.changeset = 0;
        }
        $.breaking = $breaking;
        return self


@@ 76,15 74,15 @@ class Version::Chronological::Ryov {
        ($.year,
         zero-pad($.month, 2),
         zero-pad($.day, 2),
         $.patchset > 0 ?? $.patchset !! |(),
         $.changeset > 0 ?? $.changeset !! |(),
        ).join('.') ~ ($.breaking ?? "-break" !! '');
    }

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

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

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

plan 4;

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

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

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

is $base-ver-str ~ '.1-break',
   Version::Chronological::Ryov.new($base-ver-str).bump(:breaking).Str,
   'Bump omitted patchset with breaking change.';
   Version::Chronologic.new($base-ver-str).bump(:breaking).Str,
   'Bump omitted changeset 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';
   Version::Chronologic.new($base-ver-str).bump.bump(:breaking).Str,
   'Bump non-omitted changeset with breaking change';

done-testing;

M t/test-malformed.t => t/test-malformed.t +8 -8
@@ 1,18 1,18 @@
#!/usr/bin/env raku
use Test;
use lib 'lib';
use Version::Chronological::Ryov;
use Version::Chronologic;

plan 12;

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

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



@@ 25,9 25,9 @@ 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';
is-well-formed '2020.01.01',         'omitted changeset';
is-well-formed '2020.01.01-break',   'omitted changeset with break label';
is-well-formed '2020.01.01.0',       'included 0 changeset';
is-well-formed '2020.01.01.0-break', 'included 0 changeset with break label';

done-testing;

M t/test-roundtrip.t => t/test-roundtrip.t +2 -2
@@ 2,11 2,11 @@
use Test;
use lib 'lib';

use Version::Chronological::Ryov;
use Version::Chronologic;

plan 1;

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

done-testing;