add link to changes
This commit is contained in:
parent
d4ad827471
commit
d68f49668d
@ -26,114 +26,7 @@ sub _build_changelog($self) {
|
||||
}
|
||||
|
||||
with 'App::Changelord::Role::ChangeTypes';
|
||||
|
||||
sub render_header($self) {
|
||||
|
||||
my $output = "# Changelog";
|
||||
|
||||
my $name = $self->changelog->{project}{name};
|
||||
|
||||
my %links = ();
|
||||
|
||||
if( $self->changelog->{project}{homepage} ) {
|
||||
$name = "[$name][homepage]";
|
||||
$links{homepage} = $self->changelog->{project}{homepage};
|
||||
}
|
||||
|
||||
$output .= " for $name" if $name;
|
||||
|
||||
if(%links) {
|
||||
$output .= "\n\n";
|
||||
$output .= $self->render_refs(%links);
|
||||
}
|
||||
|
||||
$output .= "\n\n";
|
||||
|
||||
}
|
||||
|
||||
sub render_refs($self,%links) {
|
||||
my $output = '';
|
||||
|
||||
for my $ref ( sort keys %links ) {
|
||||
$output .= " [$ref]: $links{$ref}\n"
|
||||
}
|
||||
|
||||
return $output . "\n";
|
||||
}
|
||||
|
||||
sub as_markdown($self) {
|
||||
my $changelog = $self->changelog;
|
||||
|
||||
my $output = $self->render_header;
|
||||
|
||||
my $n = 0;
|
||||
$output .= join "\n", map { $self->render_release($_, $n++) } $changelog->{releases}->@*;
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
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 .= "\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";
|
||||
}
|
||||
with 'App::Changelord::Role::Render';
|
||||
|
||||
sub run($self) {
|
||||
no warnings 'utf8';
|
||||
|
@ -15,6 +15,12 @@ properties:
|
||||
description: name of the project
|
||||
examples:
|
||||
- App::Changelord
|
||||
ticket_url:
|
||||
type: string
|
||||
description: perl code that takes a ticket string (e.g. 'GH123') via the `$_` variable and turns it into a link.
|
||||
examples:
|
||||
- s!GH(\d+)!https://github.com/yanick/App-Changelord/issue/$1/
|
||||
- /^\d+$/ ? "https://.../$_" : undef
|
||||
change_types:
|
||||
type: array
|
||||
items:
|
||||
|
137
lib/App/Changelord/Role/Render.pm
Normal file
137
lib/App/Changelord/Role/Render.pm
Normal file
@ -0,0 +1,137 @@
|
||||
package App::Changelord::Role::Render;
|
||||
|
||||
use v5.36.0;
|
||||
|
||||
use Moo::Role;
|
||||
|
||||
use List::AllUtils qw/ pairmap partition_by /;
|
||||
|
||||
sub render_header ($self) {
|
||||
|
||||
my $output = "# Changelog";
|
||||
|
||||
my $name = $self->changelog->{project}{name};
|
||||
|
||||
my %links = ();
|
||||
|
||||
if ( $self->changelog->{project}{homepage} ) {
|
||||
$name = "[$name][homepage]";
|
||||
$links{homepage} = $self->changelog->{project}{homepage};
|
||||
}
|
||||
|
||||
$output .= " for $name" if $name;
|
||||
|
||||
if (%links) {
|
||||
$output .= "\n\n";
|
||||
$output .= $self->render_refs(%links);
|
||||
}
|
||||
|
||||
$output .= "\n\n";
|
||||
|
||||
}
|
||||
|
||||
sub render_refs ( $self, %links ) {
|
||||
my $output = '';
|
||||
|
||||
for my $ref ( sort keys %links ) {
|
||||
$output .= " [$ref]: $links{$ref}\n";
|
||||
}
|
||||
|
||||
return $output . "\n";
|
||||
}
|
||||
|
||||
sub as_markdown ($self) {
|
||||
my $changelog = $self->changelog;
|
||||
|
||||
my $output = $self->render_header;
|
||||
|
||||
my $n = 0;
|
||||
$output .= join "\n",
|
||||
map { $self->render_release( $_, $n++ ) } $changelog->{releases}->@*;
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
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 .= "\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 .= join '', map { $self->render_change($_) } @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->@*;
|
||||
}
|
||||
}
|
||||
|
||||
my $links = '';
|
||||
$output =~ s/(\n \[.*?\]: .*?)\n/$links .= $1;''/gem;
|
||||
|
||||
return $output . $links . "\n";
|
||||
}
|
||||
|
||||
sub render_change ( $self, $change ) {
|
||||
my $out = " * " . $change->{desc};
|
||||
|
||||
my $link = "";
|
||||
|
||||
if ( $change->{ticket} ) {
|
||||
$out .= " [$change->{ticket}]";
|
||||
if ( $self->changelog->{project}{ticket_url} ) {
|
||||
local $_ = $change->{ticket};
|
||||
eval $self->changelog->{project}{ticket_url};
|
||||
warn $@ if $@;
|
||||
if ($_) {
|
||||
$link = " [$change->{ticket}]: $_";
|
||||
$out .= "\n\n$link";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $out . "\n";
|
||||
}
|
||||
|
||||
1;
|
69
t/render.t
Normal file
69
t/render.t
Normal file
@ -0,0 +1,69 @@
|
||||
use Test2::V0;
|
||||
|
||||
use v5.36.0;
|
||||
|
||||
package TestMe {
|
||||
use Moo;
|
||||
with 'App::Changelord::Role::Render';
|
||||
with 'App::Changelord::Role::ChangeTypes';
|
||||
|
||||
has changelog => (
|
||||
is => 'ro',
|
||||
default => sub {{
|
||||
project => { ticket_url => undef }
|
||||
}}
|
||||
);
|
||||
|
||||
sub set_url($self, $url) {
|
||||
$self->changelog->{project}{ticket_url} = $url;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
my $test = TestMe->new();
|
||||
|
||||
is $test->render_change( { desc => 'blah', ticket => 'GT123' } ),
|
||||
<<'END', "no ticket_url";
|
||||
* blah [GT123]
|
||||
END
|
||||
|
||||
$test->set_url( 's!GT!https://github.com/yanick/App-Changelord/issue/!' );
|
||||
|
||||
is $test->render_change( { desc => 'blah', ticket => 'GT123' } ),
|
||||
<<'END', 'with a ticket_url';
|
||||
* blah [GT123]
|
||||
|
||||
[GT123]: https://github.com/yanick/App-Changelord/issue/123
|
||||
END
|
||||
|
||||
$test->set_url( '$_ = undef' );
|
||||
|
||||
is $test->render_change( { desc => 'blah', ticket => 'GT123' } ),
|
||||
<<'END', 'with a ticket_url, but returns nothing';
|
||||
* blah [GT123]
|
||||
END
|
||||
|
||||
subtest 'all links go at the bottom' => sub {
|
||||
$test->set_url( 's!^!link://!' );
|
||||
|
||||
is $test->render_release({
|
||||
changes => [
|
||||
{ desc => 'this', ticket => 1 },
|
||||
{ desc => 'that', ticket => 2 },
|
||||
{ desc => 'else' },
|
||||
]
|
||||
}), <<'END';
|
||||
## NEXT
|
||||
|
||||
* this [1]
|
||||
* that [2]
|
||||
* else
|
||||
|
||||
[1]: link://1
|
||||
[2]: link://2
|
||||
END
|
||||
|
||||
|
||||
};
|
||||
|
||||
done_testing;
|
Loading…
Reference in New Issue
Block a user