chiark / gitweb /
dgit: --clean=dpkg-source: Check for untracked unignored files
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 13 Oct 2018 12:12:39 +0000 (13:12 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 13 Oct 2018 15:46:29 +0000 (16:46 +0100)
We would like to spot if the user forgot to `git add' a file.
This can be done by calling clean_tree_check_git, after rules
clean (if applicable).

We need to make this configurable.  We do so via the clean mode, with
a comma-separated checking control suffix (and short aliases) like we
did for --clean=git,ignores.

The default should be cautious, ie to do this check, but often the
user will want to disable it because the source package has a buggy
clean target or no or insufficient .gitignore.  Existing users should
probably get the new check until they choose otherwise (which we have
made easier for them with the .clean-mode-newer config option).

So we change the meanings of -wd and -wdd to include the new check,
and provide new build modes ...,no-check aka -wdn / -wddn to disable
it.

To implement this we introduce a new clean_tree_check_git_wd function
to do the actual work, particularly because both during cleaning and
cleanliness checking, we want to print some hints to the user if the
check fails.

We can't do the new check if we applied patches dirtily to run the
rules target, because it will trip over the result of patch
application.  This way of working is just too poor to support this new
check.

The test suite generally tests the default versions, not the no-check
versions.  We must teach the test to expect the new check.  This is
most easily done with a separate case for the check side of the -wd
clean modes.  And we need to support the no-check variant too,
because:

The push-source-with-changes test does in fact work with a built tree
and needs to test the no-check variant.

The gbp tests sometimes involve patch application.  Rather than trying
to predict which of them do (in which cases there would be no clean
check), we force them all to ,no-check.

The oldnewtagalt test can use -wgf.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
dgit
dgit.1
tests/lib-build-modes
tests/tests/build-modes-gbp
tests/tests/oldnewtagalt
tests/tests/push-source-with-changes

diff --git a/dgit b/dgit
index 57e1e40d13d5c848b91a49ddd756d5bae27d1a78..654b3d1d4cc1817d378740cb2a4b3d7870b2221d 100755 (executable)
--- a/dgit
+++ b/dgit
@@ -101,7 +101,7 @@ our %forceopts = map { $_=>0 }
 our %format_ok = map { $_=>1 } ("1.0","3.0 (native)","3.0 (quilt)");
 
 our $suite_re = '[-+.0-9a-z]+';
 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 )?
+our $cleanmode_re = qr{(?: dpkg-source (?: -d )? (?: ,no-check )?
                          | git | git-ff
                          | check (?: ,ignores )?
                          | none
                          | git | git-ff
                          | check (?: ,ignores )?
                          | none
@@ -6214,6 +6214,19 @@ sub clean_tree_check_git ($$) {
     }
 }
 
     }
 }
 
+sub clean_tree_check_git_wd ($) {
+    my ($message) = @_;
+    return if $cleanmode =~ m{no-check};
+    return if $patches_applied_dirtily; # yuk
+    clean_tree_check_git 1,
+                         (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.
 sub clean_tree_check () {
     # Not yet fully implemented.
     # This function needs to not care about modified but tracked files.
@@ -6222,6 +6235,9 @@ sub clean_tree_check () {
     if ($cleanmode =~ m{^check}) {
        clean_tree_check_git +($cleanmode =~ m{ignores}), __
  "tree contains uncommitted files and --clean=check specified";
     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)";
     }
 }
 
     }
 }
 
@@ -6234,6 +6250,8 @@ sub clean_tree () {
        push @cmd, qw(-T clean);
        maybe_apply_patches_dirtily();
        runcmd_ordryrun_local @cmd;
        push @cmd, qw(-T clean);
        maybe_apply_patches_dirtily();
        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') {
     } elsif ($cleanmode eq 'git') {
        runcmd_ordryrun_local @git, qw(clean -xdf);
     } elsif ($cleanmode eq 'git-ff') {
@@ -7262,10 +7280,11 @@ sub parseopts () {
                } elsif (s/^-wgf$//s) {
                    push @ropts, $&;
                    $cleanmode = 'git-ff';
                } elsif (s/^-wgf$//s) {
                    push @ropts, $&;
                    $cleanmode = 'git-ff';
-               } elsif (s/^-wd(d?)$//s) {
+               } elsif (s/^-wd(d?)([n]?)$//s) {
                    push @ropts, $&;
                    $cleanmode = 'dpkg-source';
                    $cleanmode .= '-d' if $1;
                    push @ropts, $&;
                    $cleanmode = 'dpkg-source';
                    $cleanmode .= '-d' if $1;
+                   $cleanmode .= ',no-check' if $2 eq 'n';
                } elsif (s/^-wc$//s) {
                    push @ropts, $&;
                    $cleanmode = 'check';
                } elsif (s/^-wc$//s) {
                    push @ropts, $&;
                    $cleanmode = 'check';
diff --git a/dgit.1 b/dgit.1
index 1ee02301ffa02ffe18e22975dd0102599a9f73ec..ed5205c4d6b087835741bfbc954cb9225aec2508 100644 (file)
--- a/dgit.1
+++ b/dgit.1
@@ -598,6 +598,20 @@ from your working tree,
 rather than from your git branch
 (for example because of --include-dirty
 or because the binary package build uses your working tree).
 rather than from your git branch
 (for example because of --include-dirty
 or because the binary package build uses your working tree).
+
+In all cases,
+dgit will check that there are (after rules clean, if applicable) no
+untracked un-ignored files,
+in case these are files you forgot to git add.
+(Except that this check is not done
+for a `3.0 (quilt)' package
+when dgit has to apply patches, dirtily, to the working tree.)
+If your package does not have a good .gitignore
+you will probably need --clean=dpkg-source,no-check aka -wdn.
+.TP
+.BR --clean=dpkg-source "[" -d "]" ,no-check " | " -wdn " | " -wddn
+Like --clean=dpkg-source, but
+does not care about untracked un-ignored files.
 .TP
 .BR -N " | " --new
 The package is or may be new in this suite.  Without this, dgit will
 .TP
 .BR -N " | " --new
 The package is or may be new in this suite.  Without this, dgit will
