def testLocalPath(self):
		# 0launch --get-selections Local.xml
		iface = os.path.join(mydir, "Local.xml")
		driver = Driver(requirements = Requirements(iface), config = self.config)
		driver.need_download()
		assert driver.solver.ready
		s1 = driver.solver.selections
		xml = s1.toDOM().toxml("utf-8")

		# Reload selections and check they're the same
		root = qdom.parse(BytesIO(xml))
		s2 = selections.Selections(root)
		local_path = s2.selections[iface].local_path
		assert os.path.isdir(local_path), local_path
		assert not s2.selections[iface].digests, s2.selections[iface].digests

		# Add a newer implementation and try again
		feed = self.config.iface_cache.get_feed(iface)
		impl = model.ZeroInstallImplementation(feed, "foo bar=123", local_path = None)
		impl.version = model.parse_version('1.0')
		impl.commands["run"] = model.Command(qdom.Element(namespaces.XMLNS_IFACE, 'command', {'path': 'dummy', 'name': 'run'}), None)
		impl.add_download_source('http://localhost/bar.tgz', 1000, None)
		feed.implementations = {impl.id: impl}
		assert driver.need_download()
		assert driver.solver.ready, driver.solver.get_failure_reason()
		s1 = driver.solver.selections
		xml = s1.toDOM().toxml("utf-8")
		root = qdom.parse(BytesIO(xml))
		s2 = selections.Selections(root)
		xml = s2.toDOM().toxml("utf-8")
		qdom.parse(BytesIO(xml))
		assert s2.selections[iface].local_path is None
		assert not s2.selections[iface].digests, s2.selections[iface].digests
		assert s2.selections[iface].id == 'foo bar=123'
Example #2
0
    def testLocalPath(self):
        # 0launch --get-selections Local.xml
        iface = os.path.join(mydir, "Local.xml")
        p = policy.Policy(iface, config=self.config)
        p.need_download()
        assert p.ready
        s1 = selections.Selections(p)
        xml = s1.toDOM().toxml("utf-8")

        # Reload selections and check they're the same
        root = qdom.parse(StringIO(xml))
        s2 = selections.Selections(root)
        local_path = s2.selections[iface].local_path
        assert os.path.isdir(local_path), local_path
        assert not s2.selections[iface].digests, s2.selections[iface].digests

        # Add a newer implementation and try again
        feed = self.config.iface_cache.get_feed(iface)
        impl = model.ZeroInstallImplementation(feed, "foo bar=123", local_path=None)
        impl.version = model.parse_version("1.0")
        impl.commands["run"] = model.Command(qdom.Element(namespaces.XMLNS_IFACE, "command", {"path": "dummy"}), None)
        impl.add_download_source("http://localhost/bar.tgz", 1000, None)
        feed.implementations = {impl.id: impl}
        assert p.need_download()
        assert p.ready, p.solver.get_failure_reason()
        s1 = selections.Selections(p)
        xml = s1.toDOM().toxml("utf-8")
        root = qdom.parse(StringIO(xml))
        s2 = selections.Selections(root)
        xml = s2.toDOM().toxml("utf-8")
        qdom.parse(StringIO(xml))
        assert s2.selections[iface].local_path is None
        assert not s2.selections[iface].digests, s2.selections[iface].digests
        assert s2.selections[iface].id == "foo bar=123"
Example #3
0
	def get_selections(self, prompt = False):
		if self._selections:
			assert not prompt
			return self._selections

		selections_file = self.config.get('compile', 'selections')
		if selections_file:
			if prompt:
				raise SafeException("Selections are fixed by %s" % selections_file)
			stream = file(selections_file)
			try:
				self._selections = selections.Selections(qdom.parse(stream))
			finally:
				stream.close()
			from zeroinstall.injector import handler
			from zeroinstall.injector.config import load_config
			if os.isatty(1):
				h = handler.ConsoleHandler()
			else:
				h = handler.Handler()
			config = load_config(h)
			blocker = self._selections.download_missing(config)
			if blocker:
				print "Waiting for selected implementations to be downloaded..."
				h.wait_for_blocker(blocker)
		else:
			command = install_prog + ['download', '--source', '--xml']
			if prompt and '--console' not in install_prog:
				if os.name == 'nt':
					command[0] += '-win'
				command.append('--gui')
			command.append(self.interface)
			child = subprocess.Popen(command, stdout = subprocess.PIPE)
			try:
				self._selections = selections.Selections(qdom.parse(child.stdout))
			finally:
				if child.wait():
					raise SafeException(' '.join(repr(x) for x in command) + " failed (exit code %d)" % child.returncode)

		self.root_impl = self._selections.selections[self.interface]

		self.orig_srcdir = os.path.realpath(lookup(self.root_impl))
		self.user_srcdir = None

		if os.path.isdir('src'):
			self.user_srcdir = os.path.realpath('src')
			if self.user_srcdir == self.orig_srcdir or \
			   self.user_srcdir.startswith(os.path.join(self.orig_srcdir, '')) or \
			   self.orig_srcdir.startswith(os.path.join(self.user_srcdir, '')):
				info("Ignoring 'src' directory because it coincides with %s",
					self.orig_srcdir)
				self.user_srcdir = None

		return self._selections
Example #4
0
	def get_selections(self, prompt = False):
		if self._selections:
			assert not prompt
			return self._selections

		selections_file = self.config.get('compile', 'selections')
		if selections_file:
			if prompt:
				raise SafeException("Selections are fixed by %s" % selections_file)
			stream = file(selections_file)
			try:
				self._selections = selections.Selections(qdom.parse(stream))
			finally:
				stream.close()
			from zeroinstall.injector import handler
			from zeroinstall.injector.config import load_config
			if os.isatty(1):
				h = handler.ConsoleHandler()
			else:
				h = handler.Handler()
			config = load_config(h)
			blocker = self._selections.download_missing(config)
			if blocker:
				print "Waiting for selected implementations to be downloaded..."
				h.wait_for_blocker(blocker)
		else:
			command = install_prog + ['download', '--source', '--xml']
			if prompt and '--console' not in install_prog:
				if os.name == 'nt':
					command[0] += '-win'
				command.append('--gui')
			command.append(self.interface)
			child = subprocess.Popen(command, stdout = subprocess.PIPE)
			try:
				self._selections = selections.Selections(qdom.parse(child.stdout))
			finally:
				if child.wait():
					raise SafeException(' '.join(repr(x) for x in command) + " failed (exit code %d)" % child.returncode)

		self.root_impl = self._selections.selections[self.interface]

		self.orig_srcdir = os.path.realpath(lookup(self.root_impl))
		self.user_srcdir = None

		if os.path.isdir('src'):
			self.user_srcdir = os.path.realpath('src')
			if self.user_srcdir == self.orig_srcdir or \
			   self.user_srcdir.startswith(os.path.join(self.orig_srcdir, '')) or \
			   self.orig_srcdir.startswith(os.path.join(self.user_srcdir, '')):
				info("Ignoring 'src' directory because it coincides with %s",
					self.orig_srcdir)
				self.user_srcdir = None

		return self._selections
	def testOverlay(self):
		for xml, expected in [(b'<overlay/>', '<overlay . on />'),
				      (b'<overlay src="usr"/>', '<overlay usr on />'),
				      (b'<overlay src="package" mount-point="/usr/games"/>', '<overlay package on /usr/games>')]:
			e = qdom.parse(BytesIO(xml))
			ol = model.process_binding(e)
			self.assertEqual(expected, str(ol))

			doc = minidom.parseString('<doc/>')
			new_xml = ol._toxml(doc, None).toxml(encoding = 'utf-8')
			new_e = qdom.parse(BytesIO(new_xml))
			new_ol = model.process_binding(new_e)
			self.assertEqual(expected, str(new_ol))
