Beispiel #1
0
    def testReplacedConflicts(self):
        self.import_feed('http://localhost:8000/Hello', 'Hello')
        s = solver.DefaultSolver(self.config)
        replaced_path = model.canonical_iface_uri(
            os.path.join(mydir, 'Replaced.xml'))
        replaced_conflicts_path = model.canonical_iface_uri(
            os.path.join(mydir, 'ReplacedConflicts.xml'))
        r = Requirements(replaced_conflicts_path)
        s.solve_for(r)
        assert s.ready, s.get_failure_reason()
        assert s.selections
        self.assertEqual("b",
                         s.selections.selections[replaced_conflicts_path].id)
        self.assertEqual(
            "2", s.selections.selections[replaced_conflicts_path].version)
        self.assertEqual(
            "sha1=3ce644dc725f1d21cfcf02562c76f375944b266a",
            s.selections.selections["http://localhost:8000/Hello"].id)
        self.assertEqual(2, len(s.selections.selections))

        s.extra_restrictions[self.config.iface_cache.get_interface(
            r.interface_uri)] = [
                model.VersionRangeRestriction(model.parse_version('2'), None)
            ]

        s.solve_for(r)
        assert s.ready, s.get_failure_reason()
        assert s.selections
        self.assertEqual(
            "1", s.selections.selections[replaced_conflicts_path].version)
        self.assertEqual("0", s.selections.selections[replaced_path].version)
        self.assertEqual(2, len(s.selections.selections))
	def __init__(self, config, requirements):
		"""
		@param config: The configuration settings to use
		@type config: L{config.Config}
		@param requirements: Details about the program we want to run
		@type requirements: L{requirements.Requirements}
		@since: 0.53
		"""
		self.watchers = []

		assert config
		self.config = config

		assert requirements
		self.requirements = requirements

		self.target_arch = arch.get_architecture(requirements.os, requirements.cpu)

		from zeroinstall.injector.solver import DefaultSolver
		self.solver = DefaultSolver(self.config)

		debug(_("Supported systems: '%s'"), arch.os_ranks)
		debug(_("Supported processors: '%s'"), arch.machine_ranks)

		if requirements.before or requirements.not_before:
			self.solver.extra_restrictions[config.iface_cache.get_interface(requirements.interface_uri)] = [
					model.VersionRangeRestriction(model.parse_version(requirements.before),
								      model.parse_version(requirements.not_before))]
    def __init__(self, guid, data):
        self._importance = data.get('importance', model.Dependency.Essential)
        self._metadata = {}
        self.qdom = None
        self.interface = guid
        self.restrictions = []
        self.bindings = []

        for not_before, before in data.get('restrictions') or []:
            restriction = model.VersionRangeRestriction(
                not_before=parse_version(not_before),
                before=parse_version(before))
            self.restrictions.append(restriction)
Beispiel #4
0
def run_test_combinations(config, spec):
    r = requirements.Requirements(spec.test_iface)
    r.command = spec.command

    d = driver.Driver(config=config, requirements=r)
    solver = d.solver

    # Explore all combinations...

    tested_iface = config.iface_cache.get_interface(spec.test_iface)
    results = Results(spec)
    for combo in spec.get_combos(spec.test_ifaces):
        key = set()
        restrictions = {}
        selections = {}
        for (uri, version) in combo.iteritems():
            iface = config.iface_cache.get_interface(uri)
            selections[iface] = version

            if version.startswith('%'):
                if version == '%nonlocal':
                    restrictions[iface] = [NonlocalRestriction()]
                else:
                    raise model.SafeException(
                        "Unknown special '{special}'".format(special=version))
            elif ',' in version:
                not_before, before = [
                    model.parse_version(v) if v != "" else None
                    for v in version.split(',')
                ]
                if (not_before and before) and not_before >= before:
                    raise model.SafeException(
                        "Low version >= high version in %s!" % version)
                restrictions[iface] = [
                    model.VersionRangeRestriction(before, not_before)
                ]
            else:
                restrictions[iface] = [
                    model.VersionExpressionRestriction(version)
                ]
            key.add((uri, version))

        solver.extra_restrictions = restrictions
        solve = d.solve_with_downloads()
        tasks.wait_for_blocker(solve)
        if not solver.ready:
            logging.info("Can't select combination %s: %s", combo,
                         solver.get_failure_reason())
            result = 'skipped'
            for uri, impl in solver.selections.iteritems():
                if impl is None:
                    selections[uri] = selections.get(uri, None) or '?'
                else:
                    selections[uri] = impl.get_version()
            if not selections:
                selections = solver.get_failure_reason()
        else:
            selections = {}
            for iface, impl in solver.selections.iteritems():
                if impl:
                    version = impl.get_version()
                else:
                    impl = None
                selections[iface] = version
            download = d.download_uncached_implementations()
            if download:
                config.handler.wait_for_blocker(download)

            print format_combo(selections)

            result = run_tests(config, tested_iface, solver.selections, spec)

        results.by_status[result].append(selections)
        results.by_combo[frozenset(key)] = (result, selections)

    return results
