From 9e95b512f5f3f7f78282e8deccfc5a38dfc75d31 Mon Sep 17 00:00:00 2001
From: Benjamin Drung <bdrung@ubuntu.com>
Date: Tue, 28 Dec 2010 19:59:34 +0100
Subject: [PATCH 01/17] ack-sync: Fix undefined variables.

---
 ack-sync | 29 +++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/ack-sync b/ack-sync
index 5871963..05efc99 100755
--- a/ack-sync
+++ b/ack-sync
@@ -51,7 +51,7 @@ def strip_epoch(version):
     version = ':'.join(parts)
     return version
 
-def LogCall(command):
+def log_call(command):
     command = map(str, command)
     logging.info("Running %s", " ".join(command))
     return command
@@ -88,22 +88,22 @@ def get_source(package, version, section, dist, uploader_name, uploader_email,
         sys.exit(1)
     return dsc_file
 
-def build_source(dist, dsc_file):
+def build_source(dist, dsc_file, pbuilder, sbuild):
     try:
         if sbuild:
             cmd = ["sbuild", "-d", dist, "-A", dsc_file]
-            subprocess.check_call(LogCall(cmd))
+            subprocess.check_call(log_call(cmd))
         else:
             if not os.path.isdir("buildresult"):
                 os.makedirs("buildresult")
             cmd = ["sudo", "-E", "DIST=" + dist, pbuilder, "--build",
                    "--buildresult", "buildresult", dsc_file]
-            subprocess.check_call(LogCall(cmd))
+            subprocess.check_call(log_call(cmd))
     except subprocess.CalledProcessError:
         print >> sys.stderr, "E: %s failed to build." % (dsc_file)
         sys.exit(1)
 
-def test_install(dist, dsc_file):
+def test_install(dist, dsc_file, sbuild, lvm):
     changes_files = glob.glob(os.path.splitext(dsc_file)[0]+"_*.changes")
     changes_file = ""
 
@@ -122,9 +122,9 @@ def test_install(dist, dsc_file):
                "restricted multiverse", changes_file]
         if sbuild:
             lvm_volume = lvm + "/" + dist + "_chroot"
-            subprocess.check_call(LogCall(cmd + ["--lvm-volume="+lvm_volume]))
+            subprocess.check_call(log_call(cmd + ["--lvm-volume="+lvm_volume]))
         else:
-            subprocess.check_call(LogCall(cmd + ["--pbuilder"]))
+            subprocess.check_call(log_call(cmd + ["--pbuilder"]))
     except subprocess.CalledProcessError:
         print >> sys.stderr, "E: %s failed to install. Please check log" % \
                              (changes_file)
@@ -154,8 +154,8 @@ def unsubscribe_sponsors(launchpad, bug):
 
 
 def ack_sync(bug_numbers, all_package, all_version, all_section, update,
-             all_uploader_email, key, upload, lpinstance, verbose=False,
-             silent=False):
+             all_uploader_email, key, upload, lpinstance, pbuilder, sbuild, lvm,
+             piuparts, verbose, verbose=False, silent=False):
     launchpad = get_launchpad("ubuntu-dev-tools", server=lpinstance)
     # TODO: use release-info (once available)
     series = launchpad.distributions["ubuntu"].current_series
@@ -164,10 +164,10 @@ def ack_sync(bug_numbers, all_package, all_version, all_section, update,
     # update pbuilder
     if update:
         if sbuild:
-            subprocess.call(LogCall(["sbuild-update", dist]))
+            subprocess.call(log_call(["sbuild-update", dist]))
         else:
             cmd = ["sudo", "-E", "DIST=" + dist, pbuilder, "--update"]
-            subprocess.call(LogCall(cmd))
+            subprocess.call(log_call(cmd))
 
     for bug_number in bug_numbers:
         bug = launchpad.bugs[bug_number]
@@ -270,10 +270,10 @@ def ack_sync(bug_numbers, all_package, all_version, all_section, update,
         env['DEB_VENDOR'] = 'Ubuntu'
         subprocess.check_call(["dpkg-source", "-x", dsc_file], env=env)
 
-        build_source(dist, dsc_file)
+        build_source(dist, dsc_file, pbuilder, sbuild)
 
         if piuparts:
-            test_install(dist, dsc_file)
+            test_install(dist, dsc_file, sbuild, lvm)
 
         print bug.title
         print '%s (was %s)' % (task.status, old_status)
@@ -430,7 +430,8 @@ def main():
     #TODO: Support WORKDIR
 
     ack_sync(bug_numbers, package, version, section, update, uploader_email,
-             key, upload, lpinstance, verbose, silent)
+             key, upload, lpinstance, pbuilder, sbuild, lvm, piuparts, verbose,
+             silent)
 
 if __name__ == '__main__':
     main()

From c279a9ba14a9b69c09434d2c75488d7003586ba5 Mon Sep 17 00:00:00 2001
From: Benjamin Drung <bdrung@ubuntu.com>
Date: Tue, 28 Dec 2010 20:02:02 +0100
Subject: [PATCH 02/17] ack-sync: Fix duplicate argument 'verbose' in function
 definition

---
 ack-sync | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ack-sync b/ack-sync
index 05efc99..4d9b87f 100755
--- a/ack-sync
+++ b/ack-sync
@@ -155,7 +155,7 @@ def unsubscribe_sponsors(launchpad, bug):
 
 def ack_sync(bug_numbers, all_package, all_version, all_section, update,
              all_uploader_email, key, upload, lpinstance, pbuilder, sbuild, lvm,
-             piuparts, verbose, verbose=False, silent=False):
+             piuparts, verbose=False, silent=False):
     launchpad = get_launchpad("ubuntu-dev-tools", server=lpinstance)
     # TODO: use release-info (once available)
     series = launchpad.distributions["ubuntu"].current_series