Example #6
0
	def testOverlay(self):
		for xml, expected in [('<overlay/>', '<overlay . on />'),
				      ('<overlay src="usr"/>', '<overlay usr on />'),
				      ('<overlay src="package" mount-point="/usr/games"/>', '<overlay package on /usr/games>')]:
			e = qdom.parse(StringIO(xml))
			ol = model.process_binding(e)
			self.assertEquals(expected, str(ol))

			doc = minidom.parseString('<doc/>')
			new_xml = str(ol._toxml(doc).toxml())
			new_e = qdom.parse(StringIO(new_xml))
			new_ol = model.process_binding(new_e)
			self.assertEquals(expected, str(new_ol))
Example #7
0
    def testOldCommands(self):
        command_feed = os.path.join(mydir, 'old-selections.xml')
        with open(command_feed, 'rb') as stream:
            s1 = selections.Selections(qdom.parse(stream))
        self.assertEqual("run", s1.command)
        self.assertEqual(2, len(s1.commands))
        self.assertEqual("bin/java", s1.commands[1].path)

        xml = s1.toDOM().toxml("utf-8")
        root = qdom.parse(BytesIO(xml))
        s2 = selections.Selections(root)

        self.assertEqual("run", s2.command)
        self.assertEqual(2, len(s2.commands))
        self.assertEqual("bin/java", s2.commands[1].path)
Example #8
0
	def testOldCommands(self):
		command_feed = os.path.join(mydir, 'old-selections.xml')
		with open(command_feed, 'rb') as stream:
			s1 = selections.Selections(qdom.parse(stream))
		self.assertEqual("run", s1.command)
		self.assertEqual(2, len(s1.commands))
		self.assertEqual("bin/java", s1.commands[1].path)

		xml = s1.toDOM().toxml("utf-8")
		root = qdom.parse(BytesIO(xml))
		s2 = selections.Selections(root)

		self.assertEqual("run", s2.command)
		self.assertEqual(2, len(s2.commands))
		self.assertEqual("bin/java", s2.commands[1].path)
Example #9
0
    def get_selections(self,
                       snapshot_date=None,
                       may_update=False,
                       use_gui=None):
        """Load the selections.
		If may_update is True then the returned selections will be cached and available.
		@param snapshot_date: get a historical snapshot
		@type snapshot_date: (as returned by L{get_history}) | None
		@param may_update: whether to check for updates
		@type may_update: bool
		@param use_gui: whether to use the GUI for foreground updates
		@type use_gui: bool | None (never/always/if possible)
		@return: the selections
		@rtype: L{selections.Selections}"""
        if snapshot_date:
            assert may_update is False, "Can't update a snapshot!"
            sels_file = os.path.join(self.path,
                                     'selections-' + snapshot_date + '.xml')
        else:
            sels_file = os.path.join(self.path, 'selections.xml')

        try:
            with open(sels_file, 'rb') as stream:
                sels = selections.Selections(qdom.parse(stream))
        except IOError as ex:
            if may_update and ex.errno == errno.ENOENT:
                logger.info("App selections missing: %s", ex)
                sels = None
            else:
                raise

        if may_update:
            sels = self._check_for_updates(sels, use_gui)

        return sels
Example #10
0
    def testSelectionsWithFeed(self):
        from zeroinstall.injector import cli

        root = qdom.parse(file("selections.xml"))
        sels = selections.Selections(root)

        with output_suppressed():
            self.child = server.handle_requests(
                "Hello.xml",
                "6FCF121BE2390E0B.gpg",
                "/key-info/key/DE937DD411906ACF7C263B396FCF121BE2390E0B",
                "HelloWorld.tgz",
            )
            sys.stdin = Reply("Y\n")

            self.config.handler.wait_for_blocker(
                self.config.fetcher.download_and_import_feed(
                    "http://example.com:8000/Hello.xml", self.config.iface_cache
                )
            )

            cli.main(["--download-only", "selections.xml"], config=self.config)
            path = self.config.stores.lookup_any(sels.selections["http://example.com:8000/Hello.xml"].digests)
            assert os.path.exists(os.path.join(path, "HelloWorld", "main"))

            assert sels.download_missing(self.config) is None
Example #11
0
    def testSelections(self):
        from zeroinstall.injector import cli

        root = qdom.parse(file("selections.xml"))
        sels = selections.Selections(root)

        class Options:
            dry_run = False

        with output_suppressed():
            self.child = server.handle_requests(
                "Hello.xml",
                "6FCF121BE2390E0B.gpg",
                "/key-info/key/DE937DD411906ACF7C263B396FCF121BE2390E0B",
                "HelloWorld.tgz",
            )
            sys.stdin = Reply("Y\n")
            try:
                self.config.stores.lookup_any(sels.selections["http://example.com:8000/Hello.xml"].digests)
                assert False
            except NotStored:
                pass
            cli.main(["--download-only", "selections.xml"])
            path = self.config.stores.lookup_any(sels.selections["http://example.com:8000/Hello.xml"].digests)
            assert os.path.exists(os.path.join(path, "HelloWorld", "main"))

            assert sels.download_missing(self.config) is None
Example #12
0
def update_user_overrides(interface):
	"""Update an interface with user-supplied information.
	Sets preferred stability and updates extra_feeds.
	@param interface: the interface object to update
	@type interface: L{model.Interface}
	"""
	user = basedir.load_first_config(config_site, config_prog,
					   'interfaces', model._pretty_escape(interface.uri))
	if user is None:
		# For files saved by 0launch < 0.49
		user = basedir.load_first_config(config_site, config_prog,
						   'user_overrides', escape(interface.uri))
	if not user:
		return

	try:
		root = qdom.parse(file(user))
	except Exception as ex:
		warn(_("Error reading '%(user)s': %(exception)s"), {'user': user, 'exception': ex})
		raise

	stability_policy = root.getAttribute('stability-policy')
	if stability_policy:
		interface.set_stability_policy(stability_levels[str(stability_policy)])

	for item in root.childNodes:
		if item.uri != XMLNS_IFACE: continue
		if item.name == 'feed':
			feed_src = item.getAttribute('src')
			if not feed_src:
				raise InvalidInterface(_('Missing "src" attribute in <feed>'))
			interface.extra_feeds.append(Feed(feed_src, item.getAttribute('arch'), True, langs = item.getAttribute('langs')))
