chiark / gitweb /
dgit-badcommit-fixup: Ship
[dgit.git] / Debian / Dgit.pm
index bfa76cc70de127d66e1e235db79c0b83e2f2a16e..e9921d6a33435c5c34164eca3f2dc2174bf1e4ef 100644 (file)
@@ -1,4 +1,21 @@
 # -*- perl -*-
+# dgit
+# Debian::Dgit: functions common to dgit and its helpers and servers
+#
+# Copyright (C) 2015-2016  Ian Jackson
+#
+#    This program is free software; you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation; either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 package Debian::Dgit;
 
@@ -19,12 +36,14 @@ BEGIN {
     $VERSION     = 1.00;
     @ISA         = qw(Exporter);
     @EXPORT      = qw(setup_sigwarn
+                     dep14_version_mangle
                       debiantags debiantag_old debiantag_new
                      server_branch server_ref
                       stat_exists link_ltarget
                      hashfile
                       fail ensuredir executable_on_path
-                      waitstatusmsg failedcmd
+                      waitstatusmsg failedcmd_waitstatus
+                     failedcmd_report_cmd failedcmd
                       cmdoutput cmdoutput_errok
                       git_rev_parse git_get_ref git_for_each_ref
                       git_for_each_tag_referring is_fast_fwd
@@ -35,7 +54,7 @@ BEGIN {
                       $debugprefix *debuglevel *DEBUG
                       shellquote printcmd messagequote);
     # implicitly uses $main::us
-    %EXPORT_TAGS = ( policyflags => [qw(NOFFCHECK FRESHREPO)] );
+    %EXPORT_TAGS = ( policyflags => [qw(NOFFCHECK FRESHREPO NOCOMMITCHECK)] );
     @EXPORT_OK   = @{ $EXPORT_TAGS{policyflags} };
 }
 
@@ -52,6 +71,7 @@ our $branchprefix = 'dgit';
 # dynamic loader, runtime, etc., failures, which report 127 or 255
 sub NOFFCHECK () { return 0x2; }
 sub FRESHREPO () { return 0x4; }
+sub NOCOMMITCHECK () { return 0x8; }
 
 our $debugprefix;
 our $debuglevel = 0;
@@ -126,16 +146,22 @@ sub debugcmd {
     printcmd(\*DEBUG,$debugprefix.$extraprefix,@_) if $debuglevel>0;
 }
 
+sub dep14_version_mangle ($) {
+    my ($v) = @_;
+    # DEP-14 patch proposed 2016-11-09  "Version Mangling"
+    $v =~ y/~:/_%/;
+    $v =~ s/\.(?=\.|$|lock$)/.#/g;
+    return $v;
+}
+
 sub debiantag_old ($$) { 
     my ($v,$distro) = @_;
-    $v =~ y/~:/_%/;
-    return "$distro/$v";
+    return "$distro/". dep14_version_mangle $v;
 }
 
 sub debiantag_new ($$) { 
     my ($v,$distro) = @_;
-    $v =~ y/~:/_%/;
-    return "archive/$distro/$v";
+    return "archive/$distro/".dep14_version_mangle $v;
 }
 
 sub debiantags ($$) {
@@ -159,6 +185,7 @@ sub _us () {
 
 sub fail { 
     my $s = "@_\n";
+    $s =~ s/\n\n$/\n/;
     my $prefix = _us().": ";
     $s =~ s/^/$prefix/gm;
     die $s;
@@ -199,6 +226,22 @@ sub waitstatusmsg () {
     }
 }
 
+sub failedcmd_report_cmd {
+    my $intro = shift @_;
+    $intro //= "failed command";
+    { local ($!); printcmd \*STDERR, _us().": $intro:", @_ or die $!; };
+}
+
+sub failedcmd_waitstatus {
+    if ($? < 0) {
+       return "failed to fork/exec: $!";
+    } elsif ($?) {
+       return "subprocess ".waitstatusmsg();
+    } else {
+       return "subprocess produced invalid output";
+    }
+}
+
 sub failedcmd {
     # Expects $!,$? as set by close - see below.
     # To use with system(), set $?=-1 first.
@@ -211,14 +254,8 @@ sub failedcmd {
     #   success              trashed     $?==0       system
     #   program failed       trashed     $? >0       system
     #   syscall failure      $! >0       unchanged   system
-    { local ($!); printcmd \*STDERR, _us().": failed command:", @_ or die $!; };
-    if ($? < 0) {
-       fail "failed to fork/exec: $!";
-    } elsif ($?) {
-       fail "subprocess ".waitstatusmsg();
-    } else {
-       fail "subprocess produced invalid output";
-    }
+    failedcmd_report_cmd undef, @_;
+    fail failedcmd_waitstatus();
 }
 
 sub cmdoutput_errok {
@@ -253,7 +290,9 @@ sub link_ltarget ($$) {
     if (-l _) {
        $old = cmdoutput qw(realpath  --), $old;
     }
-    link $old, $new or die "link $old $new: $!";
+    my $r = link $old, $new;
+    $r = symlink $old, $new if !$r && $!==EXDEV;
+    $r or die "(sym)link $old $new: $!";
 }
 
 sub hashfile ($) {