def testEscapeInterface(self): self.assertEqual(["http", "example.com", "foo.xml"], model.escape_interface_uri("http://example.com/foo.xml")) self.assertEqual(["http", "example.com", "foo__.bar.xml"], model.escape_interface_uri("http://example.com/foo/.bar.xml")) self.assertEqual(["file", "root__foo.xml"], model.escape_interface_uri("/root/foo.xml")) try: model.escape_interface_uri("ftp://example.com/foo.xml") assert 0 except AssertionError: pass
def update_from_cache(interface, iface_cache=None): """Read a cached interface and any native feeds or user overrides. @param interface: the interface object to update @type interface: L{model.Interface} @return: True if cached version and user overrides loaded OK. False if upstream not cached. Local interfaces (starting with /) are always considered to be cached, although they are not actually stored in the cache. Internal: use L{iface_cache.IfaceCache.get_interface} instread. @rtype: bool""" interface.reset() if iface_cache is None: import warnings warnings.warn("iface_cache should be specified", DeprecationWarning, 2) from zeroinstall.injector import policy iface_cache = policy.get_deprecated_singleton_config().iface_cache # Add the distribution package manager's version, if any path = basedir.load_first_data(config_site, 'native_feeds', model._pretty_escape(interface.uri)) if path: # Resolve any symlinks logger.info(_("Adding native packager feed '%s'"), path) interface.extra_feeds.append(Feed(os.path.realpath(path), None, False)) # Add locally-compiled binaries, if any escaped_uri = model.escape_interface_uri(interface.uri) known_site_feeds = set() for path in basedir.load_data_paths(config_site, 'site-packages', *escaped_uri): try: _add_site_packages(interface, path, known_site_feeds) except Exception as ex: logger.warn("Error loading site packages from {path}: {ex}".format( path=path, ex=ex)) update_user_overrides(interface, known_site_feeds) main_feed = iface_cache.get_feed(interface.uri, force=True) if main_feed: update_user_feed_overrides(main_feed) return main_feed is not None
def update_from_cache(interface, iface_cache=None): """Read a cached interface and any native feeds or user overrides. @param interface: the interface object to update @type interface: L{model.Interface} @return: True if cached version and user overrides loaded OK. False if upstream not cached. Local interfaces (starting with /) are always considered to be cached, although they are not actually stored in the cache. Internal: use L{iface_cache.IfaceCache.get_interface} instread. @rtype: bool""" interface.reset() if iface_cache is None: import warnings warnings.warn("iface_cache should be specified", DeprecationWarning, 2) from zeroinstall.injector import policy iface_cache = policy.get_deprecated_singleton_config().iface_cache # Add the distribution package manager's version, if any path = basedir.load_first_data(config_site, "native_feeds", model._pretty_escape(interface.uri)) if path: # Resolve any symlinks logger.info(_("Adding native packager feed '%s'"), path) interface.extra_feeds.append(Feed(os.path.realpath(path), None, False)) # Add locally-compiled binaries, if any escaped_uri = model.escape_interface_uri(interface.uri) known_site_feeds = set() for path in basedir.load_data_paths(config_site, "site-packages", *escaped_uri): try: _add_site_packages(interface, path, known_site_feeds) except Exception as ex: logger.warn("Error loading site packages from {path}: {ex}".format(path=path, ex=ex)) update_user_overrides(interface, known_site_feeds) main_feed = iface_cache.get_feed(interface.uri, force=True) if main_feed: update_user_feed_overrides(main_feed) return main_feed is not None
def compile_and_register(self, sels, forced_iface_uri = None): """If forced_iface_uri, register as an implementation of this interface, ignoring the any <feed-for>, etc.""" buildenv = BuildEnv(need_config = False) buildenv.config.set('compile', 'interface', sels.interface) buildenv.config.set('compile', 'selections', 'selections.xml') # Download any required packages now, so we can use the GUI to request confirmation, etc download_missing = sels.download_missing(self.config, include_packages = True) if download_missing: yield download_missing tasks.check(download_missing) tmpdir = tempfile.mkdtemp(prefix = '0compile-') try: os.chdir(tmpdir) # Write configuration for build... buildenv.save() sel_file = open('selections.xml', 'w') try: doc = sels.toDOM() doc.writexml(sel_file) sel_file.write('\n') finally: sel_file.close() # Do the build... build = self.spawn_build(buildenv.iface_name) if build: yield build tasks.check(build) # Register the result... dom = minidom.parse(buildenv.local_iface_file) feed_for_elem, = dom.getElementsByTagNameNS(namespaces.XMLNS_IFACE, 'feed-for') claimed_iface = feed_for_elem.getAttribute('interface') if forced_iface_uri is not None: if forced_iface_uri != claimed_iface: self.note("WARNING: registering as feed for {forced}, though feed claims to be for {claimed}".format( forced = forced_iface_uri, claimed = claimed_iface)) else: forced_iface_uri = claimed_iface # (the top-level interface being built) version = sels.selections[sels.interface].version site_package_versions_dir = basedir.save_data_path('0install.net', 'site-packages', *model.escape_interface_uri(forced_iface_uri)) leaf = '%s-%s' % (version, uname[4]) site_package_dir = os.path.join(site_package_versions_dir, leaf) self.note("Storing build in %s" % site_package_dir) # 1. Copy new version in under a temporary name. Names starting with '.' are ignored by 0install. tmp_distdir = os.path.join(site_package_versions_dir, '.new-' + leaf) shutil.copytree(buildenv.distdir, tmp_distdir, symlinks = True) # 2. Rename the previous build to .old-VERSION (deleting that if it already existed) if os.path.exists(site_package_dir): self.note("(moving previous build out of the way)") previous_build_dir = os.path.join(site_package_versions_dir, '.old-' + leaf) if os.path.exists(previous_build_dir): shutil.rmtree(previous_build_dir) os.rename(site_package_dir, previous_build_dir) else: previous_build_dir = None # 3. Rename the new version immediately after renaming away the old one to minimise time when there's # no version. os.rename(tmp_distdir, site_package_dir) # 4. Delete the old version. if previous_build_dir: self.note("(deleting previous build)") shutil.rmtree(previous_build_dir) local_feed = os.path.join(site_package_dir, '0install', 'feed.xml') assert os.path.exists(local_feed), "Feed %s not found!" % local_feed # Reload - our 0install will detect the new feed automatically iface = self.config.iface_cache.get_interface(forced_iface_uri) reader.update_from_cache(iface, iface_cache = self.config.iface_cache) self.config.iface_cache.get_feed(local_feed, force = True) # Write it out - 0install will add the feed so that older 0install versions can find it writer.save_interface(iface) except: self.note("\nBuild failed: leaving build directory %s for inspection...\n" % tmpdir) raise else: # Can't delete current directory on Windows, so move to parent first os.chdir(os.path.join(tmpdir, os.path.pardir)) ro_rmtree(tmpdir)
def compile_and_register(self, sels, forced_iface_uri=None): """If forced_iface_uri, register as an implementation of this interface, ignoring the any <feed-for>, etc.""" buildenv = BuildEnv(need_config=False) buildenv.config.set('compile', 'interface', sels.interface) buildenv.config.set('compile', 'selections', 'selections.xml') # Download any required packages now, so we can use the GUI to request confirmation, etc download_missing = sels.download_missing(self.config, include_packages=True) if download_missing: yield download_missing tasks.check(download_missing) tmpdir = tempfile.mkdtemp(prefix='0compile-') try: os.chdir(tmpdir) # Write configuration for build... buildenv.save() sel_file = open('selections.xml', 'w') try: doc = sels.toDOM() doc.writexml(sel_file) sel_file.write('\n') finally: sel_file.close() # Do the build... build = self.spawn_build(buildenv.iface_name) if build: yield build tasks.check(build) # Register the result... dom = minidom.parse(buildenv.local_iface_file) feed_for_elem, = dom.getElementsByTagNameNS( namespaces.XMLNS_IFACE, 'feed-for') claimed_iface = feed_for_elem.getAttribute('interface') if forced_iface_uri is not None: if forced_iface_uri != claimed_iface: self.note( "WARNING: registering as feed for {forced}, though feed claims to be for {claimed}" .format(forced=forced_iface_uri, claimed=claimed_iface)) else: forced_iface_uri = claimed_iface # (the top-level interface being built) version = sels.selections[sels.interface].version site_package_versions_dir = basedir.save_data_path( '0install.net', 'site-packages', *model.escape_interface_uri(forced_iface_uri)) leaf = '%s-%s' % (version, build_target_machine_type) site_package_dir = os.path.join(site_package_versions_dir, leaf) self.note("Storing build in %s" % site_package_dir) # 1. Copy new version in under a temporary name. Names starting with '.' are ignored by 0install. tmp_distdir = os.path.join(site_package_versions_dir, '.new-' + leaf) shutil.copytree(buildenv.distdir, tmp_distdir, symlinks=True) # 2. Rename the previous build to .old-VERSION (deleting that if it already existed) if os.path.exists(site_package_dir): self.note("(moving previous build out of the way)") previous_build_dir = os.path.join(site_package_versions_dir, '.old-' + leaf) if os.path.exists(previous_build_dir): shutil.rmtree(previous_build_dir) os.rename(site_package_dir, previous_build_dir) else: previous_build_dir = None # 3. Rename the new version immediately after renaming away the old one to minimise time when there's # no version. os.rename(tmp_distdir, site_package_dir) # 4. Delete the old version. if previous_build_dir: self.note("(deleting previous build)") shutil.rmtree(previous_build_dir) local_feed = os.path.join(site_package_dir, '0install', 'feed.xml') assert os.path.exists( local_feed), "Feed %s not found!" % local_feed # Reload - our 0install will detect the new feed automatically iface = self.config.iface_cache.get_interface(forced_iface_uri) reader.update_from_cache(iface, iface_cache=self.config.iface_cache) self.config.iface_cache.get_feed(local_feed, force=True) # Write it out - 0install will add the feed so that older 0install versions can find it writer.save_interface(iface) seen_key = (forced_iface_uri, sels.selections[sels.interface].id) assert seen_key not in self.seen, seen_key self.seen[seen_key] = site_package_dir except: self.note( "\nBuild failed: leaving build directory %s for inspection...\n" % tmpdir) raise else: # Can't delete current directory on Windows, so move to parent first os.chdir(os.path.join(tmpdir, os.path.pardir)) ro_rmtree(tmpdir)