chiark / gitweb /
dgit: Remove redundant use of List::Util qw(any). Closes:#851280.
[dgit.git] / dgit
diff --git a/dgit b/dgit
index 824e9d1b3ccaaf010c25e4102bf6d3e2e9d04655..fbf844e08370225f191f4bdc3a63ce602c80d703 100755 (executable)
--- a/dgit
+++ b/dgit
@@ -34,7 +34,6 @@ use POSIX;
 use IPC::Open2;
 use Digest::SHA;
 use Digest::MD5;
-use List::Util qw(any);
 use List::MoreUtils qw(pairwise);
 use Text::Glob qw(match_glob);
 use Fcntl qw(:DEFAULT :flock);
@@ -70,7 +69,6 @@ our $overwrite_version; # undef: not specified; '': check changelog
 our $quilt_mode;
 our $quilt_modes_re = 'linear|smash|auto|nofix|nocheck|gbp|dpm|unapplied';
 our $dodep14tag;
-our $dodep14tag_re = 'want|no|always';
 our $split_brain_save;
 our $we_are_responder;
 our $we_are_initiator;
@@ -156,6 +154,7 @@ our $split_brain = 0;
 
 END {
     local ($@, $?);
+    return unless forkcheck_mainprocess();
     print STDERR "! $_\n" foreach $supplementary_message =~ m/^.+$/mg;
 }
 
@@ -220,6 +219,7 @@ initdebug('');
 our @end;
 END { 
     local ($?);
+    return unless forkcheck_mainprocess();
     foreach my $f (@end) {
        eval { $f->(); };
        print STDERR "$us: cleanup: $@" if length $@;
@@ -2070,23 +2070,44 @@ sub generate_commits_from_dsc () {
     foreach my $fi (@dfi) {
        my $f = $fi->{Filename};
        die "$f ?" if $f =~ m#/|^\.|\.dsc$|\.tmp$#;
+       my $upper_f = "../../../../$f";
+
+       printdebug "considering reusing $f: ";
+
+       if (link_ltarget "$upper_f,fetch", $f) {
+           printdebug "linked (using ...,fetch).\n";
+       } elsif ((printdebug "($!) "),
+                $! != ENOENT) {
+           fail "accessing ../$f,fetch: $!";
+       } elsif (link_ltarget $upper_f, $f) {
+           printdebug "linked.\n";
+       } elsif ((printdebug "($!) "),
+                $! != ENOENT) {
+           fail "accessing ../$f: $!";
+       } else {
+           printdebug "absent.\n";
+       }
 
-       printdebug "considering linking $f: ";
-
-       link_ltarget "../../../../$f", $f
-           or ((printdebug "($!) "), 0)
-           or $!==&ENOENT
-           or die "$f $!";
-
-       printdebug "linked.\n";
-
-       complete_file_from_dsc('.', $fi)
+       my $refetched;
+       complete_file_from_dsc('.', $fi, \$refetched)
            or next;
 
-       if (is_orig_file_in_dsc($f, \@dfi)) {
-           link $f, "../../../../$f"
-               or $!==&EEXIST
-               or die "$f $!";
+       printdebug "considering saving $f: ";
+
+       if (link $f, $upper_f) {
+           printdebug "linked.\n";
+       } elsif ((printdebug "($!) "),
+                $! != EEXIST) {
+           fail "saving ../$f: $!";
+       } elsif (!$refetched) {
+           printdebug "no need.\n";
+       } elsif (link $f, "$upper_f,fetch") {
+           printdebug "linked (using ...,fetch).\n";
+       } elsif ((printdebug "($!) "),
+                $! != EEXIST) {
+           fail "saving ../$f,fetch: $!";
+       } else {
+           printdebug "cannot.\n";
        }
     }
 
@@ -2457,39 +2478,56 @@ END
     return @output;
 }
 
-sub complete_file_from_dsc ($$) {
-    our ($dstdir, $fi) = @_;
-    # Ensures that we have, in $dir, the file $fi, with the correct
+sub complete_file_from_dsc ($$;$) {
+    our ($dstdir, $fi, $refetched) = @_;
+    # Ensures that we have, in $dstdir, the file $fi, with the correct
     # contents.  (Downloading it from alongside $dscurl if necessary.)
+    # If $refetched is defined, can overwrite "$dstdir/$fi->{Filename}"
+    # and will set $$refetched=1 if it did so (or tried to).
 
     my $f = $fi->{Filename};
     my $tf = "$dstdir/$f";
     my $downloaded = 0;
 
+    my $got;
+    my $checkhash = sub {
+       open F, "<", "$tf" or die "$tf: $!";
+       $fi->{Digester}->reset();
+       $fi->{Digester}->addfile(*F);
+       F->error and die $!;
+       my $got = $fi->{Digester}->hexdigest();
+       return $got eq $fi->{Hash};
+    };
+
     if (stat_exists $tf) {
-       progress "using existing $f";
+       if ($checkhash->()) {
+           progress "using existing $f";
+           return 1;
+       }
+       if (!$refetched) {
+           fail "file $f has hash $got but .dsc".
+               " demands hash $fi->{Hash} ".
+               "(perhaps you should delete this file?)";
+       }
+       progress "need to fetch correct version of $f";
+       unlink $tf or die "$tf $!";
+       $$refetched = 1;
     } else {
        printdebug "$tf does not exist, need to fetch\n";
-       my $furl = $dscurl;
-       $furl =~ s{/[^/]+$}{};
-       $furl .= "/$f";
-       die "$f ?" unless $f =~ m/^\Q${package}\E_/;
-       die "$f ?" if $f =~ m#/#;
-       runcmd_ordryrun_local @curl,qw(-f -o),$tf,'--',"$furl";
-       return 0 if !act_local();
-       $downloaded = 1;
-    }
-
-    open F, "<", "$tf" or die "$tf: $!";
-    $fi->{Digester}->reset();
-    $fi->{Digester}->addfile(*F);
-    F->error and die $!;
-    my $got = $fi->{Digester}->hexdigest();
-    $got eq $fi->{Hash} or
+    }
+
+    my $furl = $dscurl;
+    $furl =~ s{/[^/]+$}{};
+    $furl .= "/$f";
+    die "$f ?" unless $f =~ m/^\Q${package}\E_/;
+    die "$f ?" if $f =~ m#/#;
+    runcmd_ordryrun_local @curl,qw(-f -o),$tf,'--',"$furl";
+    return 0 if !act_local();
+
+    $checkhash->() or
        fail "file $f has hash $got but .dsc".
            " demands hash $fi->{Hash} ".
-           ($downloaded ? "(got wrong file from archive!)"
-            : "(perhaps you should delete this file?)");
+           "(got wrong file from archive!)";
 
     return 1;
 }
@@ -2517,7 +2555,7 @@ sub lrfetchref () { return lrfetchrefs.'/'.server_branch($csuite); }
 # (If we deleted them unconditionally, then we might end up
 # re-fetching the same git objects each time dgit fetch was run.)
 #
-# So, leach use of lrfetchrefs needs to be accompanied by arrangements
+# So, each use of lrfetchrefs needs to be accompanied by arrangements
 # in git_fetch_us to fetch the refs in question, and possibly a call
 # to lrfetchref_used.
 
@@ -2724,8 +2762,8 @@ sub git_fetch_us () {
        } elsif ($here{$lref} eq $objid) {
            lrfetchref_used $fullrefname;
        } else {
-           print STDERR \
-               "Not updateting $lref from $here{$lref} to $objid.\n";
+           print STDERR
+               "Not updating $lref from $here{$lref} to $objid.\n";
        }
     });
 }
