[jhbuild] Implement sysdeps --install for path systemmodules (GNOME bug 681344)



commit 0cb02c5f542ffaf7dbb3f4d551739cfe196b8625
Author: Craig Keogh <cskeogh adam com au>
Date:   Thu Aug 16 17:01:51 2012 +0930

    Implement sysdeps --install for path systemmodules (GNOME bug 681344)
    
    Implement PKSystemInstall

 jhbuild/commands/sysdeps.py    |   40 +++++++++++---
 jhbuild/config.py              |    2 +-
 jhbuild/defaults.jhbuildrc     |    4 +
 jhbuild/utils/systeminstall.py |  121 ++++++++++++++++++++++++---------------
 4 files changed, 111 insertions(+), 56 deletions(-)
---
diff --git a/jhbuild/commands/sysdeps.py b/jhbuild/commands/sysdeps.py
index 66812b9..4ab5a05 100644
--- a/jhbuild/commands/sysdeps.py
+++ b/jhbuild/commands/sysdeps.py
@@ -19,6 +19,7 @@
 
 from optparse import make_option
 import logging
+import os.path
 
 import jhbuild.moduleset
 from jhbuild.errors import FatalError
@@ -89,7 +90,8 @@ class cmd_sysdeps(cmd_build):
             print _('    (none)')
 
         print _('  No matching system package installed:')
-        uninstalled = []
+        uninstalled_pkgconfigs = []
+        uninstalled_filenames = []
         for module, (req_version, installed_version, new_enough, systemmodule) in module_state.iteritems():
             if installed_version is None and (not new_enough) and systemmodule:
                 print ('    %s %s' % (module.name,
@@ -97,8 +99,22 @@ class cmd_sysdeps(cmd_build):
                                                   req_version,
                                                   installed_version)))
                 if module.pkg_config is not None:
-                    uninstalled.append(module.pkg_config[:-3]) # remove .pc
-        if len(uninstalled) == 0:
+                    uninstalled_pkgconfigs.append((module.name,
+                                                   # remove .pc
+                                                   module.pkg_config[:-3]))
+                elif module.systemdependencies is not None:
+                    for dep_type, value in module.systemdependencies:
+                        if dep_type.lower() == 'path':
+                            uninstalled_filenames.append(
+                                (module.name,
+                                 os.path.join(config.system_prefix, 'bin',
+                                              value),))
+                        elif dep_type.lower() == 'c_include':
+                            uninstalled_filenames.append(
+                                (module.name,
+                                 os.path.join(config.system_prefix, 'include',
+                                              value),))
+        if len(uninstalled_pkgconfigs) + len(uninstalled_filenames) == 0:
             print _('    (none)')
 
         have_too_old = False
@@ -124,8 +140,11 @@ class cmd_sysdeps(cmd_build):
                                                       req_version,
                                                       installed_version)))
                     if module.pkg_config is not None:
-                        uninstalled.append(module.pkg_config[:-3]) # remove .pc
-            if len(uninstalled) == 0:
+                        uninstalled_pkgconfigs.append((module.name,
+                                                       # remove .pc
+                                                       module.pkg_config[:-3]))
+
+            if len(uninstalled_pkgconfigs) == 0:
                 print _('  (none)')
 
             if options.install:
@@ -141,10 +160,15 @@ class cmd_sysdeps(cmd_build):
 
                     raise FatalError(_("Don't know how to install packages on this system"))
 
-                if len(uninstalled) == 0:
+                if (len(uninstalled_pkgconfigs) +
+                    len(uninstalled_filenames)) == 0:
                     logging.info(_("No uninstalled system dependencies to install for modules: %r" % (modules, )))
                 else:
-                    logging.info(_("Installing dependencies on system: %s" % (' '.join(uninstalled), )))
-                    installer.install(uninstalled)
+                    logging.info(_("Installing dependencies on system: %s" % \
+                                   ' '.join([pkg[0] for pkg in
+                                             uninstalled_pkgconfigs +
+                                             uninstalled_filenames])))
+                    installer.install(uninstalled_pkgconfigs,
+                                      uninstalled_filenames)
 
 register_command(cmd_sysdeps)
