[jhbuild/desrt/master: 8/8] systeminstall: add new backend for Debian



commit 10f4c04e1b2be2b953eeef8fc90888feb86b549b
Author: Ryan Lortie <desrt desrt ca>
Date:   Fri Jan 2 13:37:11 2015 -0500

    systeminstall: add new backend for Debian
    
    Add a new systeminstall backend for popular Debian-based distributions.
    
    This backend uses a hardcoded package map for currently-interesting
    releases of Debian and Ubuntu.
    
    A script is included for keeping the mapping file up to date.

 jhbuild/utils/Makefile.am      |    1 +
 jhbuild/utils/debian_data.py   |  229 ++++++++++++++++++++++++++++++++++++++++
 jhbuild/utils/systeminstall.py |   43 ++++++++-
 scripts/debian-sysdeps.py      |  168 +++++++++++++++++++++++++++++
 4 files changed, 440 insertions(+), 1 deletions(-)
---
diff --git a/jhbuild/utils/Makefile.am b/jhbuild/utils/Makefile.am
index 3234930..1bb0d24 100644
--- a/jhbuild/utils/Makefile.am
+++ b/jhbuild/utils/Makefile.am
@@ -3,6 +3,7 @@ appdir = $(pythondir)/jhbuild/utils/
 app_PYTHON = \
        __init__.py \
        cmds.py \
+       debian_data.py \
        fileutils.py \
        httpcache.py \
        lockfile.py \