From 99f78224ac00122f39fa38592f0f8dc571ff2894 Mon Sep 17 00:00:00 2001
From: Benjamin Drung <bdrung@ubuntu.com>
Date: Tue, 28 Dec 2010 20:44:22 +0100
Subject: [PATCH 03/17] sponsor_patch.py: Fix bug task selection and put it in
 separate function.

---
 ubuntutools/sponsor_patch/sponsor_patch.py | 61 ++++++++++++----------
 1 file changed, 34 insertions(+), 27 deletions(-)

diff --git a/ubuntutools/sponsor_patch/sponsor_patch.py b/ubuntutools/sponsor_patch/sponsor_patch.py
index 57452c2..a24167f 100644
--- a/ubuntutools/sponsor_patch/sponsor_patch.py
+++ b/ubuntutools/sponsor_patch/sponsor_patch.py
@@ -218,6 +218,39 @@ def apply_patch(task, patch):
                 edit = True
     return edit
 
+def get_open_ubuntu_bug_task(launchpad, bug):
+    """Returns an open Ubuntu bug task for a given Launchpad bug.
+
+    The bug task needs to be open (not complete) and target Ubuntu. The user
+    will be ask to select one if multiple open Ubuntu bug task exits for the
+    bug.
+    """
+    bug_tasks = [BugTask(x, launchpad) for x in bug.bug_tasks]
+    ubuntu_tasks = [x for x in bug_tasks if x.is_ubuntu_task()]
+    if len(ubuntu_tasks) == 0:
+        Logger.error("No Ubuntu bug task found on bug #%i." % (bug.id))
+        sys.exit(1)
+    elif len(ubuntu_tasks) == 1:
+        task = ubuntu_tasks[0]
+    if len(ubuntu_tasks) > 1:
+        task_list = [t.get_short_info() for t in ubuntu_tasks]
+        Logger.info("%i Ubuntu tasks exist for bug #%i.\n%s", len(ubuntu_tasks),
+                    bug.id, "\n".join(task_list))
+        open_ubuntu_tasks = [x for x in ubuntu_tasks if not x.is_complete()]
+        if len(open_ubuntu_tasks) == 1:
+            task = open_ubuntu_tasks[0]
+        else:
+            Logger.normal("https://launchpad.net/bugs/%i has %i Ubuntu tasks:" \
+                          % (bug.id, len(ubuntu_tasks)))
+            for i in xrange(len(ubuntu_tasks)):
+                print "%i) %s" % (i + 1,
+                                  ubuntu_tasks[i].get_package_and_series())
+            selected = input_number("To which Ubuntu tasks do the patch belong",
+                                    1, len(ubuntu_tasks))
+            task = ubuntu_tasks[selected - 1]
+    Logger.info("Selected Ubuntu task: %s" % (task.get_short_info()))
+    return task
+
 def sponsor_patch(bug_number, build, builder, edit, keyid, lpinstance, update,
                   upload, workdir, verbose=False):
     workdir = os.path.expanduser(workdir)