@@ -2760,6 +2798,11 @@ sub fetch_from_archive_record_2 ($) {
     }
 }
 
+sub parse_dsc_field_def_dsc_distro () {
+    $dsc_distro //= cfg qw(dgit.default.old-dsc-distro
+                          dgit.default.distro);
+}
+
 sub parse_dsc_field ($$) {
     my ($dsc, $what) = @_;
     my $f;
@@ -2767,16 +2810,17 @@ sub parse_dsc_field ($$) {
        $f = $dsc->{$field};
        last if defined $f;
     }
+
     if (!defined $f) {
        progress "$what: NO git hash";
+       parse_dsc_field_def_dsc_distro();
     } elsif (($dsc_hash, $dsc_distro, $dsc_hint_tag, $dsc_hint_url)
             = $f =~ m/^(\w+)\s+($distro_re)\s+($versiontag_re)\s+(\S+)(?:\s|$)/) {
        progress "$what: specified git info ($dsc_distro)";
        $dsc_hint_tag = [ $dsc_hint_tag ];
     } elsif ($f =~ m/^\w+\s*$/) {
        $dsc_hash = $&;
-       $dsc_distro //= cfg qw(dgit.default.old-dsc-distro
-                              dgit.default.distro);
+       parse_dsc_field_def_dsc_distro();
        $dsc_hint_tag = [ debiantags +(getfield $dsc, 'Version'),
                          $dsc_distro ];
        progress "$what: specified git hash";
@@ -2843,8 +2887,10 @@ END
     };
 
     if (parse_cfg_bool 'rewrite-map-enable', 'true', $rewrite_enable) {
-       my $lrf = $do_fetch->("rewrite map", $rewritemap) or return;
-       $mapref = $lrf.'/'.$rewritemap;
+       if (!defined $mapref) {
+           my $lrf = $do_fetch->("rewrite map", $rewritemap) or return;
+           $mapref = $lrf.'/'.$rewritemap;
+       }
        my $rewritemapdata = git_cat_file $mapref.':map';
        if (defined $rewritemapdata
            && $rewritemapdata =~ m/^$dsc_hash(?:[ \t](\w+))/m) {
@@ -2870,7 +2916,7 @@ but we could not obtain that object anywhere.
 END
        foreach my $t (@tags) {
            my $fullrefname = $lrf.'/'.$t;
-           print STDERR "CHK $t $fullrefname ".Dumper(\%lrfetchrefs_f);
+#          print STDERR "CHK $t $fullrefname ".Dumper(\%lrfetchrefs_f);
            next unless $lrfetchrefs_f{$fullrefname};
            next unless is_fast_fwd "$fullrefname~0", $dsc_hash;
            lrfetchref_used $fullrefname;
@@ -3281,6 +3327,7 @@ sub multisuite_suite_child ($$$) {
     my $canonsuitefh = IO::File::new_tmpfile;
     my $pid = fork // die $!;
     if (!$pid) {
+       forkcheck_setup();
        $isuite = $tsuite;
        $us .= " [$isuite]";
        $debugprefix .= " ";
@@ -4432,7 +4479,10 @@ sub i_cleanup {
     }
 }
 
-END { i_cleanup(); }
+END {
+    return unless forkcheck_mainprocess();
+    i_cleanup();
+}
 
 sub i_method {
     my ($base,$selector,@args) = @_;
@@ -5623,12 +5673,12 @@ sub cmd_clean () {
 sub build_prep_early () {
     our $build_prep_early_done //= 0;
     return if $build_prep_early_done++;
-    notpushing();
     badusage "-p is not allowed when building" if defined $package;
     my $clogp = parsechangelog();
     $isuite = getfield $clogp, 'Distribution';
     $package = getfield $clogp, 'Source';
     $version = getfield $clogp, 'Version';
+    notpushing();
     check_not_dirty();
 }
 
@@ -6066,6 +6116,12 @@ sub cmd_import_dsc {
 
     parse_dsc_field($dsc, "Dgit metadata in .dsc")
        unless forceing [qw(import-dsc-with-dgit-field)];
+    parse_dsc_field_def_dsc_distro();
+
+    $isuite = 'DGIT-IMPORT-DSC';
+    $idistro //= $dsc_distro;
+
+    notpushing();
 
     if (defined $dsc_hash) {
        progress "dgit: import-dsc of .dsc with Dgit field, using git hash";
@@ -6209,7 +6265,9 @@ sub cmd_version {
 }
 
 our (%valopts_long, %valopts_short);
+our (%funcopts_long);
 our @rvalopts;
+our (@modeopt_cfgs);
 
 sub defvalopt ($$$$) {
     my ($long,$short,$val_re,$how) = @_;
@@ -6245,6 +6303,26 @@ defvalopt '--initiator-tempdir','','.*', sub {
        " absolute, not relative, directory."
 };
 
+sub defoptmodes ($@) {
+    my ($varref, $cfgkey, $default, %optmap) = @_;
+    my %permit;
+    while (my ($opt,$val) = each %optmap) {
+       $funcopts_long{$opt} = sub { $$varref = $val; };
+       $permit{$val} = $val;
+    }
+    push @modeopt_cfgs, {
+        Var => $varref,
+        Key => $cfgkey,
+        Default => $default,
+        Vals => \%permit
+    };
+}
+
+defoptmodes \$dodep14tag, qw( dep14tag          want
+                             --dep14tag        want
+                             --no-dep14tag     no
+                             --always-dep14tag always );
+
 sub parseopts () {
     my $om;
 
@@ -6327,15 +6405,6 @@ sub parseopts () {
            } elsif (m/^--overwrite=(.+)$/s) {
                push @ropts, $_;
                $overwrite_version = $1;
-           } elsif (m/^--dep14tag$/s) {
-               push @ropts, $_;
-               $dodep14tag= 'want';
-           } elsif (m/^--no-dep14tag$/s) {
-               push @ropts, $_;
-               $dodep14tag= 'no';
-           } elsif (m/^--always-dep14tag$/s) {
-               push @ropts, $_;
-               $dodep14tag= 'always';
            } elsif (m/^--delayed=(\d+)$/s) {
                push @ropts, $_;
                push @dput, $_;
@@ -6374,6 +6443,9 @@ sub parseopts () {
            } elsif (m/^(--[-0-9a-z]+)(=|$)/ && ($oi = $valopts_long{$1})) {
                $val = $2 ? $' : undef; #';
                $valopt->($oi->{Long});
+           } elsif ($funcopts_long{$_}) {
+               push @ropts, $_;
+               $funcopts_long{$_}();
            } else {
                badusage "unknown long option \`$_'";
            }
@@ -6506,12 +6578,14 @@ sub parseopts_late_defaults () {
        $quilt_mode = $1;
     }
 
-    if (!defined $dodep14tag) {
+    foreach my $moc (@modeopt_cfgs) {
        local $access_forpush;
-       $dodep14tag = access_cfg('dep14tag', 'RETURN-UNDEF') // 'want';
-       $dodep14tag =~ m/^($dodep14tag_re)$/ 
-           or badcfg "unknown dep14tag setting \`$dodep14tag'";
-       $dodep14tag = $1;
+       my $vr = $moc->{Var};
+       next if defined $$vr;
+       $$vr = access_cfg($moc->{Key}, 'RETURN-UNDEF') // $moc->{Default};
+       my $v = $moc->{Vals}{$$vr};
+       badcfg "unknown $moc->{Key} setting \`$$vr'" unless defined $v;
+       $$vr = $v;
     }
 
     $need_split_build_invocation ||= quiltmode_splitbrain();