Example #13
0
def handle(config, options, args):
    if len(args) != 1:
        raise UsageError()

    app = config.app_mgr.lookup_app(args[0], missing_ok=True)
    if app is not None:
        sels = app.get_selections()

        r = app.get_requirements()

        if r.extra_restrictions and not options.xml:
            print("User-provided restrictions in force:")
            for uri, expr in r.extra_restrictions.items():
                print("  {uri}: {expr}".format(uri=uri, expr=expr))
            print()
    elif os.path.exists(args[0]):
        with open(args[0], 'rb') as stream:
            sels = selections.Selections(qdom.parse(stream))
    else:
        raise SafeException(_("Neither an app nor a file: '%s'") % args[0])

    if options.root_uri:
        print(sels.interface)
    elif options.xml:
        select.show_xml(sels)
    else:
        select.show_human(sels, config.stores)
    def testSelections(self):
        from zeroinstall.injector import cli
        root = qdom.parse(file("selections.xml"))
        sels = selections.Selections(root)

        class Options:
            dry_run = False

        with output_suppressed():
            self.child = server.handle_requests(
                'Hello.xml', '6FCF121BE2390E0B.gpg',
                '/key-info/key/DE937DD411906ACF7C263B396FCF121BE2390E0B',
                'HelloWorld.tgz')
            sys.stdin = Reply("Y\n")
            try:
                self.config.stores.lookup_any(
                    sels.selections['http://example.com:8000/Hello.xml'].
                    digests)
                assert False
            except NotStored:
                pass
            cli.main(['--download-only', 'selections.xml'], config=self.config)
            path = self.config.stores.lookup_any(
                sels.selections['http://example.com:8000/Hello.xml'].digests)
            assert os.path.exists(os.path.join(path, 'HelloWorld', 'main'))

            assert sels.download_missing(self.config) is None
Example #15
0
def load_feed(source, local=False, selections_ok=False):
    """Load a feed from a local file.
	@param source: the name of the file to read
	@type source: str
	@param local: this is a local feed
	@type local: bool
	@param selections_ok: if it turns out to be a local selections document, return that instead
	@type selections_ok: bool
	@raise InvalidInterface: if the source's syntax is incorrect
	@return: the new feed
	@since: 0.48
	@see: L{iface_cache.iface_cache}, which uses this to load the feeds"""
    try:
        root = qdom.parse(open(source))
    except IOError as ex:
        if ex.errno == errno.ENOENT and local:
            raise MissingLocalFeed(
                _("Feed not found. Perhaps this is a local feed that no longer exists? You can remove it from the list of feeds in that case."
                  ))
        raise InvalidInterface(_("Can't read file"), ex)
    except Exception as ex:
        raise InvalidInterface(_("Invalid XML"), ex)

    if local:
        if selections_ok and root.uri == XMLNS_IFACE and root.name == 'selections':
            from zeroinstall.injector import selections
            return selections.Selections(root)
        local_path = source
    else:
        local_path = None
    feed = ZeroInstallFeed(root, local_path)
    feed.last_modified = int(os.stat(source).st_mtime)
    return feed
Example #16
0
    def build(selections_xml):
        # Get the chosen versions
        sels = selections.Selections(qdom.parse(BytesIO(selections_xml)))

        impl = sels.selections[interface_uri]

        min_version = impl.attrs.get(XMLNS_0COMPILE + " min-version", our_min_version)
        # Check the syntax is valid and the version is high enough
        if model.parse_version(min_version) < model.parse_version(our_min_version):
            min_version = our_min_version

            # Do the whole build-and-register-feed
        c = Command()
        c.run(
            (
                "0launch",
                "--message",
                _("Download the 0compile tool, to compile the source code"),
                "--not-before=" + min_version,
                "http://0install.net/2006/interfaces/0compile.xml",
                "gui",
                interface_uri,
            ),
            lambda unused: on_success(),
        )
Example #17
0
    def testDownload(self):
        out, err = self.run_0install(["download"])
        assert out.lower().startswith("usage:")
        assert "--show" in out

        out, err = self.run_0install(["download", "Local.xml", "--show"])
        assert not err, err
        assert "Version: 0.1" in out

        local_uri = model.canonical_iface_uri("Local.xml")
        out, err = self.run_0install(["download", "Local.xml", "--xml"])
        assert not err, err
        sels = selections.Selections(qdom.parse(StringIO(str(out))))
        assert sels.selections[local_uri].version == "0.1"

        out, err = self.run_0install(["download", "Local.xml", "--show", "--with-store=/foo"])
        assert not err, err
        assert self.config.stores.stores[-1].dir == "/foo"

        out, err = self.run_0install(["download", "--offline", "selections.xml"])
        assert "Would download" in err
        self.config.network_use = model.network_full

        self.config.stores = TestStores()
        digest = "sha1=3ce644dc725f1d21cfcf02562c76f375944b266a"
        self.config.fetcher.allow_download(digest)
        out, err = self.run_0install(["download", "Hello.xml", "--show"])
        assert not err, err
        assert self.config.stores.lookup_any([digest]).startswith("/fake")
        assert "Version: 1\n" in out

        out, err = self.run_0install(["download", "--offline", "selections.xml", "--show"])
        assert "/fake_store" in out
        self.config.network_use = model.network_full
Example #18
0
	def action_help(self, uri):
		from zeroinstall.injector.config import load_config
		c = load_config()
		xml = subprocess.check_output(['0install', 'download', '--xml', '--', uri], universal_newlines = False)

		sels = selections.Selections(qdom.parse(BytesIO(xml)))

		impl = sels.selections[uri]
		assert impl, "Failed to choose an implementation of %s" % uri
		help_dir = impl.attrs.get('doc-dir')

		if impl.id.startswith('package:'):
			assert os.path.isabs(help_dir), "Package doc-dir must be absolute!"
			path = help_dir
		else:
			path = impl.local_path or c.stores.lookup_any(impl.digests)

			assert path, "Chosen implementation is not cached!"
			if help_dir:
				path = os.path.join(path, help_dir)
			else:
				main = impl.main
				if main:
					# Hack for ROX applications. They should be updated to
					# set doc-dir.
					help_dir = os.path.join(path, os.path.dirname(main), 'Help')
					if os.path.isdir(help_dir):
						path = help_dir

		# xdg-open has no "safe" mode, so check we're not "opening" an application.
		if os.path.exists(os.path.join(path, 'AppRun')):
			raise Exception(_("Documentation directory '%s' is an AppDir; refusing to open") % path)

		subprocess.Popen(['xdg-open', path])
