def testFeeds(self): iface = model.Interface('http://test/test') main_feed = model.ZeroInstallFeed(test_feed, local_path='/Hello') self.config.iface_cache._feeds[iface.uri] = main_feed iface.stability_policy = model.developer main_feed.last_checked = 100 iface.extra_feeds.append(model.Feed('http://sys-feed', None, False)) iface.extra_feeds.append( model.Feed('http://user-feed', 'Linux-*', True)) writer.save_interface(iface) writer.save_feed(main_feed) iface = model.Interface('http://test/test') self.assertEquals(None, iface.stability_policy) main_feed = model.ZeroInstallFeed(test_feed, local_path='/Hello') self.config.iface_cache._feeds[iface.uri] = main_feed reader.update_user_overrides(iface) reader.update_user_feed_overrides(main_feed) self.assertEquals(model.developer, iface.stability_policy) self.assertEquals(100, main_feed.last_checked) self.assertEquals("[<Feed from http://user-feed>]", str(iface.extra_feeds)) feed = iface.extra_feeds[0] self.assertEquals('http://user-feed', feed.uri) self.assertEquals('Linux', feed.os) self.assertEquals(None, feed.machine)
def testLocalArchive(self): local_iface = os.path.join(mydir, 'LocalArchive.xml') with open(local_iface, 'rb') as stream: root = qdom.parse(stream) # Not local => error feed = model.ZeroInstallFeed(root) impl = feed.implementations['impl1'] blocker = self.config.fetcher.download_impls([impl], self.config.stores) try: tasks.wait_for_blocker(blocker) assert 0 except model.SafeException as ex: assert "Relative URL 'HelloWorld.tgz' in non-local feed" in str( ex), ex feed = model.ZeroInstallFeed(root, local_path=local_iface) # Missing file impl2 = feed.implementations['impl2'] blocker = self.config.fetcher.download_impls([impl2], self.config.stores) try: tasks.wait_for_blocker(blocker) assert 0 except model.SafeException as ex: assert 'tests/IDONTEXIST.tgz' in str(ex), ex # Wrong size impl3 = feed.implementations['impl3'] blocker = self.config.fetcher.download_impls([impl3], self.config.stores) try: tasks.wait_for_blocker(blocker) assert 0 except model.SafeException as ex: assert 'feed says 177, but actually 176 bytes' in str(ex), ex self.config.network_use = model.network_offline r = Requirements(local_iface) r.command = None driver = Driver(requirements=r, config=self.config) driver.need_download() assert driver.solver.ready, driver.solver.get_failure_reason() # Local => OK impl = feed.implementations['impl1'] path = self.config.stores.lookup_maybe(impl.digests) assert not path blocker = self.config.fetcher.download_impls([impl], self.config.stores) tasks.wait_for_blocker(blocker) path = self.config.stores.lookup_any(impl.digests) assert os.path.exists(os.path.join(path, 'HelloWorld'))
def build_feed(self): def child(parent, name, attrs=None): new = qdom.Element(XMLNS_IFACE, name, attrs or {}) parent.childNodes.append(new) return new root = qdom.Element(XMLNS_IFACE, 'interface', {'uri': uri_prefix + self.name}) child(root, 'name').content = self.name child(root, 'summary').content = self.name i = 0 for version in self.versions.values(): attrs = { 'id': str(i), 'version': str(version.n), 'main': 'dummy', } if version.arch: attrs['arch'] = version.arch impl = child(root, 'implementation', attrs) child(impl, 'manifest-digest', {'sha1new': '1234'}) for lib, min_v, max_v in version.requires: req = child(impl, 'requires', {'interface': uri_prefix + lib}) child(req, 'version', { 'before': str(int(max_v) + 1), 'not-before': min_v }) i += 1 feed = model.ZeroInstallFeed(root) feed.last_modified = 1 return feed
def ask_if_previous_still_testing(master_doc, new_version): new_version_parsed = model.parse_version(new_version) xml = master_doc.toxml(encoding = 'utf-8') master = model.ZeroInstallFeed(qdom.parse(BytesIO(xml))) previous_versions = [impl.version for impl in master.implementations.values() if impl.version < new_version_parsed] if not previous_versions: return previous_version = max(previous_versions) # (all the <implementations> with this version number) previous_testing_impls = [impl for impl in master.implementations.values() if impl.version == previous_version and impl.upstream_stability == model.testing] if not previous_testing_impls: return print("The previous release, version {version}, is still marked as 'testing'. Set to stable?".format( version = model.format_version(previous_version))) if get_choice(['Yes', 'No']) != 'Yes': return ids_to_change = frozenset(impl.id for impl in previous_testing_impls) for impl in master_doc.getElementsByTagNameNS(XMLNS_IFACE, 'implementation'): if impl.getAttribute('id') in ids_to_change: impl.setAttribute('stability', 'stable')
def graduation_check(feeds, feeds_dir): # Warn about releases that are still 'testing' a while after release now = time.time() def age(impl): released = impl.metadata.get('released', None) if not released: return 0 released_time = time.mktime(time.strptime(released, '%Y-%m-%d')) return now - released_time shown_header = False for feed in feeds: with open(feed.source_path, 'rb') as stream: zfeed = model.ZeroInstallFeed(qdom.parse(stream)) if zfeed.implementations: # Find the latest version number (note that there may be several implementations with this version number) latest_version = max(impl.version for impl in zfeed.implementations.values()) testing_impls = [impl for impl in zfeed.implementations.values() if impl.version == latest_version and impl.upstream_stability == model.stability_levels['testing'] and age(impl) > TIME_TO_GRADUATE] if testing_impls: if not shown_header: print("Releases which are still marked as 'testing' after {days} days:".format( days = TIME_TO_GRADUATE / DAY)) shown_header = True print("- {name} v{version}, {age} days ({path})".format( age = int(age(testing_impls[0]) / DAY), name = zfeed.get_name(), path = os.path.relpath(feed.source_path, feeds_dir), version = model.format_version(latest_version)))
def testDebian(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) host.get_package_info('gimp', factory) self.assertEqual({}, self.feed.implementations) # Initially, we only get information about the installed version... host.get_package_info('python-bittorrent', factory) self.assertEqual(1, len(self.feed.implementations)) # Tell distro to fetch information about candidates... master_feed = parse_impls( """<package-implementation package='python-bittorrent'> <restricts interface='http://python.org/python'> <version not-before='3'/> </restricts> </package-implementation> """) h = handler.Handler() candidates = host.fetch_candidates(master_feed) if candidates: h.wait_for_blocker(candidates) # Now we see the uninstalled package self.feed = host.get_feed(master_feed) self.assertEqual(2, len(self.feed.implementations)) # Check restriction appears for both candidates for impl in self.feed.implementations.values(): self.assertEqual(1, len(impl.requires)) self.assertEqual("http://python.org/python", impl.requires[0].interface) self.assertEqual(2, len(self.feed.implementations)) bittorrent_installed = self.feed.implementations[ 'package:deb:python-bittorrent:3.4.2-10:*'] bittorrent_uninstalled = self.feed.implementations[ 'package:deb:python-bittorrent:3.4.2-11.1:*'] self.assertEqual('3.4.2-10', bittorrent_installed.get_version()) self.assertTrue(bittorrent_installed.installed) self.assertFalse(bittorrent_uninstalled.installed) self.assertEqual(None, bittorrent_installed.machine) self.feed = model.ZeroInstallFeed(empty_feed, local_path='/empty.xml') host.get_package_info('libxcomposite-dev', factory) self.assertEqual(1, len(self.feed.implementations)) libxcomposite = self.feed.implementations[ 'package:deb:libxcomposite-dev:0.3.1-1:i386'] self.assertEqual('0.3.1-1', libxcomposite.get_version()) self.assertEqual('i386', libxcomposite.machine) # Java is special... master_feed = parse_impls( """<package-implementation package='openjdk-7-jre'/>""") feed = host.get_feed(master_feed) self.assertEqual(1, len(feed.implementations)) self.assertEqual('7.3-2.1.1-3', list(feed.implementations.values())[0].get_version())
def testLocale(self): local_path = os.path.join(mydir, 'Local.xml') with open(local_path, 'rb') as stream: dom = qdom.parse(stream) feed = model.ZeroInstallFeed(dom, local_path=local_path) # (defaults to en-US if no language is set in the locale) self.assertEqual("Local feed (English)", feed.summary) self.assertEqual("English", feed.description) self.assertEqual(4, len(feed.summaries)) self.assertEqual(2, len(feed.descriptions)) try: basetest.test_locale = ('es_ES', 'UTF8') self.assertEqual("Fuente local", feed.summary) self.assertEqual("Español", feed.description) basetest.test_locale = ('en_GB', 'UTF8') self.assertEqual("Local feed (English GB)", feed.summary) basetest.test_locale = ('fr_FR', 'UTF8') self.assertEqual("Local feed (English)", feed.summary) self.assertEqual("English", feed.description) finally: basetest.test_locale = (None, None)
def load_built_feed(self): path = self.local_iface_file stream = file(path) try: feed = model.ZeroInstallFeed(qdom.parse(stream), local_path = path) finally: stream.close() return feed
def testMetadata(self): main_feed = model.ZeroInstallFeed(empty_feed, local_path = '/foo') e = qdom.parse(StringIO('<ns:b xmlns:ns="a" foo="bar"/>')) main_feed.metadata = [e] assert main_feed.get_metadata('a', 'b') == [e] assert main_feed.get_metadata('b', 'b') == [] assert main_feed.get_metadata('a', 'a') == [] assert e.getAttribute('foo') == 'bar'
def testDownloadSource(self): f = model.ZeroInstallFeed(empty_feed, local_path='/foo') a = model.ZeroInstallImplementation(f, 'foo', None) a.add_download_source('ftp://foo', 1024, None) a.add_download_source('ftp://foo.tgz', 1025, 'foo') assert a.download_sources[0].url == 'ftp://foo' assert a.download_sources[0].size == 1024 assert a.download_sources[0].extract == None assert a.feed is f
def parse_impls(impls): xml = """<?xml version="1.0" ?> <interface xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <name>Foo</name> <summary>Foo</summary> <description>Foo</description> {impls} </interface>""".format(impls=impls) element = qdom.parse(BytesIO(xml.encode('utf-8'))) return model.ZeroInstallFeed(element, "myfeed.xml")
def testMetadata(self): main_feed = model.ZeroInstallFeed(empty_feed, local_path='/foo') assert main_feed.local_path == "/foo" e = qdom.parse(BytesIO(b'<ns:b xmlns:ns="a" foo="bar"/>')) main_feed.metadata = [e] assert main_feed.get_metadata('a', 'b') == [e] assert main_feed.get_metadata('b', 'b') == [] assert main_feed.get_metadata('a', 'a') == [] assert e.getAttribute('foo') == 'bar' self.assertEqual(None, main_feed.get_replaced_by())
def parse_impls(impls): xml = """<?xml version="1.0" ?> <interface xmlns="http://zero-install.sourceforge.net/2004/injector/interface"> <name>Foo</name> <summary>Foo</summary> <description>Foo</description> %s </interface>""" % impls element = qdom.parse(StringIO(xml)) return model.ZeroInstallFeed(element, "myfeed.xml")
def testDefault(self): host = distro.Distribution() factory = self.make_factory(host) host.get_package_info('gimp', factory) self.assertEqual(self.feed.implementations, {}) # Special case: we can always find a version of Python master_feed = model.ZeroInstallFeed(None) master_feed.url = 'http://repo.roscidus.com/python/python' feed = host.get_feed(master_feed) self.assertEqual(1, len(feed.implementations))
def import_feed(self, url, contents): """contents can be a path or an Element.""" iface_cache = self.config.iface_cache iface_cache.get_interface(url) if isinstance(contents, qdom.Element): feed = model.ZeroInstallFeed(contents) else: feed = reader.load_feed(contents) iface_cache._feeds[url] = feed return feed
def testDebian(self): dpkgdir = os.path.join(os.path.dirname(__file__), 'dpkg') host = distro.DebianDistribution( os.path.join(dpkgdir, 'status'), os.path.join(dpkgdir, 'pkgcache.bin')) host._packagekit = DummyPackageKit() factory = self.make_factory(host) host.get_package_info('gimp', factory) self.assertEquals({}, self.feed.implementations) # Initially, we only get information about the installed version... host.get_package_info('python-bittorrent', factory) self.assertEquals(1, len(self.feed.implementations)) # Tell distro to fetch information about candidates... master_feed = parse_impls("""<package-implementation package='python-bittorrent'/>""") h = handler.Handler() candidates = host.fetch_candidates(master_feed) if candidates: h.wait_for_blocker(candidates) # Now we see the uninstalled package self.feed = model.ZeroInstallFeed(empty_feed, local_path = '/empty.xml') host.get_package_info('python-bittorrent', factory) self.assertEquals(2, len(self.feed.implementations)) self.assertEquals(2, len(self.feed.implementations)) bittorrent_installed = self.feed.implementations['package:deb:python-bittorrent:3.4.2-10:*'] bittorrent_uninstalled = self.feed.implementations['package:deb:python-bittorrent:3.4.2-11.1:*'] self.assertEquals('3.4.2-10', bittorrent_installed.get_version()) self.assertTrue(bittorrent_installed.installed) self.assertFalse(bittorrent_uninstalled.installed) self.assertEquals(None, bittorrent_installed.machine) self.feed = model.ZeroInstallFeed(empty_feed, local_path = '/empty.xml') host.get_package_info('libxcomposite-dev', factory) self.assertEquals(1, len(self.feed.implementations)) libxcomposite = self.feed.implementations['package:deb:libxcomposite-dev:0.3.1-1:i386'] self.assertEquals('0.3.1-1', libxcomposite.get_version()) self.assertEquals('i386', libxcomposite.machine)
def import_missing_archive(config, impl, archive): from io import BytesIO from zeroinstall.injector import model, qdom from repo import archives print("Importing missing archive {name}".format(name = archive)) doc = qdom.parse(BytesIO(impl.ownerDocument.documentElement.toxml('utf-8'))) feed = model.ZeroInstallFeed(doc) impl = feed.implementations[impl.getAttribute('id')] required_digest = archives.pick_digest(impl) new_archives = [] for method in impl.download_sources: new_archives += archives.process_method(config, 'incoming', impl, method, required_digest) archives.upload_archives(config, new_archives) for x in new_archives: os.unlink(x.incoming_path) return config.archive_db.lookup(archive)
def testCommand(self): local_path = os.path.join(mydir, 'Command.xml') dom = qdom.parse(open(local_path)) feed = model.ZeroInstallFeed(dom, local_path = local_path) assert feed.implementations['a'].main == 'foo' assert feed.implementations['a'].commands['run'].path == 'foo' assert feed.implementations['a'].commands['test'].path == 'test-foo' assert feed.implementations['b'].main == 'bar' assert feed.implementations['b'].commands['run'].path == 'bar' assert feed.implementations['b'].commands['test'].path == 'test-foo' assert feed.implementations['c'].main == 'runnable/missing' assert feed.implementations['c'].commands['run'].path == 'runnable/missing' assert feed.implementations['c'].commands['test'].path == 'test-baz'
def testCommand(self): local_path = os.path.join(mydir, 'Command.xml') with open(local_path, 'rb') as stream: dom = qdom.parse(stream) feed = model.ZeroInstallFeed(dom, local_path=local_path) assert feed.implementations['a'].main == 'foo' assert feed.implementations['a'].commands['run'].path == 'foo' assert feed.implementations['a'].commands['test'].path == 'test-foo' assert feed.implementations['b'].main == 'bar' assert feed.implementations['b'].commands['run'].path == 'bar' assert feed.implementations['b'].commands['test'].path == 'test-foo' assert feed.implementations['c'].main == 'test-gui' assert feed.implementations['c'].commands['run'].path == 'test-gui' assert feed.implementations['c'].commands['test'].path == 'test-baz'
def testCommand(self): comp_dir = os.path.join(self.tmpdir, 'cprog-command') compile('setup', local_cprog_command_path, comp_dir, expect='Created directory') os.chdir(comp_dir) compile('build', expect='Hello from C!') target_dir = 'cprog-command-%s' % support.get_arch_name().lower() binary_feed = os.path.join(target_dir, '0install', 'feed.xml') run(zi_command, "run", binary_feed, expect='Hello from C!') s = open(binary_feed, 'r') feed = model.ZeroInstallFeed(qdom.parse(s), binary_feed) s.close() impl, = feed.implementations.values() assert impl.arch, "Missing arch on %s" % impl self.assertEqual("Public Domain", str(impl.metadata['license']))
def check(data, warnings = True): assert type(data) == bytes, type(data) # (must not be unicode) try: doc = minidom.parseString(data) if doc.documentElement.getAttribute('uri'): local_path = None else: local_path = '/tmp/local.xml' model.ZeroInstallFeed(qdom.parse(io.BytesIO(data)), local_path = local_path) except InvalidInterface as ex: raise except Exception as ex: warn("Internal error: %s", ex) raise InvalidInterface(str(ex)) if warnings: checkElement(doc.documentElement)
def testArch(self): archdir = os.path.join(os.path.dirname(__file__), 'arch') arch = distro.ArchDistribution(archdir) factory = self.make_factory(arch) arch.get_package_info('gimp', factory) self.assertEqual({}, self.feed.implementations) arch.get_package_info('zeroinstall-injector', factory) self.assertEqual(1, len(self.feed.implementations)) zip = self.feed.implementations[ 'package:arch:zeroinstall-injector:1.5-1:*'] self.assertEqual('1.5-1', zip.get_version()) self.feed = model.ZeroInstallFeed(empty_feed, local_path='/empty.xml') arch.get_package_info('python2', factory) impl, = self.feed.implementations.values() self.assertEqual('2.7.2-4', impl.get_version())
def testSetAtttibs(self): local_data = open(local_file).read() result = release.set_attributes(local_data, '0.2', id='sha1=98765', version='3.7', main=None) feed = model.ZeroInstallFeed(qdom.parse(io.BytesIO(result)), "local.xml") assert len(feed.implementations) == 1 assert feed.implementations['sha1=98765'].get_version() == '3.7' try: result = release.set_attributes(local_data, '0.3', id='sha1=98765', version='3.7', main=None) assert 0 except Exception as ex: assert str(ex) == 'No implementations with version=0.3'
def create_from_local(local): path = os.path.abspath(local) with open(path, 'rb') as stream: feed = model.ZeroInstallFeed(qdom.parse(stream), local_path=path) if not feed.feed_for: raise Exception( "No <feed-for> in '%s'; can't use it as a local feed." % local) if len(feed.feed_for) != 1: raise Exception("Multiple <feed-for> elements. Not supported, sorry!") uri = list(feed.feed_for)[0] doc = minidom.parse(local) root = doc.documentElement root.setAttribute('uri', uri) for element in root.getElementsByTagNameNS(XMLNS_IFACE, 'feed-for'): if element.parentNode is root: remove_with_preceding_comments(element) root.appendChild(doc.createTextNode('\n')) # minidom's writer loses the newline after the PI return xml_header + root.toxml('utf-8')
def testImpl(self): f = model.ZeroInstallFeed(None) f.url = 'http://foo' a = model.ZeroInstallImplementation(f, 'foo', None) assert a.id == 'foo' assert a.size == a.version == a.user_stability == None assert a.arch == a.upstream_stability == None assert a.dependencies == {} assert a.download_sources == [] assert a.get_stability() is model.testing a.upstream_stability = model.stable assert a.get_stability() is model.stable a.user_stability = model.buggy assert a.get_stability() is model.buggy a.version = model.parse_version('1.2.3') self.assertEqual('1.2.3', a.get_version()) a.version = model.parse_version('1.2.3-rc2-post') self.assertEqual('1.2.3-rc2-post', a.get_version()) assert str(a) == 'foo' b = model.ZeroInstallImplementation(f, 'foo', None) b.version = model.parse_version("1.2.1") assert b > a
def get_public_feed(self, name, uri_basename): with open(os.path.join(self.tmp, 'my-repo', 'public', uri_basename), 'rb') as stream: return model.ZeroInstallFeed(qdom.parse(stream))
def get_public_feed(self, name, uri_basename): with open(name, 'rb') as stream: return model.ZeroInstallFeed(qdom.parse(stream))
def process(config, xml_file, delete_on_success): # Step 1 : check everything looks sensible, reject if not with open(xml_file, 'rb') as stream: xml_text = stream.read() sig_index = xml_text.rfind('\n<!-- Base64 Signature') if sig_index != -1: stream.seek(0) stream, sigs = gpg.check_stream(stream) else: sig_index = len(xml_text) sigs = [] root = qdom.parse(BytesIO(xml_text)) master = get_feed_url(root, xml_file) import_master = 'uri' in root.attrs if not import_master: root.attrs['uri'] = master # (hack so we can parse it here without setting local_path) # Check signatures are valid if config.CONTRIBUTOR_GPG_KEYS is not None: for sig in sigs: if isinstance(sig, gpg.ValidSig) and sig.fingerprint in config.CONTRIBUTOR_GPG_KEYS: break else: raise SafeException("No trusted signatures on feed {path}; signatures were: {sigs}".format( path = xml_file, sigs = ', '.join([str(s) for s in sigs]))) feed = model.ZeroInstallFeed(root) # Perform custom checks defined by the repository owner for impl in feed.implementations.values(): problem = config.check_new_impl(impl) if problem: raise SafeException("{problem} in {xml_file}\n(this check was configured in {config}: check_new_impl())".format( problem = problem, xml_file = xml_file, config = config.__file__)) feeds_rel_path = paths.get_feeds_rel_path(config, master) feed_path = join("feeds", feeds_rel_path) feed_dir = dirname(feed_path) if not os.path.isdir(feed_dir): os.makedirs(feed_dir) scm.ensure_no_uncommitted_changes(feed_path) if import_master: if os.path.exists(feed_path): with open(feed_path, 'rb') as stream: existing = stream.read() if existing == xml_text[:sig_index]: print("Already imported {feed}; skipping".format(feed = feed_path)) if delete_on_success: os.unlink(xml_file) return None else: raise SafeException("Can't import '{url}'; non-identical feed {path} already exists.\n\n" "To ADD new versions to this feed, remove the a 'uri' attribute from " "the root element in {new}.\n\n" "To EDIT the feed, just edit {path} directly rather than trying to add it again.\n\n" "To RE-UPLOAD the archives, do that manually and then edit archives.db." .format(url = feed.url, new = xml_file, path = feed_path)) # Calculate commit message if import_master: name = basename(xml_file) if name == 'feed.xml': name = basename(dirname(xml_file)) action = 'Imported {file}'.format(file = name) else: versions = set(i.get_version() for i in feed.implementations.values()) action = 'Added {name} {versions}'.format(name = feed.get_name(), versions = ', '.join(versions)) commit_msg = '%s\n\n%s' % (action, xml_text.decode('utf-8')) # Calculate new XML new_file = not os.path.exists(feed_path) git_path = relpath(feed_path, 'feeds') if import_master: assert new_file new_xml = xml_text[:sig_index] elif new_file: new_xml = create_from_local(master, xml_file) else: # Merge into existing feed try: new_doc = merge.merge_files(master, feed_path, xml_file) except merge.DuplicateIDException as ex: # Did we already import this XML? Compare with the last Git log entry. msg, previous_commit_xml = get_last_commit(git_path) if previous_commit_xml == xml_text: print("Already merged this into {feed}; skipping".format(feed = feed_path)) return msg raise ex new_xml = None # (will regenerate from new_doc below) # Step 2 : upload archives to hosting processed_archives = archives.process_archives(config, incoming_dir = dirname(xml_file), feed = feed) # Step 3 : merge XML into feeds directory # Regenerate merged feed if new_xml is None: new_versions = frozenset(impl.get_version() for impl in feed.implementations.values()) if len(new_versions) == 1 and getattr(config, 'TRACK_TESTING_IMPLS', True): ask_if_previous_still_testing(new_doc, list(new_versions)[0]) new_xml = formatting.format_doc(new_doc) did_git_add = False try: with open(feed_path + '.new', 'wb') as stream: stream.write(new_xml) support.portable_rename(feed_path + '.new', feed_path) # Commit if new_file: subprocess.check_call(['git', 'add', git_path], cwd = 'feeds') did_git_add = True # (this must be last in the try block) scm.commit('feeds', [git_path], commit_msg, key = config.GPG_SIGNING_KEY) except Exception as ex: # Roll-back (we didn't commit to Git yet) print(ex) print("Error updating feed {feed}; rolling-back...".format(feed = xml_file)) if new_file: if os.path.exists(feed_path): os.unlink(feed_path) if did_git_add: subprocess.check_call(['git', 'rm', '--', git_path], cwd = 'feeds') else: subprocess.check_call(['git', 'checkout', 'HEAD', '--', git_path], cwd = 'feeds') raise # Delete XML and archives from incoming directory if delete_on_success: os.unlink(xml_file) for archive in processed_archives: os.unlink(archive.incoming_path) return commit_msg.split('\n', 1)[0]
def testReplaced(self): local_path = os.path.join(mydir, 'Replaced.xml') with open(local_path, 'rb') as stream: dom = qdom.parse(stream) feed = model.ZeroInstallFeed(dom, local_path=local_path) self.assertEqual("http://localhost:8000/Hello", feed.get_replaced_by())
def testInterface(self): i = model.Interface('http://foo') self.assertEqual('(foo)', i.get_name()) feed = model.ZeroInstallFeed(empty_feed, local_path='/foo') self.assertEqual('Empty', feed.get_name()) repr(i)