index 232d322e139fe983b3a730be15b7f80e717dd2f1..837dde0c88e17fccfdd38f533693a842885cfff3 100644 (file)
@@ -49,7 +49,7 @@ bm-gbp-example-acts () {
 
        bm-prep-ownpackage-branches for-build-modes
 
 
        bm-prep-ownpackage-branches for-build-modes
 
-       cleanmodes='git dpkg-source'
+       cleanmodes='git dpkg-source,no-check'
 
        for act in "$@"; do
                bm-guess-e-source-e-targets "$act"
 
        for act in "$@"; do
                bm-guess-e-source-e-targets "$act"
@@ -151,18 +151,28 @@ bm-compute-expected () {
        git)            echo >&4 'BUILD-MODES PROGRAM git clean -xdf' ;;
        git-ff)         echo >&4 'BUILD-MODES PROGRAM git clean -xdff' ;;
        check|Ccheck)   echo >&4 'BUILD-MODES PROGRAM git clean -dn -x' ;;
        git)            echo >&4 'BUILD-MODES PROGRAM git clean -xdf' ;;
        git-ff)         echo >&4 'BUILD-MODES PROGRAM git clean -xdff' ;;
        check|Ccheck)   echo >&4 'BUILD-MODES PROGRAM git clean -dn -x' ;;
-       dpkg-source-d)
+       dpkg-source-d|dpkg-source-d,no-check)
                        echo >&4 "EXAMPLE RULES TARGET clean"
                        ;;
                        echo >&4 "EXAMPLE RULES TARGET clean"
                        ;;
-       dpkg-source)
+       dpkg-source|dpkg-source,no-check)
                        bm-build-deps-ok || tolerate_fail=tolerate
                        echo >&4 "EXAMPLE RULES TARGET clean"
                        ;;
        none)           ;;
                        bm-build-deps-ok || tolerate_fail=tolerate
                        echo >&4 "EXAMPLE RULES TARGET clean"
                        ;;
        none)           ;;
+       Cdpkg-source*)  ;; # handled below
        C*)             echo "TODO bm eff_cleanmode=$eff_cleanmode" ;;
        *)              fail "t-compute-expected-run $cleanmode ??" ;;
        esac
 
        C*)             echo "TODO bm eff_cleanmode=$eff_cleanmode" ;;
        *)              fail "t-compute-expected-run $cleanmode ??" ;;
        esac
 
+       case $eff_cleanmode in
+       dpkg-source|Cdpkg-source|dpkg-source-d|Cdpkg-source-d)
+                       echo >&4 'BUILD-MODES PROGRAM git clean -dn'
+                       ;;
+       dpkg-source*,no-check|Cdpkg-source*,no-check)
+                       ;;
+       Cdpkg-source*)  fail "t-compute-expected-run wd $cleanmode ??" ;;
+       esac
+
        if [ "x$e_targets" != x ]; then
                # e_targets can be " " to mean `/may/ fail due to b-d'
                bm-build-deps-ok || tolerate_fail=tolerate
        if [ "x$e_targets" != x ]; then
                # e_targets can be " " to mean `/may/ fail due to b-d'
                bm-build-deps-ok || tolerate_fail=tolerate
index d99b791ad27e57a8e83a67019aad6a47de0731ad..93d0811aa6ff389da98cddcf01d33c2771a7bc27 100755 (executable)
@@ -21,6 +21,7 @@ quirk-clean-fixup () {
 }
 bm_quirk_before_diff=quirk-clean-fixup
 
 }
 bm_quirk_before_diff=quirk-clean-fixup
 
+cleanmodes_dpkgsource_extra=,no-check
 bm-prep
 
 for act in                                     \
 bm-prep
 
 for act in                                     \
index 098fe191eac5c6238c4051583dee0b82a1a063ba..6730918bff99e7c8dea504b026c3c26a6633d0cf 100755 (executable)
@@ -9,7 +9,7 @@ cd $p
 
 test-push () {
        t-commit "$1"
 
 test-push () {
        t-commit "$1"
-       t-dgit build-source
+       t-dgit -wgf build-source
        t-dgit push
 }
 
        t-dgit push
 }
 
index 580ea3acd5e80b9befd6d1ccf8c66f12e3e4c0dd..26584853e33269e6d52a16a75f5f0ad04f40b49c 100755 (executable)
@@ -20,7 +20,7 @@ t-dgit -C ../${p}_1.0_multi.changes push-source --new
 
 # (2) try pushing a source-only changes file
 
 
 # (2) try pushing a source-only changes file
 
-t-dgit --dpkg-buildpackage:-d build-source
+t-dgit -wddn --dpkg-buildpackage:-d build-source
 t-dgit -C ../${p}_1.0_source.changes push-source --new
 
 t-pushed-good master
 t-dgit -C ../${p}_1.0_source.changes push-source --new
 
 t-pushed-good master