From b9eab48655470c21845127734d6f17331de84bb4 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 11 May 2020 00:58:05 +0100 Subject: [PATCH] nailing-cargo: alt_cargo_lock.force mode Signed-off-by: Ian Jackson --- nailing-cargo | 80 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 27 deletions(-) diff --git a/nailing-cargo b/nailing-cargo index f0456da..529066b 100755 --- a/nailing-cargo +++ b/nailing-cargo @@ -261,7 +261,15 @@ sub consider_alt_cargo_lock () { # User should *either* have Cargo.lock in .gitignore, # or expect to commit Cargo.lock.example ($alt_cargo_lock) - $alt_cargo_lock = (cfg_uc @ck) // Types::Serialiser::true; + $alt_cargo_lock = (cfg_uc @ck); + + my $force = 0; + if (defined($alt_cargo_lock) && ref($alt_cargo_lock) eq 'HASH') { + $force = cfg_bool qw(alt_cargo_lock force); + my @ck = qw(alt_cargo_lock file); + $alt_cargo_lock = cfg_uc @ck; + } + $alt_cargo_lock //= Types::Serialiser::true; if (Types::Serialiser::is_bool $alt_cargo_lock) { if (!$alt_cargo_lock) { $alt_cargo_lock = undef; return; } @@ -273,7 +281,7 @@ sub consider_alt_cargo_lock () { } if (!stat_exists $alt_cargo_lock, "alt_cargo_lock") { - $alt_cargo_lock = undef; + $alt_cargo_lock = undef unless $force; return; } @@ -286,7 +294,9 @@ sub consider_oot () { $oot_dir = cfgs qw(oot dir); my $use = cfgs qw(oot use); unless (defined($oot_dir) || defined($use)) { - $cargo_lock_update//=0; + die "$self: specified --cargo-lock-update but not out-of-tree build!\n" + if $cargo_lock_update; + $cargo_lock_update=0; return; } $oot_dir //= 'Build'; @@ -511,30 +521,37 @@ END { } } -our $cleanup_remove_cargo_lock; +our $cleanup_cargo_lock; sub makebackups () { foreach my $mf (keys %manifests) { link "$mf", "$mf.unnailed" or $!==EEXIST or die "$self: make backup link $mf.unnailed: $!\n"; } - if (defined $alt_cargo_lock) { - print STDERR "$self: using alt_cargo_lock `$alt_cargo_lock'..." - if $verbose>=3; - if (link $alt_cargo_lock, 'Cargo.lock') { - print STDERR " linked\n" if $verbose>=3; - } elsif ($! != EEXIST) { - print STDERR "\n" if $verbose>=3; - die "$self: make \`Cargo.lock' available as \`$alt_cargo_lock': $!\n"; - } else { - print STDERR "checking quality." if $verbose>=3; - my @lock_stat = stat 'Cargo.lock' - or die "$self: stat Cargo.lock (for alt check: $!\n"; - same_file(\@alt_cargo_lock_stat, \@lock_stat) - or die + if (defined($alt_cargo_lock)) { + if (@alt_cargo_lock_stat) { + print STDERR "$self: using alt_cargo_lock `$alt_cargo_lock'..." + if $verbose>=3; + if (link $alt_cargo_lock, 'Cargo.lock') { + print STDERR " linked\n" if $verbose>=3; + } elsif ($! != EEXIST) { + print STDERR "\n" if $verbose>=3; + die "$self: make \`Cargo.lock' available as \`$alt_cargo_lock': $!\n"; + } else { + print STDERR "checking quality." if $verbose>=3; + my @lock_stat = stat 'Cargo.lock' + or die "$self: stat Cargo.lock (for alt check: $!\n"; + same_file(\@alt_cargo_lock_stat, \@lock_stat) + or die "$self: \`Cargo.lock' and alt file \`$alt_cargo_lock' both exist and are not the same file!\n"; + } + $cleanup_cargo_lock = 1; + } else { + $cleanup_cargo_lock = 1; + # If Cargo.lock exists and alt doesn't, that means either + # that a previous run was interrupted, or that the user has + # messed up. } - $cleanup_remove_cargo_lock = 1; } } @@ -587,12 +604,13 @@ sub invoke () { } sub cargo_lock_update_after () { - return unless $cargo_lock_update; - # avoids importing File::Copy and the error handling is about as good - $!=0; $?=0; - my $r= system qw(cp --), "$build_absdir/Cargo.lock", "Cargo.lock"; - die "$self: run cp: $! $?" if $r<0 || $r & 0xff; - die "$self: failed to update local Cargo.lock (wait status $r)\n" if $r; + if ($cargo_lock_update) { + # avoids importing File::Copy and the error handling is about as good + $!=0; $?=0; + my $r= system qw(cp --), "$build_absdir/Cargo.lock", "Cargo.lock"; + die "$self: run cp: $! $?" if $r<0 || $r & 0xff; + die "$self: failed to update local Cargo.lock (wait status $r)\n" if $r; + } } sub uninstall1 ($$) { @@ -604,10 +622,18 @@ sub uninstall1 ($$) { sub unaltcargolock ($) { my ($enoentok) = @_; - return unless $cleanup_remove_cargo_lock; + return unless $cleanup_cargo_lock; die 'internal error!' unless defined $alt_cargo_lock; - unlink 'Cargo.lock' or ($enoentok && $!==ENOENT) or die + + # we ignore $enoentok because we don't know if one was supposed to + # have been created. + + rename('Cargo.lock', $alt_cargo_lock) or $!==ENOENT or die + "$self: cleanup: rename possibly-updated \`Cargo.lock' to \`$alt_cargo_lock': $!\n"; + + unlink 'Cargo.lock' or $!==ENOENT or die "$self: cleanup: remove \`Cargo.lock' in favour of \`$alt_cargo_lock': $!\n"; + # ^ this also helps clean up the stupid rename() corner case } sub uninstall () { -- 2.30.2