use Digest::MD5;
use List::Util qw(any);
use List::MoreUtils qw(pairwise);
+use Text::Glob qw(match_glob);
use Carp;
use Debian::Dgit;
if (defined $idistro) {
return $idistro;
} else {
- return cfg("dgit-suite.$isuite.distro",
- "dgit.default.distro");
+ my $def = cfg("dgit-suite.$isuite.distro", 'RETURN-UNDEF');
+ return $def if defined $def;
+ foreach my $src (@gitcfgsources, 'internal') {
+ my $kl = $src eq 'internal' ? \%defcfg : $gitcfgs{$src};
+ next unless $kl;
+ foreach my $k (keys %$kl) {
+ next unless $k =~ m#^dgit-suite\.(.*)\.distro$#;
+ my $dpat = $1;
+ next unless match_glob $dpat, $isuite;
+ return $kl->{$k};
+ }
+ }
+ return cfg("dgit.default.distro");
}
}
+sub access_nomdistro () {
+ my $base = access_basedistro();
+ return cfg("dgit-distro.$base.nominal-distro",'RETURN-UNDEF') // $base;
+}
+
sub access_quirk () {
# returns (quirk name, distro to use instead or undef, quirk-specific info)
my $basedistro = access_basedistro();
unshift @l, $instead_distro;
@l = grep { defined } @l;
+ push @l, access_nomdistro();
+
if (access_forpush()) {
@l = map { ("$_/push", $_) } @l;
}
}
sub parsecontrol {
- my ($file, $desc) = @_;
+ my ($file, $desc, $allowsigned) = @_;
my $fh = new IO::Handle;
open $fh, '<', $file or die "$file: $!";
- my $c = parsecontrolfh($fh,$desc);
+ my $c = parsecontrolfh($fh,$desc,$allowsigned);
$fh->error and die $!;
close $fh;
return $c;
{ no strict qw(refs); &{"${method}_${proto}"}($proto,$data,@_); }
}
+sub archive_query_prepend_mirror {
+ my $m = access_cfg('mirror');
+ return map { [ $_->[0], $m.$_->[1], @$_[2..$#$_] ] } @_;
+}
+
sub pool_dsc_subpath ($$) {
my ($vsn,$component) = @_; # $package is implict arg
my $prefix = substr($package, 0, $package =~ m/^l/ ? 4 : 1);
if length $@;
}
@rows = sort { -version_compare($a->[0],$b->[0]) } @rows;
- return @rows;
+ return archive_query_prepend_mirror @rows;
}
sub file_in_archive_ftpmasterapi {
#---------- `madison' archive query method ----------
sub archive_query_madison {
- return map { [ @$_[0..1] ] } madison_get_parse(@_);
+ return archive_query_prepend_mirror
+ map { [ @$_[0..1] ] } madison_get_parse(@_);
}
sub madison_get_parse {
my ($vsn,$component,$filename,$sha256sum) = @$_;
[ $vsn, "/pool/$component/$filename",$digester,$sha256sum ];
} @rows;
- return @rows;
+ return archive_query_prepend_mirror @rows;
}
sub canonicalise_suite_sshpsql ($$) {
}
C->error and die "$dpath: $!";
close C;
- return sort { -version_compare($a->[0],$b->[0]); } @rows;
+ return archive_query_prepend_mirror
+ sort { -version_compare($a->[0],$b->[0]); } @rows;
}
sub file_in_archive_dummycat () { return undef; }
canonicalise_suite();
my @vsns = archive_query('archive_query');
foreach my $vinfo (@vsns) {
- my ($vsn,$subpath,$digester,$digest) = @$vinfo;
- $dscurl = access_cfg('mirror').$subpath;
+ my ($vsn,$vsn_dscurl,$digester,$digest) = @$vinfo;
+ $dscurl = $vsn_dscurl;
$dscdata = url_get($dscurl);
if (!$dscdata) {
$skew_warning_vsn = $vsn if !defined $skew_warning_vsn;
vendor_patches_distro(Dpkg::Vendor::get_current_vendor(),
"Dpkg::Vendor \`current vendor'");
vendor_patches_distro(access_basedistro(),
- "distro being accessed");
+ "(base) distro being accessed");
+ vendor_patches_distro(access_nomdistro(),
+ "(nominal) distro being accessed");
}
sub generate_commits_from_dsc () {
my @specs = deliberately_not_fast_forward ? qw(tags/*) :
map { "tags/$_" }
(quiltmode_splitbrain
- ? (map { $_->('*',access_basedistro) }
+ ? (map { $_->('*',access_nomdistro) }
\&debiantag_new, \&debiantag_maintview)
- : debiantags('*',access_basedistro));
+ : debiantags('*',access_nomdistro));
push @specs, server_branch($csuite);
push @specs, qw(heads/*) if deliberately_not_fast_forward;
# git fetch to try to generate it. If we don't manage to generate
# the target state, we try again.
+ printdebug "git_fetch_us specs @specs\n";
+
my $specre = join '|', map {
my $x = $_;
$x =~ s/\W/\\$&/g;
my $fetch_iteration = 0;
FETCH_ITERATION:
for (;;) {
+ printdebug "git_fetch_us iteration $fetch_iteration\n";
if (++$fetch_iteration > 10) {
fail "too many iterations trying to get sane fetch!";
}
# OK, now %want is exactly what we want for refs in @specs
my @fspecs = map {
- return () if !m/\*$/ && !exists $wantr{"refs/$_"};
+ !m/\*$/ && !exists $wantr{"refs/$_"} ? () :
"+refs/$_:".lrfetchrefs."/$_";
} @specs;
+ printdebug "git_fetch_us fspecs @fspecs\n";
+
my @fcmd = (@git, qw(fetch -p -n -q), access_giturl(), @fspecs);
runcmd_ordryrun_local @git, qw(fetch -p -n -q), access_giturl(),
@fspecs;
Dumper(\%lrfetchrefs_f);
my %here;
- my @tagpats = debiantags('*',access_basedistro);
+ my @tagpats = debiantags('*',access_nomdistro);
git_for_each_ref([map { "refs/tags/$_" } @tagpats], sub {
my ($objid,$objtype,$fullrefname,$reftail) = @_;
};
if (defined $dsc_hash) {
- fail "missing remote git history even though dsc has hash -".
- " could not find ref ".rref()." at ".access_giturl()
- unless $lastpush_hash;
ensure_we_have_orig();
- if ($dsc_hash eq $lastpush_hash) {
+ if (!$lastpush_hash || $dsc_hash eq $lastpush_hash) {
@mergeinputs = $dsc_mergeinput
} elsif (is_fast_fwd($dsc_hash,$lastpush_hash)) {
print STDERR <<END or die $!;
die "$lasth $hash $what ?" unless is_fast_fwd($lasth, $hash);
};
- $chkff->($lastpush_hash, 'dgit repo server tip (last push)');
+ $chkff->($lastpush_hash, 'dgit repo server tip (last push)')
+ if $lastpush_hash;
$chkff->($lastfetch_hash, 'local tracking tip (last fetch)');
runcmd @git, qw(update-ref -m), "dgit fetch $csuite",
if (defined $overwrite_version) {
} elsif (!eval {
- my $t_dep14 = debiantag_maintview $i_arch_v->[0], access_basedistro;
+ my $t_dep14 = debiantag_maintview $i_arch_v->[0], access_nomdistro;
my $i_dep14 = infopair_lrf_tag_lookup($t_dep14, "maintainer view tag");
- my $t_dgit = debiantag_new $i_arch_v->[0], access_basedistro;
+ my $t_dgit = debiantag_new $i_arch_v->[0], access_nomdistro;
my $i_dgit = infopair_lrf_tag_lookup($t_dgit, "dgit view tag");
my $i_archive = [ $archive_hash, "current archive contents" ];
my $clogp = Dpkg::Control::Hash->new();
$clogp->load($clogpfn) or die;
- $package = getfield $clogp, 'Source';
+ my $clogpackage = getfield $clogp, 'Source';
+ $package //= $clogpackage;
+ fail "-p specified $package but changelog specified $clogpackage"
+ unless $package eq $clogpackage;
my $cversion = getfield $clogp, 'Version';
- my $tag = debiantag($cversion, access_basedistro);
+ my $tag = debiantag($cversion, access_nomdistro);
runcmd @git, qw(check-ref-format), $tag;
my $dscfn = dscfn($cversion);
};
}
foreach my $tw (@tagwants) {
- $tw->{Tag} = $tw->{TagFn}($cversion, access_basedistro);
+ $tw->{Tag} = $tw->{TagFn}($cversion, access_nomdistro);
$tw->{Tfn} = sub { $tfbase.$tw->{TfSuffix}.$_[0]; };
}
printdebug 'push_tagwants: ', Dumper(\@_, \@tagwants);
# to control the "tagger" (b) we can do remote signing
my $authline = clogp_authline $clogp;
my $delibs = join(" ", "",@deliberatelies);
- my $declaredistro = access_basedistro();
+ my $declaredistro = access_nomdistro();
my $mktag = sub {
my ($tw) = @_;
sub cmd_pull {
parseopts();
fetchpullargs();
+ if (quiltmode_splitbrain()) {
+ my ($format, $fopts) = get_source_format();
+ madformat($format) and fail <<END
+dgit pull not yet supported in split view mode (--quilt=$quilt_mode)
+END
+ }
pull();
}
maybe_unapply_patches_again();
}
-sub build_prep () {
+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;
- check_not_dirty();
- clean_tree();
my $clogp = parsechangelog();
$isuite = getfield $clogp, 'Distribution';
$package = getfield $clogp, 'Source';
$version = getfield $clogp, 'Version';
+ check_not_dirty();
+}
+
+sub build_prep () {
+ build_prep_early();
+ clean_tree();
build_maybe_quilt_fixup();
if ($rmchanges) {
my $pat = changespat $version;
}
sub cmd_gbp_build {
+ build_prep_early();
+
+ # gbp can make .origs out of thin air. In my tests it does this
+ # even for a 1.0 format package, with no origs present. So I
+ # guess it keys off just the version number. We don't know
+ # exactly what .origs ought to exist, but let's assume that we
+ # should run gbp if: the version has an upstream part and the main
+ # orig is absent.
+ my $upstreamversion = upstreamversion $version;
+ my $origfnpat = srcfn $upstreamversion, '.orig.tar.*';
+ my $gbp_make_orig = $version =~ m/-/ && !(() = glob "../$origfnpat");
+
+ if ($gbp_make_orig) {
+ clean_tree();
+ $cleanmode = 'none'; # don't do it again
+ $need_split_build_invocation = 1;
+ }
+
my @dbp = @dpkgbuildpackage;
my $wantsrc = massage_dbp_args \@dbp, \@ARGV;
push @cmd, (qw(-us -uc --git-no-sign-tags), "--git-builder=@dbp");
+ if ($gbp_make_orig) {
+ ensuredir '.git/dgit';
+ my $ok = '.git/dgit/origs-gen-ok';
+ unlink $ok or $!==&ENOENT or die $!;
+ my @origs_cmd = @cmd;
+ push @origs_cmd, qw(--git-cleaner=true);
+ push @origs_cmd, "--git-prebuild=touch $ok .git/dgit/no-such-dir/ok";
+ push @origs_cmd, @ARGV;
+ if (act_local()) {
+ debugcmd @origs_cmd;
+ system @origs_cmd;
+ do { local $!; stat_exists $ok; }
+ or failedcmd @origs_cmd;
+ } else {
+ dryrun_report @origs_cmd;
+ }
+ }
+
if ($wantsrc > 0) {
build_source();
midbuild_checkchanges_vanilla $wantsrc;
defvalopt '--existing-package','', '.*', \$existing_package;
defvalopt '--build-products-dir','','.*', \$buildproductsdir;
defvalopt '--clean', '', $cleanmode_re, \$cleanmode;
+defvalopt '--package', '-p', $package_re, \$package;
defvalopt '--quilt', '', $quilt_modes_re, \$quilt_mode;
defvalopt '', '-C', '.+', sub {