Example #19
0
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')
Example #20
0
def handle(config, options, args):
	if len(args) == 0:
		raise UsageError()

	url = config.mirror + '/search/?q=' + quote(' '.join(args))
	logger.info("Fetching %s...", url)
	root = qdom.parse(urllib2.urlopen(url))
	assert root.name == 'results'

	first = True
	for child in root.childNodes:
		if child.name != 'result': continue

		if first:
			first = False
		else:
			print()

		print(child.attrs['uri'])
		score = child.attrs['score']

		details = {}
		for detail in child.childNodes:
			details[detail.name] = detail.content
		print("  {name} - {summary} [{score}%]".format(
			name = child.attrs['name'],
			summary = details.get('summary', ''),
			score = score))
Example #21
0
def load_feed(source, local = False, selections_ok = False):
	"""Load a feed from a local file.
	@param source: the name of the file to read
	@type source: str
	@param local: this is a local feed
	@type local: bool
	@param selections_ok: if it turns out to be a local selections document, return that instead
	@type selections_ok: bool
	@raise InvalidInterface: if the source's syntax is incorrect
	@return: the new feed
	@since: 0.48
	@see: L{iface_cache.iface_cache}, which uses this to load the feeds"""
	try:
		with open(source, 'rb') as stream:
			root = qdom.parse(stream)
	except IOError as ex:
		if ex.errno == errno.ENOENT and local:
			raise MissingLocalFeed(_("Feed not found. Perhaps this is a local feed that no longer exists? You can remove it from the list of feeds in that case."))
		raise InvalidInterface(_("Can't read file"), ex)
	except Exception as ex:
		raise InvalidInterface(_("Invalid XML"), ex)

	if local:
		if selections_ok and root.uri == XMLNS_IFACE and root.name == 'selections':
			from zeroinstall.injector import selections
			return selections.Selections(root)
		local_path = source
	else:
		local_path = None
	feed = ZeroInstallFeed(root, local_path)
	feed.last_modified = int(os.stat(source).st_mtime)
	return feed
Example #22
0
	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)
Example #23
0
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')
Example #24
0
def handle(args):
    files = [abspath(f) for f in args.path]

    if not cmd.find_config(missing_ok=True):
        # Import into appropriate registry for this feed
        with open(files[0], 'rb') as stream:
            doc = qdom.parse(stream)
        master = incoming.get_feed_url(doc, files[0])

        from_registry = registry.lookup(master)

        assert from_registry[
            'type'] == 'local', 'Unsupported registry type in %s' % from_registry
        os.chdir(from_registry['path'])

        print("Adding to registry '{path}'".format(path=from_registry['path']))

    config = cmd.load_config()

    messages = []
    for feed in files:
        print("Adding", feed)
        msg = incoming.process(config, feed, delete_on_success=False)
        if msg:
            messages.append(msg)
    update.do_update(config, messages=messages)
Example #25
0
	def testSelect(self):
		out, err = self.run_ocaml(['select'])
		assert out.lower().startswith("usage:")
		assert '--xml' in out

		out, err = self.run_ocaml(['select', 'Local.xml'])
		assert not err, err
		assert 'Version: 0.1' in out

		out, err = self.run_ocaml(['select', 'Local.xml', '--command='])
		assert not err, err
		assert 'Version: 0.1' in out

		local_uri = os.path.realpath('Local.xml')
		out, err = self.run_ocaml(['select', 'Local.xml'])
		assert not err, err
		assert 'Version: 0.1' in out

		out, err = self.run_ocaml(['select', 'Local.xml', '--xml'])
		sels = selections.Selections(qdom.parse(BytesIO(str(out).encode('utf-8'))))
		assert sels.selections[local_uri].version == '0.1'

		# This now triggers a download to fetch the feed.
		#out, err = self.run_ocaml(['select', 'selections.xml'])
		#assert not err, err
		#assert 'Version: 1\n' in out
		#assert '(not cached)' in out

		out, err = self.run_ocaml(['select', 'runnable/RunExec.xml'])
		assert not err, err
		assert 'Runner' in out, out
Example #26
0
    def testSelect(self):
        out, err = self.run_0install(["select"])
        assert out.lower().startswith("usage:")
        assert "--xml" in out

        out, err = self.run_0install(["select", "Local.xml"])
        assert not err, err
        assert "Version: 0.1" in out

        out, err = self.run_0install(["select", "Local.xml", "--command="])
        assert not err, err
        assert "Version: 0.1" in out

        local_uri = model.canonical_iface_uri("Local.xml")
        out, err = self.run_0install(["select", "Local.xml"])
        assert not err, err
        assert "Version: 0.1" in out

        out, err = self.run_0install(["select", "Local.xml", "--xml"])
        sels = selections.Selections(qdom.parse(StringIO(str(out))))
        assert sels.selections[local_uri].version == "0.1"

        out, err = self.run_0install(["select", "selections.xml"])
        assert not err, err
        assert "Version: 1\n" in out
        assert "(not cached)" in out

        out, err = self.run_0install(["select", "runnable/RunExec.xml"])
        assert not err, err
        assert "Runner" in out, out
Example #27
0
def handle(args):
	files = [abspath(f) for f in args.path]

	if not cmd.find_config(missing_ok = True):
		# Import into appropriate registry for this feed
		with open(files[0], 'rb') as stream:
			doc = qdom.parse(stream)
		master = incoming.get_feed_url(doc, files[0])

		from_registry = registry.lookup(master)

		assert from_registry['type'] == 'local', 'Unsupported registry type in %s' % from_registry
		os.chdir(from_registry['path'])

		print("Adding to registry '{path}'".format(path = from_registry['path']))

	config = cmd.load_config()

	messages = []
	for feed in files:
		print("Adding", feed)
		msg = incoming.process(config, feed, delete_on_success = False)
		if msg:
			messages.append(msg)
	update.do_update(config, messages = messages)