diff --git a/jhbuild/utils/debian_data.py b/jhbuild/utils/debian_data.py
new file mode 100644
index 0000000..2560c77
--- /dev/null
+++ b/jhbuild/utils/debian_data.py
@@ -0,0 +1,229 @@
+# this file was generated by scripts/debian-sysdeps.py
+
+# scanning 'debian-7'
+# warning: debian-7: unable to locate dependency 'path:ruby'
+# warning: debian-7: unable to locate dependency 'pkgconfig:json-c'
+# warning: debian-7: unable to locate dependency 'pkgconfig:mozjs-17.0'
+# warning: debian-7: unable to locate dependency 'pkgconfig:mozjs-24'
+# warning: debian-7: unable to locate dependency 'pkgconfig:python2'
+# warning: debian-7: unable to locate dependency 'pkgconfig:smbclient'
+# warning: debian-7: unable to locate dependency 'pkgconfig:webkit2gtk-4.0'
+# scanning 'debian-8'
+# warning: debian-8: unable to locate dependency 'pkgconfig:mozjs-17.0'
+# scanning 'ubuntu-14.04'
+# warning: ubuntu-14.04: unable to locate dependency 'pkgconfig:webkit2gtk-4.0'
+# scanning 'ubuntu-14.10'
+# warning: ubuntu-14.10: unable to locate dependency 'pkgconfig:webkit2gtk-4.0'
+# scanning 'ubuntu-15.04'
+# warning: ubuntu-15.04: unable to locate dependency 'pkgconfig:mozjs-17.0'
+
+package_lists = {
+  'common': {
+    'c_include:X11/extensions/Xinerama.h': ['libdevel/libxinerama-dev'],
+    'c_include:crack.h': ['libdevel/libcrack2-dev'],
+    'c_include:expat.h': ['libdevel/libexpat1-dev'],
+    'c_include:ltdl.h': ['libdevel/libltdl-dev'],
+    'c_include:mpfr.h': ['libdevel/libmpfr-dev'],
+    'c_include:readline/readline.h': ['libdevel/libreadline-gplv2-dev', 'libdevel/libreadline6-dev'],
+    'c_include:security/pam_appl.h': ['libdevel/libpam0g-dev'],
+    'c_include:sys/capability.h': ['libdevel/libcap-dev'],
+    'c_include:webp/decode.h': ['libdevel/libwebp-dev'],
+    'c_include:yaml.h': ['libdevel/libyaml-dev'],
+    'path:c++': ['g++', 'clang'],
+    'path:cc': ['gcc', 'clang'],
+    'path:cups-config': ['libdevel/libcups2-dev'],
+    'path:gperf': ['devel/gperf'],
+    'path:intltoolize': ['devel/intltool'],
+    'path:libtoolize': ['devel/libtool'],
+    'path:makeinfo': ['text/texinfo'],
+    'path:msgfmt': ['devel/gettext'],
+    'path:wget': ['web/wget'],
+    'path:xmllint': ['text/libxml2-utils'],
+    'path:xsltproc': ['text/xsltproc'],
+    'pkgconfig:alsa': ['libdevel/libasound2-dev'],
+    'pkgconfig:avahi-gobject': ['libdevel/libavahi-gobject-dev'],
+    'pkgconfig:cairomm-1.0': ['libdevel/libcairomm-1.0-dev'],
+    'pkgconfig:dbus-1': ['libdevel/libdbus-1-dev'],
+    'pkgconfig:dbus-glib-1': ['libdevel/libdbus-glib-1-dev'],
+    'pkgconfig:egl': ['libdevel/libegl1-mesa-dev'],
+    'pkgconfig:enchant': ['libdevel/libenchant-dev'],
+    'pkgconfig:exempi-2.0': ['libdevel/libexempi-dev'],
+    'pkgconfig:flac': ['libdevel/libflac-dev'],
+    'pkgconfig:fontconfig': ['libdevel/libfontconfig1-dev'],
+    'pkgconfig:freetype2': ['libdevel/libfreetype6-dev'],
+    'pkgconfig:gbm': ['libdevel/libgbm-dev'],
+    'pkgconfig:gmime-2.6': ['libdevel/libgmime-2.6-dev'],
+    'pkgconfig:icu-i18n': ['libdevel/libicu-dev'],
+    'pkgconfig:kbproto': ['x11/x11proto-kb-dev'],
+    'pkgconfig:lcms2': ['libdevel/liblcms2-dev'],
+    'pkgconfig:libarchive': ['libdevel/libarchive-dev'],
+    'pkgconfig:libcanberra-gtk': ['libdevel/libcanberra-gtk-dev'],
+    'pkgconfig:libdrm': ['libdevel/libdrm-dev'],
+    'pkgconfig:libexif': ['libdevel/libexif-dev'],
+    'pkgconfig:libffi': ['libdevel/libffi-dev'],
+    'pkgconfig:libical': ['libdevel/libical-dev'],
+    'pkgconfig:libpng': ['libdevel/libpng12-dev'],
+    'pkgconfig:libproxy-1.0': ['libdevel/libproxy-dev'],
+    'pkgconfig:libstartup-notification-1.0': ['libdevel/libstartup-notification0-dev'],
+    'pkgconfig:libusb-1.0': ['libdevel/libusb-1.0-0-dev'],
+    'pkgconfig:libv4l2': ['libdevel/libv4l-dev'],
+    'pkgconfig:libxklavier': ['libdevel/libxklavier-dev'],
+    'pkgconfig:libxml-2.0': ['libdevel/libxml2-dev'],
+    'pkgconfig:libxslt': ['libdevel/libxslt1-dev'],
+    'pkgconfig:nice': ['libdevel/libnice-dev'],
+    'pkgconfig:nspr': ['libdevel/libnspr4-dev'],
+    'pkgconfig:nss': ['libdevel/libnss3-dev'],
+    'pkgconfig:oauth': ['libdevel/liboauth-dev'],
+    'pkgconfig:p11-kit-1': ['libdevel/libp11-kit-dev'],
+    'pkgconfig:pixman-1': ['libdevel/libpixman-1-dev'],
+    'pkgconfig:poppler-glib': ['libdevel/libpoppler-glib-dev'],
+    'pkgconfig:py3cairo': ['python/python3-cairo-dev'],
+    'pkgconfig:python3': ['python/python3-dev'],
+    'pkgconfig:shared-mime-info': ['misc/shared-mime-info'],
+    'pkgconfig:sm': ['libdevel/libsm-dev'],
+    'pkgconfig:sndfile': ['libdevel/libsndfile1-dev'],
+    'pkgconfig:speex': ['libdevel/libspeex-dev'],
+    'pkgconfig:sqlite3': ['libdevel/libsqlite3-dev'],
+    'pkgconfig:taglib': ['libdevel/libtag1-dev'],
+    'pkgconfig:uuid': ['libdevel/uuid-dev'],
+    'pkgconfig:vpx': ['libdevel/libvpx-dev'],
+    'pkgconfig:wavpack': ['libdevel/libwavpack-dev'],
+    'pkgconfig:webkitgtk-3.0': ['libdevel/libwebkitgtk-3.0-dev'],
+    'pkgconfig:x11': ['libdevel/libx11-dev'],
+    'pkgconfig:xcb': ['libdevel/libxcb1-dev'],
+    'pkgconfig:xcb-dri2': ['libdevel/libxcb-dri2-0-dev'],
+    'pkgconfig:xcomposite': ['libdevel/libxcomposite-dev'],
+    'pkgconfig:xcursor': ['libdevel/libxcursor-dev'],
+    'pkgconfig:xdamage': ['libdevel/libxdamage-dev'],
+    'pkgconfig:xext': ['libdevel/libxext-dev'],
+    'pkgconfig:xfixes': ['libdevel/libxfixes-dev'],
+    'pkgconfig:xft': ['libdevel/libxft-dev'],
+    'pkgconfig:xkbfile': ['libdevel/libxkbfile-dev'],
+    'pkgconfig:xkeyboard-config': ['x11/xkb-data'],
+    'pkgconfig:xorg-macros': ['x11/xutils-dev'],
+    'pkgconfig:xproto': ['x11/x11proto-core-dev'],
+    'pkgconfig:xrandr': ['libdevel/libxrandr-dev'],
+    'pkgconfig:xt': ['libdevel/libxt-dev'],
+    'pkgconfig:xtrans': ['x11/xtrans-dev'],
+    'pkgconfig:xtst': ['libdevel/libxtst-dev'],
+    'python2:libxml2': ['python/python-libxml2'],
+    'xml:http://docbook.sourceforge.net/release/xsl/current/': ['docbook-xsl'],
+    '': []
+  },
+
+  'debian-7': {
+    'c_include:db.h': ['libdevel/libdb5.1-dev'],
+    'c_include:gcrypt.h': ['libdevel/libgcrypt11-dev'],
+    'c_include:jpeglib.h': ['oldlibs/libjpeg62-dev', 'libdevel/libjpeg8-dev'],
+    'c_include:tiff.h': ['libdevel/libtiff4-dev', 'libdevel/libtiff5-dev'],
+    'path:bison': ['devel/bison', 'devel/bison++'],
+    'path:flex': ['devel/flex', 'devel/flex-old'],
+    'path:ragel': ['devel/ragel'],
+    'path:rdfpipe': ['python/python-rdflib'],
+    'pkgconfig:gl': ['libdevel/libgl1-mesa-dev'],
+    'pkgconfig:gnutls': ['libdevel/libgnutls-dev'],
+    'pkgconfig:iso-codes': ['misc/iso-codes'],
+    'pkgconfig:libgphoto2': ['libdevel/libgphoto2-2-dev'],
+    'pkgconfig:libmusicbrainz5': ['libdevel/libmusicbrainz5-dev'],
+    'pkgconfig:libtasn1': ['libdevel/libtasn1-3-dev'],
+    '': []
+  },
+
+  'debian-8': {
+    'c_include:db.h': ['libdevel/libdb5.3-dev'],
+    'c_include:gcrypt.h': ['libdevel/libgcrypt20-dev'],
+    'c_include:jpeglib.h': ['libdevel/libjpeg62-turbo-dev', 'libdevel/libjpeg8-dev', 
'libdevel/libjpeg9-dev'],
+    'c_include:tiff.h': ['libdevel/libtiff5-dev'],
+    'path:bison': ['devel/bison', 'devel/bison++'],
+    'path:flex': ['devel/flex', 'devel/flex-old'],
+    'path:ragel': ['devel/ragel'],
+    'path:rdfpipe': ['python/python-rdflib-tools'],
+    'path:ruby': ['ruby/ruby'],
+    'pkgconfig:gl': ['libdevel/libgl1-mesa-dev', 'libdevel/libgl1-mesa-swx11-dev'],
+    'pkgconfig:gnutls': ['libdevel/libgnutls28-dev'],
+    'pkgconfig:iso-codes': ['misc/iso-codes'],
+    'pkgconfig:json-c': ['libdevel/libjson-c-dev'],
+    'pkgconfig:libgphoto2': ['libdevel/libgphoto2-dev'],
+    'pkgconfig:libmusicbrainz5': ['libdevel/libmusicbrainz5-dev'],
+    'pkgconfig:libtasn1': ['libdevel/libtasn1-6-dev'],
+    'pkgconfig:mozjs-24': ['libdevel/libmozjs-24-dev'],
+    'pkgconfig:python2': ['python/python-dev'],
+    'pkgconfig:smbclient': ['libdevel/libsmbclient-dev'],
+    'pkgconfig:webkit2gtk-4.0': ['libdevel/libwebkit2gtk-4.0-dev'],
+    '': []
+  },
+
+  'ubuntu-14.04': {
+    'c_include:db.h': ['libdevel/libdb5.3-dev', 'universe/libdevel/libdb6.0-dev', 
'universe/libdevel/libdb5.1-dev'],
+    'c_include:gcrypt.h': ['libdevel/libgcrypt11-dev', 'universe/libdevel/libgcrypt20-dev'],
+    'c_include:jpeglib.h': ['libdevel/libjpeg-turbo8-dev', 'libdevel/libjpeg62-dev'],
+    'c_include:tiff.h': ['libdevel/libtiff5-dev'],
+    'path:bison': ['devel/bison', 'universe/devel/bison++'],
+    'path:flex': ['devel/flex', 'universe/devel/flex-old'],
+    'path:ragel': ['universe/devel/ragel'],
+    'path:rdfpipe': ['python/python-rdflib'],
+    'path:ruby': ['interpreters/ruby'],
+    'pkgconfig:gl': ['libdevel/libgl1-mesa-dev'],
+    'pkgconfig:gnutls': ['libdevel/libgnutls-dev', 'universe/libdevel/libgnutls28-dev'],
+    'pkgconfig:iso-codes': ['libs/iso-codes'],
+    'pkgconfig:json-c': ['libdevel/libjson-c-dev'],
+    'pkgconfig:libgphoto2': ['libdevel/libgphoto2-dev'],
+    'pkgconfig:libmusicbrainz5': ['universe/libdevel/libmusicbrainz5-dev'],
+    'pkgconfig:libtasn1': ['libdevel/libtasn1-6-dev'],
+    'pkgconfig:mozjs-17.0': ['universe/libdevel/libmozjs-17.0-dev'],
+    'pkgconfig:mozjs-24': ['universe/libdevel/libmozjs-24-dev'],
+    'pkgconfig:python2': ['python/python-dev'],
+    'pkgconfig:smbclient': ['libdevel/libsmbclient-dev'],
+    '': []
+  },
+
+  'ubuntu-14.10': {
+    'c_include:db.h': ['libdevel/libdb5.3-dev', 'universe/libdevel/libdb5.1-dev'],
+    'c_include:gcrypt.h': ['libdevel/libgcrypt11-dev', 'libdevel/libgcrypt20-dev'],
+    'c_include:jpeglib.h': ['libdevel/libjpeg-turbo8-dev', 'libdevel/libjpeg62-dev'],
+    'c_include:tiff.h': ['libdevel/libtiff5-dev'],
+    'path:bison': ['devel/bison', 'universe/devel/bison++'],
+    'path:flex': ['devel/flex', 'universe/devel/flex-old'],
+    'path:ragel': ['universe/devel/ragel'],
+    'path:rdfpipe': ['universe/python/python-rdflib-tools'],
+    'path:ruby': ['interpreters/ruby'],
+    'pkgconfig:gl': ['libdevel/libgl1-mesa-dev'],
+    'pkgconfig:gnutls': ['libdevel/libgnutls-dev'],
+    'pkgconfig:iso-codes': ['libs/iso-codes'],
+    'pkgconfig:json-c': ['libdevel/libjson-c-dev'],
+    'pkgconfig:libgphoto2': ['libdevel/libgphoto2-dev'],
+    'pkgconfig:libmusicbrainz5': ['universe/libdevel/libmusicbrainz5-dev'],
+    'pkgconfig:libtasn1': ['libdevel/libtasn1-6-dev'],
+    'pkgconfig:mozjs-17.0': ['universe/libdevel/libmozjs-17.0-dev'],
+    'pkgconfig:mozjs-24': ['universe/libdevel/libmozjs-24-dev'],
+    'pkgconfig:python2': ['python/python-dev'],
+    'pkgconfig:smbclient': ['libdevel/libsmbclient-dev'],
+    '': []
+  },
+
+  'ubuntu-15.04': {
+    'c_include:db.h': ['libdevel/libdb5.3-dev'],
+    'c_include:gcrypt.h': ['libdevel/libgcrypt20-dev'],
+    'c_include:jpeglib.h': ['libdevel/libjpeg-turbo8-dev', 'libdevel/libjpeg62-dev'],
+    'c_include:tiff.h': ['libdevel/libtiff5-dev'],
+    'path:bison': ['devel/bison', 'universe/devel/bison++'],
+    'path:flex': ['devel/flex', 'universe/devel/flex-old'],
+    'path:ragel': ['universe/devel/ragel'],
+    'path:rdfpipe': ['universe/python/python-rdflib-tools'],
+    'path:ruby': ['interpreters/ruby'],
+    'pkgconfig:gl': ['libdevel/libgl1-mesa-dev'],
+    'pkgconfig:gnutls': ['libdevel/libgnutls-dev'],
+    'pkgconfig:iso-codes': ['libs/iso-codes'],
+    'pkgconfig:json-c': ['libdevel/libjson-c-dev'],
+    'pkgconfig:libgphoto2': ['libdevel/libgphoto2-dev'],
+    'pkgconfig:libmusicbrainz5': ['universe/libdevel/libmusicbrainz5-dev'],
+    'pkgconfig:libtasn1': ['libdevel/libtasn1-6-dev'],
+    'pkgconfig:mozjs-24': ['universe/libdevel/libmozjs-24-dev'],
+    'pkgconfig:python2': ['python/python-dev'],
+    'pkgconfig:smbclient': ['libdevel/libsmbclient-dev'],
+    'pkgconfig:webkit2gtk-4.0': ['universe/libdevel/libwebkit2gtk-4.0-dev'],
+    '': []
+  },
+
+  '': {}
+}
diff --git a/jhbuild/utils/systeminstall.py b/jhbuild/utils/systeminstall.py
index dfcbf6c..9e9ab26 100644
--- a/jhbuild/utils/systeminstall.py
+++ b/jhbuild/utils/systeminstall.py
@@ -24,6 +24,8 @@ import shlex
 import subprocess
 import pipes
 import imp