Beispiel #5
0
def run_gui(args):
	parser = OptionParser(usage=_("usage: %prog [options] interface"))
	parser.add_option("", "--before", help=_("choose a version before this"), metavar='VERSION')
	parser.add_option("", "--cpu", help=_("target CPU type"), metavar='CPU')
	parser.add_option("-c", "--cache", help=_("show the cache"), action='store_true')
	parser.add_option("-d", "--download-only", help=_("fetch but don't run"), action='store_true')
	parser.add_option("", "--message", help=_("message to display when interacting with user"))
	parser.add_option("", "--not-before", help=_("minimum version to choose"), metavar='VERSION')
	parser.add_option("", "--os", help=_("target operation system type"), metavar='OS')
	parser.add_option("-r", "--refresh", help=_("check for updates of all interfaces"), action='store_true')
	parser.add_option("-s", "--source", help=_("select source code"), action='store_true')
	parser.add_option("", "--systray", help=_("download in the background"), action='store_true')
	parser.add_option("-v", "--verbose", help=_("more verbose output"), action='count')
	parser.add_option("-V", "--version", help=_("display version information"), action='store_true')
	parser.add_option("", "--with-store", help=_("add an implementation cache"), action='append', metavar='DIR')

	parser.disable_interspersed_args()

	(options, args) = parser.parse_args(args)

	if options.verbose:
		import logging
		logger = logging.getLogger()
		if options.verbose == 1:
			logger.setLevel(logging.INFO)
		else:
			logger.setLevel(logging.DEBUG)

	if options.cache:
		# Must fork before importing gtk, or ATK dies
		if os.fork():
			# We exit, so our parent can call waitpid and unblock.
			sys.exit(0)
		# The grandchild continues...

	if options.with_store:
		from zeroinstall import zerostore
		for x in options.with_store:
			iface_cache.stores.stores.append(zerostore.Store(os.path.abspath(x)))

	import gui

	if options.version:
		print "0launch-gui (zero-install) " + gui.version
		print "Copyright (C) 2009 Thomas Leonard"
		print _("This program comes with ABSOLUTELY NO WARRANTY,"
				"\nto the extent permitted by law."
				"\nYou may redistribute copies of this program"
				"\nunder the terms of the GNU Lesser General Public License."
				"\nFor more information about these matters, see the file named COPYING.")
		sys.exit(0)

	import gtk
	if gtk.gdk.get_display() is None:
		print >>sys.stderr, "Failed to connect to display. Aborting."
		sys.exit(1)

	if not hasattr(gtk, 'combo_box_new_text'):
		import combo_compat

	if options.cache:
		import cache
		cache_explorer = cache.CacheExplorer()
		cache_explorer.show()
		cache_explorer.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
		gtk.gdk.flush()
		cache_explorer.populate_model()
		cache_explorer.window.set_cursor(None)
		gtk.main()
		sys.exit(0)

	handler = gui.GUIHandler()

	if len(args) < 1:
		import preferences
		# Once we separate configuration from Policy, this hack can go away
		class DummyPolicy(Policy):
			def recalculate(fetch_stale_interfaces = True):
				pass
			def solve_with_downloads(force = False):
				pass
		box = preferences.show_preferences(DummyPolicy('http://localhost/dummy', handler))
		box.connect('destroy', gtk.main_quit)
		gtk.main()
		sys.exit(0)

	interface_uri = args[0]

	if len(args) > 1:
		parser.print_help()
		sys.exit(1)

	import mainwindow, dialog

	restrictions = []
	if options.before or options.not_before:
		restrictions.append(model.VersionRangeRestriction(model.parse_version(options.before),
								  model.parse_version(options.not_before)))

	widgets = dialog.Template('main')

	policy = Policy(interface_uri, handler, src = bool(options.source))
	policy.target_arch = arch.get_architecture(options.os, options.cpu)
	root_iface = iface_cache.get_interface(interface_uri)
	policy.solver.extra_restrictions[root_iface] = restrictions
	policy.solver.record_details = True

	window = mainwindow.MainWindow(policy, widgets, download_only = bool(options.download_only))
	handler.mainwindow = window

	if options.message:
		window.set_message(options.message)

	root = iface_cache.get_interface(policy.root)
	window.browser.set_root(root)

	window.window.connect('destroy', lambda w: handler.abort_all_downloads())

	if options.systray:
		window.use_systray_icon()

	@tasks.async
	def main():
		force_refresh = bool(options.refresh)
		while True:
			window.refresh_button.set_sensitive(False)
			window.browser.set_update_icons(force_refresh)

			solved = policy.solve_with_downloads(force = force_refresh)

			if not window.systray_icon:
				window.show()
			yield solved
			try:
				window.refresh_button.set_sensitive(True)
				tasks.check(solved)
			except Exception, ex:
				window.report_exception(ex)

			if window.systray_icon and window.systray_icon.get_visible() and \
			   window.systray_icon.is_embedded():
				if policy.ready:
					window.systray_icon.set_tooltip(_('Downloading updates for %s') % root_iface.get_name())
					window.run_button.set_active(True)
				else:
					# Should already be reporting an error, but
					# blink it again just in case
					window.systray_icon.set_blinking(True)

			yield dialog.ButtonClickedBlocker(window.refresh_button)
			force_refresh = True
