Generate README.Debian from patch README-Debian psuedo-headers
authorRob Browning <rlb@defaultvalue.org>
Sun, 26 Mar 2023 18:06:49 +0000 (13:06 -0500)
committerRob Browning <rlb@defaultvalue.org>
Fri, 5 Jan 2024 01:35:48 +0000 (19:35 -0600)
Rework debian/patch-to-news to generate the README.Debian entry from a
README-Debian DEP-3 style psuedo-header, when present.  The header's
syntax is similar to the debian/control Description format.  Among
other things, this change makes the common case of cherry-picking
upstream patches easier, and less invasive, since in many cases, a
simple README-Debian header can be appended while adding the other
headers, instead of (as previously) reindenting the upstream commit,
etc.

debian/emacs-common.README.in
debian/patch-to-news
debian/rules

index 28a9e1a0e8ac77bc30c8fd576e76c168ef2ae91d..7ed3ba1cd8d8bce21ecbb4a88a5c6a1781e486ea 100644 (file)
@@ -1,11 +1,7 @@
 This file details the Debian specific changes to Emacs.
 
-The following tags may be used in the sections below: Patch, Status,
-Author, Added-by, Provided-by, and Date.  When known, Author is used
-to indicate the person believed to have written the relevant code.
-Provided-by may be used to indicate the person who submitted the code
-to Debian, and Added-by indicates the person who actually added the
-code to the Debian package.
+Some of the patches referred to below may follow DEP-3 format
+(https://dep-team.pages.debian.net/deps/dep3/).
 
 * The Debian copy of the upstream source contains no .elc files.
 
index f1f7abc880fa736ea5b8f4f78873c26dea74aa76..bb5ffde497daeaafdc4af4de8a66f18cd0e9d661 100755 (executable)
@@ -1,23 +1,99 @@
-#!/bin/bash
-
-set -eo pipefail
-
-patch="$1"
-
-sed '
-  # delete everything after the first line starting with "--- " (the diff)
-  /^--- [^ ]/,$d' < "$patch" \
-| tac \
-| sed '
-  # delete everything up to the first line containing only "---" (the diffstat)
-  1,/^---$/d' \
-| tac \
-| sed '
-  # delete everything before the first blank line (git summary line)
-  1,/^$/d' \
-| sed '
-  # convert to our README.Debian NEWS format
-  1 s/^/* /
-  2,$ s/^/  /'
-
-echo "  Patch: $(basename $patch)"
+#!/usr/bin/perl -w
+
+use English;
+use File::Basename;
+use strict;
+
+## Given a patch file paths on the command line,
+## e.g. debian/patches/*.patch (or quilt series), generate blank-line
+## separate entries formated for README.Debian.  If a patch file
+## doesn't contain a "README-Debian:" pseudo-header, then just include
+## the entire commit message.  If it does include the header, then
+## parse it roughly like a debian/control "Description:" field.  In
+## particular, any blank line ends the header, continuation lines must
+## start with a single space, and blank lines can be included in the
+## content via lines contining just a space and a full stop ".".
+## Currently, there is also no reformatting, so all lines are
+## "verbatim", not just lines starting with a double space.
+
+sub get_patch_readme
+{
+    my ($patch) = @_;
+    open(PATCH, '<', $patch) or die "Unable to open $patch: $!";
+    my @header = <PATCH>;
+    close PATCH;
+    chomp @header;
+
+    my @result;
+    my $in_header = 0;
+    foreach my $line (@header) {
+        last if $line eq '---';
+        if ($line =~ m/^README-Debian:\s*(.*)/gio) {
+            push @result, $1;
+            $in_header = 1;
+        } elsif ($line =~ m/^\S*$/o) {
+            $in_header = 0;
+        } elsif ($in_header) {
+            if ($line eq ' .') {
+                push @result, '';
+            } elsif (substr($line, 0, 2) eq ' .') {
+                die "Invalid ' .' prefix in line: '$line'";
+            } elsif ($line =~ m/^ (.*)/o) {
+                push @result, $1;
+            } else {
+                $in_header = 0;
+            }
+        }
+    }
+
+    if (!scalar(@result)) {
+        # No README-Debian, include the whole message
+        my $i = 0;
+        my $subject;
+        foreach my $line (@header) {
+            if ($line =~ m/^Subject:\s*(.*)/io) {
+                $subject = $1;
+            }
+            $i++;
+            last if $line eq '';
+        }
+        die 'No subject in patch' unless $subject;
+        push @result, $subject;
+        while ($i < scalar(@header)) {
+            last if $header[$i] eq '---';
+            push @result, $header[$i];
+            $i++;
+        }
+    }
+
+    # Remove trailing blank lines
+    while ($result[-1] eq '') { pop @result; }
+    return \@result;
+}
+
+sub render_patch_readme
+{
+    my ($patch) = @_;
+    my $news = get_patch_readme($patch);
+    my $base = basename($patch);
+    print "* @$news[0]\n";
+    my $news_len = scalar(@$news);
+    foreach my $line (@$news[1..$news_len - 1]) {
+        print "$line\n";
+    }
+    print "\n" if scalar(@$news) > 1;
+    print "Patch: $base\n";
+}
+
+my @patches = @ARGV;
+my $patch_count = @patches;
+
+if ($patch_count)
+{
+    render_patch_readme($patches[0]);
+    foreach my $patch (@patches[1..$patch_count - 1])
+    {
+        print "\n";
+        render_patch_readme($patch);
+    }
+}
index 55f7b6f22f40cdf3cc44707d6c348680e994001d..38965316f3dc226a833f5dc98e91a21b3938ee8c 100755 (executable)
@@ -262,10 +262,8 @@ debian/emacs-common.README.Debian: \
          csplit -s -f emacs-common.README. \
          emacs-common.README.in '/@@PATCH_LIST_HERE@@/'
        cp debian/emacs-common.README.00 debian/emacs-common.README.tmp
-       for p in $$($(quilt) series); do \
-         debian/patch-to-news "$$p" >> debian/emacs-common.README.tmp \
-         && echo >> debian/emacs-common.README.tmp; \
-       done
+       debian/patch-to-news $$($(quilt) series) \
+         >> debian/emacs-common.README.tmp
        tail -n +2 \
          < debian/emacs-common.README.01 \
          >> debian/emacs-common.README.tmp