#perl -MFile::Slurp -MXML::Simple -MData::Dumper -e'print scalar Dumper ( XMLin( read_file(shift @ARGV).""))'
use warnings;
use strict;
use Term::ANSIScreen;
use Text::Autoformat;
use YAML;
use File::Slurp;
use XML::Simple;
use Term::ReadKey;
use Data::Dumper;
use File::Temp qw/ tempfile tempdir /;
my @tags = qw(doc install core plugin security view t-discard backward-compatiblity-problem u-pubsub r-crud e-testing);
my %tags = map { substr($_,0,1) => $_ } @tags;
my $mode = shift @ARGV;
my ($source,$dest);
if ($mode eq '--generate') {
$source = shift @ARGV;
$dest = shift @ARGV;
}
elsif ($mode eq '--edit') {
$source = shift @ARGV;
$dest = shift @ARGV;
}
unless ($source && -f $source && $dest) { die "$0 --generate SOURCEFILE DESTFILE\n or \n$0 --edit SOURCEFILE DESTFILE" }
my $data = XMLin(read_file($source)."");
if ($mode eq '--edit') {
foreach my $entry (@{$data->{'logentry'}}) {
my %entries;
foreach my $entry (@{$data->{'logentry'}}) {
push @{$entries{$entry->{section}||'uncategorized'}}, $entry;
}
foreach my $key ( keys %entries) {
foreach my $entry (@{$entries{$key}}){
act_on($entry);
}
}
}
do_quit();
} elsif ($mode eq '--generate') {
my %entries;
foreach my $entry (@{$data->{'logentry'}}) {
push @{$entries{$entry->{section}||'uncategorized'}}, $entry;
}
foreach my $key ( keys %entries) {
my $title = $key;
$title =~ s/^\w\-//;
print uc($key)."\n";
print "=" x length($key) ;
print "\n\n";
foreach my $entry (@{$entries{$key}}){
format_entry($entry) ;
print "\n";
}
}
}
sub act_on {
my $entry = shift;
my $console = Term::ANSIScreen->new;
while (1) {
my $command = '';
while (!$command) {
$console->Cls;
$console->Cursor(1,1);
if (!$entry->{'edited_msg'} && ref($entry->{msg})) { $entry->{'edited_msg'} = Dumper($entry->{'msg'}); }
format_entry ($entry => 1);
my $in = getchar();
if ($in eq 's') {
return;
}
elsif ($in eq 'c') { $command = 'chomp'; }
elsif ($in eq 'e') { $command = 'edit'; }
elsif ($in eq 'q') { $command = 'quit'; }
elsif ($in eq 't') { $command = 'tag' }
elsif ($in eq ' ') {
return
}
}
if ($command eq 'tag') {
tag($entry);
}
elsif ( $command eq 'write' ) {
warn "Writing";
} elsif ( $command eq 'chomp' ) {
my $msg = ( $entry->{'edited_msg'} || $entry->{'msg'} );
my @lines = split( "\n", $msg );
shift @lines;
$entry->{'edited_msg'} = join( "\n", @lines );
} elsif ( $command eq 'edit' ) {
warn "Chomping";
my ( $fh, $filename ) = tempfile();
print $fh ( $entry->{'edited_msg'} || $entry->{'msg'} ) || die $!;
close $fh;
system( ( $ENV{EDITOR} || 'vi' ), $filename );
$entry->{'edited_msg'} = read_file($filename);
} elsif ($command eq 'quit') {
do_quit();
}
}
}
sub tag {
my $entry = shift;
my $tag;
print "Valid tags are: " . join( ', ', @tags ) . "\n";
while ( !$tag ) {
my $key = getchar();
return if ( $key eq ' ' );
print "You picked " . $key . "\n";
if ( $tags{$key} ) {
$tag = $tags{$key};
print "You tagged it $tag\n";
} else {
print "NO. THAT IS NOT A VALID TAG\n";
}
}
$entry->{section} = $tag;
}
sub do_quit {
my $out;
open( $out, ">$dest" );
print $out XMLout($data, NoAttr => 1 );
close($out);
exit;
}
sub getchar {
ReadMode 4;
my $key = ReadKey(0);
ReadMode 0;
return $key
}
sub format_entry {
my $entry = shift;
my $verbose = shift ||0;
if ($verbose ) {
print "r".$entry->{revision}." - ";
print $entry->{'section'} || "UNCATEGORIZED - HIT 't'";
print "\n".("="x60)."\n";
}
my $msg = ( $entry->{'edited_msg'} || $entry->{'msg'});
if ($msg =~ /^[\s\*]*\w/) {
$msg =~ s/^[\s\*]*/ * /;
}
$msg =~ s/\n+$//g;
$msg .= " - ".$entry->{'author'}."\n";
$msg = autoformat ($msg, { left=>0, right=>78 });
$msg =~ s/\n+$//g;
print $msg."\n";
if ($verbose ) {
print YAML::Dump( $entry->{'paths'});
print "\n";
}
}