@@ -239,33 +272,7 @@ def sponsor_patch(bug_number, build, builder, edit, keyid, lpinstance, update,
     #pylint: enable=E1101
 
     (patch, branch) = get_patch_or_branch(bug)
-
-    bug_tasks = [BugTask(x, launchpad) for x in bug.bug_tasks]
-    ubuntu_tasks = [x for x in bug_tasks if x.is_ubuntu_task()]
-    if len(ubuntu_tasks) == 0:
-        Logger.error("No Ubuntu bug task found on bug #%i." % (bug_number))
-        sys.exit(1)
-    elif len(ubuntu_tasks) == 1:
-        task = ubuntu_tasks[0]
-    if len(ubuntu_tasks) > 1:
-        if verbose:
-            Logger.info("%i Ubuntu tasks exist for bug #%i." % \
-                        (len(ubuntu_tasks), bug_number))
-            for task in ubuntu_tasks:
-                print task.get_short_info()
-        open_ubuntu_tasks = [x for x in ubuntu_tasks if x.is_complete()]
-        if len(open_ubuntu_tasks) == 1:
-            task = open_ubuntu_tasks[0]
-        else:
-            Logger.normal("https://launchpad.net/bugs/%i has %i Ubuntu tasks:" \
-                          % (bug_number, len(ubuntu_tasks)))
-            for i in xrange(len(ubuntu_tasks)):
-                print "%i) %s" % (i + 1,
-                                  ubuntu_tasks[i].get_package_and_series())
-            selected = input_number("To which Ubuntu tasks do the patch belong",
-                                    1, len(ubuntu_tasks))
-            task = ubuntu_tasks[selected - 1]
-    Logger.info("Selected Ubuntu task: %s" % (task.get_short_info()))
+    task = get_open_ubuntu_bug_task(launchpad, bug)
 
     dsc_file = task.download_source()
     assert os.path.isfile(dsc_file), "%s does not exist." % (dsc_file)

From 9c916053b14d14af3b2c6b6c60260b3a898b2835 Mon Sep 17 00:00:00 2001
From: Stefano Rivera <stefanor@ubuntu.com>
Date: Tue, 4 Jan 2011 22:24:06 +0200
Subject: [PATCH 04/17] import-bug-from-debian: Add --package option, for
 importing bugs from psuedo-packages.

---
 debian/changelog             |  4 +++-
 doc/import-bug-from-debian.1 |  7 ++++++-
 import-bug-from-debian       | 14 ++++++++++++--
 3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 6fcdc87..94a6bed 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -29,6 +29,8 @@ ubuntu-dev-tools (0.109) UNRELEASED; urgency=low
   * pull-debian-debdiff: Rewrite in Python, and use snapshot.debian.org.
   * pull-lp-source: Support -d (LP: #681699)
   * suspicious-source: Whitelist Python source code.
+  * import-bug-from-debian: Add --package option, for importing bugs from
+    psuedo-packages.
 
   [ Michael Bienia ]
   * ubuntutools/lp/lpapicache.py: Allow easier selection of 'staging' as LP
@@ -52,7 +54,7 @@ ubuntu-dev-tools (0.109) UNRELEASED; urgency=low
   * add "add-patch" that provides the non-interactive version of
     edit-patch
 
- -- Benjamin Drung <bdrung@ubuntu.com>  Mon, 27 Dec 2010 22:38:34 +0100
+ -- Stefano Rivera <stefanor@ubuntu.com>  Tue, 04 Jan 2011 22:23:20 +0200
 
 ubuntu-dev-tools (0.108) experimental; urgency=low
 
diff --git a/doc/import-bug-from-debian.1 b/doc/import-bug-from-debian.1
index aede43a..5276d1f 100644
--- a/doc/import-bug-from-debian.1
+++ b/doc/import-bug-from-debian.1
@@ -4,7 +4,7 @@ import\-bug\-from\-debian \- Import bugs from Debian's BTS, and file
 them against Ubuntu in LP.
 
 .SH SYNOPSIS
-.B import\-bug\-from\-debian \fR[\fB\-nb\fR] \fIbug\fR...
+.B import\-bug\-from\-debian \fR[\fIoptions\fR] \fIbug\fR...
 .br
 .B import\-bug\-from\-debian \-h
 
@@ -28,6 +28,11 @@ Display a help message and exit.
 Use the specified instance of Launchpad (e.g. "staging"), instead of
 the default of "production".
 .TP
+.B \-p \fIPACKAGE\fR, \fB\-\-package\fR=\fIPACKAGE\fR
+Launchpad package to file bug against, if not the same source package
+name as Debian.
+Useful for importing removal bugs filed against \fBftp.debian.org\fR.
+.TP
 .B \-\-no\-conf
 Do not read any configuration files, or configuration from environment
 variables.
diff --git a/import-bug-from-debian b/import-bug-from-debian
index fa1e250..a5b4e06 100755
--- a/import-bug-from-debian
+++ b/import-bug-from-debian
@@ -54,6 +54,10 @@ def main():
     parser.add_option("-n", "--dry-run",
                       help=SUPPRESS_HELP,
                       dest="lpinstance", action="store_const", const="staging")
+    parser.add_option("-p", "--package", metavar="PACKAGE",
+                      help="Launchpad package to file bug against "
+                           "(default: Same as Debian)",
+                      dest="package", default=None)
     parser.add_option("--no-conf", dest="no_conf", default=False,
                       help="Don't read config files or environment variables.",
                       action="store_true")
@@ -96,15 +100,21 @@ def main():
     for bug in bugs:
         bug = bug.value
         package = bug.package
+        ubupackage = package
+        if options.package:
+            ubupackage = options.package
         bug_num = bug.bug_num
         subject = bug.subject
         log = debbugs.get_bug_log(bug_num)
         summary = log[0][0]
-        target = ubuntu.getSourcePackage(name=package)
+        target = ubuntu.getSourcePackage(name=ubupackage)
         u_bug = launchpad.bugs.createBug(target=target, title=subject,
                 description="Imported from Debian bug %d:\n\n%s"
                     % (bug_num, summary))
-        d_task = u_bug.addTask(target=debian.getSourcePackage(name=package))
+        d_sp = debian.getSourcePackage(name=package)
+        if d_sp is None and options.package:
+            d_sp = debian.getSourcePackage(name=options.package)
+        d_task = u_bug.addTask(target=d_sp)
         d_watch = u_bug.addWatch(remote_bug=bug_num, bug_tracker=lp_debbugs)
         d_task.bug_watch = d_watch
         d_task.lp_save()

From ec5abfe6f2063adeb706b15c49f4af05d0c13f32 Mon Sep 17 00:00:00 2001
From: Stefano Rivera <stefanor@ubuntu.com>
Date: Tue, 4 Jan 2011 22:26:24 +0200
Subject: [PATCH 05/17] Include BTS URL, as launchpad links 'bug XYZ' to LP:
 #XYZ

---
 import-bug-from-debian | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/import-bug-from-debian b/import-bug-from-debian
index a5b4e06..e397bae 100755
--- a/import-bug-from-debian
+++ b/import-bug-from-debian
@@ -109,8 +109,9 @@ def main():
         summary = log[0][0]
         target = ubuntu.getSourcePackage(name=ubupackage)
         u_bug = launchpad.bugs.createBug(target=target, title=subject,
-                description="Imported from Debian bug %d:\n\n%s"
-                    % (bug_num, summary))
+                description='Imported from Debian bug '
+                            'http://bugs.debian.org/%d:\n\n%s'
+                            % (bug_num, summary))
         d_sp = debian.getSourcePackage(name=package)
         if d_sp is None and options.package:
             d_sp = debian.getSourcePackage(name=options.package)

From 5d642ab04230b9915ab301c57b25a5c3eb1a8aae Mon Sep 17 00:00:00 2001
From: Stefano Rivera <stefanor@ubuntu.com>
Date: Wed, 5 Jan 2011 09:45:31 +0200
Subject: [PATCH 06/17] Typo

---
 debian/changelog | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/debian/changelog b/debian/changelog
index 94a6bed..cbbcd4c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -30,7 +30,7 @@ ubuntu-dev-tools (0.109) UNRELEASED; urgency=low
   * pull-lp-source: Support -d (LP: #681699)
   * suspicious-source: Whitelist Python source code.
   * import-bug-from-debian: Add --package option, for importing bugs from
-    psuedo-packages.
+    pseudo-packages.
 
   [ Michael Bienia ]
   * ubuntutools/lp/lpapicache.py: Allow easier selection of 'staging' as LP

From 1e5b8d0e5b8550d77019ec4058d034dd803c2abc Mon Sep 17 00:00:00 2001
From: Luca Falavigna <dktrkranz@debian.org>
Date: Thu, 6 Jan 2011 23:22:35 +0100
Subject: [PATCH 07/17] Remove myself from Uploaders

---
 debian/control | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/debian/control b/debian/control
index 89c9ee7..82fe296 100644
--- a/debian/control
+++ b/debian/control
@@ -2,8 +2,7 @@ Source: ubuntu-dev-tools
 Section: devel
 Priority: optional
 Maintainer: Ubuntu Developers <ubuntu-dev-team@lists.alioth.debian.org>
-Uploaders: Luca Falavigna <dktrkranz@debian.org>,
-           Benjamin Drung <bdrung@ubuntu.com>
+Uploaders: Benjamin Drung <bdrung@ubuntu.com>
 Vcs-Bzr: lp:ubuntu-dev-tools
 Vcs-Browser: https://code.launchpad.net/~ubuntu-dev/ubuntu-dev-tools/trunk
 Build-Depends: dctrl-tools,

From b37b89865391493a43d05373acfb6d99a4d8d756 Mon Sep 17 00:00:00 2001
From: Benjamin Drung <bdrung@ubuntu.com>
Date: Fri, 7 Jan 2011 00:04:56 +0100
Subject: [PATCH 08/17] Update my email address and remove DM-Upload-Allowed.

---
 debian/control | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/debian/control b/debian/control
index 82fe296..372e831 100644
--- a/debian/control
+++ b/debian/control
@@ -2,7 +2,7 @@ Source: ubuntu-dev-tools
 Section: devel
 Priority: optional
 Maintainer: Ubuntu Developers <ubuntu-dev-team@lists.alioth.debian.org>
-Uploaders: Benjamin Drung <bdrung@ubuntu.com>
+Uploaders: Benjamin Drung <bdrung@debian.org>
 Vcs-Bzr: lp:ubuntu-dev-tools
 Vcs-Browser: https://code.launchpad.net/~ubuntu-dev/ubuntu-dev-tools/trunk
 Build-Depends: dctrl-tools,
@@ -22,7 +22,6 @@ Build-Depends: dctrl-tools,
                python-setuptools,
                python-soappy,
                python-unittest2
-DM-Upload-Allowed: yes
 X-Python-Version: >= 2.5
 Homepage: https://launchpad.net/ubuntu-dev-tools
 Standards-Version: 3.9.1

From 8d12afe1e9167b5a9e20ae7da46bd26abf7f74a8 Mon Sep 17 00:00:00 2001
From: Martin Pitt <martin.pitt@canonical.com>
Date: Thu, 13 Jan 2011 19:10:37 -0600
Subject: [PATCH 09/17] Add check-mir script: Check components of build
 dependencies and warn about universe/multiverse ones, for a package destined
 for main/restricted. Add doc/check-mir.1 manpage.

---
 check-mir        | 101 +++++++++++++++++++++++++++++++++++++++++++++++
 debian/changelog |   5 +++
 doc/check-mir.1  |  18 +++++++++
 setup.py         |   1 +
 4 files changed, 125 insertions(+)
 create mode 100755 check-mir
 create mode 100644 doc/check-mir.1

diff --git a/check-mir b/check-mir
new file mode 100755
index 0000000..aad9f8b
--- /dev/null
+++ b/check-mir
@@ -0,0 +1,101 @@
+#!/usr/bin/python
+#
+# Check components of build dependencies and warn about universe/multiverse
+# ones, for a package destined for main/restricted
+#
+# Copyright (C) 2011 Canonical
+#
+# Authors:
+#  Martin Pitt
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation; version 3.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import apt, sys, os.path
+
+apt_cache = apt.Cache()
+
+def check_support(pkgname, alt=False):
+    '''Check if pkgname is in main or restricted.
+
+    This prints messages if a package is not in main/restricted, or only
+    partially (i.  e. source in main, but binary in universe).
+    '''
+    if alt:
+        prefix = '  ... alternative ' + pkgname
+    else:
+        prefix = ' * ' + pkgname
+
+    try:
+        pkg = apt_cache[pkgname]
+    except KeyError:
+        print >> sys.stderr, pkgname, 'does not exist (pure virtual?)'
+        return False
+    
+    section = pkg.candidate.section
+    if section.startswith('universe') or section.startswith('multiverse'):
+        # check if the source package is in main and thus will only need binary
+        # promotion
+        sr = apt.apt_pkg.SourceRecords()
+        if not sr.lookup(pkg.candidate.source_name):
+            print >> sys.stderr, 'ERROR: Cannot lookup source package for', pkg.name
+            print prefix, 'package is in', section.split('/')[0]
+            return False
+        src = apt.apt_pkg.TagSection(sr.record)
+        if src['Section'].startswith('universe') or src['Section'].startswith('multiverse'):
+            print prefix, 'binary and source package is in', section.split('/')[0]
+            return False
+        else:
+            print prefix, 'is in', section.split('/')[0] + ', but its source', pkg.candidate.source_name, 'is already in main; file an ubuntu-archive bug for promoting the current preferred alternative'
+            return True
+
+    if alt:
+        print prefix, 'is already in main; consider preferring it'
+
+    return True
+
+
+#
+# main
+#
+
+if not os.path.exists('debian/control'):
+    print >> sys.stderr, 'debian/control not found. You need to run this tool in a source package directory'
+    sys.exit(1)
+
+print 'Checking support status of build dependencies...'
+
+# get build dependencies from debian/control
+control=apt.apt_pkg.TagFile(open('debian/control'))
+control.next()
+
+
+any_unsupported = False
+
+for field in ('Build-Depends', 'Build-Depends-Indep'):
+    if field not in control.section:
+        continue
+    for or_group in apt.apt_pkg.parse_src_depends(control.section[field]):
+        pkgname = or_group[0][0]
+        if not check_support(pkgname):
+            # check non-preferred alternatives
+            for altpkg in or_group[1:]:
+                if check_support(altpkg[0], alt=True):
+                    break
+            else:
+                any_unsupported = True
+
+if any_unsupported:
+    print '\nPlease check https://wiki.ubuntu.com/MainInclusionProcess if this source package needs to get into in main/restricted, or reconsider if the package really needs above dependencies.'
+else:
+    print 'All build dependencies are supported in main or restricted.'
diff --git a/debian/changelog b/debian/changelog
index cbbcd4c..bea2526 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -54,6 +54,11 @@ ubuntu-dev-tools (0.109) UNRELEASED; urgency=low
   * add "add-patch" that provides the non-interactive version of
     edit-patch
 
+  [ Martin Pitt ]
+  * Add check-mir script: Check components of build dependencies and warn
+    about universe/multiverse ones, for a package destined for
+    main/restricted. Add doc/check-mir.1 manpage.
+
  -- Stefano Rivera <stefanor@ubuntu.com>  Tue, 04 Jan 2011 22:23:20 +0200
 
 ubuntu-dev-tools (0.108) experimental; urgency=low
diff --git a/doc/check-mir.1 b/doc/check-mir.1
new file mode 100644
index 0000000..8c5a131
--- /dev/null
+++ b/doc/check-mir.1
@@ -0,0 +1,18 @@
+.TH check\-mir "1" "13 January 2011" "ubuntu-dev-tools"
+.SH NAME
+check\-mir \- check support status of dependencies
+
+.SH SYNOPSIS
+.B check\-build\-deps
+
+.SH DESCRIPTION
+This script checks if any of a package's build or binary dependencies is
+in universe/multiverse. If the source package is destined for Ubuntu main or
+restricted, these either need to be eliminated or need to be promoted to main,
+following \fBhttps://wiki.ubuntu.com/MainInclusionProcess\fR.
+
+There are no options, just run it in a source package directory.
+
+.SH AUTHOR
+.B check\-mir
+was written by Martin Pitt <martin.pitt@ubuntu.com>.
diff --git a/setup.py b/setup.py
index d084c81..5e1117b 100755
--- a/setup.py
+++ b/setup.py
@@ -15,6 +15,7 @@ if os.path.exists(changelog):
 
 scripts = ['404main',
            'backportpackage',
+           'check-mir',
            'check-symbols',
            'dch-repeat',
            'dgetlp',

From 1961071ff3f29c58f3440727f3416d07c54f04fe Mon Sep 17 00:00:00 2001
From: Martin Pitt <martin.pitt@canonical.com>
Date: Thu, 13 Jan 2011 19:16:38 -0600
Subject: [PATCH 10/17] releasing version 0.109

---
 debian/changelog | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index bea2526..d73bc0b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-ubuntu-dev-tools (0.109) UNRELEASED; urgency=low
+ubuntu-dev-tools (0.109) natty; urgency=low
 
   [ Stefano Rivera ]
   * Convert debian/copyright to DEP5, make sure all scripts are listed
@@ -59,7 +59,7 @@ ubuntu-dev-tools (0.109) UNRELEASED; urgency=low
     about universe/multiverse ones, for a package destined for
     main/restricted. Add doc/check-mir.1 manpage.
 
- -- Stefano Rivera <stefanor@ubuntu.com>  Tue, 04 Jan 2011 22:23:20 +0200
+ -- Martin Pitt <martin.pitt@ubuntu.com>  Thu, 13 Jan 2011 19:16:33 -0600
 
 ubuntu-dev-tools (0.108) experimental; urgency=low
 

From 887160966040284069570b5b677766fefb21f48f Mon Sep 17 00:00:00 2001
From: Martin Pitt <martin.pitt@canonical.com>
Date: Thu, 13 Jan 2011 19:24:22 -0600
Subject: [PATCH 11/17] doc/check-mir.1: Fix typo.

---
 debian/changelog | 6 ++++++
 doc/check-mir.1  | 2 +-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/debian/changelog b/debian/changelog
index d73bc0b..a96996e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+ubuntu-dev-tools (0.110) UNRELEASED; urgency=low
+
+  * doc/check-mir.1: Fix typo.
+
+ -- Martin Pitt <martin.pitt@ubuntu.com>  Thu, 13 Jan 2011 19:24:07 -0600
+
 ubuntu-dev-tools (0.109) natty; urgency=low
 
   [ Stefano Rivera ]
diff --git a/doc/check-mir.1 b/doc/check-mir.1
index 8c5a131..53eb6ac 100644
--- a/doc/check-mir.1
+++ b/doc/check-mir.1
@@ -3,7 +3,7 @@
 check\-mir \- check support status of dependencies
 
 .SH SYNOPSIS
-.B check\-build\-deps
+.B check\-mir
 
 .SH DESCRIPTION
 This script checks if any of a package's build or binary dependencies is

From 8460bb2bdf4802874518572e09edbab2983ae481 Mon Sep 17 00:00:00 2001
From: Martin Pitt <martin.pitt@canonical.com>
Date: Thu, 13 Jan 2011 19:24:40 -0600
Subject: [PATCH 12/17] check-mir: Check binary dependencies, too.

---
 check-mir        | 26 ++++++++++++++++++++++++--
 debian/changelog |  1 +
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/check-mir b/check-mir
index aad9f8b..dac85bf 100755
--- a/check-mir
+++ b/check-mir
@@ -39,7 +39,7 @@ def check_support(pkgname, alt=False):
     try:
         pkg = apt_cache[pkgname]
     except KeyError:
-        print >> sys.stderr, pkgname, 'does not exist (pure virtual?)'
+        print >> sys.stderr, prefix, 'does not exist (pure virtual?)'
         return False
     
     section = pkg.candidate.section
@@ -95,7 +95,29 @@ for field in ('Build-Depends', 'Build-Depends-Indep'):
             else:
                 any_unsupported = True
 
+print '\nChecking support status of binary dependencies...'
+while True:
+    try:
+        control.next()
+    except StopIteration:
+        break
+
+    for field in ('Depends', 'Pre-Depends', 'Recommends'):
+        if field not in control.section:
+            continue
+        for or_group in apt.apt_pkg.parse_depends(control.section[field]):
+            pkgname = or_group[0][0]
+            if pkgname.startswith('$'):
+                continue
+            if not check_support(pkgname):
+                # check non-preferred alternatives
+                for altpkg in or_group[1:]:
+                    if check_support(altpkg[0], alt=True):
+                        break
+                else:
+                    any_unsupported = True
+
 if any_unsupported:
     print '\nPlease check https://wiki.ubuntu.com/MainInclusionProcess if this source package needs to get into in main/restricted, or reconsider if the package really needs above dependencies.'
 else:
-    print 'All build dependencies are supported in main or restricted.'
+    print 'All dependencies are supported in main or restricted.'
diff --git a/debian/changelog b/debian/changelog
index a96996e..d99f313 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,7 @@
 ubuntu-dev-tools (0.110) UNRELEASED; urgency=low
 
   * doc/check-mir.1: Fix typo.
+  * check-mir: Check binary dependencies, too.
 
  -- Martin Pitt <martin.pitt@ubuntu.com>  Thu, 13 Jan 2011 19:24:07 -0600
 

From 8cb609f2b2c1e01856ec306ecabd5079dd1cdc22 Mon Sep 17 00:00:00 2001
From: Martin Pitt <martin.pitt@canonical.com>
Date: Thu, 13 Jan 2011 19:28:18 -0600
Subject: [PATCH 13/17] debian/control: Add check-mir to package description.

---
 debian/changelog | 1 +
 debian/control   | 1 +
 2 files changed, 2 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index d99f313..34793ae 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,6 +2,7 @@ ubuntu-dev-tools (0.110) UNRELEASED; urgency=low
 
   * doc/check-mir.1: Fix typo.
   * check-mir: Check binary dependencies, too.
+  * debian/control: Add check-mir to package description.
 
  -- Martin Pitt <martin.pitt@ubuntu.com>  Thu, 13 Jan 2011 19:24:07 -0600
 
diff --git a/debian/control b/debian/control
index 372e831..67c613e 100644
--- a/debian/control
+++ b/debian/control
@@ -66,6 +66,7 @@ Description: useful tools for Ubuntu developers
  .
   - 404main - used to check what components a package's deps are in, for
     doing a main inclusion report for example.
+  - check-mir - check support status of build/binary dependencies
   - check-symbols - will compare and give you a diff of the exported symbols of
     all .so files in a binary package.
   - dch-repeat - used to repeat a change log into an older release.

From 15beff979ff803b3ed5a9abbc2cc17c625e6a238 Mon Sep 17 00:00:00 2001
From: Martin Pitt <martin.pitt@canonical.com>
Date: Thu, 13 Jan 2011 19:28:27 -0600
Subject: [PATCH 14/17] releasing version 0.110

---
 debian/changelog | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 34793ae..1cb3540 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,10 +1,10 @@
-ubuntu-dev-tools (0.110) UNRELEASED; urgency=low
+ubuntu-dev-tools (0.110) natty; urgency=low
 
   * doc/check-mir.1: Fix typo.
   * check-mir: Check binary dependencies, too.
   * debian/control: Add check-mir to package description.
 
- -- Martin Pitt <martin.pitt@ubuntu.com>  Thu, 13 Jan 2011 19:24:07 -0600
+ -- Martin Pitt <martin.pitt@ubuntu.com>  Thu, 13 Jan 2011 19:28:20 -0600
 
 ubuntu-dev-tools (0.109) natty; urgency=low
 

From 45317aa8e06134daee04630af3f04dad103e8c90 Mon Sep 17 00:00:00 2001
From: Martin Pitt <martin.pitt@canonical.com>
Date: Thu, 13 Jan 2011 20:14:52 -0600
Subject: [PATCH 15/17] ubuntutools/test/test_help.py: Blacklist --help test
 for check-mir, it does not have help. Fixes FTBFS on the buildd.

---
 debian/changelog              | 7 +++++++
 ubuntutools/test/test_help.py | 1 +
 2 files changed, 8 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 1cb3540..bfc9470 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+ubuntu-dev-tools (0.111) UNRELEASED; urgency=low
+
+  * ubuntutools/test/test_help.py: Blacklist --help test for check-mir, it
+    does not have help. Fixes FTBFS on the buildd.
+
+ -- Martin Pitt <martin.pitt@ubuntu.com>  Thu, 13 Jan 2011 20:14:35 -0600
+
 ubuntu-dev-tools (0.110) natty; urgency=low
 
   * doc/check-mir.1: Fix typo.
diff --git a/ubuntutools/test/test_help.py b/ubuntutools/test/test_help.py
index 4f402d1..d405d17 100644
--- a/ubuntutools/test/test_help.py
+++ b/ubuntutools/test/test_help.py
@@ -25,6 +25,7 @@ import setup
 from ubuntutools.test import unittest
 
 BLACKLIST = {
+    'check-mir': 'No Help',
     'check-symbols': 'No Help',
     'edit-patch': 'No Help',
     'get-build-deps': 'No Help, runs sudo',

From 4c299794a9786e47e5c100b9e6b4d488bb82652e Mon Sep 17 00:00:00 2001
From: Martin Pitt <martin.pitt@canonical.com>
Date: Thu, 13 Jan 2011 20:15:44 -0600
Subject: [PATCH 16/17] releasing version 0.111

---
 debian/changelog | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index bfc9470..3f14316 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,9 +1,9 @@
-ubuntu-dev-tools (0.111) UNRELEASED; urgency=low
+ubuntu-dev-tools (0.111) natty; urgency=low
 
   * ubuntutools/test/test_help.py: Blacklist --help test for check-mir, it
     does not have help. Fixes FTBFS on the buildd.
 
- -- Martin Pitt <martin.pitt@ubuntu.com>  Thu, 13 Jan 2011 20:14:35 -0600
+ -- Martin Pitt <martin.pitt@ubuntu.com>  Thu, 13 Jan 2011 20:15:41 -0600
 
 ubuntu-dev-tools (0.110) natty; urgency=low
 

From a99497b5ce06ad0cf9431284b9540df6f61f82fc Mon Sep 17 00:00:00 2001
From: Benjamin Drung <bdrung@ubuntu.com>
Date: Fri, 14 Jan 2011 11:09:21 +0100
Subject: [PATCH 17/17] Make pylint happy about check-mir.

---
 check-mir | 136 +++++++++++++++++++++++++++++++-----------------------
 1 file changed, 78 insertions(+), 58 deletions(-)

diff --git a/check-mir b/check-mir
index dac85bf..4f4686e 100755
--- a/check-mir
+++ b/check-mir
@@ -21,15 +21,15 @@
 # this program; if not, write to the Free Software Foundation, Inc.,
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
-import apt, sys, os.path
+import apt
+import sys
+import os.path
 
-apt_cache = apt.Cache()
-
-def check_support(pkgname, alt=False):
+def check_support(apt_cache, pkgname, alt=False):
     '''Check if pkgname is in main or restricted.
 
     This prints messages if a package is not in main/restricted, or only
-    partially (i.  e. source in main, but binary in universe).
+    partially (i. e. source in main, but binary in universe).
     '''
     if alt:
         prefix = '  ... alternative ' + pkgname
@@ -46,17 +46,23 @@ def check_support(pkgname, alt=False):
     if section.startswith('universe') or section.startswith('multiverse'):
         # check if the source package is in main and thus will only need binary
         # promotion
-        sr = apt.apt_pkg.SourceRecords()
-        if not sr.lookup(pkg.candidate.source_name):
-            print >> sys.stderr, 'ERROR: Cannot lookup source package for', pkg.name
+        source_records = apt.apt_pkg.SourceRecords()
+        if not source_records.lookup(pkg.candidate.source_name):
+            print >> sys.stderr, 'ERROR: Cannot lookup source package for', \
+                                 pkg.name
             print prefix, 'package is in', section.split('/')[0]
             return False
-        src = apt.apt_pkg.TagSection(sr.record)
-        if src['Section'].startswith('universe') or src['Section'].startswith('multiverse'):
-            print prefix, 'binary and source package is in', section.split('/')[0]
+        src = apt.apt_pkg.TagSection(source_records.record)
+        if (src['Section'].startswith('universe') or
+            src['Section'].startswith('multiverse')):
+            print prefix, 'binary and source package is in', \
+                  section.split('/')[0]
             return False
         else:
-            print prefix, 'is in', section.split('/')[0] + ', but its source', pkg.candidate.source_name, 'is already in main; file an ubuntu-archive bug for promoting the current preferred alternative'
+            print prefix, 'is in', section.split('/')[0] + ', but its source', \
+                  pkg.candidate.source_name, \
+                  ('is already in main; file an ubuntu-archive bug for '
+                   'promoting the current preferred alternative')
             return True
 
     if alt:
@@ -64,60 +70,74 @@ def check_support(pkgname, alt=False):
 
     return True
 
+def check_build_dependencies(apt_cache, control):
+    print 'Checking support status of build dependencies...'
 
-#
-# main
-#
+    any_unsupported = False
 
-if not os.path.exists('debian/control'):
-    print >> sys.stderr, 'debian/control not found. You need to run this tool in a source package directory'
-    sys.exit(1)
-
-print 'Checking support status of build dependencies...'
-
-# get build dependencies from debian/control
-control=apt.apt_pkg.TagFile(open('debian/control'))
-control.next()
-
-
-any_unsupported = False
-
-for field in ('Build-Depends', 'Build-Depends-Indep'):
-    if field not in control.section:
-        continue
-    for or_group in apt.apt_pkg.parse_src_depends(control.section[field]):
-        pkgname = or_group[0][0]
-        if not check_support(pkgname):
-            # check non-preferred alternatives
-            for altpkg in or_group[1:]:
-                if check_support(altpkg[0], alt=True):
-                    break
-            else:
-                any_unsupported = True
-
-print '\nChecking support status of binary dependencies...'
-while True:
-    try:
-        control.next()
-    except StopIteration:
-        break
-
-    for field in ('Depends', 'Pre-Depends', 'Recommends'):
+    for field in ('Build-Depends', 'Build-Depends-Indep'):
         if field not in control.section:
             continue
-        for or_group in apt.apt_pkg.parse_depends(control.section[field]):
+        for or_group in apt.apt_pkg.parse_src_depends(control.section[field]):
             pkgname = or_group[0][0]
-            if pkgname.startswith('$'):
-                continue
-            if not check_support(pkgname):
+            if not check_support(apt_cache, pkgname):
                 # check non-preferred alternatives
                 for altpkg in or_group[1:]:
-                    if check_support(altpkg[0], alt=True):
+                    if check_support(apt_cache, altpkg[0], alt=True):
                         break
                 else:
                     any_unsupported = True
 
-if any_unsupported:
-    print '\nPlease check https://wiki.ubuntu.com/MainInclusionProcess if this source package needs to get into in main/restricted, or reconsider if the package really needs above dependencies.'
-else:
-    print 'All dependencies are supported in main or restricted.'
+    return any_unsupported
+
+def check_binary_dependencies(apt_cache, control):
+    any_unsupported = False
+
+    print '\nChecking support status of binary dependencies...'
+    while True:
+        try:
+            control.next()
+        except StopIteration:
+            break
+
+        for field in ('Depends', 'Pre-Depends', 'Recommends'):
+            if field not in control.section:
+                continue
+            for or_group in apt.apt_pkg.parse_depends(control.section[field]):
+                pkgname = or_group[0][0]
+                if pkgname.startswith('$'):
+                    continue
+                if not check_support(apt_cache, pkgname):
+                    # check non-preferred alternatives
+                    for altpkg in or_group[1:]:
+                        if check_support(apt_cache, altpkg[0], alt=True):
+                            break
+                    else:
+                        any_unsupported = True
+
+    return any_unsupported
+
+def main():
+    apt_cache = apt.Cache()
+
+    if not os.path.exists('debian/control'):
+        print >> sys.stderr, ('debian/control not found. You need to run '
+                              'this tool in a source package directory')
+        sys.exit(1)
+
+    # get build dependencies from debian/control
+    control = apt.apt_pkg.TagFile(open('debian/control'))
+    control.next()
+
+    unsupported_build_deps = check_build_dependencies(apt_cache, control)
+    unsupported_binary_deps = check_binary_dependencies(apt_cache, control)
+
+    if unsupported_build_deps or unsupported_binary_deps:
+        print ('\nPlease check https://wiki.ubuntu.com/MainInclusionProcess if '
+               'this source package needs to get into in main/restricted, or '
+               'reconsider if the package really needs above dependencies.')
+    else:
+        print 'All dependencies are supported in main or restricted.'
+
+if __name__ == '__main__':
+    main()