emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
blob 8d14a757dd2b471a976e8afe9a4dd04e7a769ea0 2696 bytes (raw)
name: UTILITIES/make_emacs_changelog 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
 
#!/usr/bin/perl

$commitrange = shift @ARGV;
if (!$commitrange) {
  print STDERR "Enter commitrange: ";
  $commitrange = <>;
  $commitrange =~ s/\s*(.*?)\s+/$1/;
}

$syncdate = shift @ARGV;
if (!$syncdate) {
  print STDERR "Enter syncdate YYYY-MM-DD: ";
  $syncdate = <>;
  $syncdate =~ s/\s*(.*?)\s+/$1/;
}

$kind = shift @ARGV;
if (!$kind) {
  print STDERR 'Enter kind ("lisp" or "texi" or "card" or press RET): ';
  $kind = <>;
  $kind =~ s/\s*(.*?)\s+/$1/;
  $kind =~ s/"(.*?)"/$1/;
}

if ($kind ne "lisp" and $kind ne "texi" and  $kind ne "card"
    and $kind ne "") {
  die "Invalid Changelog kind";
}

# Run git log to get the commits the messages
open IN,"git log $commitrange|";
undef $/;
$log = <IN>;
@commits = split(/^(?=commit)/m,$log);

for $i (0..$#commits) {
  $entry = ""; $tiny = "";
  $commit = $commits[$i];
  $author = $1 if $commit=~/^Author: ([^\n]+)/m;
  $date   = $1 if $commit=~/^Date: ([^\n]+)/m;
  $entry  = $1 if $commit=~/^([ \t]*\* [^\f]*?)(\n[ \t]*\n([^*]|\Z)|\Z)/m;
  $tiny   = "  (tiny change)" if $commit =~ /TINYCHANGE/;

  # split author into name and address
  if ($author =~ /(.*?)\s+(<.*?>)/) {
    $name = $1;
    $address = $2;
  } else {
    warn "No name/address";
    next;
  }

  if ($entry) {

    # Fix the path when directories have been omitted

    $entry =~ s/^([ \t]*\* )([-a-zA-Z]+\.el)/$1lisp\/$2/mg;
    $entry =~ s/^([ \t]*\* )(org[a-z]*\.texi?)/$1doc\/$2/mg;
    
    # remove stuff which is not for this output
    if ($kind =~ /\S/) { 
      remove_parts("contrib/","testing/","xemacs/");
      remove_parts("Makefile","README");
    }
    if ($kind eq "lisp") { remove_parts("doc/")                               }
    if ($kind eq "texi") { remove_parts("lisp/","doc/orgcard","doc/orgguide") }
    if ($kind eq "card") { remove_parts("lisp/","doc/org\\.","doc/orgguide")  }

    # indent each line by 1 TAB
    $entry =~ s/^[ \t]*/\t/gm;

    # Add empty lines if there are several files in there
    $entry =~ s/(\n[ \t]+\* )/\n$1/g;

    # remove blocks of more than one empty line
    while ($entry =~s/\n[ \t]*\n[ \t]*\n/\n/g) {};

    # remove/replace parts of the path

    $entry =~ s/^([ \t]+\* )lisp\//$1/mg;
    $entry =~ s/^([ \t]+\* )doc\/orgcard/$1 refcards\/orgcard/mg;
    $entry =~ s/^([ \t]+\* )doc\//$1misc\//mg;

    # remove empty space at beginning and end
    $entry =~ s/\A\s*/\t/;
    $entry =~ s/\s*\Z/\n/;

    # If there is anything left in the entry, print it
    if ($entry =~ /\S/) {
      print "$syncdate  $name  $address$tiny\n\n$entry\n";
    }
  }
}
 
sub remove_parts {
  foreach $path (@_) {
    $re = "^[ \t]*\\*\\s+" . $path . "[^\\000]*?(?=^[ \\t]*\\*|\\Z)";
    $entry =~ s/$re/\n$1/mg;
  }
}

debug log:

solving 8d14a757dd2b471a976e8afe9a4dd04e7a769ea0 ...
found 8d14a757dd2b471a976e8afe9a4dd04e7a769ea0 in https://git.savannah.gnu.org/cgit/emacs/org-mode.git

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).