diff --git a/jhbuild/config.py b/jhbuild/config.py
index 0a83c16..8638d49 100644
--- a/jhbuild/config.py
+++ b/jhbuild/config.py
@@ -62,7 +62,7 @@ _known_keys = [ 'moduleset', 'modules', 'skip', 'tags', 'prefix',
                 'build_targets', 'cmakeargs', 'module_cmakeargs',
                 'print_command_pattern', 'static_analyzer',
                 'module_static_analyzer', 'static_analyzer_template',
-                'static_analyzer_outputdir', 'check_sysdeps',
+                'static_analyzer_outputdir', 'check_sysdeps', 'system_prefix',
               ]
 
 env_prepends = {}
diff --git a/jhbuild/defaults.jhbuildrc b/jhbuild/defaults.jhbuildrc
index aa74a6f..d88773f 100644
--- a/jhbuild/defaults.jhbuildrc
+++ b/jhbuild/defaults.jhbuildrc
@@ -205,3 +205,7 @@ print_command_pattern = '%(command)s'
 
 # Check system dependencies. If not dependencies not met, raise error
 check_sysdeps = True
+
+# system_prefix used when searching for files within available packages
+# during 'sysdeps --install'
+system_prefix = '/usr'
diff --git a/jhbuild/utils/systeminstall.py b/jhbuild/utils/systeminstall.py
index 9ddf4a2..0242299 100755
--- a/jhbuild/utils/systeminstall.py
+++ b/jhbuild/utils/systeminstall.py
@@ -155,6 +155,12 @@ PK_FILTER_ENUM_ARCH = 1 << 18
 class PKSystemInstall(SystemInstall):
     def __init__(self):
         SystemInstall.__init__(self)
+        self._loop = None
+        # PackageKit 0.8.1 has API breaks in the D-BUS interface, for now
+        # we try to support both it and older PackageKit
+        self._using_pk_0_8_1 = None
+        self._sysbus = None
+        self._pkdbus = None
 
     def _on_pk_message(self, msgtype, msg):
         logging.info(_('PackageKit: %s' % (msg,)))
@@ -162,67 +168,88 @@ class PKSystemInstall(SystemInstall):
     def _on_pk_error(self, msgtype, msg):
         logging.error(_('PackageKit: %s' % (msg,)))
 
