From b3972b10625740698753571f6e449d1618866149 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Sat, 16 Jul 2022 13:33:03 -0400 Subject: [PATCH] add command 'version' --- lib/App/Changelord.pm | 15 +++--- lib/App/Changelord/Command/Version.pm | 67 ++++++++++++++++++++++++++ lib/App/Changelord/Role/ChangeTypes.pm | 24 +++++++++ t/versions.t | 26 ++++++++++ 4 files changed, 123 insertions(+), 9 deletions(-) create mode 100644 lib/App/Changelord/Command/Version.pm create mode 100644 lib/App/Changelord/Role/ChangeTypes.pm create mode 100644 t/versions.t diff --git a/lib/App/Changelord.pm b/lib/App/Changelord.pm index f0e849d..3a0fdb6 100644 --- a/lib/App/Changelord.pm +++ b/lib/App/Changelord.pm @@ -1,5 +1,7 @@ package App::Changelord; +# version next latest + use 5.36.0; use Moo; @@ -8,6 +10,8 @@ use YAML; use List::AllUtils qw/ pairmap partition_by /; +use App::Changelord::Role::ChangeTypes; + option source => ( is => 'ro', format => 's', @@ -23,15 +27,7 @@ has changelog => ( } ); -has change_types => ( - is => 'ro', - default => sub($self) { - return [ - { title => 'Features' , level => 'minor', keywords => [ 'feat' ] } , - { title => 'Bug fixes' , level => 'patch', keywords => [ 'fix' ] }, - ] - } -); +with 'App::Changelord::Role::ChangeTypes'; sub render_header($self) { @@ -148,5 +144,6 @@ sub run($self) { subcommand 'schema' => 'App::Changelord::Command::Schema'; subcommand 'validate' => 'App::Changelord::Command::Validate'; +subcommand 'version' => 'App::Changelord::Command::Version'; 'end of App::Changeman'; diff --git a/lib/App/Changelord/Command/Version.pm b/lib/App/Changelord/Command/Version.pm new file mode 100644 index 0000000..c616917 --- /dev/null +++ b/lib/App/Changelord/Command/Version.pm @@ -0,0 +1,67 @@ +package App::Changelord::Command::Version; +# SYNOPSIS: output the latest / next version + +use 5.36.0; + +use Moo; +use CLI::Osprey + desc => 'output the latest/next version'; + +use Path::Tiny; +use JSON; +use YAML::XS; +use List::AllUtils qw/ first min /; +use Version::Dotted::Semantic; + +with 'App::Changelord::Role::ChangeTypes'; + +has changelog => ( + is => 'lazy' +); + +sub _build_changelog($self){ $self->parent_command->changelog } + +sub latest_version($self){ + first { $_ } grep { $_ ne 'NEXT' } map { eval { $_->{version} } } $self->changelog->{releases}->@*; +} + +sub next_version($self) { + my $version = Version::Dotted::Semantic->new($self->latest_version // '0.0.0'); + + my $upcoming = $self->changelog->{releases}[0]; + + if( $upcoming->{version} and $upcoming->{version} ne 'NEXT') { + $upcoming = { changes => [] }; + } + + my %mapping = map { + my $level = $_->{level}; + map { $_ => $level } $_->{keywords}->@* + } $self->change_types->@*; + + my $bump =min 2, map { $_ eq 'major' ? 0 : $_ eq 'minor' ? 1 : 2 } map { $mapping{$_->{type}} || 'patch' } $upcoming->{changes}->@*; + + $version->bump($bump); + + return $version->normal; +} + +sub run($self) { + my $param = shift @ARGV; + + die "invalid parameter '$param', needs to be nothing, 'next' or 'latest'\n" + if $param and not grep { $param eq $_ } qw/ next latest /; + + if(!$param) { + say "latest version: ", $self->latest_version; + say "next version: ", $self->next_version; + } + elsif( $param eq 'next' ) { + say $self->next_version; + } + else { + say $self->latest_version; + } +} + +'end of App::Changelog::Command::Version'; diff --git a/lib/App/Changelord/Role/ChangeTypes.pm b/lib/App/Changelord/Role/ChangeTypes.pm new file mode 100644 index 0000000..68bbae9 --- /dev/null +++ b/lib/App/Changelord/Role/ChangeTypes.pm @@ -0,0 +1,24 @@ +package App::Changelord::Role::ChangeTypes; + +use v5.36.0; + +use Moo::Role; + +use feature 'try'; + +has change_types => ( + is => 'lazy', +); + +sub _build_change_types($self) { + no warnings; + return eval { + $self->changelog->{change_types}; + } || [ + { title => 'Features' , level => 'minor', keywords => [ 'feat' ] } , + { title => 'Bug fixes' , level => 'patch', keywords => [ 'fix' ] }, + ] +} + + +1; diff --git a/t/versions.t b/t/versions.t new file mode 100644 index 0000000..67e5145 --- /dev/null +++ b/t/versions.t @@ -0,0 +1,26 @@ +use 5.36.0; + +use Test2::V0; + +use App::Changelord::Command::Version; + +my $version = App::Changelord::Command::Version->new( + changelog => { + releases => [ + { version => 'NEXT' }, + { version => 'v1.2.3' }, + ] + } +); + +is $version->latest_version => 'v1.2.3'; + +is $version->next_version => 'v1.2.4'; + +$version->{changelog}{releases}[0]{changes} = [ + { type => 'feat' } +]; + +is $version->next_version => 'v1.3.0'; + +done_testing();