Example #28
0
	def testDownload(self):
		out, err = self.run_0install(['download'])
		assert out.lower().startswith("usage:")
		assert '--show' in out

		out, err = self.run_0install(['download', 'Local.xml', '--show'])
		assert not err, err
		assert 'Version: 0.1' in out

		local_uri = model.canonical_iface_uri('Local.xml')
		out, err = self.run_0install(['download', 'Local.xml', '--xml'])
		assert not err, err
		sels = selections.Selections(qdom.parse(BytesIO(str(out).encode('utf-8'))))
		assert sels.selections[local_uri].version == '0.1'

		out, err = self.run_0install(['download', 'Local.xml', '--show', '--with-store=/foo'])
		assert not err, err
		assert self.config.stores.stores[-1].dir == '/foo'

		out, err = self.run_0install(['download', '--offline', 'selections.xml'])
		assert 'Would download' in err
		self.config.network_use = model.network_full

		self.config.stores = TestStores()
		digest = 'sha1=3ce644dc725f1d21cfcf02562c76f375944b266a'
		self.config.fetcher.allow_download(digest)
		out, err = self.run_0install(['download', 'Hello.xml', '--show'])
		assert not err, err
		assert self.config.stores.lookup_any([digest]).startswith('/fake')
		assert 'Version: 1\n' in out

		out, err = self.run_0install(['download', '--offline', 'selections.xml', '--show'])
		assert '/fake_store' in out
		self.config.network_use = model.network_full
Example #29
0
def load_feed(source, local=False):
    """Load a feed from a local file.
	@param source: the name of the file to read
	@type source: str
	@param local: this is a local feed
	@type local: bool
	@return: the new feed
	@rtype: L{ZeroInstallFeed}
	@raise InvalidInterface: if the source's syntax is incorrect
	@since: 0.48
	@see: L{iface_cache.iface_cache}, which uses this to load the feeds"""
    try:
        with open(source, "rb") as stream:
            root = qdom.parse(stream, filter_for_version=True)
    except IOError as ex:
        if ex.errno == errno.ENOENT and local:
            raise MissingLocalFeed(
                _(
                    "Feed not found. Perhaps this is a local feed that no longer exists? You can remove it from the list of feeds in that case."
                )
            )
        raise InvalidInterface(_("Can't read file"), ex)
    except Exception as ex:
        raise InvalidInterface(_("Invalid XML"), ex)

    if local:
        assert os.path.isabs(source), source
        local_path = source
    else:
        local_path = None
    feed = ZeroInstallFeed(root, local_path)
    feed.last_modified = int(os.stat(source).st_mtime)
    return feed
Example #30
0
	def get_selections(self, snapshot_date = None, may_update = False, use_gui = None):
		"""Load the selections.
		If may_update is True then the returned selections will be cached and available.
		@param snapshot_date: get a historical snapshot
		@type snapshot_date: (as returned by L{get_history}) | None
		@param may_update: whether to check for updates
		@type may_update: bool
		@param use_gui: whether to use the GUI for foreground updates
		@type use_gui: bool | None (never/always/if possible)
		@return: the selections
		@rtype: L{selections.Selections}"""
		if snapshot_date:
			assert may_update is False, "Can't update a snapshot!"
			sels_file = os.path.join(self.path, 'selections-' + snapshot_date + '.xml')
		else:
			sels_file = os.path.join(self.path, 'selections.xml')

		try:
			with open(sels_file, 'rb') as stream:
				sels = selections.Selections(qdom.parse(stream))
		except IOError as ex:
			if may_update and ex.errno == errno.ENOENT:
				logger.info("App selections missing: %s", ex)
				sels = None
			else:
				raise

		if may_update:
			sels = self._check_for_updates(sels, use_gui)

		return sels
Example #31
0
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)))
Example #32
0
	def testSelect(self):
		out, err = self.run_0install(['select'])
		assert out.lower().startswith("usage:")
		assert '--xml' in out

		out, err = self.run_0install(['select', 'Local.xml'])
		assert not err, err
		assert 'Version: 0.1' in out

		out, err = self.run_0install(['select', 'Local.xml', '--command='])
		assert not err, err
		assert 'Version: 0.1' in out

		local_uri = model.canonical_iface_uri('Local.xml')
		out, err = self.run_0install(['select', 'Local.xml'])
		assert not err, err
		assert 'Version: 0.1' in out

		out, err = self.run_0install(['select', 'Local.xml', '--xml'])
		sels = selections.Selections(qdom.parse(BytesIO(str(out).encode('utf-8'))))
		assert sels.selections[local_uri].version == '0.1'

		out, err = self.run_0install(['select', 'selections.xml'])
		assert not err, err
		assert 'Version: 1\n' in out
		assert '(not cached)' in out

		out, err = self.run_0install(['select', 'runnable/RunExec.xml'])
		assert not err, err
		assert 'Runner' in out, out
Example #33
0
def handle(config, options, args):
	if len(args) != 1:
		raise UsageError()

	app = config.app_mgr.lookup_app(args[0], missing_ok = True)
	if app is not None:
		sels = app.get_selections()

		r = app.get_requirements()

		if r.extra_restrictions and not options.xml:
			print("User-provided restrictions in force:")
			for uri, expr in r.extra_restrictions.items():
				print("  {uri}: {expr}".format(uri = uri, expr = expr))
			print()
	elif os.path.exists(args[0]):
		with open(args[0], 'rb') as stream:
			sels = selections.Selections(qdom.parse(stream))
	else:
		raise SafeException(_("Neither an app nor a file: '%s'") % args[0])

	if options.root_uri:
		print(sels.interface)
	elif options.xml:
		select.show_xml(sels)
	else:
		select.show_human(sels, config.stores)
Example #34
0
    def testSelect(self):
        out, err = self.run_0install(['select'])
        assert out.lower().startswith("usage:")
        assert '--xml' in out

        out, err = self.run_0install(['select', 'Local.xml'])
        assert not err, err
        assert 'Version: 0.1' in out

        out, err = self.run_0install(['select', 'Local.xml', '--command='])
        assert not err, err
        assert 'Version: 0.1' in out

        local_uri = model.canonical_iface_uri('Local.xml')
        out, err = self.run_0install(['select', 'Local.xml'])
        assert not err, err
        assert 'Version: 0.1' in out

        out, err = self.run_0install(['select', 'Local.xml', '--xml'])
        sels = selections.Selections(
            qdom.parse(BytesIO(str(out).encode('utf-8'))))
        assert sels.selections[local_uri].version == '0.1'

        out, err = self.run_0install(['select', 'selections.xml'])
        assert not err, err
        assert 'Version: 1\n' in out
        assert '(not cached)' in out

        out, err = self.run_0install(['select', 'runnable/RunExec.xml'])
        assert not err, err
        assert 'Runner' in out, out
Example #35
0
    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)
