From d727f9d24fc047a3823cc3ac379d21b2c8ebba7f Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 31 Dec 2019 11:04:25 +0000 Subject: [PATCH] catacomb-import-update: Separate import from convert 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 --- catacomb-import-update | 77 ++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/catacomb-import-update b/catacomb-import-update index c71359c..43fc780 100755 --- a/catacomb-import-update +++ b/catacomb-import-update @@ -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 -- 2.30.2