| #!perl |
| use strict; |
| use warnings; |
| use autodie; |
| |
| use Getopt::Long; |
| use Pod::Simple::HTML; |
| |
| sub main { |
| my ( $help, $type, $html ); |
| GetOptions( |
| 'type:s' => \$type, |
| 'html' => \$html, |
| 'help' => \$help, |
| ); |
| |
| if ($help) { |
| print <<'EOF'; |
| make-rmg-checklist [--type TYPE] |
| |
| This script creates a release checklist as a simple HTML document. It accepts |
| the following arguments: |
| |
| --type The release type for the checklist. This can be BLEAD-FINAL, |
| BLEAD-POINT, MAINT, or RC. This defaults to BLEAD-POINT. |
| |
| --html Output HTML instead of POD |
| |
| EOF |
| |
| exit; |
| } |
| |
| $type = _validate_type($type); |
| |
| open my $fh, '<', 'Porting/release_managers_guide.pod'; |
| my $pod = do { local $/; <$fh> }; |
| close $fh; |
| |
| my $heads = _parse_rmg( $pod, $type ); |
| my $new_pod = _munge_pod( $pod, $heads ); |
| |
| if ($html) { |
| my $simple = Pod::Simple::HTML->new(); |
| $simple->output_fh(*STDOUT); |
| $simple->parse_string_document($new_pod); |
| } |
| else { |
| print $new_pod; |
| } |
| } |
| |
| sub _validate_type { |
| my $type = shift || 'BLEAD-POINT'; |
| |
| my @valid = qw( BLEAD-FINAL BLEAD-POINT MAINT RC ); |
| my %valid = map { $_ => 1 } @valid; |
| |
| unless ( $valid{ uc $type } ) { |
| my $err |
| = "The type you provided ($type) is not a valid release type. It must be one of "; |
| $err .= join ', ', @valid; |
| $err .= "\n"; |
| |
| die $err; |
| } |
| |
| return $type; |
| } |
| |
| sub _parse_rmg { |
| my $pod = shift; |
| my $type = shift; |
| |
| my @heads; |
| my $include = 0; |
| my %skip; |
| |
| for ( split /\n/, $pod ) { |
| if (/^=for checklist begin/) { |
| $include = 1; |
| next; |
| } |
| |
| next unless $include; |
| |
| last if /^=for checklist end/; |
| |
| if (/^=for checklist skip (.+)/) { |
| %skip = map { $_ => 1 } split / /, $1; |
| next; |
| } |
| |
| if (/^=head(\d) (.+)/) { |
| unless ( keys %skip && $skip{$type} ) { |
| push @heads, [ $1, $2 ]; |
| } |
| |
| %skip = (); |
| } |
| } |
| |
| return \@heads; |
| } |
| |
| sub _munge_pod { |
| my $pod = shift; |
| my $heads = shift; |
| |
| $pod =~ s/=head1 NAME.+?(=head1 SYNOPSIS)/$1/s; |
| |
| my $new_pod = <<'EOF'; |
| =head1 NAME |
| |
| Release Manager's Guide with Checklist |
| |
| =head2 Checklist |
| |
| EOF |
| |
| my $last_level = 0; |
| for my $head ( @{$heads} ) { |
| my $level = $head->[0] - 1; |
| |
| if ( $level > $last_level ) { |
| $new_pod .= '=over ' . $level * 4; |
| $new_pod .= "\n\n"; |
| } |
| elsif ( $level < $last_level ) { |
| $new_pod .= "=back\n\n" for 1 .. ( $last_level - $level ); |
| } |
| |
| $new_pod .= '=item * ' . 'L<< /' . $head->[1] . " >>\n\n"; |
| |
| $last_level = $level; |
| } |
| |
| $new_pod .= "=back\n\n" while $last_level--; |
| |
| $new_pod .= $pod; |
| |
| return $new_pod; |
| } |
| |
| main(); |