chiark / gitweb /
catacomb-import-update: Separate import from convert
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Tue, 31 Dec 2019 11:04:25 +0000 (11:04 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 1 Jan 2020 23:48:14 +0000 (23:48 +0000)
We want the actual source (PFM) in the secnet git repository, so we
should include the *un*converted files, and convert at build time.

So program is now to be called twice: --import, to update the local
git repository from ../catacomb into ./catacomb-import, and --convert,
to massage those into the output files we want for secnet.

We have a new variable $DOCONVERT which says which mode we're working
in.  It is most convenient to test this in note_path and convert_*,
rather than at each call site.

The only nontrivial changes are to commit_changes, where we no longer
care about recip paths and just use donor paths.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
catacomb-import-update

index c71359c83be0fbea817f48494627f316fc522c4f..43fc780f9a79172b25b38d7aee3579c5bcb2600b 100755 (executable)
@@ -26,9 +26,11 @@ use IPC::System::Simple qw{runx capturex $EXITVAL};
 
 use Data::Dumper;
 
+my $DOCONVERT;
 my $DONOR_VERSION = "UNKNOWN";
 my $DONOR_REVISION = "UNKNOWN";
-my $DONOR_DIR = "../catacomb";
+my $DONOR_DIR;
+my $DONOR_IMPORT_DIR = "catacomb-import";
 
 (my $PROG = $0) =~ s{^.*/}{};
 
@@ -46,8 +48,10 @@ my %RECIP_CACHE = ();
 sub note_path ($$) {
   my ($donor, $recip) = @_;
 
+  return if $DOCONVERT;
+
   my $recip_rev = capturex "git", "rev-list", "--max-count=1",
-    "HEAD", "--", $recip; chomp $recip_rev;
+    "HEAD", "--", "$DONOR_IMPORT_DIR/$donor"; chomp $recip_rev;
 
   my $donor_rev;
   if ($recip_rev eq "")
@@ -88,15 +92,19 @@ sub commit_changes () {
   my $msg = "";
   my $any_changes = 0;
 
+  return if $DOCONVERT;
+
+  my @paths = sort keys %DONOR_REV_MAP;
+  runx 'rsync', '-Rc', (map { "$DONOR_DIR/./$_" } @paths), $DONOR_IMPORT_DIR;
+  
+  my $dir = $DONOR_IMPORT_DIR;
   ## Stage updated files for commit.
-  my %recip_map;
-  for my $path (keys %DONOR_PATH_MAP)
-    { push @{$recip_map{$DONOR_PATH_MAP{$path}}}, $path; }
-  runx "git", "update-index", "--add", "--", keys %recip_map;
+  runx "git", "update-index", "--add", "--",
+      map { "$dir/$_" } keys %DONOR_REV_MAP;
 
   ## Inspect the changed files.  Notice whether we've actually changed or
   ## added files.
-  chomp (my @diff = capturex "git", "diff-index", "--cached", "HEAD");
+  chomp (my @diff = capturex "git", "diff-index", "--cached", "HEAD", $dir);
   my %changed = ();
   my %new = ();
   for my $line (@diff) {
@@ -107,45 +115,27 @@ sub commit_changes () {
                ([^\t]+) (?: \t ([^\t]+))? $/x
       or die "incomprehensible git-diff line `$line'";
     my $path = ($3 eq "C" or $3 eq "R") ? $5 : $4;
-    $changed{$path} = 1; $new{$path} = ($1 !~ /[^0]/);
+    my $old = $1;
+    next unless $path =~ s{^$dir/}{};
+    $changed{$path} = 1; $new{$path} = ($old !~ /[^0]/);
   }
 
   ## Files which haven't changed aren't interesting any more.
-  for my $path (keys %DONOR_PATH_MAP) {
-    my $recip = $DONOR_PATH_MAP{$path};
-    if (!$changed{$recip}) {
-      delete $recip_map{$recip};
+  for my $path (keys %DONOR_REV_MAP) {
+    if (!$changed{$path}) {
       delete $DONOR_REV_MAP{$path};
     }
   }
-  if (!%recip_map) { moan "no changes to import"; return ""; }
+  if (!%DONOR_REV_MAP) { moan "no changes to import"; return ""; }
 
   ## Build the commit preamble.
   $msg .= "Update crypto code from Catacomb $DONOR_VERSION.\n\n";
   $msg .= "This change committed automatically by `$PROG'.\n\n";
 
   ## Construct the summary of changes.
-  my @recip = sort keys %recip_map;
-  for my $recip (@recip) {
-    my $disp = $new{$recip} ? "new" : "updated";
-    my $line = "  * Import $disp `$recip' from upstream";
-    my @p = sort @{$recip_map{$recip}};
-    for (my $i = 0; $i < @p; $i++) {
-      my $p = $p[$i];
-      if (!$i) { }
-      else {
-       @p == 2 or $line .= ",";
-       if ($i == @p - 1) {
-         if (length($line) + 4 > 72)
-           { $msg .= $line . "\n"; $line = "   "; }
-         $line .= " and";
-       }
-      }
-      if (length($line) + length($p) + 3 > 72)
-       { $msg .= $line . "\n"; $line = "   "; }
-      $line .= " `$p'"
-    }
-    $msg .= $line . ".\n";
+  for my $path (@paths) {
+    my $disp = $new{$path} ? "new" : "updated";
+    my $msg .= "  * Import $disp `$path' from upstream.\n";
   }
 
   ## Now the detailed list of upstream commits.
@@ -182,7 +172,8 @@ sub commit_changes () {
   $msg .= "\nUpstream-Revision: $DONOR_REVISION\n";
 
   ## Commit everything.
-  runx "git", "commit", "--edit", "--message", $msg, @recip;
+  runx "git", "commit", "--edit", "--message", $msg,
+      map { "$dir/$_" } @paths;
 }
 
 ###--------------------------------------------------------------------------
@@ -193,6 +184,8 @@ sub convert_c ($$) {
   ## Convert a C source or header file.  FROM is the source file name; TO is
   ## the destination file name.  Also clobbers `TO.new'.
 
+  return unless $DOCONVERT;
+
   (my $file = $from) =~ s{^ .* / ([^/]+ / [^/]+) $}{$1}x;
 
   open my $in, "<", $from;
@@ -492,6 +485,8 @@ sub convert_test ($$$) {
   ##
   ## Yes, this is quite hairy.
 
+  return unless $DOCONVERT;
+
   ## Convert the VARMAP into an actual hash.  (We want the list version
   ## because it has the correct output order.)
   my %varmap = @$varmap;
@@ -882,6 +877,16 @@ my @WANT_TEST =
        "kmac128" => undef,
        "kmac256" => undef]);
 
+die "usage: $PROG --import|--convert\n"
+    unless @ARGV && (shift @ARGV) =~ m/^--(import|convert)$/;
+$DOCONVERT = $1 eq 'convert';
+
+if ($DOCONVERT) {
+  $DONOR_DIR = $DONOR_IMPORT_DIR;
+} else {
+  $DONOR_DIR = "../catacomb";
+}
+
 chomp ($DONOR_VERSION = capturex @with_dir, $DONOR_DIR,
        "git", "describe", "--abbrev=4", "--dirty=+");
 chomp ($DONOR_REVISION = capturex @with_dir, $DONOR_DIR,
@@ -916,7 +921,7 @@ for (my $i = 0; $i < @WANT_TEST; $i += 2) {
   convert_test \@in, "$base-tests.in", $varmap;
 }
 
-commit_changes();
+commit_changes() if !$DOCONVERT;
 
 # Local variables:
 # cperl-indent-level: 2