use Dpkg::Version;
use POSIX;
use IPC::Open2;
-use File::Temp;
our $our_version = 'UNRELEASED'; ###substituted###
our (@debsign) = qw(debsign);
our (@gpg) = qw(gpg);
our (@sbuild) = qw(sbuild -A);
-our (@ssh) = qw(ssh);
+our (@ssh) = 'ssh';
our (@dgit) = qw(dgit);
our (@dpkgbuildpackage) = qw(dpkg-buildpackage -i\.git/ -I.git);
our (@dpkgsource) = qw(dpkg-source -i\.git/ -I.git);
'ch' => \@changesopts,
'mergechanges' => \@mergechanges);
+our %opts_opt_cmdonly = ('gpg' => 1);
+
our $keyid;
our $debug = 0;
# > file begin changes
# [etc]
#
+# > param head HEAD
+#
# > want signed-tag
# [indicates that signed tag is wanted]
# < data-block NBYTES
# < data-end
# < files-end
#
-# > want signed-changes-dsc
-# < data-block NBYTES [transfer of signed changes]
-# [etc]
+# > want signed-dsc-changes
# < data-block NBYTES [transfer of signed dsc]
# [etc]
+# < data-block NBYTES [transfer of signed changes]
+# [etc]
# < files-end
#
# > complete
fail "protocol violation; $m not expected";
}
-sub protocol_expect ($&) {
- my ($fh, $match) = @_;
+sub protocol_expect (&$) {
+ my ($match, $fh) = @_;
local $_;
$_ = <$fh>;
defined && chomp or badproto $fh, "eof";
my ($fh, $ourfn) = @_;
open PF, ">", $ourfn or die "$ourfn: $!";
for (;;) {
- protocol_expect \*STDIN, { m/^data-block (.*})$|data-end$/ };
+ protocol_expect { m/^data-block (.*})$|data-end$/ } \*STDIN;
length $1 or last;
my $d = protocol_read_bytes \*STDIN, $1;
print PF $d or die $!;
foreach my $fn (@ourfns) {
protocol_receive_file \*STDIN, $fn;
}
- protocol_expect \*STDIN, { m/^files-end$/ };
+ protocol_expect { m/^files-end$/ } \*STDIN;
}
#---------- remote protocol support, initiator ----------
sub initiator_expect (&) {
my ($match) = @_;
- protocol_expect \*RO, &$match;
+ protocol_expect { &$match } \*RO;
}
#---------- end remote code ----------
return $value;
}
+sub string_to_ssh ($) {
+ my ($spec) = @_;
+ if ($spec =~ m/\s/) {
+ return qw(sh -ec), 'exec '.$spec.' "$@"', 'x';
+ } else {
+ return ($spec);
+ }
+}
+
+sub access_cfg_ssh () {
+ my $gitssh = access_cfg('ssh', 'RETURN-UNDEF');
+ if (!defined $gitssh) {
+ return @ssh;
+ } else {
+ return string_to_ssh $gitssh;
+ }
+}
+
sub access_someuserhost ($) {
my ($some) = @_;
my $user = access_cfg("$some-user",'username');
my ($proto,$data) = @_;
$data =~ s/:.*// or badcfg "invalid sshdakls method string \`$data'";
my $dakls = cmdoutput
- access_cfg('ssh'), $data, qw(dak ls -asource),"-s$isuite",$package;
+ access_cfg_ssh, $data, qw(dak ls -asource),"-s$isuite",$package;
return madison_parse($dakls);
}
my ($proto,$data) = @_;
$data =~ m/:/ or badcfg "invalid sshdakls method string \`$data'";
my @cmd =
- (access_cfg('ssh'), $`,
+ (access_cfg_ssh, $`,
"set -e; cd $';".
" if test -h $isuite; then readlink $isuite; exit 0; fi;".
" if test -d $isuite; then echo $isuite; exit 0; fi;".
my $how = access_cfg('git-check');
if ($how eq 'ssh-cmd') {
my @cmd =
- (access_cfg('ssh'),access_gituserhost(),
+ (access_cfg_ssh, access_gituserhost(),
" set -e; cd ".access_cfg('git-path').";".
" if test -d $package.git; then echo 1; else echo 0; fi");
my $r= cmdoutput @cmd;
my $how = access_cfg('git-create');
if ($how eq 'ssh-cmd') {
runcmd_ordryrun
- (access_cfg('ssh'),access_gituserhost(),
+ (access_cfg_ssh, access_gituserhost(),
"set -e; cd ".access_cfg('git-path').";".
" cp -a _template $package.git");
} else {
return ($clogp, $cversion, $tag, $dscfn);
}
-sub push_parse_dsc ($$) {
+sub push_parse_dsc ($$$) {
my ($dscfn,$dscfnwhat, $cversion) = @_;
$dsc = parsecontrol($dscfn,$dscfnwhat);
my $dversion = getfield $dsc, 'Version';
" does not match changelog \`$clogp->{$field}'";
}
+ my $cversion = getfield $clogp, 'Version';
+
# We make the git tag by hand because (a) that makes it easier
# to control the "tagger" (b) we can do remote signing
my $authline = clogp_authline $clogp;
return ($tagobjfn);
}
+sub sign_changes ($) {
+ my ($changesfile) = @_;
+ if ($sign) {
+ my @debsign_cmd = @debsign;
+ push @debsign_cmd, "-k$keyid" if defined $keyid;
+ push @debsign_cmd, "-p$gpg[0]" if $gpg[0] ne 'gpg';
+ push @debsign_cmd, $changesfile;
+ runcmd_ordryrun @debsign_cmd;
+ }
+}
+
sub dopush () {
print DEBUG "actually entering push\n";
prep_ud();
}
}
- responder_send_file('changes',$changesfn);
+ responder_send_file('changes',$changesfile);
my $tfn = sub { ".git/dgit/tag$_[0]"; };
my ($tagobjfn) =
}
}
- if ($sign) {
- if ($we_are_responder) {
- my $dryrunsuffix = $dryrun ? ".tmp" : "";
- responder_receive_files('signed-changes-dsc',
- "$changesfile$dryrunsuffix",
- "../$dscfn$dryrunsuffix");
- } else {
- my @debsign_cmd = @debsign;
- push @debsign_cmd, "-k$keyid" if defined $keyid;
- push @debsign_cmd, $changesfile;
- runcmd_ordryrun @debsign_cmd;
- }
+ if ($we_are_responder) {
+ my $dryrunsuffix = $dryrun ? ".tmp" : "";
+ responder_receive_files('signed-dsc-changes',
+ "../$dscfn$dryrunsuffix",
+ "$changesfile$dryrunsuffix");
+ } else {
+ sign_changes $changesfile;
}
+
runcmd_ordryrun @git, qw(push),access_giturl(),"refs/tags/$tag";
my $host = access_cfg('upload-host','RETURN-UNDEF');
my @hostarg = defined($host) ? ($host,) : ();
die unless @rargs;
my ($dir) = @rargs;
chdir $dir or die "$dir: $!";
- $we_are_remote = 1;
+ $we_are_responder = 1;
$|=1;
responder_send_command("dgit-remote-push-ready");
&cmd_push;
$dir =~ s{^-}{./-};
my @rargs = ($dir);
my @rdgit;
- push @rdgit, @dgit
+ push @rdgit, @dgit;
push @rdgit, @ropts;
push @rdgit, (scalar @rargs), @rargs;
push @rdgit, @ARGV;
protocol_receive_file \*RO, $localpath;
}
+our %i_param;
+
+sub i_param ($) {
+ $_[0] =~ m/^(\S+) (.*)$/;
+ $i_param{$1} = $2;
+}
+
+our %i_wanted;
+
sub i_resp_want ($) {
my ($keyword) = @_;
+ die "$keyword ?" if $i_wanted{$keyword}++;
my @localpaths = i_method "i_want_", $keyword;
foreach my $localpath (@localpaths) {
protocol_send_file \*RI, $localpath;
($i_clogp, $i_version, $i_tag, $i_dscfn) =
push_parse_changelog 'remote-changelog.822';
die if $i_dscfn =~ m#/|^\W#;
- return $dscfn;
+ return $i_dscfn;
+}
+
+sub i_want_signed_tag {
+ defined $i_param{'head'} && defined $i_dscfn
+ or badproto \*RO, "sequencing error";
+ my $head = $i_param{'head'};
+ die if $head =~ m/[^0-9a-f]/ || $head !~ m/^../;
+
+ push_parse_dsc $i_dscfn, 'remote dsc',
+
+ push_mktag $head, $i_clogp, $i_tag,
+ $dsc, $i_dscfn,
+ 'remote.changes', 'remote changes',
+ 'tag.tag';
+
+ return 'tag.tag';
+}
+
+sub i_want_signed_dsc_changes {
+ rename "$i_dscfn.tmp","$i_dscfn" or die "$i_dscfn $!";
+ sign_changes 'remote.changes';
+ return ($i_dscfn, 'remote.changes');
}
#---------- building etc. ----------
sub parseopts () {
my $om;
+
+ if (defined $ENV{'DGIT_SSH'}) {
+ @ssh = string_to_ssh $ENV{'DGIT_SSH'};
+ } elsif (defined $ENV{'GIT_SSH'}) {
+ @ssh = ($ENV{'GIT_SSH'});
+ }
+
while (@ARGV) {
last unless $ARGV[0] =~ m/^-/;
$_ = shift @ARGV;
push @ropts, $_;
$om->[0] = $2;
} elsif (m/^--(\w+):(.*)/s &&
+ !$opts_opt_cmdonly{$1} &&
($om = $opts_opt_map{$1})) {
push @ropts, $_;
push @$om, $2;