[devscripts] 01/01: Add sadt, a simple implementation of DEP-8 test runner

James McCoy jamessan at debian.org
Sun Dec 29 03:53:43 UTC 2013


This is an automated email from the git hooks/post-receive script.

jamessan pushed a commit to branch master
in repository devscripts.

commit 230d3c2d02214a5e7b4a499902fd36db56c906cf
Author: Jakub Wilk <jwilk at debian.org>
Date:   Sat Dec 28 19:33:13 2013 +0100

    Add sadt, a simple implementation of DEP-8 test runner
    
    Closes: #712095
    Signed-off-by: James McCoy <jamessan at debian.org>
---
 .gitignore                |   3 +
 Makefile.common           |   4 +-
 debian/changelog          |   6 +
 debian/control            |   1 +
 debian/copyright          |   1 +
 po4a/Makefile             |   6 +
 po4a/devscripts-po4a.conf |   2 +
 po4a/po/de.po             | 169 ++++++++++++++----
 po4a/po/devscripts.pot    | 156 ++++++++++++----
 po4a/po/fr.po             | 169 ++++++++++++++----
 scripts/Makefile          |   3 +
 scripts/sadt              | 444 ++++++++++++++++++++++++++++++++++++++++++++++
 scripts/sadt.pod          |  67 +++++++
 13 files changed, 928 insertions(+), 103 deletions(-)