+import sysid
+import debian_data
 from StringIO import StringIO
 
 import cmds
@@ -333,6 +335,45 @@ class YumSystemInstall(SystemInstall):
         return cmds.has_command('yum')
 
 
+class DebianSystemInstall(SystemInstall):
+    def __init__(self):
+        SystemInstall.__init__(self)
+
+    def install(self, uninstalled):
+        myid = sysid.get_id()
+
+        package_list = dict(debian_data.package_lists[myid])
+        package_list.update(debian_data.package_lists['common'])
+
+        to_install = set()
+
+        logging.info(_("Using internal database for '%s' to find packages") % (myid,))
+
+        for modname, deptype, value in uninstalled:
+            depname = deptype + ':' + value
+
+            if depname in package_list:
+                # as below, just blindly take the first hit
+                to_install.add(package_list[depname][0].split('/')[-1])
+
+            else:
+                logging.info(_('No native package found for %(id)s '
+                               '(%(filename)s)') % {'id'       : modname,
+                                                    'filename' : depname})
+
+        if to_install:
+            logging.info(_('Installing: %(pkgs)s') % {'pkgs': ' '.join(sorted(to_install))})
+            args = self._root_command_prefix_args + ['apt-get', 'install']
+            args.extend(sorted(to_install))
+            subprocess.check_call(args)
+        else:
+            logging.info(_('Nothing to install'))
+
+    @classmethod
+    def detect(cls):
+        return sysid.get_id() in debian_data.package_lists
+
+
 class AptSystemInstall(SystemInstall):
     def __init__(self):
         SystemInstall.__init__(self)