Example #36
0
def handle(config, options, args):
    if len(args) == 0:
        raise UsageError()

    url = config.mirror + '/search/?q=' + quote(' '.join(args))
    logger.info("Fetching %s...", url)
    root = qdom.parse(urllib2.urlopen(url))
    assert root.name == 'results'

    first = True
    for child in root.childNodes:
        if child.name != 'result': continue

        if first:
            first = False
        else:
            print()

        print(child.attrs['uri'])
        score = child.attrs['score']

        details = {}
        for detail in child.childNodes:
            details[detail.name] = detail.content
        print("  {name} - {summary} [{score}%]".format(
            name=child.attrs['name'],
            summary=details.get('summary', ''),
            score=score))
	def testCommands(self):
		iface = os.path.join(mydir, "Command.xml")
		p = policy.Policy(iface, config = self.config)
		p.need_download()
		assert p.ready

		impl = p.solver.selections[self.config.iface_cache.get_interface(iface)]
		assert impl.id == 'c'
		assert impl.main == 'runnable/missing'

		dep_impl_uri = impl.commands['run'].requires[0].interface
		dep_impl = p.solver.selections[self.config.iface_cache.get_interface(dep_impl_uri)]
		assert dep_impl.id == 'sha1=256'

		s1 = selections.Selections(p)
		assert s1.commands[0].path == 'runnable/missing'
		xml = s1.toDOM().toxml("utf-8")
		root = qdom.parse(StringIO(xml))
		s2 = selections.Selections(root)

		assert s2.commands[0].path == 'runnable/missing'
		impl = s2.selections[iface]
		assert impl.id == 'c'

		assert s2.commands[0].qdom.attrs['http://custom attr'] == 'namespaced'
		custom_element = s2.commands[0].qdom.childNodes[0]
		assert custom_element.name == 'child'

		dep_impl = s2.selections[dep_impl_uri]
		assert dep_impl.id == 'sha1=256'
    def testCommands(self):
        iface = os.path.join(mydir, "Command.xml")
        p = policy.Policy(iface, config=self.config)
        p.need_download()
        assert p.ready

        impl = p.solver.selections[self.config.iface_cache.get_interface(
            iface)]
        assert impl.id == 'c'
        assert impl.main == 'runnable/missing'

        dep_impl_uri = impl.commands['run'].requires[0].interface
        dep_impl = p.solver.selections[self.config.iface_cache.get_interface(
            dep_impl_uri)]
        assert dep_impl.id == 'sha1=256'

        s1 = selections.Selections(p)
        assert s1.commands[0].path == 'runnable/missing'
        xml = s1.toDOM().toxml("utf-8")
        root = qdom.parse(StringIO(xml))
        s2 = selections.Selections(root)

        assert s2.commands[0].path == 'runnable/missing'
        impl = s2.selections[iface]
        assert impl.id == 'c'

        assert s2.commands[0].qdom.attrs['http://custom attr'] == 'namespaced'
        custom_element = s2.commands[0].qdom.childNodes[0]
        assert custom_element.name == 'child'

        dep_impl = s2.selections[dep_impl_uri]
        assert dep_impl.id == 'sha1=256'
Example #39
0
def handle_invoke(config, options, ticket, request):
    try:
        command = request[0]
        logger.debug("Got request '%s'", command)
        if command == 'get-selections-gui':
            response = do_get_selections_gui(config, request[1:])
        elif command == 'wait-for-network':
            response = do_wait_for_network(config)
        elif command == 'download-selections':
            l = stdin.readline().strip()
            xml = qdom.parse(BytesIO(stdin.read(int(l))))
            blocker = do_download_selections(config, options, request[1:], xml)
            reply_when_done(ticket, blocker)
            return  #async
        elif command == 'get-package-impls':
            l = stdin.readline().strip()
            xml = qdom.parse(BytesIO(stdin.read(int(l))))
            response = do_get_package_impls(config, options, request[1:], xml)
        elif command == 'is-distro-package-installed':
            l = stdin.readline().strip()
            xml = qdom.parse(BytesIO(stdin.read(int(l))))
            response = do_is_distro_package_installed(config, options, xml)
        elif command == 'get-distro-candidates':
            l = stdin.readline().strip()
            xml = qdom.parse(BytesIO(stdin.read(int(l))))
            blocker = do_get_distro_candidates(config, request[1:], xml)
            reply_when_done(ticket, blocker)
            return  # async
        elif command == 'download-and-import-feed':
            blocker = do_download_and_import_feed(config, request[1:])
            reply_when_done(ticket, blocker)
            return  # async
        elif command == 'notify-user':
            response = do_notify_user(config, request[1])
        else:
            raise SafeException("Internal error: unknown command '%s'" %
                                command)
        response = ['ok', response]
    except SafeException as ex:
        logger.info("Replying with error: %s", ex)
        response = ['error', str(ex)]
    except Exception as ex:
        import traceback
        logger.info("Replying with error: %s", ex)
        response = ['error', traceback.format_exc().strip()]

    send_json(["return", ticket, response])
	def testSitePackages(self):
		# The old system (0install < 1.9):
		# - 0compile stores implementations to ~/.cache, and 
		# - adds to extra_feeds
		#
		# The middle system (0install 1.9..1.12)
		# - 0compile stores implementations to ~/.local/0install.net/site-packages
		#   but using an obsolete escaping scheme, and
		# - modern 0install finds them via extra_feeds
		#
		# The new system (0install >= 1.13):
		# - 0compile stores implementations to ~/.local/0install.net/site-packages, and
		# - 0install finds them automatically

		# For backwards compatibility, 0install >= 1.9:
		# - writes discovered feeds to extra_feeds
		# - skips such entries in extra_feeds when loading

		expected_escape = 'section__prog_5f_1.xml'

		meta_dir = basedir.save_data_path('0install.net', 'site-packages',
						   'http', 'example.com', expected_escape, '1.0', '0install')
		feed = os.path.join(meta_dir, 'feed.xml')
		shutil.copyfile(os.path.join(mydir, 'Local.xml'), feed)

		# Check that we find the feed without us having to register it
		iface = self.config.iface_cache.get_interface('http://example.com/section/prog_1.xml')
		self.assertEqual(1, len(iface.extra_feeds))
		site_feed, = iface.extra_feeds
		self.assertEqual(True, site_feed.site_package)

		# Check that we write it out, so that older 0installs can find it
		writer.save_interface(iface)

		config_file = basedir.load_first_config('0install.net', 'injector',
							'interfaces', 'http:##example.com#section#prog_1.xml')
		with open(config_file, 'rb') as s:
			doc = qdom.parse(s)

		feed_node = None
		for item in doc.childNodes:
			if item.name == 'feed':
				feed_node = item
		self.assertEqual('True', feed_node.getAttribute('is-site-package'))

		# Check we ignore this element
		iface.reset()
		self.assertEqual([], iface.extra_feeds)
		reader.update_user_overrides(iface)
		self.assertEqual([], iface.extra_feeds)

		# Check feeds are automatically removed again
		reader.update_from_cache(iface, iface_cache = self.config.iface_cache)
		self.assertEqual(1, len(iface.extra_feeds))
		shutil.rmtree(basedir.load_first_data('0install.net', 'site-packages',
							'http', 'example.com', expected_escape))

		reader.update_from_cache(iface, iface_cache = self.config.iface_cache)
		self.assertEqual(0, len(iface.extra_feeds))
