chiark / gitweb /
nailing-cargo: alt_cargo_lock.force mode
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 10 May 2020 23:58:05 +0000 (00:58 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 10 May 2020 23:58:05 +0000 (00:58 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
nailing-cargo

index f0456da24307de2df6280a765d20e472ce2a8eda..529066b6f4c838634b8028afb3d3125af2dbf158 100755 (executable)
@@ -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 () {