-    def install(self, pkgconfig_ids):
-        import dbus
-        import dbus.glib
-        import glib
-
-        # PackageKit 0.8.1 has API breaks in the D-BUS interface, for now
-        # we try to support both it and older PackageKit
-        using_pk_0_8_1 = False
-
-        loop = glib.MainLoop()
-        
-        sysbus = dbus.SystemBus()
-        pk = dbus.Interface(sysbus.get_object('org.freedesktop.PackageKit',
+    def _get_new_transaction(self):
+        if self._loop is None:
+            import glib
+            self._loop = glib.MainLoop()
+        if self._sysbus is None:
+            import dbus.glib
+            import dbus
+            self._dbus = dbus
+            self._sysbus = dbus.SystemBus()
+        if self._pkdbus is None:
+            self._pkdbus = dbus.Interface(self._sysbus.get_object('org.freedesktop.PackageKit',
                                               '/org/freedesktop/PackageKit'),
                             'org.freedesktop.PackageKit')
-        try:
-            txn_path = pk.CreateTransaction()
-            txn = sysbus.get_object('org.freedesktop.PackageKit', txn_path)
-            using_pk_0_8_1 = True
-        except dbus.exceptions.DBusException:
-            tid = pk.GetTid()
-            txn = sysbus.get_object('org.freedesktop.PackageKit', tid)
-
-        txn_tx = dbus.Interface(txn, 'org.freedesktop.PackageKit.Transaction')
+        if self._using_pk_0_8_1 is None:
+            try:
+                txn_path = self._pkdbus.CreateTransaction()
+                txn = self._sysbus.get_object('org.freedesktop.PackageKit', txn_path)
+                self._using_pk_0_8_1 = True
+            except dbus.exceptions.DBusException:
+                tid = self._pkdbus.GetTid()
+                txn = self._sysbus.get_object('org.freedesktop.PackageKit', tid)
+                self._using_pk_0_8_1 = False
+        elif self._using_pk_0_8_1:
+            txn_path = self._pkdbus.CreateTransaction()
+            txn = self._sysbus.get_object('org.freedesktop.PackageKit', txn_path)
+        else:
+            tid = self._pkdbus.GetTid()
+            txn = self._sysbus.get_object('org.freedesktop.PackageKit', tid)
+        txn_tx = self._dbus.Interface(txn, 'org.freedesktop.PackageKit.Transaction')
         txn.connect_to_signal('Message', self._on_pk_message)
         txn.connect_to_signal('ErrorCode', self._on_pk_error)
-        txn.connect_to_signal('Destroy', lambda *args: loop.quit())
+        txn.connect_to_signal('Destroy', lambda *args: self._loop.quit())
+        return txn_tx, txn
 
+    def install(self, uninstalled_pkgconfigs, uninstalled_filenames):
         pk_package_ids = set()
-        txn.connect_to_signal('Package', lambda info, pkid, summary: pk_package_ids.add(pkid))
-        if using_pk_0_8_1:
-            txn_tx.WhatProvides(PK_FILTER_ENUM_ARCH | PK_FILTER_ENUM_NEWEST | PK_FILTER_ENUM_NOT_INSTALLED,
-                                PK_PROVIDES_ANY,
-                                ['pkgconfig(%s)' % pkg for pkg in pkgconfig_ids])
-        else:
-            txn_tx.WhatProvides("arch;newest;~installed", "any",
-                                ['pkgconfig(%s)' % pkg for pkg in pkgconfig_ids])
-        loop.run()
 
-        del txn
+        if uninstalled_pkgconfigs:
+            txn_tx, txn = self._get_new_transaction()
+            txn.connect_to_signal('Package', lambda info, pkid, summary: pk_package_ids.add(pkid))
+            if self._using_pk_0_8_1:
+                txn_tx.WhatProvides(PK_FILTER_ENUM_ARCH | PK_FILTER_ENUM_NEWEST |
+                                    PK_FILTER_ENUM_NOT_INSTALLED,
+                                    PK_PROVIDES_ANY,
+                                    ['pkgconfig(%s)' % pkg for modname, pkg in
+                                     uninstalled_pkgconfigs])
+            else:
+                txn_tx.WhatProvides('arch;newest;~installed', 'any',
+                                    ['pkgconfig(%s)' % pkg for modname, pkg in
+                                     uninstalled_pkgconfigs])
+            self._loop.run()
+            del txn, txn_tx
+
+        if uninstalled_filenames:
+            txn_tx, txn = self._get_new_transaction()
+            txn.connect_to_signal('Package', lambda info, pkid, summary: pk_package_ids.add(pkid))
+            if self._using_pk_0_8_1:
+                txn_tx.SearchFiles(PK_FILTER_ENUM_ARCH | PK_FILTER_ENUM_NEWEST |
+                                   PK_FILTER_ENUM_NOT_INSTALLED,
+                                   [pkg for modname, pkg in
+                                    uninstalled_filenames])
+            else:
+                txn_tx.SearchFiles('arch;newest;~installed',
+                                   [pkg for modname, pkg in
+                                    uninstalled_filenames])
+            self._loop.run()
+            del txn, txn_tx
+
+        # On Fedora 17 a file can be in two packages: the normal package and
+        # an older compat- package. Don't install compat- packages.
+        pk_package_ids = [pkg for pkg in pk_package_ids
+                          if not pkg.startswith('compat-')]
 
         if len(pk_package_ids) == 0:
             logging.info(_('Nothing available to install'))
             return
 
-        logging.info(_('Installing: %s' % (' '.join(pk_package_ids, ))))
-
-        if using_pk_0_8_1:
-            txn_path = pk.CreateTransaction()
-            txn = sysbus.get_object('org.freedesktop.PackageKit', txn_path)
-        else:
-            tid = pk.GetTid()
-            txn = sysbus.get_object('org.freedesktop.PackageKit', tid)
-
-        txn_tx = dbus.Interface(txn, 'org.freedesktop.PackageKit.Transaction')
-        txn.connect_to_signal('Message', self._on_pk_message)
-        txn.connect_to_signal('ErrorCode', self._on_pk_error)
-        txn.connect_to_signal('Destroy', lambda *args: loop.quit())
+        logging.info(_('Installing:\n  %s' % ('\n  '.join(pk_package_ids, ))))
 
+        txn_tx, txn = self._get_new_transaction()
         txn_tx.InstallPackages(True, pk_package_ids)
-        loop.run()
+        self._loop.run()
 
         logging.info(_('Complete!'))
 



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