@@ -384,7 +425,7 @@ class AptSystemInstall(SystemInstall):
         return cmds.has_command('apt-file')
 
 # Ordered from best to worst
-_classes = [AptSystemInstall, PKSystemInstall, YumSystemInstall]
+_classes = [DebianSystemInstall, AptSystemInstall, PKSystemInstall, YumSystemInstall]
 
 if __name__ == '__main__':
     logging.basicConfig(level=logging.INFO)
diff --git a/scripts/debian-sysdeps.py b/scripts/debian-sysdeps.py
new file mode 100755
index 0000000..92d693a
--- /dev/null
+++ b/scripts/debian-sysdeps.py
@@ -0,0 +1,168 @@
+#!/usr/bin/python2
+
+# Run this script like so:
+#
+#  jhbuild sysdeps --dump-all | ./debian-sysdeps.py debian_data.py
+
+import subprocess
+import gzip
+import sys
+import os
+
+# in general, we aim to support (roughly):
+#
+#  - Debian: oldstable, stable, testing, unstable
+#
+#  - Ubuntu: last LTS, last stable, current unstable
+#
+# note for Debian: sid seems to identify itself in os-release under the
+#                  codename of the current testing release, so we probably
+#                  won't see 'unstable' here separately
+releases = {
+  'debian-7':       'http://ftp.debian.org/debian/dists/wheezy/main',
+  'debian-8':       'http://ftp.debian.org/debian/dists/jessie/main',
+  'ubuntu-14.04':   'http://archive.ubuntu.com/ubuntu/dists/trusty',
+  'ubuntu-14.10':   'http://archive.ubuntu.com/ubuntu/dists/utopic',
+  'ubuntu-15.04':   'http://archive.ubuntu.com/ubuntu/dists/vivid'
+}
+
+# We always search using Contents-amd64 under the premise that the package
+# names for the dependency won't change depending on the arch.  We can
+# therefore freely hardcode 'x86_64-linue-gnu' below.
+#
+# python2 is currently a bit of a hack since we always assume 2.7, but
+# that seems to be a valid assumption for now
+c_include_paths = ['/usr/include', '/usr/include/x86_64-linux-gnu']
+pkgconfig_paths = ['/usr/lib/x86_64-linux-gnu/pkgconfig', '/usr/lib/pkgconfig', '/usr/share/pkgconfig']
+path_paths = ['/usr/bin', '/usr/sbin', '/bin', '/sbin']
+python2_paths = ['/usr/lib/python2.7/dist-packages']
+
+# things that we know we won't find, either because we're not clever
+# enough (xml) or because of alternatives (not listed in apt-file)
+hints = {
+  'xml:http://docbook.sourceforge.net/release/xsl/current/':         ['docbook-xsl'],
+  'path:cc':                                                         ['gcc', 'clang'],
+  'path:c++':                                                        ['g++', 'clang']
+}
+
+def add_paths(mapping, key, prefixes, name):
+    for p in prefixes:
+        filename = p[1:] + '/' + name
+        mapping[filename] = key
+
+def collect_depends(fp):
+    filemap = {}
+
+    for line in sys.stdin:
+        line = line.strip()
+        reqtype, _, name = line.partition(':')
+
+        if reqtype == 'path':
+            add_paths(filemap, line, path_paths, name)
+
+        elif reqtype =='c_include':
+            add_paths(filemap, line, c_include_paths, name)
+
+        elif reqtype == 'pkgconfig':
+            add_paths(filemap, line, pkgconfig_paths, name + '.pc')
+
+        elif reqtype == 'python2':
+            add_paths(filemap, line, python2_paths, name + '/__init__.py')
+            add_paths(filemap, line, python2_paths, name + '.py')
+
+        else:
+            filemap[line] = line
+
+    return filemap
+
+def find_interesting_lines(fp, search_items):
+    line = fp.next()
+    while True:
+        res = cmp(search_items[0], line)
+
+        if res > 0:
+            line = fp.next()
+
+        else:
+            # apt-file has a weird format -- it is whitespace-delimited
+            # but the filenames can also contain spaces...
+            # it is unlikely that we will find a filename that starts
+            # with the name of a file that we are looking for followed
+            # by a space...
+            if line.startswith(search_items[0]) and line[len(search_items[0])].isspace():
+                yield line.split()
+
+            del search_items[0]
+            if not search_items:
+                return
+
+def handle_distro(name, filemap, log = sys.stderr):
+    contents = gzip.open(name + '-Contents-amd64.gz')
+    keys = set(filemap.itervalues())
+    result = {}
+
+    while not contents.next().startswith('FILE'):
+        pass
+
+    for filename, pkgs in find_interesting_lines(contents, sorted(filemap)):
+        key = filemap[filename]
+        assert key not in result
+        result[key] = pkgs.split(',')
+
+    for key in sorted(keys):
+        if key not in result:
+            if key in hints:
+                result[key] = hints[key]
+            else:
+                log.write("# warning: %s: unable to locate dependency '%s'\n" % (name, key,))
+
+    return result
+
+def print_sorted_dict(outfile, name, items):
+    outfile.write('  %r: {\n' % (name,))
+    for key in sorted(items):
+        outfile.write('    %r: %r,\n' % (key, items[key]))
+    outfile.write("    '': []\n")
+    outfile.write('  },\n\n')
+
+def generate_debian_py(outfile, infile, log = sys.stderr):
+    outfile.write('# this file was generated by scripts/debian-sysdeps.py\n\n')
+
+    filemap = collect_depends(infile)
+    package_lists = {}
+    common = {}
+
+    for name in sorted(releases):
+        log.write("# scanning '%s'\n" % (name,))
+        package_lists[name] = handle_distro(name, filemap, log)
+
+    for dep in set(filemap.itervalues()):
+        pkgs = [dist.get(dep) for dist in package_lists.itervalues()]
+        if all(pkg == pkgs[0] for pkg in pkgs):
+            common[dep] = pkgs[0]
+            for dist in package_lists.itervalues():
+                del dist[dep]
+
+    outfile.write('\n')
+    outfile.write('package_lists = {\n')
+    print_sorted_dict(outfile, 'common', common)
+    for dist in sorted(package_lists):
+        print_sorted_dict(outfile, dist, package_lists[dist])
+    outfile.write("  '': {}\n}\n")
+
+def download_files(urls, filename):
+    for name, url in urls.iteritems():
+        fullname = name + '-' + filename
+        if not os.path.isfile(fullname):
+            subprocess.check_call(['wget', '-O', fullname + '.partial', url + '/' + filename])
+            os.rename(fullname + '.partial', fullname)
+
+if __name__ == '__main__':
+    if len(sys.argv) != 2:
+        sys.stderr.write("this script must be run with a single argument: the name of the output file\n")
+        sys.exit(1)
+
+    download_files(releases, 'Contents-amd64.gz')
+    output = open(sys.argv[1], 'w')
+    generate_debian_py(output, sys.stdin, log = output)
+    output.close()


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]