From 0f688d833efebd076da949aff3632c499e4cb429 Mon Sep 17 00:00:00 2001 From: Thomas Leonard Date: Tue, 20 Mar 2012 19:53:30 +0000 Subject: [PATCH] Added to support Debian multi-arch Java packages --- tests/testdistro.py | 15 +++++++++++++++ zeroinstall/injector/distro.py | 12 +++++++----- zeroinstall/injector/model.py | 43 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 63 insertions(+), 7 deletions(-) diff --git a/tests/testdistro.py b/tests/testdistro.py index 0a677d9..c425250 100755 --- a/tests/testdistro.py +++ b/tests/testdistro.py @@ -247,5 +247,20 @@ class TestDistro(BaseTest): self.assertEqual('0.3-post1-rc2', distro.try_cleanup_distro_version('0.3-post1-rc2')) self.assertEqual('0.3.1-2', distro.try_cleanup_distro_version('0.3.1-r2-r3')) + def testGlob(self): + dpkgdir = os.path.join(os.path.dirname(__file__), 'dpkg') + host = distro.DebianDistribution( + os.path.join(dpkgdir, 'status')) + host._packagekit = DummyPackageKit() + + factory = self.make_factory(host) + + master_feed = parse_impls("""""") + icache = iface_cache.IfaceCache(distro = host) + icache._feeds[master_feed.url] = master_feed + #del icache._feeds['distribution:' + master_feed.url] + impl, = icache.get_feed(master_feed.get_distro_feed()).implementations.values() + self.assertEqual('/etc/hostname', impl.main) + if __name__ == '__main__': unittest.main() diff --git a/zeroinstall/injector/distro.py b/zeroinstall/injector/distro.py index 59b031c..425d402 100644 --- a/zeroinstall/injector/distro.py +++ b/zeroinstall/injector/distro.py @@ -183,17 +183,19 @@ class Distribution(object): if only_if_missing: return None warn(_("Duplicate ID '%s' for DistributionImplementation"), id) - impl = model.DistributionImplementation(feed, id, self) + impl = model.DistributionImplementation(feed, id, self, item) feed.implementations[id] = impl impl.installed = installed impl.metadata = item_attrs item_main = item_attrs.get('main', None) - if item_main and not item_main.startswith('/'): - raise model.InvalidInterface(_("'main' attribute must be absolute, but '%s' doesn't start with '/'!") % - item_main) - impl.main = item_main + if item_main: + if item_main.startswith('/'): + impl.main = item_main + else: + raise model.InvalidInterface(_("'main' attribute must be absolute, but '%s' doesn't start with '/'!") % + item_main) impl.upstream_stability = model.packaged return impl diff --git a/zeroinstall/injector/model.py b/zeroinstall/injector/model.py index ce5f50e..08f5483 100644 --- a/zeroinstall/injector/model.py +++ b/zeroinstall/injector/model.py @@ -679,17 +679,56 @@ class Implementation(object): """ raise NotImplementedError("abstract") +# Calculates "path" lazily, since it may involve searching the file system +class _DistributionCommand(Command): + __slots__ = ['impl', '_path'] + + def __init__(self, impl, qdom): + Command.__init__(self, qdom, None) + self.impl = impl + self._path = False # lazy + + @property + def path(self): + if self._path is False: + self._path = self.qdom.attrs.get("path", None) + if self._path is None: + pattern = self.qdom.attrs.get("glob", None) + if pattern: + if not pattern.startswith('/'): + raise SafeException("Glob pattern '{glob}' should start with '/' (in feed {feed})".format( + glob = pattern, feed = self.impl.feed.url)) + import glob + matches = glob.glob(pattern) + if len(matches) == 1: + self._path = matches[0] + elif matches: + raise SafeException("Multiple matches for glob '{glob}'".format(glob = pattern)) + else: + raise SafeException("No matches for glob '{glob}'".format(glob = pattern)) + return self._path + + class DistributionImplementation(Implementation): """An implementation provided by the distribution. Information such as the version comes from the package manager. + @ivar package_implementation: the element that generated this impl (since 1.7) + @type package_implementation: L{qdom.Element} @since: 0.28""" - __slots__ = ['distro', 'installed'] + __slots__ = ['distro', 'installed', 'package_implementation'] - def __init__(self, feed, id, distro): + def __init__(self, feed, id, distro, package_implementation = None): assert id.startswith('package:') Implementation.__init__(self, feed, id) self.distro = distro self.installed = False + self.package_implementation = package_implementation + + if package_implementation: + for item in package_implementation.childNodes: + if item.uri != XMLNS_IFACE: continue + if item.name == 'command': + self.commands[item.getAttribute("name")] = _DistributionCommand(self, item) @property def requires_root_install(self): -- 2.11.4.GIT