#!/usr/bin/env perl
|
|
|
|
=pod
|
|
|
|
=head1 NAME
|
|
|
|
git-changelog - generate a Debian changelog based on tags or on all commits
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
git-changeloge [ B<--project=...> B<--distribution=...>]
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
Should produce a Debian changelog, more or less, based on the git commit log
|
|
and tags for the current directory.
|
|
|
|
The idea here is that each tag represents a version, and should contain bullet
|
|
points for each commit since the previous version.
|
|
|
|
=head1 CAVEATS
|
|
|
|
Urgency is just hardcoded to "high". I guess it probably ought to be...
|
|
Sensitive to semver or something? I don't really know.
|
|
|
|
=head1 AUTHOR
|
|
|
|
Brennen Bearnes
|
|
|
|
=head1 COPYING
|
|
|
|
Knock yourself out.
|
|
|
|
To the extent possible under law, Brennen Bearnes has waived all copyright and
|
|
related or neighboring rights to git-changelog.
|
|
|
|
=cut
|
|
|
|
use warnings;
|
|
use strict;
|
|
use 5.10.0;
|
|
use Getopt::Long;
|
|
use POSIX qw(strftime);
|
|
|
|
my $project_name = 'project';
|
|
my $distribution = 'distribution';
|
|
GetOptions(
|
|
"project:s" => \$project_name,
|
|
"distribution:s" => \$distribution,
|
|
);
|
|
|
|
# See PRETTY FORMATS in git-log(1) for placeholders.
|
|
# https://git-scm.com/docs/pretty-formats
|
|
open (my $logstream, "git log --reverse --pretty='format:%H\t%d\t%aD\t%aN\t%aE\t%s' |")
|
|
or die("$0: Failed to run git\n$!\n");
|
|
|
|
my @changes;
|
|
my @changelog_entries;
|
|
while (my $line = <$logstream>)
|
|
{
|
|
chomp($line);
|
|
my @fields = split "\t", $line;
|
|
my ($hash, $decoration, $date, $author_name, $author_mail, $subject) = @fields;
|
|
my $author = "$author_name <$author_mail>";
|
|
|
|
# Tags come in from the decoration field - placeholder %d - with (tag: foo)
|
|
# That might or might not be followed with other stuff like (tag: foo, ...)
|
|
# There's probably a fragile assumption in this, I'm not quite sure what
|
|
# happens when more than one tag points at the same commit.
|
|
my $tag;
|
|
if ($decoration =~ m{^[ ] \( tag:[ ](.*?) \) }x) {
|
|
$tag = $1;
|
|
if ($tag =~ m/(.*?),/) {
|
|
$tag = $1;
|
|
}
|
|
}
|
|
|
|
# Accumulate commit subject lines:
|
|
push @changes, $subject;
|
|
|
|
# Every time we hit a tag, create a changelog entry with the accumulated
|
|
# bullet points from changes represented by all the preceding commits.
|
|
if ($tag) {
|
|
my $bullets = '';
|
|
foreach my $change (@changes) {
|
|
if ($change) {
|
|
$bullets .= " * $change\n";
|
|
}
|
|
}
|
|
# Clear out the change list.
|
|
@changes = ();
|
|
push @changelog_entries,
|
|
changelog($tag, $date, $author, $project_name, $bullets, $distribution);
|
|
}
|
|
}
|
|
|
|
# Reverse these so they're in the proper new-to-old order:
|
|
foreach my $entry (reverse @changelog_entries) {
|
|
say $entry;
|
|
}
|
|
|
|
# Pretty much just a template.
|
|
sub changelog {
|
|
my ($tag, $date, $author, $project_name, $body, $distribution) = @_;
|
|
return <<"CHANGELOG";
|
|
$project_name ($tag) $distribution; urgency=high
|
|
|
|
$body
|
|
-- $author $date
|
|
CHANGELOG
|
|
}
|