our %format_ok = map { $_=>1 } ("1.0","3.0 (native)","3.0 (quilt)");
our $suite_re = '[-+.0-9a-z]+';
-our $cleanmode_re = 'dpkg-source(?:-d)?|git|git-ff|check|none';
+our $cleanmode_re = qr{(?: dpkg-source (?: -d )? (?: ,no-check | ,all-check )?
+ | git | git-ff
+ | check (?: ,ignores )?
+ | none
+ )}x;
our $git_authline_re = '^([^<>]+) \<(\S+)\> (\d+ [-+]\d+)$';
our $splitbraincache = 'dgit-intern/quilt-cache';
#----- other building -----
-our $clean_using_builder;
-# ^ tree is to be cleaned by dpkg-source's builtin idea that it should
-# clean the tree before building (perhaps invoked indirectly by
-# whatever we are using to run the build), rather than separately
-# and explicitly by us.
+sub clean_tree_check_git ($$) {
+ my ($honour_ignores, $message) = @_;
+ my @cmd = (@git, qw(clean -dn));
+ push @cmd, qw(-x) unless $honour_ignores;
+ my $leftovers = cmdoutput @cmd;
+ if (length $leftovers) {
+ print STDERR $leftovers, "\n" or confess $!;
+ fail $message;
+ }
+}
+
+sub clean_tree_check_git_wd ($) {
+ my ($message) = @_;
+ return if $cleanmode =~ m{no-check};
+ return if $patches_applied_dirtily; # yuk
+ clean_tree_check_git +($cleanmode !~ m{all-check}),
+ (f_ <<END, $message);
+%s
+If this is just missing .gitignore entries, use a different clean
+mode, eg --clean=dpkg-source,no-check (-wdu/-wddu) to ignore them
+or --clean=git (-wg/-wgf) to use \`git clean' instead.
+END
+}
+
+sub clean_tree_check () {
+ # Not yet fully implemented.
+ # This function needs to not care about modified but tracked files.
+ # That was done by check_not_dirty, and by now we may have run
+ # the rules clean target which might modify tracked files (!)
+ if ($cleanmode =~ m{^check}) {
+ clean_tree_check_git +($cleanmode =~ m{ignores}), __
+ "tree contains uncommitted files and --clean=check specified";
+ } elsif ($cleanmode =~ m{^dpkg-source}) {
+ clean_tree_check_git_wd __
+ "tree contains uncommitted files (NB dgit didn't run rules clean)";
+ } elsif ($cleanmode =~ m{^git}) {
+ # If we were actually cleaning these files would be summarily
+ # deleted. Since we're not, and not using the working tree
+ # anyway, we can just ignore them - nothing will use them.
+ } elsif ($cleanmode eq 'none') {
+ } else {
+ confess "$cleanmode ?";
+ }
+}
sub clean_tree () {
- return if $clean_using_builder;
- if ($cleanmode eq 'dpkg-source') {
+ # We always clean the tree ourselves, rather than leave it to the
+ # builder (dpkg-source, or soemthing which calls dpkg-source).
+ if ($cleanmode =~ m{^dpkg-source}) {
+ my @cmd = @dpkgbuildpackage;
+ push @cmd, qw(-d) if $cleanmode =~ m{^dpkg-source-d};
+ push @cmd, qw(-T clean);
maybe_apply_patches_dirtily();
- runcmd_ordryrun_local @dpkgbuildpackage, qw(-T clean);
- } elsif ($cleanmode eq 'dpkg-source-d') {
- maybe_apply_patches_dirtily();
- runcmd_ordryrun_local @dpkgbuildpackage, qw(-d -T clean);
+ runcmd_ordryrun_local @cmd;
+ clean_tree_check_git_wd __
+ "tree contains uncommitted files (after running rules clean)";
} elsif ($cleanmode eq 'git') {
runcmd_ordryrun_local @git, qw(clean -xdf);
} elsif ($cleanmode eq 'git-ff') {
runcmd_ordryrun_local @git, qw(clean -xdff);
- } elsif ($cleanmode eq 'check') {
- my $leftovers = cmdoutput @git, qw(clean -xdn);
- if (length $leftovers) {
- print STDERR $leftovers, "\n" or confess $!;
- fail __
- "tree contains uncommitted files and --clean=check specified";
- }
+ } elsif ($cleanmode =~ m{^check}) {
+ clean_tree_check();
} elsif ($cleanmode eq 'none') {
} else {
- die "$cleanmode ?";
+ confess "$cleanmode ?";
}
}
sub build_prep ($) {
my ($wantsrc) = @_;
build_prep_early();
- # clean the tree if we're trying to include dirty changes in the
- # source package, or we are running the builder in $maindir
- clean_tree() if $includedirty || ($wantsrc & WANTSRC_BUILDER);
+ if (!building_source_in_playtree() || ($wantsrc & WANTSRC_BUILDER)) {
+ # Clean the tree because we're going to use the contents of
+ # $maindir. (We trying to include dirty changes in the source
+ # package, or we are running the builder in $maindir.)
+ clean_tree();
+ } else {
+ # We don't actually need to do anything in $maindir, but we
+ # should do some kind of cleanliness check because (i) the
+ # user may have forgotten a `git add', and (ii) if the user
+ # said -wc we should still do the check.
+ clean_tree_check();
+ }
build_maybe_quilt_fixup();
if ($rmchanges) {
my $pat = changespat $version;
build_source();
midbuild_checkchanges_vanilla $wantsrc;
} else {
- if (!$clean_using_builder) {
- push @cmd, '--git-cleaner=true';
- }
+ push @cmd, '--git-cleaner=true';
}
maybe_unapply_patches_again();
if ($wantsrc & WANTSRC_BUILDER) {
} elsif (s/^-wgf$//s) {
push @ropts, $&;
$cleanmode = 'git-ff';
- } elsif (s/^-wd$//s) {
+ } elsif (s/^-wd(d?)([na]?)$//s) {
push @ropts, $&;
$cleanmode = 'dpkg-source';
- } elsif (s/^-wdd$//s) {
- push @ropts, $&;
- $cleanmode = 'dpkg-source-d';
+ $cleanmode .= '-d' if $1;
+ $cleanmode .= ',no-check' if $2 eq 'n';
+ $cleanmode .= ',all-check' if $2 eq 'a';
} elsif (s/^-wc$//s) {
push @ropts, $&;
$cleanmode = 'check';
+ } elsif (s/^-wci$//s) {
+ push @ropts, $&;
+ $cleanmode = 'check,ignores';
} elsif (s/^-c([^=]*)\=(.*)$//s) {
push @git, '-c', $&;
$gitcfgs{cmdline}{$1} = [ $2 ];
if (!defined $cleanmode) {
local $access_forpush;
- $cleanmode = access_cfg('clean-mode', 'RETURN-UNDEF');
+ $cleanmode = access_cfg('clean-mode-newer', 'RETURN-UNDEF');
+ $cleanmode = undef if $cleanmode && $cleanmode !~ m/^$cleanmode_re$/;
+
+ $cleanmode //= access_cfg('clean-mode', 'RETURN-UNDEF');
$cleanmode //= 'dpkg-source';
badcfg f_ "unknown clean-mode \`%s'", $cleanmode unless
- $cleanmode =~ m/^($cleanmode_re)$(?!\n)/s;
+ $cleanmode =~ m/$cleanmode_re/;
}
$buildproductsdir //= access_cfg('build-products-dir', 'RETURN-UNDEF');