Beispiel #6
0
def _normal_mode(options, args):
	from zeroinstall.injector import handler

	if len(args) < 1:
		if options.gui:
			from zeroinstall import helpers
			return helpers.get_selections_gui(None, [])
		else:
			raise UsageError()

	iface_uri = model.canonical_iface_uri(args[0])
	root_iface = iface_cache.get_interface(iface_uri)

	if os.isatty(1):
		h = handler.ConsoleHandler()
	else:
		h = handler.Handler()
	h.dry_run = bool(options.dry_run)

	policy = autopolicy.AutoPolicy(iface_uri,
				handler = h,
				download_only = bool(options.download_only),
				src = options.source)

	if options.before or options.not_before:
		policy.solver.extra_restrictions[root_iface] = [model.VersionRangeRestriction(model.parse_version(options.before),
									      		      model.parse_version(options.not_before))]

	if options.os or options.cpu:
		from zeroinstall.injector import arch
		policy.target_arch = arch.get_architecture(options.os, options.cpu)

	if options.offline:
		policy.network_use = model.network_offline

	if options.get_selections:
		if len(args) > 1:
			raise SafeException(_("Can't use arguments with --get-selections"))
		if options.main:
			raise SafeException(_("Can't use --main with --get-selections"))

	# Note that need_download() triggers a solve
	if options.refresh or options.gui:
		# We could run immediately, but the user asked us not to
		can_run_immediately = False
	else:
		can_run_immediately = (not policy.need_download()) and policy.ready

		stale_feeds = [feed for feed in policy.solver.feeds_used if policy.is_stale(iface_cache.get_feed(feed))]

		if options.download_only and stale_feeds:
			can_run_immediately = False

	if can_run_immediately:
		if stale_feeds:
			if policy.network_use == model.network_offline:
				logging.debug(_("No doing background update because we are in off-line mode."))
			else:
				# There are feeds we should update, but we can run without them.
				# Do the update in the background while the program is running.
				import background
				background.spawn_background_update(policy, options.verbose > 0)
		if options.get_selections:
			_get_selections(policy)
		else:
			if not options.download_only:
				from zeroinstall.injector import run
				run.execute(policy, args[1:], dry_run = options.dry_run, main = options.main, wrapper = options.wrapper)
			else:
				logging.info(_("Downloads done (download-only mode)"))
			assert options.dry_run or options.download_only
		return

	# If the user didn't say whether to use the GUI, choose for them.
	if options.gui is None and os.environ.get('DISPLAY', None):
		options.gui = True
		# If we need to download anything, we might as well
		# refresh all the interfaces first. Also, this triggers
		# the 'checking for updates' box, which is non-interactive
		# when there are no changes to the selection.
		options.refresh = True
		logging.info(_("Switching to GUI mode... (use --console to disable)"))

	prog_args = args[1:]

	try:
		from zeroinstall.injector import run
		if options.gui:
			gui_args = []
			if options.download_only:
				# Just changes the button's label
				gui_args.append('--download-only')
			if options.refresh:
				gui_args.append('--refresh')
			if options.systray:
				gui_args.append('--systray')
			if options.not_before:
				gui_args.insert(0, options.not_before)
				gui_args.insert(0, '--not-before')
			if options.before:
				gui_args.insert(0, options.before)
				gui_args.insert(0, '--before')
			if options.source:
				gui_args.insert(0, '--source')
			if options.message:
				gui_args.insert(0, options.message)
				gui_args.insert(0, '--message')
			if options.verbose:
				gui_args.insert(0, '--verbose')
				if options.verbose > 1:
					gui_args.insert(0, '--verbose')
			if options.cpu:
				gui_args.insert(0, options.cpu)
				gui_args.insert(0, '--cpu')
			if options.os:
				gui_args.insert(0, options.os)
				gui_args.insert(0, '--os')
			if options.with_store:
				for x in options.with_store:
					gui_args += ['--with-store', x]
			sels = _fork_gui(iface_uri, gui_args, prog_args, options)
			if not sels:
				sys.exit(1)		# Aborted
		else:
			#program_log('download_and_execute ' + iface_uri)
			downloaded = policy.solve_and_download_impls(refresh = bool(options.refresh))
			if downloaded:
				policy.handler.wait_for_blocker(downloaded)
			sels = selections.Selections(policy)

		if options.get_selections:
			doc = sels.toDOM()
			doc.writexml(sys.stdout)
			sys.stdout.write('\n')
		elif not options.download_only:
			run.execute_selections(sels, prog_args, options.dry_run, options.main, options.wrapper)

	except NeedDownload, ex:
		# This only happens for dry runs
		print ex