Example #41
0
def handle_invoke(config, options, ticket, request):
	try:
		command = request[0]
		logger.debug("Got request '%s'", command)
		if command == 'get-selections-gui':
			response = do_get_selections_gui(config, request[1:])
		elif command == 'wait-for-network':
			response = do_wait_for_network(config)
		elif command == 'download-selections':
			l = stdin.readline().strip()
			xml = qdom.parse(BytesIO(stdin.read(int(l))))
			blocker = do_download_selections(config, options, request[1:], xml)
			reply_when_done(ticket, blocker)
			return #async
		elif command == 'get-package-impls':
			l = stdin.readline().strip()
			xml = qdom.parse(BytesIO(stdin.read(int(l))))
			response = do_get_package_impls(config, options, request[1:], xml)
		elif command == 'is-distro-package-installed':
			l = stdin.readline().strip()
			xml = qdom.parse(BytesIO(stdin.read(int(l))))
			response = do_is_distro_package_installed(config, options, xml)
		elif command == 'get-distro-candidates':
			l = stdin.readline().strip()
			xml = qdom.parse(BytesIO(stdin.read(int(l))))
			blocker = do_get_distro_candidates(config, request[1:], xml)
			reply_when_done(ticket, blocker)
			return	# async
		elif command == 'download-and-import-feed':
			blocker = do_download_and_import_feed(config, request[1:])
			reply_when_done(ticket, blocker)
			return	# async
		elif command == 'notify-user':
			response = do_notify_user(config, request[1])
		else:
			raise SafeException("Internal error: unknown command '%s'" % command)
		response = ['ok', response]
	except SafeException as ex:
		logger.info("Replying with error: %s", ex)
		response = ['error', str(ex)]
	except Exception as ex:
		import traceback
		logger.info("Replying with error: %s", ex)
		response = ['error', traceback.format_exc().strip()]

	send_json(["return", ticket, response])
Example #42
0
	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
Example #43
0
	def testRecipeRemoveDir(self):
		run_server(('HelloWorld.tar.bz2',))
		uri = os.path.abspath('RecipeRemoveDir.xml')
		out, err = self.run_ocaml(['download', uri, '--command=', '--xml'], binary = True)
		sels = selections.Selections(qdom.parse(BytesIO(out)))
		digests = sels.selections[uri].digests
		path = self.config.stores.lookup_any(digests)
		assert not os.path.exists(os.path.join(path, 'HelloWorld'))
Example #44
0
	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'
Example #45
0
	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
Example #46
0
	def testExtractToNewSubdirectory(self):
		run_server(('HelloWorld.tar.bz2',))
		uri = os.path.abspath('HelloExtractToNewDest.xml')
		out, err = self.run_ocaml(['download', uri, '--command=', '--xml'], binary = True)
		sels = selections.Selections(qdom.parse(BytesIO(out)))
		digests = sels.selections[uri].digests
		path = self.config.stores.lookup_any(digests)
		assert os.path.exists(os.path.join(path, 'src', 'HelloWorld', 'main'))
Example #47
0
        def test(top_xml, diag_xml, expected_error):
            root = qdom.parse(
                BytesIO("""<?xml version="1.0" ?>
			<interface xmlns="http://zero-install.sourceforge.net/2004/injector/interface" uri="{top}">
			  <name>Top-level</name>
			  <summary>Top-level</summary>
			  <group>
			    {top_xml}
			  </group>
			</interface>""".format(top=top_uri, top_xml=top_xml).encode("utf-8")))
            self.import_feed(top_uri, root)

            root = qdom.parse(
                BytesIO("""<?xml version="1.0" ?>
			<interface xmlns="http://zero-install.sourceforge.net/2004/injector/interface" uri="{diag}">
			  <name>Diagnostics</name>
			  <summary>Diagnostics</summary>
			  <group>
			    {impls}
			  </group>
			</interface>""".format(diag=diag_uri, impls=diag_xml).encode("utf-8")))
            self.import_feed(diag_uri, root)

            root = qdom.parse(
                BytesIO("""<?xml version="1.0" ?>
			<interface xmlns="http://zero-install.sourceforge.net/2004/injector/interface" uri="{old}">
			  <name>Old</name>
			  <summary>Old</summary>
			  <feed src='{diag}'/>
			  <replaced-by interface='{diag}'/>
			</interface>""".format(diag=diag_uri, old=old_uri).encode("utf-8")))
            self.import_feed(old_uri, root)

            r = Requirements(top_uri)
            r.os = "Windows"
            r.cpu = "x86_64"
            s = solver.DefaultSolver(self.config)
            s.solve_for(r)
            assert not s.ready, s.selections.selections

            if expected_error != str(s.get_failure_reason()):
                print(s.get_failure_reason())

            self.assertEqual(expected_error, str(s.get_failure_reason()))

            return s
Example #48
0
    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'))
Example #49
0
	def load_built_selections(self):
		path = join(self.metadir, 'build-environment.xml')
		if os.path.exists(path):
			stream = file(path)
			try:
				return selections.Selections(qdom.parse(stream))
			finally:
				stream.close()
		return None
Example #50
0
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")
Example #51
0
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")
Example #52
0
    def testCommands(self):
        iface = os.path.join(mydir, "Command.xml")
        driver = Driver(requirements=Requirements(iface), config=self.config)
        driver.need_download()
        assert driver.solver.ready

        impl = driver.solver.selections[self.config.iface_cache.get_interface(
            iface)]
        assert impl.id == 'c'
        assert impl.main == 'test-gui'

        dep_impl_uri = impl.commands['run'].requires[0].interface
        dep_impl = driver.solver.selections[
            self.config.iface_cache.get_interface(dep_impl_uri)]
        assert dep_impl.id == 'sha1=256'

        s1 = driver.solver.selections
        assert s1.commands[0].path == 'test-gui'
        xml = s1.toDOM().toxml("utf-8")
        root = qdom.parse(BytesIO(xml))
        s2 = selections.Selections(root)

        assert s2.commands[0].path == 'test-gui'
        impl = s2.selections[iface]
        assert impl.id == 'c'

        assert s2.commands[0].qdom.attrs['http://custom attr'] == 'namespaced'
        custom_element = s2.commands[0].qdom.childNodes[0]
        assert custom_element.name == 'child'

        dep_impl = s2.selections[dep_impl_uri]
        assert dep_impl.id == 'sha1=256'

        d = Driver(self.config, requirements.Requirements(runexec))
        need_download = d.need_download()
        assert need_download == False

        xml = d.solver.selections.toDOM().toxml("utf-8")
        root = qdom.parse(BytesIO(xml))
        s3 = selections.Selections(root)
        runnable_impl = s3.selections[runnable]
        assert 'foo' in runnable_impl.commands
        assert 'run' in runnable_impl.commands
Example #53
0
 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())
