diff --git a/CHANGELOG-sample.yml b/CHANGELOG-sample.yml index bfdb91d..1ed0a75 100644 --- a/CHANGELOG-sample.yml +++ b/CHANGELOG-sample.yml @@ -2,7 +2,7 @@ project: name: App::Changeman homepage: https://git.babyl.ca/yanick/App-Changelord -type: +change_types: - feat: title: Features level: minor @@ -10,6 +10,11 @@ type: title: Bug fixes level: patch releases: + - version: v1.2.3 + date: 2022-01-02 + changes: + - type: feat + desc: doing the thing - | ## [2.0.0](https://github.com/yanick/json-schema-shorthand/compare/v1.0.0...v2.0.0) (2020-08-24) @@ -60,9 +65,13 @@ releases: * Properties can be made required via a '!' suffix. * Drop Mocha and Chai for TAP for testing. - ## 0.1.0 2016-08-01 - * Recurse down 'allOf', 'oneOf', 'anyOf', 'not'. - * Add 'install' and 'synopsis' sections in doc. + - date: 2016-08-01 + version: 0.1.0 + changes: + - Recurse down 'allOf', 'oneOf', 'anyOf', 'not'. + - Add 'install' and 'synopsis' sections in doc. - ## 0.0.1 2016-07-31 - * Initial release + - date: 2016-07-31 + version: 0.0.1 + changes: + - Initial release diff --git a/lib/App/Changelord.pm b/lib/App/Changelord.pm index 0c99b04..f0e849d 100644 --- a/lib/App/Changelord.pm +++ b/lib/App/Changelord.pm @@ -6,8 +6,11 @@ use Moo; use CLI::Osprey; use YAML; +use List::AllUtils qw/ pairmap partition_by /; + option source => ( is => 'ro', + format => 's', doc => 'changelog yaml file', default => 'CHANGELOG.yml', ); @@ -20,6 +23,16 @@ has changelog => ( } ); +has change_types => ( + is => 'ro', + default => sub($self) { + return [ + { title => 'Features' , level => 'minor', keywords => [ 'feat' ] } , + { title => 'Bug fixes' , level => 'patch', keywords => [ 'fix' ] }, + ] + } +); + sub render_header($self) { my $output = "# Changelog"; @@ -70,16 +83,62 @@ sub render_release($self, $release, $n=0) { # it's a string? Okay then! return $release unless ref $release; - my $version = $release->{version} || ( $n ? '???' : 'NEXT' ); my $date = $release->{date}; my $output = ''; $output .= "## $version"; - $output .= " ($date)" if $date; + $output .= ", $date" if $date; - return $output; + $output .= "\n"; + + if( $release->{changes} ) { + my @changes = map { ref ? $_ : { desc => $_ } } $release->{changes}->@*; + + my @keywords = map { $_->{keywords}->@* } $self->change_types->@*; + + # find the generics + my @generics = grep { + my $type = $_->{type}; + + my $res = !$type; + + if( $type and not grep { $type eq $_} @keywords ) { + $res = 1; + warn "change type '$type' is not recognized\n"; + } + $res; + } @changes; + + + $output .= "\n" if @generics; + $output .= " * $_->{desc}\n" for @generics; + + my %keyword_mapping = map { + my $title = $_->{title}; + map { $_ => $title } $_->{keywords}->@*; + } $self->change_types->@*; + + + my %groups = partition_by { + no warnings qw/ uninitialized /; + $keyword_mapping{$_->{type}} || '' + } @changes; + + for my $type ( $self->change_types->@* ) { + my $c = $groups{$type->{title}} or next; + $output .= "\n### $type->{title}\n\n"; + $output .= $self->render_change($_) for $c->@*; + } + + } + + return $output . "\n"; +} + +sub render_change($self, $change) { + return " * " . $change->{desc} . "\n"; } sub run($self) { diff --git a/lib/App/Changelord/Command/changelog-schema.yml b/lib/App/Changelord/Command/changelog-schema.yml index 676a2ab..52431da 100644 --- a/lib/App/Changelord/Command/changelog-schema.yml +++ b/lib/App/Changelord/Command/changelog-schema.yml @@ -29,3 +29,7 @@ properties: items: oneOf: - type: string + - type: object + properties: + version: { type: string } + date: { type: string } diff --git a/t/basic.t b/t/basic.t index 57321fe..8781320 100644 --- a/t/basic.t +++ b/t/basic.t @@ -6,7 +6,7 @@ use App::Changelord; my $change = App::Changelord->new( changelog => { - project => { name => 'Foo' } + project => { name => 'Foo' }, } ); @@ -20,4 +20,39 @@ subtest 'homepage' => sub { like $header, qr/\Q [homepage]: the-url/; }; +subtest 'release' => sub { + is $change->render_release("yup, that's it"), "yup, that's it"; + + like $change->render_release({ + version => 'v1.2.3', + date => '2022-01-02', + }) => qr/\Q## v1.2.3, 2022-01-02/; +}; + +subtest 'release changes' => sub { + is $change->render_release({ + version => 'v1.2.3', + date => '2022-01-02', + changes => [ + 'foo', + { type => 'feat', 'desc' => 'did the thing' }, + { type => 'fix', 'desc' => 'fixed the thing' }, + ] + }) => <<'END' +## v1.2.3, 2022-01-02 + + * foo + +### Features + + * did the thing + +### Bug fixes + + * fixed the thing + +END +}; + + done_testing();