# dgit
# Integration between git and Debian-style archives
#
-# Copyright (C)2013-2018 Ian Jackson
-# Copyright (C)2017-2018 Sean Whitton
+# Copyright (C)2013-2019 Ian Jackson
+# Copyright (C)2017-2019 Sean Whitton
+# Copyright (C)2019 Matthew Vernon / Genome Research Limited
#
# 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
our $our_version = 'UNRELEASED'; ###substituted###
our $absurdity = undef; ###substituted###
-our @rpushprotovsn_support = qw(5 4); # Reverse order!
+our @rpushprotovsn_support = qw(6 5 4); # Reverse order!
our $protovsn;
our $cmd;
our %format_ok = map { $_=>1 } ("1.0","3.0 (native)","3.0 (quilt)");
-our $suite_re = '[-+.0-9a-z]+';
our $cleanmode_re = qr{(?: dpkg-source (?: -d )? (?: ,no-check | ,all-check )?
| (?: git | git-ff ) (?: ,always )?
| check (?: ,ignores )?
our @dpkg_source_ignores = qw(-i(?:^|/)\.git(?:/|$) -I.git);
-our (@git) = qw(git);
our (@dget) = qw(dget);
our (@curl) = (qw(curl --proto-redir), '-all,http,https', qw(-L));
our (@dput) = qw(dput);
# > param head DGIT-VIEW-HEAD
# > param csuite SUITE
# > param tagformat new # $protovsn == 4
+# > param splitbrain 0|1 # $protovsn >= 6
# > param maint-view MAINT-VIEW-HEAD
#
# > param buildinfo-filename P_V_X.buildinfo # zero or more times
'dgit-distro.debian-backports.mirror' => 'http://backports.debian.org/debian-backports/',
'dgit-distro.ubuntu.git-check' => 'false',
'dgit-distro.ubuntu.mirror' => 'http://archive.ubuntu.com/ubuntu',
+ 'dgit-distro.ubuntucloud.git-check' => 'false',
+ 'dgit-distro.ubuntucloud.nominal-distro' => 'ubuntu',
+ 'dgit-distro.ubuntucloud.archive-query' => 'aptget:',
+ 'dgit-distro.ubuntucloud.mirror' => 'http://ubuntu-cloud.archive.canonical.com/ubuntu',
+ 'dgit-distro.ubuntucloud.aptget-suite-map' => 's#^([^-]+):([^:]+)$#${1}-updates/$2#; s#^(.+)-(.+):(.+)#$1-$2/$3#;',
+ 'dgit-distro.ubuntucloud.aptget-suite-rmap' => 's#/(.+)$#-$1#',
'dgit-distro.test-dummy.ssh' => "$td/ssh",
'dgit-distro.test-dummy.username' => "alice",
'dgit-distro.test-dummy.git-check' => "ssh-cmd",
my $val = $release->{$name};
if (defined $val) {
printdebug "release file $name: $val\n";
+ cfg_apply_map(\$val, 'suite rmap',
+ access_cfg('aptget-suite-rmap', 'RETURN-UNDEF'));
$val =~ m/^$suite_re$/o or fail f_
"Release file (%s) specifies intolerable %s",
$aptget_releasefile, $name;
- cfg_apply_map(\$val, 'suite rmap',
- access_cfg('aptget-suite-rmap', 'RETURN-UNDEF'));
return $val
}
}
}
sub mktree_in_ud_here () {
- playtree_setup $gitcfgs{local};
+ playtree_setup();
}
sub git_write_tree () {
record_maindir();
setup_new_tree();
clone_set_head();
- my $giturl = access_giturl(1);
- if (defined $giturl) {
- runcmd @git, qw(remote add), 'origin', $giturl;
- }
if ($hasgit) {
progress __ "fetching existing git history";
git_fetch_us();
- runcmd_ordryrun_local @git, qw(fetch origin);
} else {
progress __ "starting new git history";
}
# 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;
- my @dtxinfo = @deliberatelies;
my $mktag = sub {
my ($tw) = @_;
tagger $authline
END
- if ($tw->{View} eq 'dgit') {
- print TO f_ <<ENDT, $package, $cversion, $clogsuite, $csuite
-%s release %s for %s (%s) [dgit]
-ENDT
- or confess "$!";
- my $dtxinfo = join(" ", "",@dtxinfo);
- print TO <<END or confess "$!";
+
+ my @dtxinfo = @deliberatelies;
+ unshift @dtxinfo, "--quilt=$quilt_mode" if madformat($format);
+ unshift @dtxinfo, do_split_brain() ? "split" : "no-split"
+ # rpush protocol 5 and earlier don't tell us
+ unless $we_are_initiator && $protovsn < 6;
+ my $dtxinfo = join(" ", "",@dtxinfo);
+ my $tag_metadata = <<END;
[dgit distro=$declaredistro$dtxinfo]
END
- foreach my $ref (sort keys %previously) {
- print TO <<END or confess "$!";
+ foreach my $ref (sort keys %previously) {
+ $tag_metadata .= <<END or confess "$!";
[dgit previously:$ref=$previously{$ref}]
END
- }
+ }
+
+ if ($tw->{View} eq 'dgit') {
+ print TO sprintf <<ENDT, $package, $cversion, $clogsuite, $csuite
+%s release %s for %s (%s) [dgit]
+ENDT
+ or confess "$!";
} elsif ($tw->{View} eq 'maint') {
- print TO f_ <<END, $package, $cversion, $clogsuite, $csuite,
+ print TO sprintf <<END, $package, $cversion, $clogsuite, $csuite;
%s release %s for %s (%s)
+
+END
+ print TO f_ <<END,
(maintainer view tag generated by dgit --quilt=%s)
END
$quilt_mode
} else {
confess Dumper($tw)."?";
}
+ print TO "\n", $tag_metadata;
close TO or confess "$!";
responder_send_command("param csuite $csuite");
responder_send_command("param isuite $isuite");
responder_send_command("param tagformat new"); # needed in $protovsn==4
+ responder_send_command("param splitbrain $do_split_brain");
if (defined $maintviewhead) {
responder_send_command("param maint-view $maintviewhead");
}
pushing();
rpush_handle_protovsn_bothends();
push_parse_dsc $i_dscfn, 'remote dsc', $i_version;
+ if ($protovsn >= 6) {
+ determine_whether_split_brain getfield $dsc, 'Format';
+ $do_split_brain eq ($i_param{'splitbrain'} // '<unsent>')
+ or badproto \*RO,
+ "split brain mismatch, $do_split_brain != $i_param{'split_brain'}";
+ printdebug "rpush split brain $do_split_brain\n";
+ }
}
my @localpaths = i_method "i_want", $keyword;
sub build_or_push_prep_early () {
our $build_or_push_prep_early_done //= 0;
return if $build_or_push_prep_early_done++;
- badusage f_ "-p is not allowed with dgit %s", $subcommand
- if defined $package;
my $clogp = parsechangelog();
$isuite = getfield $clogp, 'Distribution';
- $package = getfield $clogp, 'Source';
+ my $gotpackage = getfield $clogp, 'Source';
$version = getfield $clogp, 'Version';
+ $package //= $gotpackage;
+ if ($package ne $gotpackage) {
+ fail f_ "-p specified package %s, but changelog says %s",
+ $package, $gotpackage;
+ }
$dscfn = dscfn($version);
}