our $our_version = 'UNRELEASED'; ###substituted###
-our $rpushprotovsn = 2;
+our @rpushprotovsn_support = qw(3 2);
+our $protovsn;
our $isuite = 'unstable';
our $idistro;
autoflush STDOUT 1;
+our $supplementary_message = '';
+
+END {
+ local ($@, $?);
+ print STDERR "! $_\n" foreach $supplementary_message =~ m/^.+$/mg;
+}
+
our $remotename = 'dgit';
our @ourdscfield = qw(Dgit Vcs-Dgit-Master);
our $csuite;
#---------- remote protocol support, common ----------
# remote push initiator/responder protocol:
-# < dgit-remote-push-ready [optional extra info ignored by old initiators]
+# $ dgit remote-push-build-host <n-rargs> <rargs>... <push-args>...
+# where <rargs> is <push-host-dir> <supported-proto-vsn>,... ...
+# < dgit-remote-push-ready <actual-proto-vsn>
#
# > file parsed-changelog
# [indicates that output of dpkg-parsechangelog follows]
sub protocol_read_bytes ($$) {
my ($fh, $nbytes) = @_;
- $nbytes =~ m/^[1-9]\d{0,5}$/ or badproto \*RO, "bad byte count";
+ $nbytes =~ m/^[1-9]\d{0,5}$|^0$/ or badproto \*RO, "bad byte count";
my $d;
my $got = read $fh, $d, $nbytes;
$got==$nbytes or badproto_badread $fh, "data block";
badcfg "pushing but distro is configured readonly"
if access_forpush_config() eq '0';
$access_forpush = 1;
+ $supplementary_message = <<'END' unless $we_are_responder;
+Push failed, before we got started.
+You can retry the push, after fixing the problem, if you like.
+END
+}
+
+sub supplementary_message ($) {
+ my ($msg) = @_;
+ if (!$we_are_responder) {
+ $supplementary_message = $msg;
+ return;
+ } elsif ($protovsn >= 3) {
+ responder_send_command "supplementary-message ".length($msg)
+ or die $!;
+ print PO $msg or die $!;
+ }
}
sub access_distros () {
sub dopush ($) {
my ($forceflag) = @_;
printdebug "actually entering push\n";
+ supplementary_message(<<'END');
+Push failed, while preparing your push.
+You can retry the push, after fixing the problem, if you like.
+END
prep_ud();
access_giturl(); # check that success is vaguely likely
my $tfn = sub { ".git/dgit/tag$_[0]"; };
my $tagobjfn;
+ supplementary_message(<<'END');
+Push failed, while signing the tag.
+You can retry the push, after fixing the problem, if you like.
+END
+ # If we manage to sign but fail to record it anywhere, it's fine.
if ($we_are_responder) {
$tagobjfn = $tfn->('.signed.tmp');
responder_receive_files('signed-tag', $tagobjfn);
$changesfile,$changesfile,
$tfn);
}
+ supplementary_message(<<'END');
+Push failed, *after* signing the tag.
+If you want to try again, you should use a new version number.
+END
my $tag_obj_hash = cmdoutput @git, qw(hash-object -w -t tag), $tagobjfn;
runcmd_ordryrun @git, qw(verify-tag), $tag_obj_hash;
runcmd_ordryrun_local @git, qw(update-ref), "refs/tags/$tag", $tag_obj_hash;
+ supplementary_message(<<'END');
+Push failed, while updating the remote git repository - see messages above.
+If you want to try again, you should use a new version number.
+END
if (!check_for_git()) {
create_remote_git_repo();
}
$forceflag."HEAD:".rrref(), $forceflag."refs/tags/$tag";
runcmd_ordryrun @git, qw(update-ref -m), 'dgit push', lrref(), 'HEAD';
+ supplementary_message(<<'END');
+Push failed, after updating the remote git repository.
+If you want to try again, you must use a new version number.
+END
if ($we_are_responder) {
my $dryrunsuffix = act_local() ? "" : ".tmp";
responder_receive_files('signed-dsc-changes',
sign_changes $changesfile;
}
+ supplementary_message(<<'END');
+Push failed, while uploading package(s) to the archive server.
+You can retry the upload of exactly these same files with dput of:
+ $changesfile
+If that .changes file is broken, you will need to use a new version
+number for your next attempt at the upload.
+END
my $host = access_cfg('upload-host','RETURN-UNDEF');
my @hostarg = defined($host) ? ($host,) : ();
runcmd_ordryrun @dput, @hostarg, $changesfile;
printdone "pushed and uploaded $cversion";
+ supplementary_message('');
responder_send_command("complete");
}
fail "dgit push: changelog specifies $isuite ($csuite)".
" but command line specifies $specsuite";
}
+ supplementary_message(<<'END');
+Push failed, while checking state of the archive.
+You can retry the push, after fixing the problem, if you like.
+END
if (check_for_git()) {
git_fetch_us();
}
#---------- remote commands' implementation ----------
sub cmd_remote_push_build_host {
- pushing();
my ($nrargs) = shift @ARGV;
my (@rargs) = @ARGV[0..$nrargs-1];
@ARGV = @ARGV[$nrargs..$#ARGV];
$we_are_responder = 1;
$us .= " (build host)";
+ pushing();
+
open PI, "<&STDIN" or die $!;
open STDIN, "/dev/null" or die $!;
open PO, ">&STDOUT" or die $!;
autoflush STDOUT 1;
$vsnwant //= 1;
- fail "build host has dgit rpush protocol version".
- " $rpushprotovsn but invocation host has $vsnwant"
- unless grep { $rpushprotovsn eq $_ } split /,/, $vsnwant;
+ ($protovsn) = grep {
+ $vsnwant =~ m{^(?:.*,)?$_(?:,.*)?$}
+ } @rpushprotovsn_support;
+
+ fail "build host has dgit rpush protocol versions ".
+ (join ",", @rpushprotovsn_support).
+ " but invocation host has $vsnwant"
+ unless defined $protovsn;
- responder_send_command("dgit-remote-push-ready $rpushprotovsn");
+ responder_send_command("dgit-remote-push-ready $protovsn");
changedir $dir;
&cmd_push;
$dir = nextarg;
}
$dir =~ s{^-}{./-};
- my @rargs = ($dir,$rpushprotovsn);
+ my @rargs = ($dir);
+ push @rargs, join ",", @rpushprotovsn_support;
my @rdgit;
push @rdgit, @dgit;
push @rdgit, @ropts;
}
$i_child_pid = open2(\*RO, \*RI, @cmd);
changedir $i_tmp;
- initiator_expect { m/^dgit-remote-push-ready/ };
+ ($protovsn) = initiator_expect { m/^dgit-remote-push-ready (\S+)/ };
+ die "$protovsn ?" unless grep { $_ eq $protovsn } @rpushprotovsn_support;
+ $supplementary_message = '' unless $protovsn >= 3;
for (;;) {
my ($icmd,$iargs) = initiator_expect {
m/^(\S+)(?: (.*))?$/;
progress $msg;
}
+sub i_resp_supplementary_message ($) {
+ my ($rhs) = @_;
+ $supplementary_message = protocol_read_bytes \*RO, $rhs;
+}
+
sub i_resp_complete {
my $pid = $i_child_pid;
$i_child_pid = undef; # prevents killing some other process with same pid
} elsif (m/^--since-version=([^_]+|_)$/) {
push @ropts, $_;
$changes_since_version = $1;
- } elsif (m/^--([-0-9a-z]+)=(.*)/s &&
+ } elsif (m/^--([-0-9a-z]+)=(.+)/s &&
($om = $opts_opt_map{$1}) &&
length $om->[0]) {
push @ropts, $_;