Some Perl to generate Debian-style changelogs from git logs with tags for versions.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
2.8 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. #!/usr/bin/env perl
  2. =pod
  3. =head1 NAME
  4. git-changelog - generate a Debian changelog based on tags or on all commits
  5. =head1 SYNOPSIS
  6. git-changeloge [ B<--project=...> B<--distribution=...>]
  7. =head1 DESCRIPTION
  8. Should produce a Debian changelog, more or less, based on the git commit log
  9. and tags for the current directory.
  10. The idea here is that each tag represents a version, and should contain bullet
  11. points for each commit since the previous version.
  12. =head1 CAVEATS
  13. Urgency is just hardcoded to "high". I guess it probably ought to be...
  14. Sensitive to semver or something? I don't really know.
  15. =head1 AUTHOR
  16. Brennen Bearnes
  17. =head1 COPYING
  18. Knock yourself out.
  19. To the extent possible under law, Brennen Bearnes has waived all copyright and
  20. related or neighboring rights to git-changelog.
  21. =cut
  22. use warnings;
  23. use strict;
  24. use 5.10.0;
  25. use Getopt::Long;
  26. use POSIX qw(strftime);
  27. my $project_name = 'project';
  28. my $distribution = 'distribution';
  29. GetOptions(
  30. "project:s" => \$project_name,
  31. "distribution:s" => \$distribution,
  32. );
  33. # See PRETTY FORMATS in git-log(1) for placeholders.
  34. # https://git-scm.com/docs/pretty-formats
  35. open (my $logstream, "git log --reverse --pretty='format:%H\t%d\t%aD\t%aN\t%aE\t%s' |")
  36. or die("$0: Failed to run git\n$!\n");
  37. my @changes;
  38. my @changelog_entries;
  39. while (my $line = <$logstream>)
  40. {
  41. chomp($line);
  42. my @fields = split "\t", $line;
  43. my ($hash, $decoration, $date, $author_name, $author_mail, $subject) = @fields;
  44. my $author = "$author_name <$author_mail>";
  45. # Tags come in from the decoration field - placeholder %d - with (tag: foo)
  46. # That might or might not be followed with other stuff like (tag: foo, ...)
  47. # There's probably a fragile assumption in this, I'm not quite sure what
  48. # happens when more than one tag points at the same commit.
  49. my $tag;
  50. if ($decoration =~ m{^[ ] \( tag:[ ](.*?) \) }x) {
  51. $tag = $1;
  52. if ($tag =~ m/(.*?),/) {
  53. $tag = $1;
  54. }
  55. }
  56. # Accumulate commit subject lines:
  57. push @changes, $subject;
  58. # Every time we hit a tag, create a changelog entry with the accumulated
  59. # bullet points from changes represented by all the preceding commits.
  60. if ($tag) {
  61. my $bullets = '';
  62. foreach my $change (@changes) {
  63. if ($change) {
  64. $bullets .= " * $change\n";
  65. }
  66. }
  67. # Clear out the change list.
  68. @changes = ();
  69. push @changelog_entries,
  70. changelog($tag, $date, $author, $project_name, $bullets, $distribution);
  71. }
  72. }
  73. # Reverse these so they're in the proper new-to-old order:
  74. foreach my $entry (reverse @changelog_entries) {
  75. say $entry;
  76. }
  77. # Pretty much just a template.
  78. sub changelog {
  79. my ($tag, $date, $author, $project_name, $body, $distribution) = @_;
  80. return <<"CHANGELOG";
  81. $project_name ($tag) $distribution; urgency=high
  82. $body
  83. -- $author $date
  84. CHANGELOG
  85. }