autoflush STDOUT 1;
our $supplementary_message = '';
+our $need_split_build_invocation = 0;
END {
local ($@, $?);
our $ud = '.git/dgit/unpack';
-sub prep_ud () {
- rmtree($ud);
+sub prep_ud (;$) {
+ my ($d) = @_;
+ $d //= $ud;
+ rmtree($d);
mkpath '.git/dgit';
- mkdir $ud or die $!;
+ mkdir $d or die $!;
}
sub mktree_in_ud_here () {
my $format = getfield $dsc, 'Format';
printdebug "format $format\n";
if (madformat($format)) {
+ # user might have not used dgit build, so maybe do this now:
commit_quilty_patch();
}
check_not_dirty();
}
}
-sub quiltify_trees_differ ($$) {
- my ($x,$y) = @_;
+sub quiltify_trees_differ ($$;$) {
+ my ($x,$y,$ignoregitignore) = @_;
# returns 1 iff the two tree objects differ other than in debian/
local $/=undef;
my @cmd = (@git, qw(diff-tree --name-only -z), $x, $y);
my $diffs= cmdoutput @cmd;
foreach my $f (split /\0/, $diffs) {
next if $f eq 'debian';
+ next if $f eq '.gitignore' && $ignoregitignore;
return 1;
}
return 0;
return $r;
}
-sub quiltify ($$) {
- my ($clogp,$target) = @_;
+sub quiltify ($$$) {
+ my ($clogp,$target,$unapplied) = @_;
# Quilt patchification algorithm
#
# should be contained within debian/patches.
changedir '../fake';
- remove_stray_gits();
- mktree_in_ud_here();
rmtree '.pc';
runcmd @git, qw(add -Af .);
my $oldtiptree=git_write_tree();
# 5. If we had a .pc in-tree, delete it, and git-commit
# 6. Back in the main tree, fast forward to the new HEAD
+ # Another situation we may have to cope with is gbp-style
+ # patches-unapplied trees. We want to detect these, so we know
+ # to escape into quilt_fixup_gbp.
+ #
+ # A gbp-style tree is one which is not a clean patches-applied
+ # tree, but _is_ a clean patches-unapplied tree.
+ #
+ # To help detect this, when we are extracting the fake dsc, we
+ # first extract it with --skip-patches, and then apply the patches
+ # afterwards with dpkg-source --before-build. That lets us save a
+ # tree object corresponding to .origs.
+
my $fakeversion="$upstreamversion-~~DGITFAKE";
my $fakedsc=new IO::File 'fake.dsc', '>' or die $!;
quilt_fixup_linkorigs($upstreamversion, $dscaddfile);
- my @files=qw(debian/source/format debian/rules);
+ my @files=qw(debian/source/format debian/rules
+ debian/control debian/changelog);
foreach my $maybe (qw(debian/patches debian/source/options)) {
next unless stat_exists "../../../$maybe";
push @files, $maybe;
$dscaddfile->($debtar);
close $fakedsc or die $!;
- runcmd qw(sh -ec), 'exec dpkg-source --no-check -x fake.dsc >/dev/null';
+ runcmd qw(sh -ec),
+ 'exec dpkg-source --no-check --skip-patches -x fake.dsc >/dev/null';
my $fakexdir= $package.'-'.(stripepoch $upstreamversion);
rename $fakexdir, "fake" or die "$fakexdir $!";
+ changedir 'fake';
+
+ remove_stray_gits();
+ mktree_in_ud_here();
+
+ rmtree '.pc';
+
+ runcmd @git, qw(add -Af .);
+ my $unapplied=git_write_tree();
+ printdebug "fake orig tree object $unapplied\n";
+
+ ensuredir '.pc';
+
+ runcmd qw(sh -ec),
+ 'exec dpkg-source --before-build . >/dev/null';
+
+ changedir '..';
+
quilt_fixup_mkwork($headref);
my $mustdeletepc=0;
rename '../fake/.pc','.pc' or die $!;
}
- quiltify($clogp,$headref);
+ quiltify($clogp,$headref,$unapplied);
if (!open P, '>>', ".pc/applied-patches") {
$!==&ENOENT or die $!;
sub massage_dbp_args ($;$) {
my ($cmd,$xargs) = @_;
- if ($cleanmode eq 'dpkg-source') {
+ # We need to:
+ #
+ # - if we're going to split the source build out so we can
+ # do strange things to it, massage the arguments to dpkg-buildpackage
+ # so that the main build doessn't build source (or add an argument
+ # to stop it building source by default).
+ #
+ # - add -nc to stop dpkg-source cleaning the source tree,
+ # unless we're not doing a split build and want dpkg-source
+ # as cleanmode, in which case we can do nothing
+ #
+ # return values:
+ # 0 - source will NOT need to be built separately by caller
+ # +1 - source will need to be built separately by caller
+ # +2 - source will need to be built separately by caller AND
+ # dpkg-buildpackage should not in fact be run at all!
+ debugcmd '#massaging#', @$cmd if $debuglevel>1;
+#print STDERR "MASS0 ",Dumper($cmd, $xargs, $need_split_build_invocation);
+ if ($cleanmode eq 'dpkg-source' && !$need_split_build_invocation) {
$suppress_clean = 1;
- return;
+ return 0;
}
- debugcmd '#massaging#', @$cmd if $debuglevel>1;
- my @newcmd = shift @$cmd;
# -nc has the side effect of specifying -b if nothing else specified
- push @newcmd, '-nc';
# and some combinations of -S, -b, et al, are errors, rather than
- # later simply overriding earlier
- push @newcmd, '-F' unless grep { m/^-[bBASFgG]$/ } (@$cmd, @$xargs);
- push @newcmd, @$cmd;
- @$cmd = @newcmd;
+ # later simply overriding earlie. So we need to:
+ # - search the command line for these options
+ # - pick the last one
+ # - perhaps add our own as a default
+ # - perhaps adjust it to the corresponding non-source-building version
+ my $dmode = '-F';
+ foreach my $l ($cmd, $xargs) {
+ next unless $l;
+ @$l = grep { !(m/^-[SgGFABb]$/s and $dmode=$_) } @$l;
+ }
+ push @$cmd, '-nc';
+#print STDERR "MASS1 ",Dumper($cmd, $xargs, $dmode);
+ my $r = 0;
+ if ($need_split_build_invocation) {
+ $r = $dmode =~ m/[S]/ ? +2 :
+ $dmode =~ y/gGF/ABb/ ? +1 :
+ $dmode =~ m/[ABb]/ ? 0 :
+ die "$dmode ?";
+ }
+ push @$cmd, $dmode;
+#print STDERR "MASS2 ",Dumper($cmd, $xargs, $r);
+ return $r;
}
sub cmd_build {
my @dbp = (@dpkgbuildpackage, qw(-us -uc), changesopts_initial(), @ARGV);
- massage_dbp_args \@dbp;
- build_prep();
- push @dbp, changesopts_version();
- runcmd_ordryrun_local @dbp;
+ my $wantsrc = massage_dbp_args \@dbp;
+ if ($wantsrc > 0) {
+ build_source();
+ } else {
+ build_prep();
+ }
+ if ($wantsrc < 2) {
+ push @dbp, changesopts_version();
+ runcmd_ordryrun_local @dbp;
+ }
printdone "build successful\n";
}
sub cmd_gbp_build {
my @dbp = @dpkgbuildpackage;
- massage_dbp_args \@dbp, \@ARGV;
+
+ my $wantsrc = massage_dbp_args \@dbp, \@ARGV;
my @cmd;
if (length executable_on_path('git-buildpackage')) {
}
push @cmd, (qw(-us -uc --git-no-sign-tags), "--git-builder=@dbp");
- if ($cleanmode eq 'dpkg-source') {
- $suppress_clean = 1;
+ if ($wantsrc > 0) {
+ build_source();
} else {
- push @cmd, '--git-cleaner=true';
+ if (!$suppress_clean) {
+ push @cmd, '--git-cleaner=true';
+ }
+ build_prep();
}
- build_prep();
- unless (grep { m/^--git-debian-branch|^--git-ignore-branch/ } @ARGV) {
- canonicalise_suite();
- push @cmd, "--git-debian-branch=".lbranch();
+ if ($wantsrc < 2) {
+ unless (grep { m/^--git-debian-branch|^--git-ignore-branch/ } @ARGV) {
+ canonicalise_suite();
+ push @cmd, "--git-debian-branch=".lbranch();
+ }
+ push @cmd, changesopts();
+ runcmd_ordryrun_local @cmd, @ARGV;
}
- push @cmd, changesopts();
- runcmd_ordryrun_local @cmd, @ARGV;
printdone "build successful\n";
}
sub cmd_git_build { cmd_gbp_build(); } # compatibility with <= 1.0
} elsif (m/^--deliberately-($deliberately_re)$/s) {
push @ropts, $_;
push @deliberatelies, $&;
+ } elsif (m/^--always-split-source-build$/s) {
+ # undocumented, for testing
+ push @ropts, $_;
+ $need_split_build_invocation = 1;
} elsif (m/^(--[-0-9a-z]+)(=|$)/ && ($oi = $valopts_long{$1})) {
$val = $2 ? $' : undef; #';
$valopt->($oi->{Long});