diff --git a/.gitignore b/.gitignore
index fad6cd9..7d9b8e0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,10 +12,12 @@ po4a/fr/*.1
 po4a/fr/*.5
 po4a/fr/*.dbk
 po4a/fr/*.pl
+po4a/fr/*.pod
 po4a/de/*.1
 po4a/de/*.5
 po4a/de/*.dbk
 po4a/de/*.pl
+po4a/de/*.pod
 po4a/translate
 scripts/annotate-output
 scripts/archpath
@@ -90,6 +92,7 @@ scripts/pts-subscribe
 scripts/rc-alert
 scripts/rmadison
 scripts/rmadison.1
+scripts/sadt.1
 scripts/svnpath
 scripts/svnpath.1
 scripts/tagpending
diff --git a/Makefile.common b/Makefile.common
index 74aa252..910426a 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -1,7 +1,7 @@
 GEN_MAN1S := bts.1 build-rdeps.1 chdist.1 dcontrol.1 debcheckout.1 debcommit.1 \
 	     deb-reversion.1 desktop2menu.1 dget.1 licensecheck.1 mass-bug.1 \
-	     mk-build-deps.1 namecheck.1 rmadison.1 svnpath.1 tagpending.1 \
-	     origtargz.1 transition-check.1 who-permits-upload.1
+	     mk-build-deps.1 namecheck.1 rmadison.1 sadt.1 svnpath.1 \
+	     tagpending.1 origtargz.1 transition-check.1 who-permits-upload.1
 
 PERLMOD_DIR = /usr/share/devscripts
 EXAMPLES_DIR = /usr/share/devscripts
diff --git a/debian/changelog b/debian/changelog
index 62d1451..e5e3f11 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+devscripts (2.13.10) UNRELEASED; urgency=low
+
+  * Add sadt, a simple implementation of DEP-8 test runner (closes: #712095).
+
+ -- Jakub Wilk <jwilk at debian.org>  Fri, 27 Dec 2013 18:39:11 +0100
+
 devscripts (2.13.9) unstable; urgency=low
 
   [ Martin Pitt ]
diff --git a/debian/control b/debian/control
index 2c99942..5502ce7 100644
--- a/debian/control
+++ b/debian/control
@@ -178,6 +178,7 @@ Description: scripts to make the life of a Debian Package maintainer easier
     [wget | curl]
   - rmadison: remotely query the Debian archive database about packages
     [liburi-perl, wget | curl]
+  - sadt: run DEP-8 tests [python3-debian]
   - suspicious-source: output a list of files which are not common source
     files [python3-magic]
   - svnpath: print Subversion repository paths [subversion]
diff --git a/debian/copyright b/debian/copyright
index dcf0094..10b7406 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -85,6 +85,7 @@ Files: doc/suspicious-source.1
        doc/wrap-and-sort.1
        scripts/devscripts/*
        scripts/devscripts/test/*
+       scripts/sadt*
        scripts/setup.py
        scripts/suspicious-source
        scripts/wrap-and-sort
diff --git a/po4a/Makefile b/po4a/Makefile
index 518512b..f19b24d 100644
--- a/po4a/Makefile
+++ b/po4a/Makefile
@@ -23,6 +23,9 @@ clean: ../scripts/devscripts.1
 de/%.de.1: de/%.de.pl translate
 	podchecker $<
 	pod2man --utf8 --center=" " --release="Debian-Hilfswerkzeuge" $< > $@
+de/%.de.1: de/%.de.pod translate
+	podchecker $<
+	pod2man --utf8 --center=" " --release="Debian-Hilfswerkzeuge" $< > $@
 de/%.de.1: de/%.de.dbk translate
 	xsltproc --nonet -o $@ \
 	  /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/manpages/docbook.xsl $<
@@ -33,6 +36,9 @@ de/%.de.1: de/%.de.dbk translate
 fr/%.fr.1: fr/%.fr.pl translate
 	podchecker $<
 	pod2man --utf8 --center=" " --release="Utilitaires Debian" $< > $@
+fr/%.fr.1: fr/%.fr.pod translate
+	podchecker $<
+	pod2man --utf8 --center=" " --release="Utilitaires Debian" $< > $@
 fr/%.fr.1: fr/%.fr.dbk translate
 	xsltproc --nonet -o $@ \
 	  /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/manpages/docbook.xsl $<
diff --git a/po4a/devscripts-po4a.conf b/po4a/devscripts-po4a.conf
index 432ddf0..a615a7a 100644
--- a/po4a/devscripts-po4a.conf
+++ b/po4a/devscripts-po4a.conf
@@ -108,6 +108,8 @@
 	$lang:$lang/rc-alert.$lang.1 add_$lang:?add_$lang/translator_man.add
 [type:pod] ../scripts/rmadison.pl \
 	$lang:$lang/rmadison.$lang.pl add_$lang:?add_$lang/translator_pod.add
+[type:pod] ../scripts/sadt.pod \
+	$lang:$lang/sadt.$lang.pod add_$lang:?add_$lang/translator_pod.add
 [type:man] ../doc/suspicious-source.1 \
 	$lang:$lang/suspicious-source.$lang.1 add_$lang:?add_$lang/translator_man.add
 [type:pod] ../scripts/svnpath.pl \
diff --git a/po4a/po/de.po b/po4a/po/de.po
index 98e842f..fe252cd 100644
--- a/po4a/po/de.po
+++ b/po4a/po/de.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: devscripts 2.13.4\n"
 "Report-Msgid-Bugs-To: devscripts at packages.debian.org\n"
-"POT-Creation-Date: 2013-12-10 18:26-0400\n"
+"POT-Creation-Date: 2013-12-28 19:00+0100\n"
 "PO-Revision-Date: 2013-10-07 23:11-0100\n"
 "Last-Translator: Chris Leick <c.leick at vollbio.de>\n"
 "Language-Team: de <debian-l10n-german at lists.debian.org>\n"
@@ -91,7 +91,7 @@ msgstr "DEBIAN"
 #: ../scripts/mergechanges.1:2 ../scripts/mk-build-deps.pl:24
 #: ../scripts/namecheck.pl:3 ../scripts/nmudiff.1:2 ../scripts/origtargz.pl:20
 #: ../scripts/plotchangelog.1:2 ../scripts/pts-subscribe.1:2
-#: ../scripts/rc-alert.1:2 ../scripts/rmadison.pl:201
+#: ../scripts/rc-alert.1:2 ../scripts/rmadison.pl:201 ../scripts/sadt.pod:17
 #: ../doc/suspicious-source.1:17 ../scripts/svnpath.pl:3
 #: ../scripts/tagpending.pl:79 ../scripts/transition-check.pl:23
 #: ../scripts/uscan.1:2 ../scripts/uupdate.1:2 ../doc/what-patch.1:2
@@ -129,7 +129,7 @@ msgstr "annotate-output - versieht Programmausgaben mit Zeit und Datenstrom"
 #: ../scripts/mergechanges.1:4 ../scripts/mk-build-deps.pl:28
 #: ../scripts/nmudiff.1:4 ../scripts/origtargz.pl:24
 #: ../scripts/plotchangelog.1:4 ../scripts/pts-subscribe.1:4
-#: ../scripts/rc-alert.1:4 ../scripts/rmadison.pl:205
+#: ../scripts/rc-alert.1:4 ../scripts/rmadison.pl:205 ../scripts/sadt.pod:21
 #: ../doc/suspicious-source.1:21 ../scripts/svnpath.pl:7
 #: ../scripts/tagpending.pl:83 ../scripts/transition-check.pl:27
 #: ../scripts/uscan.1:4 ../scripts/uupdate.1:4 ../doc/what-patch.1:5
@@ -168,7 +168,7 @@ msgstr "B<annotate-output> [I<Optionen>] I<Programm> [I<Argumente> …]"
 #: ../scripts/mergechanges.1:6 ../scripts/mk-build-deps.pl:34
 #: ../scripts/nmudiff.1:6 ../scripts/origtargz.pl:34
 #: ../scripts/plotchangelog.1:7 ../scripts/pts-subscribe.1:8
-#: ../scripts/rc-alert.1:8 ../scripts/rmadison.pl:213
+#: ../scripts/rc-alert.1:8 ../scripts/rmadison.pl:213 ../scripts/sadt.pod:25
 #: ../doc/suspicious-source.1:24 ../scripts/svnpath.pl:17
 #: ../scripts/tagpending.pl:87 ../scripts/transition-check.pl:33
 #: ../scripts/uscan.1:6 ../scripts/uupdate.1:8 ../doc/what-patch.1:8
@@ -211,7 +211,7 @@ msgstr ""
 #: ../scripts/mass-bug.pl:59 ../scripts/mk-build-deps.pl:44
 #: ../scripts/nmudiff.1:21 ../scripts/origtargz.pl:95
 #: ../scripts/plotchangelog.1:43 ../scripts/pts-subscribe.1:18
-#: ../scripts/rc-alert.1:17 ../scripts/rmadison.pl:222
+#: ../scripts/rc-alert.1:17 ../scripts/rmadison.pl:222 ../scripts/sadt.pod:42
 #: ../doc/suspicious-source.1:34 ../scripts/tagpending.pl:93
 #: ../scripts/transition-check.pl:42 ../scripts/uscan.1:352
 #: ../scripts/uupdate.1:52 ../doc/what-patch.1:15 ../scripts/whodepends.1:10
@@ -241,7 +241,7 @@ msgstr ""
 #: ../scripts/debcheckout.pl:93 ../scripts/debsnap.1:57 ../scripts/dget.pl:621
 #: ../scripts/dpkg-depcheck.1:96 ../scripts/getbuildlog.1:25
 #: ../scripts/mk-build-deps.pl:79 ../scripts/rmadison.pl:246
-#: ../doc/suspicious-source.1:35 ../doc/what-patch.1:17
+#: ../scripts/sadt.pod:59 ../doc/suspicious-source.1:35 ../doc/what-patch.1:17
 #: ../doc/wrap-and-sort.1:34
 #, no-wrap
 msgid "B<-h>, B<--help>"
@@ -347,7 +347,7 @@ msgstr ""
 #: ../scripts/grep-excuses.1:38 ../scripts/list-unreleased.1:19
 #: ../scripts/nmudiff.1:108 ../scripts/origtargz.pl:156
 #: ../scripts/plotchangelog.1:124 ../scripts/pts-subscribe.1:51
-#: ../scripts/rc-alert.1:121 ../scripts/rmadison.pl:333
+#: ../scripts/rc-alert.1:121 ../scripts/rmadison.pl:333 ../scripts/sadt.pod:65
 #: ../scripts/tagpending.pl:148 ../scripts/uscan.1:566
 #: ../scripts/uupdate.1:170 ../doc/what-patch.1:35
 #: ../scripts/who-permits-upload.pl:161 ../scripts/wnpp-alert.1:29
@@ -10581,8 +10581,9 @@ msgstr ""
 "Beendigung vorhanden sein werden."
 
 #. type: TP
-#: ../scripts/debsnap.1:42 ../doc/suspicious-source.1:38
-#: ../scripts/tagpending.pl:105 ../doc/wrap-and-sort.1:70
+#: ../scripts/debsnap.1:42 ../scripts/sadt.pod:46
+#: ../doc/suspicious-source.1:38 ../scripts/tagpending.pl:105
+#: ../doc/wrap-and-sort.1:70
 #, no-wrap
 msgid "B<-v>, B<--verbose>"
 msgstr "B<-v>, B<--verbose>"
@@ -12828,12 +12829,24 @@ msgstr ""
 
 #. type: IP
 #: ../scripts/devscripts.1:129
+#, fuzzy, no-wrap
+#| msgid "I<dget>(1)"
+msgid "I<sadt>(1)"
+msgstr "I<dget>(1)"
+
+#. type: Plain text
+#: ../scripts/devscripts.1:131
+msgid "run DEP-8 tests [python3-debian]"
+msgstr ""
+
+#. type: IP
+#: ../scripts/devscripts.1:131
 #, no-wrap
 msgid "I<suspicious-source>(1)"
 msgstr "I<suspicious-source>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:131
+#: ../scripts/devscripts.1:133
 msgid ""
 "output a list of files which are not common source files [python3-magic]"
 msgstr ""
@@ -12841,24 +12854,24 @@ msgstr ""
 "[python3-magic]"
 
 #. type: IP
-#: ../scripts/devscripts.1:131
+#: ../scripts/devscripts.1:133
 #, no-wrap
 msgid "I<svnpath>(1)"
 msgstr "I<svnpath>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:133
+#: ../scripts/devscripts.1:135
 msgid "print Subversion repository paths [subversion]"
 msgstr "gibt Subversion-Depotpfade aus. [subversion]"
 
 #. type: IP
-#: ../scripts/devscripts.1:133
+#: ../scripts/devscripts.1:135
 #, no-wrap
 msgid "I<tagpending>(1)"
 msgstr "I<tagpending>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:135
+#: ../scripts/devscripts.1:137
 msgid ""
 "run from a Debian source tree and tag bugs that are to be closed in the "
 "latest changelog as pending [libsoap-lite-perl]"
@@ -12868,13 +12881,13 @@ msgstr ""
 "lite-perl]"
 
 #. type: IP
-#: ../scripts/devscripts.1:135
+#: ../scripts/devscripts.1:137
 #, no-wrap
 msgid "I<transition-check>(1)"
 msgstr "I<transition-check>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:137
+#: ../scripts/devscripts.1:139
 msgid ""
 "check a list of source packages for involvement in transitions for which "
 "uploads to unstable are currently blocked [libwww-perl, libyaml-syck-perl]"
@@ -12884,13 +12897,13 @@ msgstr ""
 "syck-perl]"
 
 #. type: IP
-#: ../scripts/devscripts.1:137
+#: ../scripts/devscripts.1:139
 #, no-wrap
 msgid "I<uscan>(1)"
 msgstr "I<uscan>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:139
+#: ../scripts/devscripts.1:141
 msgid ""
 "scan upstream sites for new releases of packages [gpgv, liblwp-protocol-"
 "https-perl, libwww-perl, unzip, lzma, xz-utils]"
@@ -12900,24 +12913,24 @@ msgstr ""
 "utils]"
 
 #. type: IP
-#: ../scripts/devscripts.1:139
+#: ../scripts/devscripts.1:141
 #, no-wrap
 msgid "I<uupdate>(1)"
 msgstr "I<uupdate>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:141
+#: ../scripts/devscripts.1:143
 msgid "integrate upstream changes into a source package [patch]"
 msgstr "integriert Änderungen der Originalautoren in ein Quellpaket. [patch]"
 
 #. type: IP
-#: ../scripts/devscripts.1:141
+#: ../scripts/devscripts.1:143
 #, no-wrap
 msgid "I<what-patch>(1)"
 msgstr "I<what-patch>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:143
+#: ../scripts/devscripts.1:145
 msgid ""
 "determine what patch system, if any, a source package is using [patchutils]"
 msgstr ""
@@ -12925,24 +12938,24 @@ msgstr ""
 "[patchutils]"
 
 #. type: IP
-#: ../scripts/devscripts.1:143
+#: ../scripts/devscripts.1:145
 #, no-wrap
 msgid "I<whodepends>(1)"
 msgstr "I<whodepends>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:145
+#: ../scripts/devscripts.1:147
 msgid "check which maintainers' packages depend on a package"
 msgstr "prüft die Pakete welches Betreuers von einem Paket abhängen."
 
 #. type: IP
-#: ../scripts/devscripts.1:145
+#: ../scripts/devscripts.1:147
 #, no-wrap
 msgid "I<who-uploads>(1)"
 msgstr "I<who-uploads>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:147
+#: ../scripts/devscripts.1:149
 msgid ""
 "determine the most recent uploaders of a package to the Debian archive "
 "[gnupg, debian-keyring, debian-maintainers, wget]"
@@ -12951,13 +12964,13 @@ msgstr ""
 "haben. [gnupg, debian-keyring, debian-maintainers, wget]"
 
 #. type: IP
-#: ../scripts/devscripts.1:147
+#: ../scripts/devscripts.1:149
 #, no-wrap
 msgid "I<wnpp-alert>(1)"
 msgstr "I<wnpp-alert>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:149
+#: ../scripts/devscripts.1:151
 msgid ""
 "list installed packages which are orphaned or up for adoption [wget | curl]"
 msgstr ""
@@ -12965,13 +12978,13 @@ msgstr ""
 "sind. [wget | curl]"
 
 #. type: IP
-#: ../scripts/devscripts.1:149
+#: ../scripts/devscripts.1:151
 #, no-wrap
 msgid "I<wnpp-check>(1)"
 msgstr "I<wnpp-check>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:151
+#: ../scripts/devscripts.1:153
 msgid ""
 "check whether there is an open request for packaging or intention to package "
 "bug for a package [wget | curl]"
@@ -12980,13 +12993,13 @@ msgstr ""
 "über die Absicht zum Packen für ein Paket gibt. [wget | curl]"
 
 #. type: IP
-#: ../scripts/devscripts.1:151
+#: ../scripts/devscripts.1:153
 #, no-wrap
 msgid "I<who-permits-upload>(1)"
 msgstr "I<who-permits-upload>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:153
+#: ../scripts/devscripts.1:155
 msgid ""
 "Retrieve information about Debian Maintainer access control lists [gnupg, "
 "libencode-locale-perl, libparse-debcontrol-perl, libwww-perl, debian-keyring]"
@@ -12995,13 +13008,13 @@ msgstr ""
 "locale-perl, libparse-debcontrol-perl, libwww-perl, debian-keyring]"
 
 #. type: IP
-#: ../scripts/devscripts.1:153
+#: ../scripts/devscripts.1:155
 #, no-wrap
 msgid "I<wrap-and-sort>(1)"
 msgstr "I<wrap-and-sort>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:154
+#: ../scripts/devscripts.1:156
 msgid "wrap long lines and sort items in packaging files [python3-debian]"
 msgstr ""
 "bricht lange Zeilen um und sortiert Elemente in Paketierungsdateien. "
@@ -17189,6 +17202,94 @@ msgstr ""
 "<myon at debian.org> geschrieben. Dak wurde von James Troup <james at nocrew.org>, "
 "Anthony Towns <ajt at debian.org> und anderen verfasst."
 
+#. type: textblock
+#: ../scripts/sadt.pod:19
+msgid "sadt - simple DEP-8 test runner"
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:23
+#, fuzzy
+#| msgid "B<dch> [I<options>] [I<text> ...]"
+msgid "B<sadt> [I<options>] [I<test-name>...]"
+msgstr "B<dch> [I<Optionen>] [I<Text> …]"
+
+#. type: textblock
+#: ../scripts/sadt.pod:27
+msgid ""
+"B<sadt> is a simple implementation of DEP-8 (“automatic as-installed package "
+"testing”) test runner."
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:30
+msgid ""
+"It is your responsibility to satisfy tests' dependencies.  B<sadt> won't "
+"attempt to install any missing packages.  If a test's dependencies cannot be "
+"satisfied by packages that are currently installed, the test will be skipped."
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:34
+msgid ""
+"B<sadt> won't build the package even if a test declares the B<build-needed> "
+"restriction.  Instead, such a test will be skipped.  However, you can build "
+"the package manually, and then tell B<sadt> to assume that the package is "
+"already built using the B<-b>/B<--built-source-tree>."
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:39
+msgid ""
+"B<sadt> doesn't implement any virtualisation arrangements, therefore it "
+"skips tests that declare the B<breaks-testbed> restriction."
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:48
+msgid "Make the output more verbose."
+msgstr ""
+
+#. type: =item
+#: ../scripts/sadt.pod:50
+#, fuzzy
+#| msgid "B<-b>, B<--build-depends>"
+msgid "B<-b>, B<--built-source-tree>"
+msgstr "B<-b>, B<--build-depends>"
+
+#. type: textblock
+#: ../scripts/sadt.pod:52
+msgid ""
+"Assume that the source tree is already built.  This is equivalent to B<--"
+"ignore-restriction=build-needed>."
+msgstr ""
+
+#. type: =item
+#: ../scripts/sadt.pod:55
+#, fuzzy
+#| msgid "B<--dist=>I<distribution>"
+msgid "B<--ignore-restriction>=I<restriction>"
+msgstr "B<--dist=>I<Distribution>"
+
+#. type: textblock
+#: ../scripts/sadt.pod:57
+msgid "Don't skip tests that declare the I<restriction>."
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:61
+#, fuzzy
+#| msgid "Show this help message and exit."
+msgid "Show a help message and exit."
+msgstr "zeigt diese Hilfenachricht und wird beendet."
+
+#. type: textblock
+#: ../scripts/sadt.pod:67
+#, fuzzy
+#| msgid "B<date>(1)"
+msgid "B<adt-run>(1)"
+msgstr "B<date>(1)"
+
 #. type: TH
 #: ../doc/suspicious-source.1:15
 #, no-wrap
diff --git a/po4a/po/devscripts.pot b/po4a/po/devscripts.pot
index 21902fc..e9cc5fe 100644
--- a/po4a/po/devscripts.pot
+++ b/po4a/po/devscripts.pot
@@ -7,7 +7,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2013-12-10 18:26-0400\n"
+"POT-Creation-Date: 2013-12-28 19:00+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
 "Language-Team: LANGUAGE <LL at li.org>\n"
@@ -35,7 +35,7 @@ msgid "DEBIAN"
 msgstr ""
 
 #. type: SH
-#: ../scripts/annotate-output.1:2 ../scripts/archpath.1:2 ../scripts/bts.pl:39 ../scripts/build-rdeps.pl:18 ../scripts/chdist.pl:18 ../scripts/checkbashisms.1:2 ../scripts/cowpoke.1:18 ../scripts/cvs-debc.1:2 ../scripts/cvs-debi.1:2 ../scripts/cvs-debrelease.1:2 ../scripts/cvs-debuild.1:2 ../scripts/dcmd.1:2 ../scripts/dcontrol.pl:196 ../scripts/dd-list.1:18 ../scripts/debc.1:2 ../scripts/debchange.1:2 ../scripts/debcheckout.pl:24 ../scripts/debclean.1:2 ../scripts/debcommit.pl:3 ../scri [...]
+#: ../scripts/annotate-output.1:2 ../scripts/archpath.1:2 ../scripts/bts.pl:39 ../scripts/build-rdeps.pl:18 ../scripts/chdist.pl:18 ../scripts/checkbashisms.1:2 ../scripts/cowpoke.1:18 ../scripts/cvs-debc.1:2 ../scripts/cvs-debi.1:2 ../scripts/cvs-debrelease.1:2 ../scripts/cvs-debuild.1:2 ../scripts/dcmd.1:2 ../scripts/dcontrol.pl:196 ../scripts/dd-list.1:18 ../scripts/debc.1:2 ../scripts/debchange.1:2 ../scripts/debcheckout.pl:24 ../scripts/debclean.1:2 ../scripts/debcommit.pl:3 ../scri [...]
 #, no-wrap
 msgid "NAME"
 msgstr ""
@@ -46,7 +46,7 @@ msgid "annotate-output - annotate program output with time and stream"
 msgstr ""
 
 #. type: SH
-#: ../scripts/annotate-output.1:4 ../scripts/archpath.1:4 ../scripts/bts.pl:185 ../scripts/build-rdeps.pl:22 ../scripts/chdist.pl:22 ../scripts/checkbashisms.1:4 ../scripts/cowpoke.1:20 ../scripts/cvs-debc.1:4 ../scripts/cvs-debi.1:4 ../scripts/cvs-debrelease.1:4 ../scripts/cvs-debuild.1:4 ../scripts/dcmd.1:4 ../scripts/dcontrol.pl:200 ../scripts/dd-list.1:21 ../scripts/debc.1:4 ../scripts/debchange.1:4 ../scripts/debcheckout.pl:28 ../scripts/debclean.1:4 ../scripts/debcommit.pl:7 ../scr [...]
+#: ../scripts/annotate-output.1:4 ../scripts/archpath.1:4 ../scripts/bts.pl:185 ../scripts/build-rdeps.pl:22 ../scripts/chdist.pl:22 ../scripts/checkbashisms.1:4 ../scripts/cowpoke.1:20 ../scripts/cvs-debc.1:4 ../scripts/cvs-debi.1:4 ../scripts/cvs-debrelease.1:4 ../scripts/cvs-debuild.1:4 ../scripts/dcmd.1:4 ../scripts/dcontrol.pl:200 ../scripts/dd-list.1:21 ../scripts/debc.1:4 ../scripts/debchange.1:4 ../scripts/debcheckout.pl:28 ../scripts/debclean.1:4 ../scripts/debcommit.pl:7 ../scr [...]
 #, no-wrap
 msgid "SYNOPSIS"
 msgstr ""
@@ -57,7 +57,7 @@ msgid "B<annotate-output> [I<options>] I<program> [I<args> ...]"
 msgstr ""
 
 #. type: SH
-#: ../scripts/annotate-output.1:6 ../scripts/archpath.1:12 ../scripts/bts.pl:189 ../scripts/build-rdeps.pl:26 ../scripts/chdist.pl:26 ../scripts/checkbashisms.1:8 ../scripts/cowpoke.1:24 ../scripts/cvs-debc.1:6 ../scripts/cvs-debi.1:6 ../scripts/cvs-debrelease.1:7 ../scripts/cvs-debuild.1:7 ../scripts/dcmd.1:6 ../scripts/dcontrol.pl:208 ../scripts/dd-list.1:26 ../scripts/debc.1:6 ../scripts/debchange.1:8 ../scripts/debcheckout.pl:40 ../scripts/debclean.1:6 ../scripts/debcommit.pl:11 ../s [...]
+#: ../scripts/annotate-output.1:6 ../scripts/archpath.1:12 ../scripts/bts.pl:189 ../scripts/build-rdeps.pl:26 ../scripts/chdist.pl:26 ../scripts/checkbashisms.1:8 ../scripts/cowpoke.1:24 ../scripts/cvs-debc.1:6 ../scripts/cvs-debi.1:6 ../scripts/cvs-debrelease.1:7 ../scripts/cvs-debuild.1:7 ../scripts/dcmd.1:6 ../scripts/dcontrol.pl:208 ../scripts/dd-list.1:26 ../scripts/debc.1:6 ../scripts/debchange.1:8 ../scripts/debcheckout.pl:40 ../scripts/debclean.1:6 ../scripts/debcommit.pl:11 ../s [...]
 #, no-wrap
 msgid "DESCRIPTION"
 msgstr ""
@@ -70,7 +70,7 @@ msgid ""
 msgstr ""
 
 #. type: SH
-#: ../scripts/annotate-output.1:11 ../scripts/bts.pl:241 ../scripts/build-rdeps.pl:30 ../scripts/chdist.pl:33 ../scripts/checkbashisms.1:23 ../scripts/cowpoke.1:29 ../scripts/cvs-debc.1:24 ../scripts/cvs-debi.1:28 ../scripts/cvs-debrelease.1:21 ../scripts/cvs-debuild.1:32 ../scripts/dcmd.1:15 ../scripts/dcontrol.pl:242 ../scripts/dd-list.1:58 ../scripts/debc.1:64 ../scripts/debchange.1:145 ../scripts/debcheckout.pl:68 ../scripts/debclean.1:60 ../scripts/debcommit.pl:19 ../scripts/debdiff [...]
+#: ../scripts/annotate-output.1:11 ../scripts/bts.pl:241 ../scripts/build-rdeps.pl:30 ../scripts/chdist.pl:33 ../scripts/checkbashisms.1:23 ../scripts/cowpoke.1:29 ../scripts/cvs-debc.1:24 ../scripts/cvs-debi.1:28 ../scripts/cvs-debrelease.1:21 ../scripts/cvs-debuild.1:32 ../scripts/dcmd.1:15 ../scripts/dcontrol.pl:242 ../scripts/dd-list.1:58 ../scripts/debc.1:64 ../scripts/debchange.1:145 ../scripts/debcheckout.pl:68 ../scripts/debclean.1:60 ../scripts/debcommit.pl:19 ../scripts/debdiff [...]
 #, no-wrap
 msgid "OPTIONS"
 msgstr ""
@@ -87,7 +87,7 @@ msgid "Controls the timestamp format, as per B<date>(1).  Defaults to \"%H:%M:%S
 msgstr ""
 
 #. type: TP
-#: ../scripts/annotate-output.1:16 ../scripts/chdist.pl:37 ../scripts/dcontrol.pl:254 ../scripts/dd-list.1:59 ../scripts/debcheckout.pl:93 ../scripts/debsnap.1:57 ../scripts/dget.pl:621 ../scripts/dpkg-depcheck.1:96 ../scripts/getbuildlog.1:25 ../scripts/mk-build-deps.pl:79 ../scripts/rmadison.pl:246 ../doc/suspicious-source.1:35 ../doc/what-patch.1:17 ../doc/wrap-and-sort.1:34
+#: ../scripts/annotate-output.1:16 ../scripts/chdist.pl:37 ../scripts/dcontrol.pl:254 ../scripts/dd-list.1:59 ../scripts/debcheckout.pl:93 ../scripts/debsnap.1:57 ../scripts/dget.pl:621 ../scripts/dpkg-depcheck.1:96 ../scripts/getbuildlog.1:25 ../scripts/mk-build-deps.pl:79 ../scripts/rmadison.pl:246 ../scripts/sadt.pod:59 ../doc/suspicious-source.1:35 ../doc/what-patch.1:17 ../doc/wrap-and-sort.1:34
 #, no-wrap
 msgid "B<-h>, B<--help>"
 msgstr ""
@@ -149,7 +149,7 @@ msgid ""
 msgstr ""
 
 #. type: SH
-#: ../scripts/annotate-output.1:47 ../scripts/bts.pl:4113 ../scripts/checkbashisms.1:63 ../scripts/cowpoke.1:264 ../scripts/cvs-debc.1:58 ../scripts/cvs-debi.1:62 ../scripts/cvs-debrelease.1:64 ../scripts/cvs-debuild.1:53 ../scripts/dcmd.1:97 ../scripts/dcontrol.pl:287 ../scripts/debc.1:115 ../scripts/debchange.1:469 ../scripts/debcheckout.pl:228 ../scripts/debclean.1:107 ../scripts/debcommit.pl:874 ../scripts/debdiff.1:215 ../scripts/debi.1:132 ../scripts/debrelease.1:132 ../scripts/deb [...]
+#: ../scripts/annotate-output.1:47 ../scripts/bts.pl:4113 ../scripts/checkbashisms.1:63 ../scripts/cowpoke.1:264 ../scripts/cvs-debc.1:58 ../scripts/cvs-debi.1:62 ../scripts/cvs-debrelease.1:64 ../scripts/cvs-debuild.1:53 ../scripts/dcmd.1:97 ../scripts/dcontrol.pl:287 ../scripts/debc.1:115 ../scripts/debchange.1:469 ../scripts/debcheckout.pl:228 ../scripts/debclean.1:107 ../scripts/debcommit.pl:874 ../scripts/debdiff.1:215 ../scripts/debi.1:132 ../scripts/debrelease.1:132 ../scripts/deb [...]
 #, no-wrap
 msgid "SEE ALSO"
 msgstr ""
@@ -8120,7 +8120,7 @@ msgid ""
 msgstr ""
 
 #. type: TP
-#: ../scripts/debsnap.1:42 ../doc/suspicious-source.1:38 ../scripts/tagpending.pl:105 ../doc/wrap-and-sort.1:70
+#: ../scripts/debsnap.1:42 ../scripts/sadt.pod:46 ../doc/suspicious-source.1:38 ../scripts/tagpending.pl:105 ../doc/wrap-and-sort.1:70
 #, no-wrap
 msgid "B<-v>, B<--verbose>"
 msgstr ""
@@ -9933,142 +9933,153 @@ msgstr ""
 #. type: IP
 #: ../scripts/devscripts.1:129
 #, no-wrap
-msgid "I<suspicious-source>(1)"
+msgid "I<sadt>(1)"
 msgstr ""
 
 #. type: Plain text
 #: ../scripts/devscripts.1:131
-msgid "output a list of files which are not common source files [python3-magic]"
+msgid "run DEP-8 tests [python3-debian]"
 msgstr ""
 
 #. type: IP
 #: ../scripts/devscripts.1:131
 #, no-wrap
-msgid "I<svnpath>(1)"
+msgid "I<suspicious-source>(1)"
 msgstr ""
 
 #. type: Plain text
 #: ../scripts/devscripts.1:133
-msgid "print Subversion repository paths [subversion]"
+msgid "output a list of files which are not common source files [python3-magic]"
 msgstr ""
 
 #. type: IP
 #: ../scripts/devscripts.1:133
 #, no-wrap
-msgid "I<tagpending>(1)"
+msgid "I<svnpath>(1)"
 msgstr ""
 
 #. type: Plain text
 #: ../scripts/devscripts.1:135
+msgid "print Subversion repository paths [subversion]"
+msgstr ""
+
+#. type: IP
+#: ../scripts/devscripts.1:135
+#, no-wrap
+msgid "I<tagpending>(1)"
+msgstr ""
+
+#. type: Plain text
+#: ../scripts/devscripts.1:137
 msgid ""
 "run from a Debian source tree and tag bugs that are to be closed in the "
 "latest changelog as pending [libsoap-lite-perl]"
 msgstr ""
 
 #. type: IP
-#: ../scripts/devscripts.1:135
+#: ../scripts/devscripts.1:137
 #, no-wrap
 msgid "I<transition-check>(1)"
 msgstr ""
 
 #. type: Plain text
-#: ../scripts/devscripts.1:137
+#: ../scripts/devscripts.1:139
 msgid ""
 "check a list of source packages for involvement in transitions for which "
 "uploads to unstable are currently blocked [libwww-perl, libyaml-syck-perl]"
 msgstr ""
 
 #. type: IP
-#: ../scripts/devscripts.1:137
+#: ../scripts/devscripts.1:139
 #, no-wrap
 msgid "I<uscan>(1)"
 msgstr ""
 
 #. type: Plain text
-#: ../scripts/devscripts.1:139
+#: ../scripts/devscripts.1:141
 msgid ""
 "scan upstream sites for new releases of packages [gpgv, "
 "liblwp-protocol-https-perl, libwww-perl, unzip, lzma, xz-utils]"
 msgstr ""
 
 #. type: IP
-#: ../scripts/devscripts.1:139
+#: ../scripts/devscripts.1:141
 #, no-wrap
 msgid "I<uupdate>(1)"
 msgstr ""
 
 #. type: Plain text
-#: ../scripts/devscripts.1:141
+#: ../scripts/devscripts.1:143
 msgid "integrate upstream changes into a source package [patch]"
 msgstr ""
 
 #. type: IP
-#: ../scripts/devscripts.1:141
+#: ../scripts/devscripts.1:143
 #, no-wrap
 msgid "I<what-patch>(1)"
 msgstr ""
 
 #. type: Plain text
-#: ../scripts/devscripts.1:143
+#: ../scripts/devscripts.1:145
 msgid "determine what patch system, if any, a source package is using [patchutils]"
 msgstr ""
 
 #. type: IP
-#: ../scripts/devscripts.1:143
+#: ../scripts/devscripts.1:145
 #, no-wrap
 msgid "I<whodepends>(1)"
 msgstr ""
 
 #. type: Plain text
-#: ../scripts/devscripts.1:145
+#: ../scripts/devscripts.1:147
 msgid "check which maintainers' packages depend on a package"
 msgstr ""
 
 #. type: IP
-#: ../scripts/devscripts.1:145
+#: ../scripts/devscripts.1:147
 #, no-wrap
 msgid "I<who-uploads>(1)"
 msgstr ""
 
 #. type: Plain text
-#: ../scripts/devscripts.1:147
+#: ../scripts/devscripts.1:149
 msgid ""
 "determine the most recent uploaders of a package to the Debian archive "
 "[gnupg, debian-keyring, debian-maintainers, wget]"
 msgstr ""
 
 #. type: IP
-#: ../scripts/devscripts.1:147
+#: ../scripts/devscripts.1:149
 #, no-wrap
 msgid "I<wnpp-alert>(1)"
 msgstr ""
 
 #. type: Plain text
-#: ../scripts/devscripts.1:149
+#: ../scripts/devscripts.1:151
 msgid "list installed packages which are orphaned or up for adoption [wget | curl]"
 msgstr ""
 
 #. type: IP
-#: ../scripts/devscripts.1:149
+#: ../scripts/devscripts.1:151
 #, no-wrap
 msgid "I<wnpp-check>(1)"
 msgstr ""
 
 #. type: Plain text
-#: ../scripts/devscripts.1:151
+#: ../scripts/devscripts.1:153
 msgid ""
 "check whether there is an open request for packaging or intention to package "
 "bug for a package [wget | curl]"
 msgstr ""
 
 #. type: IP
-#: ../scripts/devscripts.1:151
+#: ../scripts/devscripts.1:153
 #, no-wrap
 msgid "I<who-permits-upload>(1)"
 msgstr ""
 
 #. type: Plain text
-#: ../scripts/devscripts.1:153
+#: ../scripts/devscripts.1:155
 msgid ""
 "Retrieve information about Debian Maintainer access control lists [gnupg, "
 "libencode-locale-perl, libparse-debcontrol-perl, libwww-perl, "
@@ -10076,13 +10087,13 @@ msgid ""
 msgstr ""
 
 #. type: IP
-#: ../scripts/devscripts.1:153
+#: ../scripts/devscripts.1:155
 #, no-wrap
 msgid "I<wrap-and-sort>(1)"
 msgstr ""
 
 #. type: Plain text
-#: ../scripts/devscripts.1:154
+#: ../scripts/devscripts.1:156
 msgid "wrap long lines and sort items in packaging files [python3-debian]"
 msgstr ""
 
@@ -13465,6 +13476,85 @@ msgid ""
 "Anthony Towns <ajt at debian.org>, and others."
 msgstr ""
 
+#. type: textblock
+#: ../scripts/sadt.pod:19
+msgid "sadt - simple DEP-8 test runner"
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:23
+msgid "B<sadt> [I<options>] [I<test-name>...]"
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:27
+msgid ""
+"B<sadt> is a simple implementation of DEP-8 (“automatic as-installed package "
+"testing”) test runner."
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:30
+msgid ""
+"It is your responsibility to satisfy tests' dependencies.  B<sadt> won't "
+"attempt to install any missing packages.  If a test's dependencies cannot be "
+"satisfied by packages that are currently installed, the test will be "
+"skipped."
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:34
+msgid ""
+"B<sadt> won't build the package even if a test declares the B<build-needed> "
+"restriction.  Instead, such a test will be skipped.  However, you can build "
+"the package manually, and then tell B<sadt> to assume that the package is "
+"already built using the B<-b>/B<--built-source-tree>."
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:39
+msgid ""
+"B<sadt> doesn't implement any virtualisation arrangements, therefore it "
+"skips tests that declare the B<breaks-testbed> restriction."
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:48
+msgid "Make the output more verbose."
+msgstr ""
+
+#. type: =item
+#: ../scripts/sadt.pod:50
+msgid "B<-b>, B<--built-source-tree>"
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:52
+msgid ""
+"Assume that the source tree is already built.  This is equivalent to "
+"B<--ignore-restriction=build-needed>."
+msgstr ""
+
+#. type: =item
+#: ../scripts/sadt.pod:55
+msgid "B<--ignore-restriction>=I<restriction>"
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:57
+msgid "Don't skip tests that declare the I<restriction>."
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:61
+msgid "Show a help message and exit."
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:67
+msgid "B<adt-run>(1)"
+msgstr ""
+
 #. type: TH
 #: ../doc/suspicious-source.1:15
 #, no-wrap
diff --git a/po4a/po/fr.po b/po4a/po/fr.po
index 4b0a6d1..cfe6dec 100644
--- a/po4a/po/fr.po
+++ b/po4a/po/fr.po
@@ -12,7 +12,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: devscripts\n"
-"POT-Creation-Date: 2013-12-10 18:26-0400\n"
+"POT-Creation-Date: 2013-12-28 19:00+0100\n"
 "PO-Revision-Date: 2013-12-10 18:23-0400\n"
 "Last-Translator: David Prévot <david at tilapin.org>\n"
 "Language-Team: French <debian-l10n-french at lists.debian.org>\n"
@@ -99,7 +99,7 @@ msgstr "DEBIAN"
 #: ../scripts/mergechanges.1:2 ../scripts/mk-build-deps.pl:24
 #: ../scripts/namecheck.pl:3 ../scripts/nmudiff.1:2 ../scripts/origtargz.pl:20
 #: ../scripts/plotchangelog.1:2 ../scripts/pts-subscribe.1:2
-#: ../scripts/rc-alert.1:2 ../scripts/rmadison.pl:201
+#: ../scripts/rc-alert.1:2 ../scripts/rmadison.pl:201 ../scripts/sadt.pod:17
 #: ../doc/suspicious-source.1:17 ../scripts/svnpath.pl:3
 #: ../scripts/tagpending.pl:79 ../scripts/transition-check.pl:23
 #: ../scripts/uscan.1:2 ../scripts/uupdate.1:2 ../doc/what-patch.1:2
@@ -138,7 +138,7 @@ msgstr ""
 #: ../scripts/mergechanges.1:4 ../scripts/mk-build-deps.pl:28
 #: ../scripts/nmudiff.1:4 ../scripts/origtargz.pl:24
 #: ../scripts/plotchangelog.1:4 ../scripts/pts-subscribe.1:4
-#: ../scripts/rc-alert.1:4 ../scripts/rmadison.pl:205
+#: ../scripts/rc-alert.1:4 ../scripts/rmadison.pl:205 ../scripts/sadt.pod:21
 #: ../doc/suspicious-source.1:21 ../scripts/svnpath.pl:7
 #: ../scripts/tagpending.pl:83 ../scripts/transition-check.pl:27
 #: ../scripts/uscan.1:4 ../scripts/uupdate.1:4 ../doc/what-patch.1:5
@@ -177,7 +177,7 @@ msgstr "B<annotate-output> [I<options>] I<programme> [I<paramètres> ...]"
 #: ../scripts/mergechanges.1:6 ../scripts/mk-build-deps.pl:34
 #: ../scripts/nmudiff.1:6 ../scripts/origtargz.pl:34
 #: ../scripts/plotchangelog.1:7 ../scripts/pts-subscribe.1:8
-#: ../scripts/rc-alert.1:8 ../scripts/rmadison.pl:213
+#: ../scripts/rc-alert.1:8 ../scripts/rmadison.pl:213 ../scripts/sadt.pod:25
 #: ../doc/suspicious-source.1:24 ../scripts/svnpath.pl:17
 #: ../scripts/tagpending.pl:87 ../scripts/transition-check.pl:33
 #: ../scripts/uscan.1:6 ../scripts/uupdate.1:8 ../doc/what-patch.1:8
@@ -220,7 +220,7 @@ msgstr ""
 #: ../scripts/mass-bug.pl:59 ../scripts/mk-build-deps.pl:44
 #: ../scripts/nmudiff.1:21 ../scripts/origtargz.pl:95
 #: ../scripts/plotchangelog.1:43 ../scripts/pts-subscribe.1:18
-#: ../scripts/rc-alert.1:17 ../scripts/rmadison.pl:222
+#: ../scripts/rc-alert.1:17 ../scripts/rmadison.pl:222 ../scripts/sadt.pod:42
 #: ../doc/suspicious-source.1:34 ../scripts/tagpending.pl:93
 #: ../scripts/transition-check.pl:42 ../scripts/uscan.1:352
 #: ../scripts/uupdate.1:52 ../doc/what-patch.1:15 ../scripts/whodepends.1:10
@@ -251,7 +251,7 @@ msgstr ""
 #: ../scripts/debcheckout.pl:93 ../scripts/debsnap.1:57 ../scripts/dget.pl:621
 #: ../scripts/dpkg-depcheck.1:96 ../scripts/getbuildlog.1:25
 #: ../scripts/mk-build-deps.pl:79 ../scripts/rmadison.pl:246
-#: ../doc/suspicious-source.1:35 ../doc/what-patch.1:17
+#: ../scripts/sadt.pod:59 ../doc/suspicious-source.1:35 ../doc/what-patch.1:17
 #: ../doc/wrap-and-sort.1:34
 #, no-wrap
 msgid "B<-h>, B<--help>"
@@ -357,7 +357,7 @@ msgstr ""
 #: ../scripts/grep-excuses.1:38 ../scripts/list-unreleased.1:19
 #: ../scripts/nmudiff.1:108 ../scripts/origtargz.pl:156
 #: ../scripts/plotchangelog.1:124 ../scripts/pts-subscribe.1:51
-#: ../scripts/rc-alert.1:121 ../scripts/rmadison.pl:333
+#: ../scripts/rc-alert.1:121 ../scripts/rmadison.pl:333 ../scripts/sadt.pod:65
 #: ../scripts/tagpending.pl:148 ../scripts/uscan.1:566
 #: ../scripts/uupdate.1:170 ../doc/what-patch.1:35
 #: ../scripts/who-permits-upload.pl:161 ../scripts/wnpp-alert.1:29
@@ -10582,8 +10582,9 @@ msgstr ""
 "fichiers récupérés seront présents à la fin."
 
 #. type: TP
-#: ../scripts/debsnap.1:42 ../doc/suspicious-source.1:38
-#: ../scripts/tagpending.pl:105 ../doc/wrap-and-sort.1:70
+#: ../scripts/debsnap.1:42 ../scripts/sadt.pod:46
+#: ../doc/suspicious-source.1:38 ../scripts/tagpending.pl:105
+#: ../doc/wrap-and-sort.1:70
 #, no-wrap
 msgid "B<-v>, B<--verbose>"
 msgstr "B<-v>, B<--verbose>"
@@ -12834,12 +12835,24 @@ msgstr ""
 
 #. type: IP
 #: ../scripts/devscripts.1:129
+#, fuzzy, no-wrap
+#| msgid "I<dget>(1)"
+msgid "I<sadt>(1)"
+msgstr "B<dget>(1)"
+
+#. type: Plain text
+#: ../scripts/devscripts.1:131
+msgid "run DEP-8 tests [python3-debian]"
+msgstr ""
+
+#. type: IP
+#: ../scripts/devscripts.1:131
 #, no-wrap
 msgid "I<suspicious-source>(1)"
 msgstr "B<suspicious-source>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:131
+#: ../scripts/devscripts.1:133
 msgid ""
 "output a list of files which are not common source files [python3-magic]"
 msgstr ""
@@ -12847,24 +12860,24 @@ msgstr ""
 "[python3-magic]"
 
 #. type: IP
-#: ../scripts/devscripts.1:131
+#: ../scripts/devscripts.1:133
 #, no-wrap
 msgid "I<svnpath>(1)"
 msgstr "B<svnpath>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:133
+#: ../scripts/devscripts.1:135
 msgid "print Subversion repository paths [subversion]"
 msgstr "afficher les chemins de dépôt Subversion [subversion]"
 
 #. type: IP
-#: ../scripts/devscripts.1:133
+#: ../scripts/devscripts.1:135
 #, no-wrap
 msgid "I<tagpending>(1)"
 msgstr "B<tagpending>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:135
+#: ../scripts/devscripts.1:137
 msgid ""
 "run from a Debian source tree and tag bugs that are to be closed in the "
 "latest changelog as pending [libsoap-lite-perl]"
@@ -12874,13 +12887,13 @@ msgstr ""
 "changelog [libsoap-lite-perl]"
 
 #. type: IP
-#: ../scripts/devscripts.1:135
+#: ../scripts/devscripts.1:137
 #, no-wrap
 msgid "I<transition-check>(1)"
 msgstr "B<transition-check>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:137
+#: ../scripts/devscripts.1:139
 msgid ""
 "check a list of source packages for involvement in transitions for which "
 "uploads to unstable are currently blocked [libwww-perl, libyaml-syck-perl]"
@@ -12890,13 +12903,13 @@ msgstr ""
 "syck-perl]"
 
 #. type: IP
-#: ../scripts/devscripts.1:137
+#: ../scripts/devscripts.1:139
 #, no-wrap
 msgid "I<uscan>(1)"
 msgstr "B<uscan>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:139
+#: ../scripts/devscripts.1:141
 msgid ""
 "scan upstream sites for new releases of packages [gpgv, liblwp-protocol-"
 "https-perl, libwww-perl, unzip, lzma, xz-utils]"
@@ -12905,24 +12918,24 @@ msgstr ""
 "protocol-https-perl, libwww-perl, unzip, lzma, xz-utils]"
 
 #. type: IP
-#: ../scripts/devscripts.1:139
+#: ../scripts/devscripts.1:141
 #, no-wrap
 msgid "I<uupdate>(1)"
 msgstr "B<uupdate>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:141
+#: ../scripts/devscripts.1:143
 msgid "integrate upstream changes into a source package [patch]"
 msgstr "intégrer les modifications amont à un paquet source [patch]"
 
 #. type: IP
-#: ../scripts/devscripts.1:141
+#: ../scripts/devscripts.1:143
 #, no-wrap
 msgid "I<what-patch>(1)"
 msgstr "B<what-patch>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:143
+#: ../scripts/devscripts.1:145
 msgid ""
 "determine what patch system, if any, a source package is using [patchutils]"
 msgstr ""
@@ -12930,24 +12943,24 @@ msgstr ""
 "source [patchutils]"
 
 #. type: IP
-#: ../scripts/devscripts.1:143
+#: ../scripts/devscripts.1:145
 #, no-wrap
 msgid "I<whodepends>(1)"
 msgstr "B<whodepends>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:145
+#: ../scripts/devscripts.1:147
 msgid "check which maintainers' packages depend on a package"
 msgstr "vérifier quels paquets (et responsables) dépendent d'un autre paquet"
 
 #. type: IP
-#: ../scripts/devscripts.1:145
+#: ../scripts/devscripts.1:147
 #, no-wrap
 msgid "I<who-uploads>(1)"
 msgstr "B<who-uploads>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:147
+#: ../scripts/devscripts.1:149
 msgid ""
 "determine the most recent uploaders of a package to the Debian archive "
 "[gnupg, debian-keyring, debian-maintainers, wget]"
@@ -12956,13 +12969,13 @@ msgstr ""
 "l'archive Debian [gnupg, debian-keyring, debian-maintainers, wget]"
 
 #. type: IP
-#: ../scripts/devscripts.1:147
+#: ../scripts/devscripts.1:149
 #, no-wrap
 msgid "I<wnpp-alert>(1)"
 msgstr "B<wnpp-alert>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:149
+#: ../scripts/devscripts.1:151
 msgid ""
 "list installed packages which are orphaned or up for adoption [wget | curl]"
 msgstr ""
@@ -12970,13 +12983,13 @@ msgstr ""
 "[wget | curl]"
 
 #. type: IP
-#: ../scripts/devscripts.1:149
+#: ../scripts/devscripts.1:151
 #, no-wrap
 msgid "I<wnpp-check>(1)"
 msgstr "B<wnpp-check>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:151
+#: ../scripts/devscripts.1:153
 msgid ""
 "check whether there is an open request for packaging or intention to package "
 "bug for a package [wget | curl]"
@@ -12985,13 +12998,13 @@ msgstr ""
 "travail (ITP) est ouvert pour un paquet [wget | curl]"
 
 #. type: IP
-#: ../scripts/devscripts.1:151
+#: ../scripts/devscripts.1:153
 #, no-wrap
 msgid "I<who-permits-upload>(1)"
 msgstr "B<who-permits-upload>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:153
+#: ../scripts/devscripts.1:155
 msgid ""
 "Retrieve information about Debian Maintainer access control lists [gnupg, "
 "libencode-locale-perl, libparse-debcontrol-perl, libwww-perl, debian-keyring]"
@@ -13001,13 +13014,13 @@ msgstr ""
 "libwww-perl, debian-keyring]"
 
 #. type: IP
-#: ../scripts/devscripts.1:153
+#: ../scripts/devscripts.1:155
 #, no-wrap
 msgid "I<wrap-and-sort>(1)"
 msgstr "B<wrap-and-sort>(1)"
 
 #. type: Plain text
-#: ../scripts/devscripts.1:154
+#: ../scripts/devscripts.1:156
 msgid "wrap long lines and sort items in packaging files [python3-debian]"
 msgstr ""
 "couper les lignes longues et trier les items des fichiers d'empaquetage "
@@ -17205,6 +17218,94 @@ msgstr ""
 "Berg <myon at debian.org>. dak a été écrit par James Troup <james at nocrew.org>, "
 "Anthony Towns <ajt at debian.org> et d'autres."
 
+#. type: textblock
+#: ../scripts/sadt.pod:19
+msgid "sadt - simple DEP-8 test runner"
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:23
+#, fuzzy
+#| msgid "B<dch> [I<options>] [I<text> ...]"
+msgid "B<sadt> [I<options>] [I<test-name>...]"
+msgstr "B<dch> [I<options>] [I<texte> ...]"
+
+#. type: textblock
+#: ../scripts/sadt.pod:27
+msgid ""
+"B<sadt> is a simple implementation of DEP-8 (“automatic as-installed package "
+"testing”) test runner."
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:30
+msgid ""
+"It is your responsibility to satisfy tests' dependencies.  B<sadt> won't "
+"attempt to install any missing packages.  If a test's dependencies cannot be "
+"satisfied by packages that are currently installed, the test will be skipped."
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:34
+msgid ""
+"B<sadt> won't build the package even if a test declares the B<build-needed> "
+"restriction.  Instead, such a test will be skipped.  However, you can build "
+"the package manually, and then tell B<sadt> to assume that the package is "
+"already built using the B<-b>/B<--built-source-tree>."
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:39
+msgid ""
+"B<sadt> doesn't implement any virtualisation arrangements, therefore it "
+"skips tests that declare the B<breaks-testbed> restriction."
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:48
+msgid "Make the output more verbose."
+msgstr ""
+
+#. type: =item
+#: ../scripts/sadt.pod:50
+#, fuzzy
+#| msgid "B<-b>, B<--build-depends>"
+msgid "B<-b>, B<--built-source-tree>"
+msgstr "B<-b>, B<--build-depends>"
+
+#. type: textblock
+#: ../scripts/sadt.pod:52
+msgid ""
+"Assume that the source tree is already built.  This is equivalent to B<--"
+"ignore-restriction=build-needed>."
+msgstr ""
+
+#. type: =item
+#: ../scripts/sadt.pod:55
+#, fuzzy
+#| msgid "B<--dist=>I<distribution>"
+msgid "B<--ignore-restriction>=I<restriction>"
+msgstr "B<--dist=>I<distribution>"
+
+#. type: textblock
+#: ../scripts/sadt.pod:57
+msgid "Don't skip tests that declare the I<restriction>."
+msgstr ""
+
+#. type: textblock
+#: ../scripts/sadt.pod:61
+#, fuzzy
+#| msgid "Show this help message and exit."
+msgid "Show a help message and exit."
+msgstr "Afficher ce message d'aide et quitter."
+
+#. type: textblock
+#: ../scripts/sadt.pod:67
+#, fuzzy
+#| msgid "B<date>(1)"
+msgid "B<adt-run>(1)"
+msgstr "B<date>(1)"
+
 #. type: TH
 #: ../doc/suspicious-source.1:15
 #, no-wrap
diff --git a/scripts/Makefile b/scripts/Makefile
index d981b81..de5baba 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -59,6 +59,9 @@ endif
 %.1: %.pl
 	podchecker $<
 	pod2man --utf8 --center=" " --release="Debian Utilities" $< > $@
+%.1: %.pod
+	podchecker $<
+	pod2man --utf8 --center=" " --release="Debian Utilities" $< > $@
 %.1: %.dbk
 	xsltproc --nonet -o $@ \
 	  /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/manpages/docbook.xsl $<
diff --git a/scripts/sadt b/scripts/sadt
new file mode 100644
index 0000000..5c9aa7b
--- /dev/null
+++ b/scripts/sadt
@@ -0,0 +1,444 @@
+#!/usr/bin/python3
+# encoding=UTF-8
+
+# Copyright © 2012, 2013 Jakub Wilk <jwilk at debian.org>
+
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+'''
+simple DEP-8 test runner
+'''
+
+import argparse
+import errno
+import gettext
+import os
+import queue as queuemod
+import re
+import shutil
+import stat
+import subprocess as ipc
+import sys
+import tempfile
+import threading
+
+import debian.deb822 as deb822
+
+def chmod_x(path):
+    '''
+    chmod a+X <path>
+    '''
+    old_mode = stat.S_IMODE(os.stat(path).st_mode)
+    new_mode = old_mode | ((old_mode & 0o444) >> 2)
+    if old_mode != new_mode:
+        os.chmod(path, new_mode)
+
+def annotate_output(child):
+    queue = queuemod.Queue()
+    def reader(fd, tag):
+        buf = b''
+        while True:
+            assert b'\n' not in buf
+            chunk = os.read(fd, 1024)
+            if chunk == b'':
+                break
+            lines = (buf + chunk).split(b'\n')
+            buf = lines.pop()
+            for line in lines:
+                queue.put((tag, line + b'\n'))
+        if buf != b'':
+            queue.put((tag, buf))
+        queue.put(None)
+    queue = queuemod.Queue()
+    threads = []
+    for pipe, tag in [(child.stdout, 'O'), (child.stderr, 'E')]:
+        thread = threading.Thread(target=reader, args=(pipe.fileno(), tag))
+        thread.start()
+        threads += [thread]
+    nthreads = len(threads)
+    while nthreads > 0:
+        item = queue.get()
+        if item is None:
+            nthreads -= 1
+            continue
+        yield item
+    for thread in threads:
+        thread.join()
+
+class Skip(Exception):
+    pass
+
+class Fail(Exception):
+    pass
+
+class Progress(object):
+
+    _hourglass = r'/-\|'
+
+    def __init__(self):
+        self._counter = 0
+        if sys.stdout.isatty():
+            self._back = '\b'
+        else:
+            self._back = ''
+
+    def _write(self, s):
+        sys.stdout.write(s)
+        sys.stdout.flush()
+
+    def ping(self):
+        if not self._back:
+            return
+        hourglass = self._hourglass
+        c = self._counter + 1
+        self._write(self._back + hourglass[c % len(hourglass)])
+        self._counter = c
+
+    def start(self, name):
+        pass
+
+    def skip(self, reason):
+        raise NotImplementedError
+
+    def fail(self, reason):
+        raise NotImplementedError
+
+    def ok(self):
+        raise NotImplementedError
+
+    def close(self):
+        pass
+
+class DefaultProgress(Progress):
+
+    def start(self, name):
+        if self._back:
+            self._write(' ')
+        self.ping()
+
+    def skip(self, reason):
+        self._write(self._back + 'S')
+
+    def fail(self, reason):
+        self._write(self._back + 'F')
+
+    def ok(self):
+        self._write(self._back + '.')
+
+    def close(self):
+        self._write('\n')
+
+class VerboseProgress(Progress):
+
+    def start(self, name):
+        self._write('{test} ... '.format(test=name) + (' ' if self._back else ''))
+        self.ping()
+
+    def skip(self, reason):
+        self._write(self._back + 'SKIP ({reason})\n'.format(reason=reason))
+
+    def fail(self, reason):
+        self._write(self._back + 'FAIL ({reason})\n'.format(reason=reason))
+
+    def ok(self):
+        self._write(self._back + 'ok\n')
+
+class TestGroup(object):
+
+    def __init__(self):
+        self.tests = []
+        self.restrictions = frozenset()
+        self.features = frozenset()
+        self.depends = '@'
+        self.tests_directory = 'debian/tests'
+        self._check_depends_cache = None
+
+    def __iter__(self):
+        return iter(self.tests)
+
+    def expand_depends(self, packages):
+        if '@' not in self.depends:
+            return
+        or_clauses = []
+        # deb822 prints a warning on stderr: http://bugs.debian.org/712513
+        # We don't want the user to see the warning, because the unusual
+        # character in the relation is intentional.
+        orig_sys_stderr = sys.stderr
+        sys.stderr = open(os.devnull, 'wt', errors='ignore')
+        try:
+            parsed_depends = deb822.PkgRelation.parse_relations(self.depends)
+        finally:
+            try:
+                sys.stderr.close()
+            finally:
+                sys.stderr = orig_sys_stderr
+        for or_clause in parsed_depends:
+            stripped_or_clause = [r for r in or_clause if r['name'] != '@']
+            if len(stripped_or_clause) < len(or_clause):
+                for package in packages:
+                    or_clauses += [
+                        stripped_or_clause +
+                        [dict(name=package, version=None, arch=None)]
+                    ]
+            else:
+                or_clauses += [or_clause]
+        self.depends = deb822.PkgRelation.str(or_clauses)
+
+    def check_depends(self):
+        assert '@' not in self.depends
+        if self._check_depends_cache is not None:
+            if isinstance(self._depends_cache, Exception):
+                raise self._check_depends_cache
+            return
+        child = ipc.Popen(['dpkg-checkbuilddeps', '-d', self.depends],
+            stderr=ipc.PIPE,
+            env={}
+        )
+        error = child.stderr.read().decode('ASCII')
+        child.stderr.close()
+        if child.wait() != 0:
+            error = re.sub('^dpkg-checkbuilddeps: Unmet build dependencies', 'unmet dependencies', error)
+            error = error.rstrip()
+            skip = Skip(error)
+            self._depends_cache = skip
+            raise skip
+        else:
+            self._depends_cache = True
+
+    def check_restrictions(self, ignored_restrictions):
+        restrictions = self.restrictions - frozenset(ignored_restrictions)
+        class options:
+            rw_build_tree_needed = False
+            allow_stderr = False
+        for r in restrictions:
+            if r == 'rw-build-tree':
+                options.needs_rw_build_tree = True
+            elif r == 'needs-root':
+                if os.getuid() != 0:
+                    raise Skip('this test needs root privileges')
+            elif r == 'breaks-testbed':
+                raise Skip('breaks-testbed restriction is not implemented; use adt-run')
+            elif r == 'build-needed':
+                raise Skip('source tree not built')
+            elif r == 'allow-stderr':
+                options.allow_stderr = True
+            else:
+                raise Skip('unknown restriction: {restr}'.format(restr=r))
+        return options
+
+    def check(self, ignored_restrictions=()):
+        options = self.check_restrictions(ignored_restrictions)
+        self.check_depends()
+        return options
+
+    def run(self, test, progress, ignored_restrictions=(), rw_build_tree=None, built_source_tree=None):
+        progress.start(test)
+        ignored_restrictions = set(ignored_restrictions)
+        if rw_build_tree:
+            ignored_restrictions.add('rw-build-tree')
+        if built_source_tree:
+            ignored_restrictions.add('build-needed')
+        try:
+            options = self.check(ignored_restrictions)
+        except Skip as exc:
+            progress.skip(str(exc))
+            raise
+        if rw_build_tree:
+            cwd = os.getcwd()
+            os.chdir(rw_build_tree)
+        else:
+            cwd = None
+        try:
+            self._run(test, progress, allow_stderr=options.allow_stderr)
+        finally:
+            if cwd is not None:
+                os.chdir(cwd)
+
+    def _run(self, test, progress, allow_stderr=False):
+        path = os.path.join(self.tests_directory, test)
+        chmod_x(path)
+        tmpdir1 = tempfile.mkdtemp(prefix='sadt.')
+        tmpdir2 = tempfile.mkdtemp(prefix='sadt.')
+        environ = dict(os.environ)
+        environ['ADTTMP'] = tmpdir1
+        environ['TMPDIR'] = tmpdir2 # only for compatibility with old DEP-8 spec.
+        child = ipc.Popen([path],
+            stdout=ipc.PIPE,
+            stderr=ipc.PIPE,
+            env=environ,
+        )
+        output = []
+        stderr = False
+        for tag, line in annotate_output(child):
+            progress.ping()
+            if tag == 'E':
+                stderr = True
+            output += ['{tag}: {line}'.format(
+                tag=tag,
+                line=line.decode(sys.stdout.encoding, 'replace'),
+            )]
+        for fp in child.stdout, child.stderr:
+            fp.close()
+        rc = child.wait()
+        shutil.rmtree(tmpdir1)
+        shutil.rmtree(tmpdir2)
+        if rc == 0:
+            if stderr and not allow_stderr:
+                rc = -1
+                fail_reason = 'stderr non-empty'
+                progress.fail(fail_reason)
+            else:
+                progress.ok()
+        else:
+            fail_reason = 'exit code: {rc}'.format(rc=rc)
+            progress.fail(fail_reason)
+        if rc != 0:
+            raise Fail(fail_reason, ''.join(output))
+
+    def add_tests(self, tests):
+        tests = tests.split()
+        self.tests = frozenset(tests)
+
+    def add_restrictions(self, restrictions):
+        restrictions = restrictions.split()
+        self.restrictions = frozenset(restrictions)
+
+    def add_features(self, features):
+        features = features.split()
+        self.features = frozenset(features)
+
+    def add_depends(self, depends):
+        self.depends = depends
+
+    def add_tests_directory(self, path):
+        self.tests_directory = path
+
+def copy_build_tree():
+    rw_build_tree = tempfile.mkdtemp(prefix='sadt-rwbt.')
+    print('sadt: info: copying build tree to {tree}'.format(tree=rw_build_tree), file=sys.stderr)
+    ipc.check_call(['cp', '-a', '.', rw_build_tree])
+    return rw_build_tree
+
+def main():
+    for description in __doc__.splitlines():
+        if description: break
+    parser = argparse.ArgumentParser(description=description)
+    parser.add_argument('-v', '--verbose', action='store_true', help='verbose output')
+    parser.add_argument('-b', '--built-source-tree', action='store_true', help='assume built source tree')
+    parser.add_argument('--ignore-restrictions', metavar='<restr>[,<restr>...]', help='ignore specified restrictions', default='')
+    parser.add_argument('tests', metavar='<test-name>', nargs='*', help='tests to run')
+    options = parser.parse_args()
+    options.tests = frozenset(options.tests)
+    options.ignore_restrictions = frozenset(options.ignore_restrictions.split(','))
+    binary_packages = set()
+    try:
+        file = open('debian/control', encoding='UTF-8')
+    except IOError as exc:
+        if exc.errno == errno.ENOENT:
+            print('sadt: error: cannot find debian/control', file=sys.stderr)
+            sys.exit(1)
+        raise
+    with file:
+        for n, para in enumerate(deb822.Packages.iter_paragraphs(file)):
+            if n == 0:
+                para['Source']
+            else:
+                binary_packages.add(para['Package'])
+    test_groups = []
+    try:
+        file = open('debian/tests/control', encoding='UTF-8')
+    except IOError as exc:
+        if exc.errno == errno.ENOENT:
+            print('sadt: error: cannot find debian/tests/control', file=sys.stderr)
+            sys.exit(1)
+        raise
+    with file:
+        for para in deb822.Packages.iter_paragraphs(file):
+            group = TestGroup()
+            for key, value in para.items():
+                lkey = key.lower().replace('-', '_')
+                try:
+                    method = getattr(group, 'add_' + lkey)
+                except AttributeError:
+                    print('sadt: warning: unknown field {field}, skipping the whole paragraph'.format(field=key), file=sys.stderr)
+                    group = None
+                    break
+                method(value)
+            if group is not None:
+                group.expand_depends(binary_packages)
+                test_groups += [group]
+    failures = []
+    n_skip = n_ok = 0
+    progress = VerboseProgress() if options.verbose else DefaultProgress()
+    rw_build_tree = None
+    try:
+        for group in test_groups:
+            for name in group:
+                if options.tests and name not in options.tests:
+                    continue
+                try:
+                    if rw_build_tree is None:
+                        try:
+                            group_options = group.check()
+                        except Skip:
+                            pass
+                        else:
+                            if group_options.rw_build_tree_needed:
+                                rw_build_tree = copy_build_tree()
+                                assert rw_build_tree is not None
+                    group.run(name,
+                        progress=progress,
+                        ignored_restrictions=options.ignore_restrictions,
+                        rw_build_tree=rw_build_tree,
+                        built_source_tree=options.built_source_tree
+                    )
+                except Skip:
+                    n_skip += 1
+                except Fail as exc:
+                    failures += [(name, exc)]
+                else:
+                    n_ok += 1
+    finally:
+        progress.close()
+    n_fail = len(failures)
+    n_test = n_fail + n_skip + n_ok
+    separator1 = '-' * 70
+    separator2 = '=' * 70
+    if failures:
+        for name, exception in failures:
+            print(separator2)
+            print('FAIL: {test}'.format(test=name))
+            print(separator1)
+            print(exception.args[1])
+    print(separator1)
+    print(gettext.ngettext('Ran {n} test', 'Ran {n} tests', n_test).format(n=n_test))
+    print()
+    extra_message = []
+    if n_skip > 0:
+        extra_message += ['skipped={n}'.format(n=n_skip)]
+    if n_fail > 0:
+        extra_message += ['failures={n}'.format(n=n_fail)]
+    if extra_message:
+        extra_message = ' ({msg})'.format(msg=', '.join(extra_message))
+    else:
+        extra_message = ''
+    message = ('OK' if n_fail == 0 else 'FAILED') + extra_message
+    print(message)
+    if rw_build_tree is not None:
+        shutil.rmtree(rw_build_tree)
+    sys.exit(n_fail > 0)
+
+if __name__ == '__main__':
+    main()
+
+# vim:ts=4 sw=4 et
diff --git a/scripts/sadt.pod b/scripts/sadt.pod
new file mode 100644
index 0000000..362ff06
--- /dev/null
+++ b/scripts/sadt.pod
@@ -0,0 +1,67 @@
+# Copyright © 2013 Jakub Wilk <jwilk at debian.org>
+
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+=encoding utf8
+
+=head1 NAME
+
+sadt - simple DEP-8 test runner
+
+=head1 SYNOPSIS
+
+B<sadt> [I<options>] [I<test-name>...]
+
+=head1 DESCRIPTION
+
+B<sadt> is a simple implementation of DEP-8 (“automatic as-installed package
+testing”) test runner.
+
+It is your responsibility to satisfy tests' dependencies.  B<sadt> won't
+attempt to install any missing packages.  If a test's dependencies cannot be
+satisfied by packages that are currently installed, the test will be skipped.
+
+B<sadt> won't build the package even if a test declares the B<build-needed>
+restriction.  Instead, such a test will be skipped.  However, you can build the
+package manually, and then tell B<sadt> to assume that the package is already
+built using the B<-b>/B<--built-source-tree>.
+
+B<sadt> doesn't implement any virtualisation arrangements, therefore it skips
+tests that declare the B<breaks-testbed> restriction.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-v>, B<--verbose>
+
+Make the output more verbose.
+
+=item B<-b>, B<--built-source-tree>
+
+Assume that the source tree is already built.
+This is equivalent to B<--ignore-restriction=build-needed>.
+
+=item B<--ignore-restriction>=I<restriction>
+
+Don't skip tests that declare the I<restriction>.
+
+=item B<-h>, B<--help>
+
+Show a help message and exit.
+
+=back
+
+=head1 SEE ALSO
+
+B<adt-run>(1)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/collab-maint/devscripts.git



More information about the devscripts-devel mailing list