Example #54
0
    def testLocalPath(self):
        # 0launch --get-selections Local.xml
        iface = os.path.join(mydir, "Local.xml")
        driver = Driver(requirements=Requirements(iface), config=self.config)
        driver.need_download()
        assert driver.solver.ready
        s1 = driver.solver.selections
        xml = s1.toDOM().toxml("utf-8")

        # Reload selections and check they're the same
        root = qdom.parse(BytesIO(xml))
        s2 = selections.Selections(root)
        local_path = s2.selections[iface].local_path
        assert os.path.isdir(local_path), local_path
        assert not s2.selections[iface].digests, s2.selections[iface].digests

        # Add a newer implementation and try again
        feed = self.config.iface_cache.get_feed(iface)
        impl = model.ZeroInstallImplementation(feed,
                                               "foo bar=123",
                                               local_path=None)
        impl.version = model.parse_version('1.0')
        impl.commands["run"] = model.Command(
            qdom.Element(namespaces.XMLNS_IFACE, 'command', {
                'path': 'dummy',
                'name': 'run'
            }), None)
        impl.add_download_source('http://localhost/bar.tgz', 1000, None)
        feed.implementations = {impl.id: impl}
        assert driver.need_download()
        assert driver.solver.ready, driver.solver.get_failure_reason()
        s1 = driver.solver.selections
        xml = s1.toDOM().toxml("utf-8")
        root = qdom.parse(BytesIO(xml))
        s2 = selections.Selections(root)
        xml = s2.toDOM().toxml("utf-8")
        qdom.parse(BytesIO(xml))
        assert s2.selections[iface].local_path is None
        assert not s2.selections[iface].digests, s2.selections[iface].digests
        assert s2.selections[iface].id == 'foo bar=123'
Example #55
0
    def get_selections(self, snapshot_date=None):
        """Load the selections. Does not check whether they are cached, nor trigger updates.
		@param snapshot_date: get a historical snapshot
		@type snapshot_date: (as returned by L{get_history}) | None
		@return: the selections
		@rtype: L{selections.Selections}"""
        if snapshot_date:
            sels_file = os.path.join(self.path,
                                     'selections-' + snapshot_date + '.xml')
        else:
            sels_file = os.path.join(self.path, 'selections.xml')
        with open(sels_file, 'rb') as stream:
            return selections.Selections(qdom.parse(stream))
Example #56
0
	def testSitePackages(self):
		# The old system (0install < 1.9):
		# - 0compile stores implementations to ~/.cache, and 
		# - adds to extra_feeds
		# The new system (0install >= 1.9):
		# - 0compile stores implementations to ~/.local/0install.net/site-packages, and
		# - 0install finds them automatically

		# For backwards compatibility, 0install >= 1.9:
		# - writes discovered feeds to extra_feeds
		# - skips such entries in extra_feeds when loading

		meta_dir = basedir.save_data_path('0install.net', 'site-packages',
						   'http:##example.com#prog.xml', '1.0', '0install')
		feed = os.path.join(meta_dir, 'feed.xml')
		shutil.copyfile(os.path.join(mydir, 'Local.xml'), feed)

		# Check that we find the feed without us having to register it
		iface = self.config.iface_cache.get_interface('http://example.com/prog.xml')
		self.assertEqual(1, len(iface.extra_feeds))
		site_feed, = iface.extra_feeds
		self.assertEqual(True, site_feed.site_package)

		# Check that we write it out, so that older 0installs can find it
		writer.save_interface(iface)

		config_file = basedir.load_first_config('0install.net', 'injector',
							'interfaces', 'http:##example.com#prog.xml')
		with open(config_file, 'rb') as s:
			doc = qdom.parse(s)

		feed_node = None
		for item in doc.childNodes:
			if item.name == 'feed':
				feed_node = item
		self.assertEqual('True', feed_node.getAttribute('site-package'))

		# Check we ignore this element
		iface.reset()
		self.assertEqual([], iface.extra_feeds)
		reader.update_user_overrides(iface)
		self.assertEqual([], iface.extra_feeds)

		# Check feeds are automatically removed again
		reader.update_from_cache(iface, iface_cache = self.config.iface_cache)
		self.assertEqual(1, len(iface.extra_feeds))
		shutil.rmtree(basedir.load_first_data('0install.net', 'site-packages',
							'http:##example.com#prog.xml'))

		reader.update_from_cache(iface, iface_cache = self.config.iface_cache)
		self.assertEqual(0, len(iface.extra_feeds))
Example #57
0
def update_user_overrides(interface, known_site_feeds=frozenset()):
    """Update an interface with user-supplied information.
	Sets preferred stability and updates extra_feeds.
	@param interface: the interface object to update
	@type interface: L{model.Interface}
	@param known_site_feeds: feeds to ignore (for backwards compatibility)
	"""
    user = basedir.load_first_config(config_site, config_prog, 'interfaces',
                                     model._pretty_escape(interface.uri))
    if user is None:
        # For files saved by 0launch < 0.49
        user = basedir.load_first_config(config_site,
                                         config_prog, 'user_overrides',
                                         escape(interface.uri))
    if not user:
        return

    try:
        with open(user, 'rb') as stream:
            root = qdom.parse(stream)
    except Exception as ex:
        logger.warn(_("Error reading '%(user)s': %(exception)s"), {
            'user': user,
            'exception': ex
        })
        raise

    stability_policy = root.getAttribute('stability-policy')
    if stability_policy:
        interface.set_stability_policy(stability_levels[str(stability_policy)])

    for item in root.childNodes:
        if item.uri != XMLNS_IFACE: continue
        if item.name == 'feed':
            feed_src = item.getAttribute('src')
            if not feed_src:
                raise InvalidInterface(_('Missing "src" attribute in <feed>'))
            # (note: 0install 1.9..1.12 used a different scheme and the "site-package" attribute;
            # we deliberately use a different attribute name to avoid confusion)
            if item.getAttribute('is-site-package'):
                # Site packages are detected earlier. This test isn't completely reliable,
                # since older versions will remove the attribute when saving the config
                # (hence the next test).
                continue
            if feed_src in known_site_feeds:
                continue
            interface.extra_feeds.append(
                Feed(feed_src,
                     item.getAttribute('arch'),
                     True,
                     langs=item.getAttribute('langs')))
Example #58
0
    def testSelectOnly(self):
        os.environ['DISPLAY'] = ':foo'
        out, err = self.run_0install(['select', '--xml', 'Hello.xml'])
        self.assertEqual("", err)

        assert out.endswith("Finished\n"), out
        out = out[:-len("Finished\n")]

        root = qdom.parse(BytesIO(str(out).encode('utf-8')))
        self.assertEqual(namespaces.XMLNS_IFACE, root.uri)
        sels = selections.Selections(root)
        sel, = sels.selections.values()
        self.assertEqual("sha1=3ce644dc725f1d21cfcf02562c76f375944b266a",
                         sel.id)