Esempio n. 1
0
	def get_package_info(self, package, factory):
		# Add any already-installed package...
		"""@type package: str"""
		installed_cached_info = self._get_dpkg_info(package)

		if installed_cached_info != '-':
			installed_version, machine = installed_cached_info.split('\t')
			impl = factory('package:deb:%s:%s:%s' % (package, installed_version, machine))
			impl.version = model.parse_version(installed_version)
			if machine != '*':
				impl.machine = machine
		else:
			installed_version = None

		# Add any uninstalled candidates (note: only one of these two methods will add anything)

		# From PackageKit...
		self.packagekit.get_candidates(package, factory, 'package:deb')

		# From apt-cache...
		cached = self.apt_cache.get(package, None)
		if cached:
			candidate_version = cached['version']
			candidate_arch = cached['arch']
			if candidate_version and candidate_version != installed_version:
				impl = factory('package:deb:%s:%s:%s' % (package, candidate_version, candidate_arch), installed = False)
				impl.version = model.parse_version(candidate_version)
				if candidate_arch != '*':
					impl.machine = candidate_arch
				impl.download_sources.append(model.DistributionSource(package, cached['size'], needs_confirmation = False))
Esempio n. 2
0
	def update_element(self, element, widgets):
		element.setAttribute('interface', widgets.get_widget('requires_uri').get_active_text())

		before = widgets.get_widget('before').get_text() or None
		not_before = widgets.get_widget('not_before').get_text() or None

		if before: model.parse_version(before)
		if not_before: model.parse_version(not_before)

		if before or not_before:
			if not self.version_element:
				self.version_element = create_element(element, 'version')
			set_or_remove(self.version_element, 'before', before)
			set_or_remove(self.version_element, 'not-before', not_before)
		elif self.version_element:
			remove_element(self.version_element)
			self.version_element = None

		env_name = widgets.get_widget('env_name').get_active_text()
		env_insert = widgets.get_widget('env_insert').get_active_text()
		env_mode = widgets.get_widget('env_mode').get_active_text().lower()
		env_default = widgets.get_widget('env_default').get_text()

		if env_name:
			if not self.env_element:
				self.env_element = create_element(element, 'environment')
			self.env_element.setAttribute('name', env_name)
			self.env_element.setAttribute('insert', env_insert)
			self.env_element.setAttribute('mode', env_mode)
			set_or_remove(self.env_element, 'default', env_default)
		elif env_insert or env_default:
			raise Exception('Missing environment variable name!')
		elif self.env_element:
			remove_element(self.env_element)
			self.env_element = None
Esempio n. 3
0
	def get_package_info(self, package, factory):
		# Add any already-installed package...
		installed_cached_info = self._get_dpkg_info(package)

		if installed_cached_info != '-':
			installed_version, machine = installed_cached_info.split('\t')
			impl = factory('package:deb:%s:%s:%s' % (package, installed_version, machine))
			impl.version = model.parse_version(installed_version)
			if machine != '*':
				impl.machine = machine
		else:
			installed_version = None

		# Add any uninstalled candidates (note: only one of these two methods will add anything)

		# From PackageKit...
		self.packagekit.get_candidates(package, factory, 'package:deb')

		# From apt-cache...
		cached = self.apt_cache.get(package, None)
		if cached:
			candidate_version = cached['version']
			candidate_arch = cached['arch']
			if candidate_version and candidate_version != installed_version:
				impl = factory('package:deb:%s:%s:%s' % (package, candidate_version, candidate_arch), installed = False)
				impl.version = model.parse_version(candidate_version)
				if candidate_arch != '*':
					impl.machine = candidate_arch
				def install(handler):
					raise model.SafeException(_("This program depends on '%s', which is a package that is available through your distribution. "
							"Please install it manually using your distribution's tools and try again. Or, install 'packagekit' and I can "
							"use that to install it.") % package)
				impl.download_sources.append(model.DistributionSource(package, cached['size'], install, needs_confirmation = False))
Esempio n. 4
0
    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)

        logger.debug(_("Supported systems: '%s'"), arch.os_ranks)
        logger.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)
                )
            ]
Esempio n. 5
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(),
        )
	def testConstraints(self):
		self.cache_iface('http://bar',
"""<?xml version="1.0" ?>
<interface last-modified="1110752708"
 uri="http://bar"
 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
  <name>Bar</name>
  <summary>Bar</summary>
  <description>Bar</description>
  <implementation id='sha1=100' version='1.0'>
    <archive href='foo' size='10'/>
  </implementation>
  <implementation id='sha1=150' stability='developer' version='1.5'>
    <archive href='foo' size='10'/>
  </implementation>
  <implementation id='sha1=200' version='2.0'>
    <archive href='foo' size='10'/>
  </implementation>
</interface>""")
		self.cache_iface(foo_iface_uri,
"""<?xml version="1.0" ?>
<interface last-modified="1110752708"
 uri="%s"
 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
  <name>Foo</name>
  <summary>Foo</summary>
  <description>Foo</description>
  <group main='dummy'>
   <requires interface='http://bar'>
    <version/>
   </requires>
   <implementation id='sha1=123' version='1.0'>
    <archive href='foo' size='10'/>
   </implementation>
  </group>
</interface>""" % foo_iface_uri)
		policy = Policy(foo_iface_uri, config = self.config)
		policy.network_use = model.network_full
		policy.freshness = 0
		#logger.setLevel(logging.DEBUG)
		recalculate(policy)
		#logger.setLevel(logging.WARN)
		foo_iface = self.config.iface_cache.get_interface(foo_iface_uri)
		bar_iface = self.config.iface_cache.get_interface('http://bar')
		assert policy.implementation[bar_iface].id == 'sha1=200'

		dep = policy.implementation[foo_iface].dependencies['http://bar']
		assert len(dep.restrictions) == 1
		restriction = dep.restrictions[0]

		restriction.before = model.parse_version('2.0')
		recalculate(policy)
		assert policy.implementation[bar_iface].id == 'sha1=100'

		restriction.not_before = model.parse_version('1.5')
		recalculate(policy)
		assert policy.implementation[bar_iface].id == 'sha1=150'
Esempio n. 7
0
	def get_previous_release(this_version):
		"""Return the highest numbered verison in the master feed before this_version.
		@return: version, or None if there wasn't one"""
		parsed_release_version = model.parse_version(this_version)

		versions = [model.parse_version(version) for version in scm.get_tagged_versions()]
		versions = [version for version in versions if version < parsed_release_version]

		if versions:
			return model.format_version(max(versions))
		return None
Esempio n. 8
0
	def __init__(self, root = None, handler = None, src = None, command = -1, config = None, requirements = None):
		"""
		@param requirements: Details about the program we want to run
		@type requirements: L{requirements.Requirements}
		@param config: The configuration settings to use, or None to load from disk.
		@type config: L{ConfigParser.ConfigParser}
		Note: all other arguments are deprecated (since 0launch 0.52)
		"""
		self.watchers = []
		if requirements is None:
			from zeroinstall.injector.requirements import Requirements
			requirements = Requirements(root)
			requirements.source = bool(src)				# Root impl must be a "src" machine type
			if command == -1:
				if src:
					command = 'compile'
				else:
					command = 'run'
			requirements.command = command
			self.target_arch = arch.get_host_architecture()
		else:
			assert root == src == None
			assert command == -1
			self.target_arch = arch.get_architecture(requirements.os, requirements.cpu)
		self.requirements = requirements

		self.stale_feeds = set()

		if config is None:
			self.config = load_config(handler or Handler())
		else:
			assert handler is None, "can't pass a handler and a config"
			self.config = config

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

		# If we need to download something but can't because we are offline,
		# warn the user. But only the first time.
		self._warned_offline = False

		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 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'
Esempio n. 10
0
	def get_candidates(self, package_name, factory, prefix):
		"""Add any cached candidates.
		The candidates are those discovered by a previous call to L{fetch_candidates}.
		@param package_name: the distribution's name for the package
		@type package_name: str
		@param factory: a function to add a new implementation to the feed
		@param prefix: the prefix for the implementation's ID
		@type prefix: str"""
		candidates = self._candidates.get(package_name, None)
		if candidates is None:
			return

		if isinstance(candidates, tasks.Blocker):
			return		# Fetch still in progress

		for candidate in candidates:
			impl_name = '%s:%s:%s:%s' % (prefix, package_name, candidate['version'], candidate['arch'])

			impl = factory(impl_name, only_if_missing = True, installed = candidate['installed'])
			if impl is None:
				# (checking this way because the cached candidate['installed'] may be stale)
				return		# Already installed

			impl.version = model.parse_version(candidate['version'])
			if candidate['arch'] != '*':
				impl.machine = candidate['arch']

			impl.download_sources.append(model.DistributionSource(package_name, candidate['size'], packagekit_id = candidate['packagekit_id']))
Esempio n. 11
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')
Esempio n. 12
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"
Esempio n. 13
0
	def get_candidates(self, package_name, factory, prefix):
		"""Add any cached candidates.
		The candidates are those discovered by a previous call to L{fetch_candidates}.
		@param package_name: the distribution's name for the package
		@param factory: a function to add a new implementation to the feed
		@param prefix: the prefix for the implementation's ID
		"""
		candidate = self._candidates.get(package_name, None)
		if candidate is None:
			return

		if isinstance(candidate, tasks.Blocker):
			return		# Fetch still in progress

		impl_name = '%s:%s:%s:%s' % (prefix, package_name, candidate['version'], candidate['arch'])

		impl = factory(impl_name, only_if_missing = True, installed = candidate['installed'])
		if impl is None:
			# (checking this way because the cached candidate['installed'] may be stale)
			return		# Already installed

		impl.version = model.parse_version(candidate['version'])
		if candidate['arch'] != '*':
			impl.machine = candidate['arch']

		def install(handler):
			packagekit_id = candidate['packagekit_id']
			def download_factory(url, hint):
				return PackageKitDownload(url, hint, pk = self.pk, packagekit_id = packagekit_id)
			dl = handler.get_download('packagekit:' + packagekit_id, factory = download_factory, hint = impl)
			dl.expected_size = candidate['size']
			return dl.downloaded
		impl.download_sources.append(model.DistributionSource(package_name, candidate['size'], install))
Esempio n. 14
0
	def get_package_info(self, package, factory):
		# Add installed versions...
		"""@type package: str"""
		for entry in os.listdir(self._packages_dir):
			name, version, build = entry.rsplit('-', 2)
			if name == package:
				gotarch = False
				# (read in binary mode to avoid unicode errors in C locale)
				with open(os.path.join(self._packages_dir, entry, "desc"), 'rb') as stream:
					for line in stream:
						if line == b"%ARCH%\n":
							gotarch = True
							continue
						if gotarch:
							arch = line.strip().decode('utf-8')
							break
				zi_arch = canonical_machine(arch)
				clean_version = try_cleanup_distro_version("%s-%s" % (version, build))
				if not clean_version:
					logger.warning(_("Can't parse distribution version '%(version)s' for package '%(package)s'"), {'version': version, 'package': name})
					continue
	
				impl = factory('package:arch:%s:%s:%s' % \
						(package, clean_version, zi_arch))
				impl.version = model.parse_version(clean_version)
				if zi_arch != '*':
					impl.machine = zi_arch

				impl.quick_test_file = os.path.join(self._packages_dir, entry, 'desc')

		# Add any uninstalled candidates found by PackageKit
		self.packagekit.get_candidates(package, factory, 'package:arch')
Esempio n. 15
0
	def get_package_info(self, package, factory):
		"""@type package: str"""
		_name_version_regexp = '^(.+)-([^-]+)$'

		nameversion = re.compile(_name_version_regexp)
		for pkgname in os.listdir(self._pkgdir):
			pkgdir = os.path.join(self._pkgdir, pkgname)
			if not os.path.isdir(pkgdir): continue

			#contents = open(os.path.join(pkgdir, '+CONTENTS')).readline().strip()

			match = nameversion.search(pkgname)
			if match is None:
				logger.warning(_('Cannot parse version from Ports package named "%(pkgname)s"'), {'pkgname': pkgname})
				continue
			else:
				name = match.group(1)
				if name != package:
					continue
				version = try_cleanup_distro_version(match.group(2))

			machine = host_machine

			impl = factory('package:ports:%s:%s:%s' % \
						(package, version, machine))
			impl.version = model.parse_version(version)
			impl.machine = machine
Esempio n. 16
0
	def get_package_info(self, package, factory):
		# Add installed versions...
		for entry in os.listdir(self._packages_dir):
			name, version, build = entry.rsplit('-', 2)
			if name == package:
				gotarch = False
				with open(os.path.join(self._packages_dir, entry, "desc"), 'rt') as stream:
					for line in stream:
						if line == "%ARCH%\n":
							gotarch = True
							continue
						if gotarch:
							arch = line.strip()
							break
				zi_arch = canonical_machine(arch)
				clean_version = try_cleanup_distro_version("%s-%s" % (version, build))
				if not clean_version:
					logger.warn(_("Can't parse distribution version '%(version)s' for package '%(package)s'"), {'version': version, 'package': name})
					continue
	
				impl = factory('package:arch:%s:%s:%s' % \
						(package, clean_version, zi_arch))
				impl.version = model.parse_version(clean_version)
				if zi_arch != '*':
					impl.machine = zi_arch

		# Add any uninstalled candidates found by PackageKit
		self.packagekit.get_candidates(package, factory, 'package:arch')
Esempio n. 17
0
	def get_feed(self, master_feed):
		"""Generate a feed containing information about distribution packages.
		This should immediately return a feed containing an implementation for the
		package if it's already installed. Information about versions that could be
		installed using the distribution's package manager can be added asynchronously
		later (see L{fetch_candidates}).
		@param master_feed: feed containing the <package-implementation> elements
		@type master_feed: L{model.ZeroInstallFeed}
		@rtype: L{model.ZeroInstallFeed}"""

		feed = model.ZeroInstallFeed(None)
		feed.url = 'distribution:' + master_feed.url

		for item, item_attrs in master_feed.get_package_impls(self):
			package = item_attrs.get('package', None)
			if package is None:
				raise model.InvalidInterface(_("Missing 'package' attribute on %s") % item)

			def factory(id, only_if_missing = False, installed = True):
				assert id.startswith('package:')
				if id in feed.implementations:
					if only_if_missing:
						return None
					warn(_("Duplicate ID '%s' for DistributionImplementation"), id)
				impl = model.DistributionImplementation(feed, id, self, item)
				feed.implementations[id] = impl

				impl.installed = installed
				impl.metadata = item_attrs

				if 'run' not in impl.commands:
					item_main = item_attrs.get('main', None)
					if item_main:
						if item_main.startswith('/'):
							impl.main = item_main
						else:
							raise model.InvalidInterface(_("'main' attribute must be absolute, but '%s' doesn't start with '/'!") %
										item_main)
				impl.upstream_stability = model.packaged

				return impl

			self.get_package_info(package, factory)

		if master_feed.url == 'http://repo.roscidus.com/python/python' and all(not impl.installed for impl in feed.implementations.values()):
			# Hack: we can support Python on platforms with unsupported package managers
			# by adding the implementation of Python running us now to the list.
			python_version = '.'.join([str(v) for v in sys.version_info if isinstance(v, int)])
			impl_id = 'package:host:python:' + python_version
			assert impl_id not in feed.implementations
			impl = model.DistributionImplementation(feed, impl_id, self)
			impl.installed = True
			impl.version = model.parse_version(python_version)
			impl.main = sys.executable
			impl.upstream_stability = model.packaged
			impl.machine = host_machine	# (hopefully)
			feed.implementations[impl_id] = impl

		return feed
Esempio n. 18
0
	def fixup(self, package, impl):
		"""@type package: str
		@type impl: L{zeroinstall.injector.model.DistributionImplementation}"""
		if impl.id.startswith('package:deb:openjdk-6-jre:') or \
		   impl.id.startswith('package:deb:openjdk-7-jre:'):
			# Debian marks all Java versions as pre-releases
			# See: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=685276
			impl.version = model.parse_version(impl.get_version().replace('-pre', '.'))
Esempio n. 19
0
		def add_versions(parent, version):
			for x in child_elements(parent):
				if x.namespaceURI != XMLNS_INTERFACE: continue
				if x.hasAttribute('version'): version = x.getAttribute('version')
				if x.localName == 'group':
					add_versions(x, version)
				elif x.localName == 'implementation':
					versions.append((model.parse_version(version), x))
Esempio n. 20
0
		def find_java(part, jvm_version, zero_version):
			for arch in ['i386', 'x86_64']:
				home = java_home(jvm_version, arch)
				if os.path.isfile(home + "/bin/java"):
					impl = factory('package:darwin:%s:%s:%s' % (package, zero_version, arch))
					impl.machine = arch
					impl.version = model.parse_version(zero_version)
					impl.upstream_stability = model.packaged
					impl.main = home + "/bin/java"
Esempio n. 21
0
	def get_package_info(self, package, factory):
		# Add installed versions...
		versions = self.versions.get(package, [])

		for version, machine in versions:
			impl = factory('package:cygwin:%s:%s:%s' % (package, version, machine))
			impl.version = model.parse_version(version)
			if machine != '*':
				impl.machine = machine
Esempio n. 22
0
		def find_program(file):
			if os.path.isfile(file) and os.access(file, os.X_OK):
				program_version = try_cleanup_distro_version(get_version(file))
				impl = factory('package:darwin:%s:%s' % (package, program_version), True)
				if impl:
					impl.installed = True
					impl.version = model.parse_version(program_version)
					impl.upstream_stability = model.packaged
					impl.machine = host_machine	# (hopefully)
					impl.main = file
Esempio n. 23
0
def get_version(x):
	root = x.ownerDocument.documentElement
	while x is not root:
		version = x.getAttribute('version')
		if version:
			mod = x.getAttribute('version-modifier')
			if mod: version += mod
			return model.parse_version(version)
		x = x.parentNode
	raise Exception("No version on %s" % x)
Esempio n. 24
0
		def find_java(part, win_version, zero_version):
			reg_path = r"SOFTWARE\JavaSoft\{part}\{win_version}".format(part = part, win_version = win_version)
			(java32_home, java64_home) = _read_hklm_reg(reg_path, "JavaHome")

			for (home, arch) in [(java32_home, 'i486'), (java64_home, 'x86_64')]:
				if os.path.isfile(home + r"\bin\java.exe"):
					impl = factory('package:windows:%s:%s:%s' % (package, zero_version, arch))
					impl.machine = arch
					impl.version = model.parse_version(zero_version)
					impl.upstream_stability = model.packaged
					impl.main = home + r"\bin\java.exe"
Esempio n. 25
0
		def find_netfx(win_version, zero_version):
			reg_path = r"SOFTWARE\Microsoft\NET Framework Setup\NDP\{win_version}".format(win_version = win_version)
			(netfx32_install, netfx64_install) = _read_hklm_reg(reg_path, "Install")

			for (install, arch) in [(netfx32_install, 'i486'), (netfx64_install, 'x86_64')]:
				impl = factory('package:windows:%s:%s:%s' % (package, zero_version, arch))
				impl.installed = (install == 1)
				impl.machine = arch
				impl.version = model.parse_version(zero_version)
				impl.upstream_stability = model.packaged
				impl.main = "" # .NET executables do not need a runner on Windows but they need one elsewhere
Esempio n. 26
0
	def get_package_info(self, package, factory):
		"""@type package: str"""
		self.darwin.get_package_info(package, factory)

		# Add installed versions...
		versions = self.versions.get(package, [])

		for version, machine in versions:
			impl = factory('package:macports:%s:%s:%s' % (package, version, machine))
			impl.version = model.parse_version(version)
			if machine != '*':
				impl.machine = machine
Esempio n. 27
0
	def get_package_info(self, package, factory):
		# Add installed versions...
		versions = self.versions.get(package, [])

		for version, machine in versions:
			impl = factory('package:rpm:%s:%s:%s' % (package, version, machine))
			impl.version = model.parse_version(version)
			if machine != '*':
				impl.machine = machine

		# Add any uninstalled candidates found by PackageKit
		self.packagekit.get_candidates(package, factory, 'package:rpm')
Esempio n. 28
0
	def testImpl(self):
		i = model.Interface('http://foo')
		a = model.ZeroInstallImplementation(i, '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(i, 'foo', None)
		b.version = model.parse_version("1.2.1")
		assert b > a
Esempio n. 29
0
	def testRestricts(self):
		iface_cache = self.config.iface_cache
		s = solver.DefaultSolver(self.config)
		uri = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'Conflicts.xml')
		versions = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'Versions.xml')
		iface = iface_cache.get_interface(uri)

		r = Requirements(uri)

		# Selects 0.2 as the highest version, applying the restriction to versions < 4.
		s.solve_for(r)
		assert s.ready
		self.assertEqual("0.2", s.selections.selections[uri].version)
		self.assertEqual("3", s.selections.selections[versions].version)

		s.extra_restrictions[iface] = [model.VersionRestriction(model.parse_version('0.1'))]
		s.solve_for(r)
		assert s.ready
		self.assertEqual("0.1", s.selections.selections[uri].version)
		self.assertEqual(None, s.selections.selections.get(versions, None))

		s.extra_restrictions[iface] = [model.VersionRestriction(model.parse_version('0.3'))]
		s.solve_for(r)
		assert not s.ready
Esempio n. 30
0
	def get_package_info(self, package, factory):
		# Add installed versions...
		for entry in os.listdir(self._packages_dir):
			name, version, arch, build = entry.rsplit('-', 3)
			if name == package:
				zi_arch = canonical_machine(arch)
				clean_version = try_cleanup_distro_version("%s-%s" % (version, build))
				if not clean_version:
					logger.warning(_("Can't parse distribution version '%(version)s' for package '%(package)s'"), {'version': version, 'package': name})
					continue
	
				impl = factory('package:slack:%s:%s:%s' % \
						(package, clean_version, zi_arch))
				impl.version = model.parse_version(clean_version)
				if zi_arch != '*':
					impl.machine = zi_arch

		# Add any uninstalled candidates found by PackageKit
		self.packagekit.get_candidates(package, factory, 'package:slack')
Esempio n. 31
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'
Esempio n. 32
0
def suggest_release_version(snapshot_version):
    """Given a snapshot version, suggest a suitable release version.
	>>> suggest_release_version('1.0-pre')
	'1.0'
	>>> suggest_release_version('0.9-post')
	'0.10'
	>>> suggest_release_version('3')
	Traceback (most recent call last):
		...
	SafeException: Version '3' is not a snapshot version (should end in -pre or -post)
	"""
    version = model.parse_version(snapshot_version)
    mod = version[-1]
    if mod == 0:
        raise SafeException(
            "Version '%s' is not a snapshot version (should end in -pre or -post)"
            % snapshot_version)
    if mod > 0:
        # -post, so increment the number
        version[-2][-1] += 1
    version[-1] = 0  # Remove the modifier
    return model.format_version(version)
Esempio n. 33
0
    def get_package_info(self, package, factory):
        _version_start_reqexp = '-[0-9]'

        if package.count('/') != 1: return False

        category, leafname = package.split('/')
        category_dir = os.path.join(self._pkgdir, category)
        match_prefix = leafname + '-'

        if not os.path.isdir(category_dir): return False

        found = False
        for filename in os.listdir(category_dir):
            if filename.startswith(match_prefix) and filename[len(
                    match_prefix)].isdigit():
                name = file(os.path.join(category_dir, filename,
                                         'PF')).readline().strip()

                match = re.search(_version_start_reqexp, name)
                if match is None:
                    warn(
                        _('Cannot parse version from Gentoo package named "%(name)s"'
                          ), {'name': name})
                    continue
                else:
                    version = try_cleanup_distro_version(name[match.start() +
                                                              1:])

                machine = file(os.path.join(category_dir, filename,
                                            'CHOST')).readline().split('-')[0]

                impl = factory('package:gentoo:%s:%s:%s' % \
                  (package, version, machine))
                impl.version = model.parse_version(version)
                found = True

        return found
Esempio n. 34
0
    def testConstraints(self):
        self.cache_iface(
            'http://bar', """<?xml version="1.0" ?>
<interface last-modified="1110752708"
 uri="http://bar"
 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
  <name>Bar</name>
  <summary>Bar</summary>
  <description>Bar</description>
  <implementation id='sha1=100' version='1.0'>
    <archive href='foo' size='10'/>
  </implementation>
  <implementation id='sha1=150' stability='developer' version='1.5'>
    <archive href='foo' size='10'/>
  </implementation>
  <implementation id='sha1=200' version='2.0'>
    <archive href='foo' size='10'/>
  </implementation>
</interface>""")
        self.cache_iface(
            foo_iface_uri, """<?xml version="1.0" ?>
<interface last-modified="1110752708"
 uri="%s"
 xmlns="http://zero-install.sourceforge.net/2004/injector/interface">
  <name>Foo</name>
  <summary>Foo</summary>
  <description>Foo</description>
  <group main='dummy'>
   <requires interface='http://bar'>
    <version/>
   </requires>
   <implementation id='sha1=123' version='1.0'>
    <archive href='foo' size='10'/>
   </implementation>
  </group>
</interface>""" % foo_iface_uri)
        driver = Driver(requirements=Requirements(foo_iface_uri),
                        config=self.config)
        self.config.network_use = model.network_full
        #logger.setLevel(logging.DEBUG)
        recalculate(driver)
        #logger.setLevel(logging.WARN)
        foo_iface = self.config.iface_cache.get_interface(foo_iface_uri)
        bar_iface = self.config.iface_cache.get_interface('http://bar')
        assert driver.solver.selections.selections[
            bar_iface.uri].id == 'sha1=200'

        dep, = driver.solver.selections.selections[foo_iface.uri].dependencies
        assert dep.interface == 'http://bar'
        assert len(dep.restrictions) == 1
        restriction = dep.restrictions[0]

        restriction.before = model.parse_version('2.0')
        recalculate(driver)
        assert driver.solver.selections.selections[
            bar_iface.uri].id == 'sha1=100'

        restriction.not_before = model.parse_version('1.5')
        recalculate(driver)
        assert driver.solver.selections.selections[
            bar_iface.uri].id == 'sha1=150'
Esempio n. 35
0
    def testUpdate(self):
        out, err = self.run_0install(['update'])
        assert out.lower().startswith("usage:")
        assert '--message' in out, out

        # Updating a local feed with no dependencies
        out, err = self.run_0install(['update', 'Local.xml'])
        assert not err, err
        assert 'No updates found' in out, out

        # Using a remote feed for the first time
        self.config.stores = TestStores()
        binary_feed = reader.load_feed('Binary.xml')
        self.config.fetcher.allow_download('sha1=123')
        self.config.fetcher.allow_feed_download('http://foo/Binary.xml',
                                                binary_feed)
        out, err = self.run_0install(['update', 'http://foo/Binary.xml'])
        assert not err, err
        assert 'Binary.xml: new -> 1.0' in out, out

        # No updates.
        self.config.fetcher.allow_feed_download('http://foo/Binary.xml',
                                                binary_feed)
        out, err = self.run_0install(['update', 'http://foo/Binary.xml'])
        assert not err, err
        assert 'No updates found' in out, out

        # New binary release available.
        new_binary_feed = reader.load_feed('Binary.xml')
        new_binary_feed.implementations[
            'sha1=123'].version = model.parse_version('1.1')
        self.config.fetcher.allow_feed_download('http://foo/Binary.xml',
                                                new_binary_feed)
        out, err = self.run_0install(['update', 'http://foo/Binary.xml'])
        assert not err, err
        assert 'Binary.xml: 1.0 -> 1.1' in out, out

        # Compiling from source for the first time.
        source_feed = reader.load_feed('Source.xml')
        compiler_feed = reader.load_feed('Compiler.xml')
        self.config.fetcher.allow_download('sha1=234')
        self.config.fetcher.allow_download('sha1=345')
        self.config.fetcher.allow_feed_download('http://foo/Compiler.xml',
                                                compiler_feed)
        self.config.fetcher.allow_feed_download('http://foo/Binary.xml',
                                                binary_feed)
        self.config.fetcher.allow_feed_download('http://foo/Source.xml',
                                                source_feed)
        out, err = self.run_0install(
            ['update', 'http://foo/Binary.xml', '--source'])
        assert not err, err
        assert 'Binary.xml: new -> 1.0' in out, out
        assert 'Compiler.xml: new -> 1.0' in out, out

        # New compiler released.
        new_compiler_feed = reader.load_feed('Compiler.xml')
        new_compiler_feed.implementations[
            'sha1=345'].version = model.parse_version('1.1')
        self.config.fetcher.allow_feed_download('http://foo/Compiler.xml',
                                                new_compiler_feed)
        self.config.fetcher.allow_feed_download('http://foo/Binary.xml',
                                                binary_feed)
        self.config.fetcher.allow_feed_download('http://foo/Source.xml',
                                                source_feed)
        out, err = self.run_0install(
            ['update', 'http://foo/Binary.xml', '--source'])
        assert not err, err
        assert 'Compiler.xml: 1.0 -> 1.1' in out, out

        # A dependency disappears.
        new_source_feed = reader.load_feed('Source.xml')
        new_source_feed.implementations['sha1=234'].requires = []
        self.config.fetcher.allow_feed_download('http://foo/Compiler.xml',
                                                new_compiler_feed)
        self.config.fetcher.allow_feed_download('http://foo/Binary.xml',
                                                binary_feed)
        self.config.fetcher.allow_feed_download('http://foo/Source.xml',
                                                new_source_feed)
        out, err = self.run_0install(
            ['update', 'http://foo/Binary.xml', '--source'])
        assert not err, err
        assert 'No longer used: http://foo/Compiler.xml' in out, out
Esempio n. 36
0
    def get_package_info(self, package, factory):
        def _is_64bit_windows():
            p = sys.platform
            from win32process import IsWow64Process
            if p == 'win64' or (p == 'win32' and IsWow64Process()): return True
            elif p == 'win32': return False
            else:
                raise Exception(
                    _("WindowsDistribution may only be used on the Windows platform"
                      ))

        def _read_hklm_reg(key_name, value_name):
            from win32api import RegOpenKeyEx, RegQueryValueEx, RegCloseKey
            from win32con import HKEY_LOCAL_MACHINE, KEY_READ
            KEY_WOW64_64KEY = 0x0100
            KEY_WOW64_32KEY = 0x0200
            if _is_64bit_windows():
                try:
                    key32 = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key_name, 0,
                                         KEY_READ | KEY_WOW64_32KEY)
                    (value32, _) = RegQueryValueEx(key32, value_name)
                    RegCloseKey(key32)
                except:
                    value32 = ''
                try:
                    key64 = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key_name, 0,
                                         KEY_READ | KEY_WOW64_64KEY)
                    (value64, _) = RegQueryValueEx(key64, value_name)
                    RegCloseKey(key64)
                except:
                    value64 = ''
            else:
                try:
                    key32 = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key_name, 0,
                                         KEY_READ)
                    (value32, _) = RegQueryValueEx(key32, value_name)
                    RegCloseKey(key32)
                except:
                    value32 = ''
                value64 = ''
            return (value32, value64)

        if package == 'openjdk-6-jre':
            (java32_home, java64_home) = _read_hklm_reg(
                r"SOFTWARE\JavaSoft\Java Runtime Environment\1.6", "JavaHome")

            if os.path.isfile(java32_home + r"\bin\java.exe"):
                impl = factory('package:windows:%s:%s:%s' %
                               (package, '6', 'i486'))
                impl.machine = 'i486'
                impl.version = model.parse_version('6')
                impl.upstream_stability = model.packaged
                impl.main = java32_home + r"\bin\java.exe"

            if os.path.isfile(java64_home + r"\bin\java.exe"):
                impl = factory('package:windows:%s:%s:%s' %
                               (package, '6', 'x86_64'))
                impl.machine = 'x86_64'
                impl.version = model.parse_version('6')
                impl.upstream_stability = model.packaged
                impl.main = java64_home + r"\bin\java.exe"

        if package == 'openjdk-6-jdk':
            (java32_home, java64_home) = _read_hklm_reg(
                r"SOFTWARE\JavaSoft\Java Development Kit\1.6", "JavaHome")

            if os.path.isfile(java32_home + r"\bin\java.exe"):
                impl = factory('package:windows:%s:%s:%s' %
                               (package, '6', 'i486'))
                impl.machine = 'i486'
                impl.version = model.parse_version('6')
                impl.upstream_stability = model.packaged
                impl.main = java32_home + r"\bin\java.exe"

            if os.path.isfile(java64_home + r"\bin\java.exe"):
                impl = factory('package:windows:%s:%s:%s' %
                               (package, '6', 'x86_64'))
                impl.machine = 'x86_64'
                impl.version = model.parse_version('6')
                impl.upstream_stability = model.packaged
                impl.main = java64_home + r"\bin\java.exe"
Esempio n. 37
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
Esempio n. 38
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
Esempio n. 39
0
 class DummyImpl:
     version = model.parse_version(v)
Esempio n. 40
0
 def pv(v):
     parsed = model.parse_version(v)
     assert model.format_version(parsed) == v
     return parsed
Esempio n. 41
0
def handle(config, options, args):
    if len(args) != 1:
        raise UsageError()

    assert not options.offline

    iface_uri = model.canonical_iface_uri(args[0])

    old_gui = options.gui

    # Select once in offline console mode to get the old values
    options.offline = True
    options.gui = False
    options.refresh = False

    try:
        old_sels = select.get_selections(config,
                                         options,
                                         iface_uri,
                                         select_only=True,
                                         download_only=False,
                                         test_callback=None)
    except SafeException:
        old_selections = {}
    else:
        if old_sels is None:
            old_selections = {}
        else:
            old_selections = old_sels.selections

    # Download in online mode to get the new values
    config.network_use = model.network_full
    options.offline = False
    options.gui = old_gui
    options.refresh = True

    sels = select.get_selections(config,
                                 options,
                                 iface_uri,
                                 select_only=False,
                                 download_only=True,
                                 test_callback=None)
    if not sels:
        sys.exit(1)  # Aborted by user

    changes = False

    for iface, old_sel in old_selections.iteritems():
        new_sel = sels.selections.get(iface, None)
        if new_sel is None:
            print(_("No longer used: %s") % iface)
            changes = True
        elif old_sel.version != new_sel.version:
            print(
                _("%s: %s -> %s") % (iface, old_sel.version, new_sel.version))
            changes = True

    for iface, new_sel in sels.selections.iteritems():
        if iface not in old_selections:
            print(_("%s: new -> %s") % (iface, new_sel.version))
            changes = True

    root_sel = sels[iface_uri]
    root_iface = config.iface_cache.get_interface(iface_uri)
    latest = max((impl.version, impl)
                 for impl in root_iface.implementations.values())[1]
    if latest.version > model.parse_version(sels[iface_uri].version):
        print(
            _("A later version ({name} {latest}) exists but was not selected. Using {version} instead."
              ).format(latest=latest.get_version(),
                       name=root_iface.get_name(),
                       version=root_sel.version))
        if not config.help_with_testing and latest.get_stability(
        ) < model.stable:
            print(
                _('To select "testing" versions, use:\n0install config help_with_testing True'
                  ))
    else:
        if not changes:
            print(
                _("No updates found. Continuing with version {version}.").
                format(version=root_sel.version))
Esempio n. 42
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
Esempio n. 43
0
 def __init__(self, version, distro):
     self.version = model.parse_version(version)
     self.distro_name = distro
Esempio n. 44
0
def write_sample_feed(buildenv, master_feed, src_impl):
    path = buildenv.local_iface_file

    old_path = os.path.join(buildenv.metadir, buildenv.iface_name + '.xml')
    if os.path.exists(old_path):
        warn("Removing old %s file: use %s instead now", old_path, path)
        os.unlink(old_path)

    impl = minidom.getDOMImplementation()

    XMLNS_IFACE = namespaces.XMLNS_IFACE

    doc = impl.createDocument(XMLNS_IFACE, "interface", None)

    root = doc.documentElement
    root.setAttributeNS(XMLNS_NAMESPACE, 'xmlns', XMLNS_IFACE)
    prefixes = Prefixes(XMLNS_IFACE)

    def addSimple(parent, name, text=None):
        elem = doc.createElementNS(XMLNS_IFACE, name)

        parent.appendChild(
            doc.createTextNode('\n' + '  ' * (1 + depth(parent))))
        parent.appendChild(elem)
        if text:
            elem.appendChild(doc.createTextNode(text))
        return elem

    def close(element):
        element.appendChild(doc.createTextNode('\n' + '  ' * depth(element)))

    addSimple(root, 'name', master_feed.name)
    addSimple(root, 'summary', master_feed.summary)
    addSimple(root, 'description', master_feed.description)
    feed_for = addSimple(root, 'feed-for')

    feed_for.setAttributeNS(None, 'interface', find_feed_for(master_feed))

    group = addSimple(root, 'group')
    main = src_impl.attrs.get(XMLNS_0COMPILE + ' binary-main', None)
    if main:
        group.setAttributeNS(None, 'main', main)

    lib_mappings = src_impl.attrs.get(XMLNS_0COMPILE + ' binary-lib-mappings',
                                      None)
    if lib_mappings:
        prefixes.setAttributeNS(group, XMLNS_0COMPILE, 'lib-mappings',
                                lib_mappings)

    for d in src_impl.dependencies:
        if parse_bool(
                d.metadata.get(XMLNS_0COMPILE + ' include-binary', 'false')):
            requires = d.qdom.toDOM(doc, prefixes)
            requires.removeAttributeNS(XMLNS_0COMPILE, 'include-binary')
            group.appendChild(requires)
    set_arch = True

    impl_elem = addSimple(group, 'implementation')
    impl_template = buildenv.get_binary_template()
    if impl_template:
        arm_if_0install_attrs(impl_template)

        # Copy attributes from template
        for fullname, value in impl_template.attrs.iteritems():
            if fullname == 'arch':
                set_arch = False
                if value == '*-*':
                    continue
            if ' ' in fullname:
                ns, localName = fullname.split(' ', 1)
            else:
                ns, localName = None, fullname
            prefixes.setAttributeNS(impl_elem, ns, localName, value)
        # Copy child nodes
        for child in impl_template.childNodes:
            impl_elem.appendChild(child.toDOM(doc, prefixes))
        if impl_template.content:
            impl_elem.appendChild(doc.createTextNode(impl_template.content))

        for version_elem in itertools.chain(
                impl_elem.getElementsByTagName('version'), ):
            pin_components = version_elem.getAttributeNS(
                XMLNS_0COMPILE, "pin-components")
            if pin_components:
                pin_components = int(pin_components)
                iface = version_elem.parentNode.getAttribute("interface")
                assert iface
                dep_impl = buildenv.chosen_impl(iface)
                impl_version = model.parse_version(
                    dep_impl.attrs.get('version'))

                pinned_components = [impl_version[0][:pin_components]]
                # (for -pre versions)
                min_version = min(pinned_components, impl_version)

                # clone and increment
                max_version = [pinned_components[0][:]]
                max_version[0][-1] += 1

                version_elem.setAttribute("not-before",
                                          model.format_version(min_version))
                version_elem.setAttribute("before",
                                          model.format_version(max_version))

    if set_arch:
        group.setAttributeNS(None, 'arch', buildenv.target_arch)

    impl_elem.setAttributeNS(None, 'version', src_impl.version)

    if not impl_elem.hasAttribute('license'):
        license = src_impl.attrs.get('license')
        if license:
            impl_elem.setAttributeNS(None, 'license', license)

    version_modifier = buildenv.version_modifier
    if version_modifier:
        impl_elem.setAttributeNS(None, 'version-modifier', version_modifier)

    impl_elem.setAttributeNS(None, 'id', '..')
    impl_elem.setAttributeNS(None, 'released', time.strftime('%Y-%m-%d'))
    close(group)
    close(root)

    for ns, prefix in prefixes.prefixes.items():
        root.setAttributeNS(XMLNS_NAMESPACE, 'xmlns:' + prefix, ns)

    stream = codecs.open(path, 'w', encoding='utf-8')
    try:
        doc.writexml(stream)
    finally:
        stream.close()
Esempio n. 45
0
def do_build_internal(options, args):
    """build-internal"""
    # If a sandbox is being used, we're in it now.
    import getpass, socket

    buildenv = BuildEnv()
    sels = buildenv.get_selections()

    builddir = os.path.realpath('build')
    ensure_dir(buildenv.metadir)

    build_env_xml = join(buildenv.metadir, 'build-environment.xml')

    buildenv_doc = sels.toDOM()

    # Create build-environment.xml file
    root = buildenv_doc.documentElement
    info = buildenv_doc.createElementNS(XMLNS_0COMPILE, 'build-info')
    root.appendChild(info)
    info.setAttributeNS(None, 'time', time.strftime('%Y-%m-%d %H:%M').strip())
    info.setAttributeNS(None, 'host', socket.getfqdn())
    info.setAttributeNS(None, 'user', getpass.getuser())
    info.setAttributeNS(None, 'arch', '%s-%s' % (uname[0], uname[4]))
    stream = file(build_env_xml, 'w')
    buildenv_doc.writexml(stream, addindent="  ", newl="\n")
    stream.close()

    # Create local binary interface file.
    # We use the main feed for the interface as the template for the name,
    # summary, etc (note: this is not necessarily the feed that contained
    # the source code).
    master_feed = iface_cache.get_feed(buildenv.interface)
    src_impl = buildenv.chosen_impl(buildenv.interface)
    write_sample_feed(buildenv, master_feed, src_impl)

    # Check 0compile is new enough
    min_version = model.parse_version(
        src_impl.attrs.get(XMLNS_0COMPILE + ' min-version', None))
    if min_version and min_version > model.parse_version(__main__.version):
        raise SafeException(
            "%s-%s requires 0compile >= %s, but we are only version %s" %
            (master_feed.get_name(), src_impl.version,
             model.format_version(min_version), __main__.version))

    # Create the patch
    patch_file = join(buildenv.metadir, 'from-%s.patch' % src_impl.version)
    if buildenv.user_srcdir:
        with open(patch_file, 'w') as stream:
            # (ignore errors; will already be shown on stderr)
            try:
                subprocess.call(["diff", "-urN", buildenv.orig_srcdir, 'src'],
                                stdout=stream)
            except OSError as ex:
                print >> sys.stderr, "WARNING: Failed to run 'diff': ", ex
        if os.path.getsize(patch_file) == 0:
            os.unlink(patch_file)
    elif os.path.exists(patch_file):
        os.unlink(patch_file)

    env('BUILDDIR', builddir)
    env('DISTDIR', buildenv.distdir)
    env('SRCDIR', buildenv.user_srcdir or buildenv.orig_srcdir)
    env('BINARYFEED', buildenv.local_iface_file)
    os.chdir(builddir)
    print "cd", builddir

    setup = CompileSetup(iface_cache.stores, sels)
    setup.prepare_env()

    # These mappings are needed when mixing Zero Install -dev packages with
    # native package binaries.
    mappings = {}
    for impl in sels.selections.values():
        # Add mappings that have been set explicitly...
        new_mappings = impl.attrs.get(XMLNS_0COMPILE + ' lib-mappings', '')
        if new_mappings:
            new_mappings = new_mappings.split(' ')
            for mapping in new_mappings:
                assert ':' in mapping, "lib-mappings missing ':' in '%s' from '%s'" % (
                    mapping, impl.feed)
                name, major_version = mapping.split(':', 1)
                assert '/' not in mapping, "lib-mappings '%s' contains a / in the version number (from '%s')!" % (
                    mapping, impl.feed)
                if sys.platform == 'darwin':
                    mappings[name] = 'lib%s.%s.dylib' % (name, major_version)
                else:
                    mappings[name] = 'lib%s.so.%s' % (name, major_version)
        # Auto-detect required mappings where possible...
        # (if the -dev package is native, the symlinks will be OK)
        if not is_package_impl(impl):
            impl_path = lookup(impl)
            for libdirname in ['lib', 'usr/lib', 'lib64', 'usr/lib64']:
                libdir = os.path.join(impl_path, libdirname)
                if os.path.isdir(libdir):
                    find_broken_version_symlinks(libdir, mappings)

    if mappings:
        set_up_mappings(mappings)

    overrides_dir = os.path.join(os.environ['TMPDIR'], PKG_CONFIG_OVERRIDES)
    if os.path.isdir(overrides_dir):
        add_overrides = model.EnvironmentBinding('PKG_CONFIG_PATH',
                                                 PKG_CONFIG_OVERRIDES)
        do_env_binding(add_overrides, os.environ['TMPDIR'])

    # Some programs want to put temporary build files in the source directory.
    # Make a copy of the source if needed.
    dup_src_type = src_impl.attrs.get(XMLNS_0COMPILE + ' dup-src', None)
    if dup_src_type == 'true':
        dup_src(copy_file)
        env('SRCDIR', builddir)
    elif dup_src_type:
        raise Exception("Unknown dup-src value '%s'" % dup_src_type)

    if options.shell:
        spawn_and_check(find_in_path('cmd' if os.name == 'nt' else 'sh'), [])
    else:
        command = sels.commands[0].qdom.attrs.get('shell-command', None)
        if command is None:
            # New style <command>
            prog_args = setup.build_command(sels.interface,
                                            sels.command) + args
        else:
            # Old style shell-command='...'
            if os.name == 'nt':
                prog_args = [
                    os.environ['0COMPILE_BASH'], '-eux', '-c', command
                ] + args
            else:
                prog_args = ['/bin/sh', '-c', command + ' "$@"', '-'] + args
            assert len(sels.commands) == 1

        # Remove any existing log files
        for log in ['build.log', 'build-success.log', 'build-failure.log']:
            if os.path.exists(log):
                os.unlink(log)

        # Run the command, copying output to a new log
        with open('build.log', 'w') as log:
            print >> log, "Build log for %s-%s" % (master_feed.get_name(),
                                                   src_impl.version)
            print >> log, "\nBuilt using 0compile-%s" % __main__.version
            print >> log, "\nBuild system: " + ', '.join(uname)
            print >> log, "\n%s:\n" % ENV_FILE
            with open(os.path.join(os.pardir, ENV_FILE)) as properties_file:
                shutil.copyfileobj(properties_file, log)

            log.write('\n')

            if os.path.exists(patch_file):
                print >> log, "\nPatched with:\n"
                shutil.copyfileobj(file(patch_file), log)
                log.write('\n')

            if command:
                print "Executing: " + command, args
                print >> log, "Executing: " + command, args
            else:
                print "Executing: " + str(prog_args)
                print >> log, "Executing: " + str(prog_args)

            # Tee the output to the console and to the log
            child = subprocess.Popen(prog_args,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.STDOUT)
            while True:
                data = os.read(child.stdout.fileno(), 100)
                if not data: break
                sys.stdout.write(data)
                log.write(data)
            status = child.wait()
            failure = None
            if status == 0:
                print >> log, "Build successful"
                shorten_dynamic_library_install_names()
                fixup_generated_pkgconfig_files()
                remove_la_files()
            elif status > 0:
                failure = "Build failed with exit code %d" % status
            else:
                failure = "Build failure: exited due to signal %d" % (-status)
            if failure:
                print >> log, failure

        if failure:
            os.rename('build.log', 'build-failure.log')
            raise SafeException("Command '%s': %s" % (prog_args, failure))
        else:
            os.rename('build.log', 'build-success.log')
Esempio n. 46
0
def handle(config, options, args):
    if len(args) != 1:
        raise UsageError()

    assert not options.offline

    old_gui = options.gui

    app = config.app_mgr.lookup_app(args[0], missing_ok=True)
    if app is not None:
        old_sels = app.get_selections()
        old_selections = old_sels.selections
        iface_uri = old_sels.interface
        r = app.get_requirements()
        r.parse_update_options(options)
    else:
        iface_uri = model.canonical_iface_uri(args[0])

        r = requirements.Requirements(iface_uri)
        r.parse_options(options)

        # Select once in offline console mode to get the old values
        options.offline = True
        options.gui = False
        options.refresh = False

        try:
            old_sels = select.get_selections_for(r,
                                                 config,
                                                 options,
                                                 select_only=True,
                                                 download_only=False,
                                                 test_callback=None)
        except SafeException:
            old_selections = {}
        else:
            if old_sels is None:
                old_selections = {}
            else:
                old_selections = old_sels.selections

    # Download in online mode to get the new values
    config.network_use = model.network_full
    options.offline = False
    options.gui = old_gui
    options.refresh = True

    sels = select.get_selections_for(r,
                                     config,
                                     options,
                                     select_only=False,
                                     download_only=True,
                                     test_callback=None)
    if not sels:
        sys.exit(1)  # Aborted by user

    root_feed = config.iface_cache.get_feed(iface_uri)
    if root_feed:
        target = root_feed.get_replaced_by()
        if target is not None:
            print(
                _("Warning: interface {old} has been replaced by {new}".format(
                    old=iface_uri, new=target)))

    from zeroinstall.cmd import whatchanged
    changes = whatchanged.show_changes(old_selections, sels.selections)
    root_sel = sels[iface_uri]

    if not changes:
        from zeroinstall.support import xmltools
        # No obvious changes, but check for more subtle updates.
        if not xmltools.nodes_equal(sels.toDOM(), old_sels.toDOM()):
            changes = True
            print(
                _("Updates to metadata found, but no change to version ({version})."
                  ).format(version=root_sel.version))

    root_iface = config.iface_cache.get_interface(iface_uri)
    # Force a reload, since we may have used the GUI to update it
    for feed in config.iface_cache.get_feeds(root_iface):
        config.iface_cache.get_feed(feed, force=True)

    root_impls = config.iface_cache.get_implementations(root_iface)

    latest = max((impl.version, impl) for impl in root_impls)[1]
    if latest.version > model.parse_version(sels[iface_uri].version):
        print(
            _("A later version ({name} {latest}) exists but was not selected. Using {version} instead."
              ).format(latest=latest.get_version(),
                       name=root_iface.get_name(),
                       version=root_sel.version))
        if not config.help_with_testing and latest.get_stability(
        ) < model.stable:
            print(
                _('To select "testing" versions, use:\n0install config help_with_testing True'
                  ))
    elif not changes:
        print(
            _("No updates found. Continuing with version {version}.").format(
                version=root_sel.version))

    if app is not None:
        if changes:
            app.set_selections(sels)
        app.set_requirements(r)
Esempio n. 47
0
    def get_feed(self, master_feed):
        """Generate a feed containing information about distribution packages.
		This should immediately return a feed containing an implementation for the
		package if it's already installed. Information about versions that could be
		installed using the distribution's package manager can be added asynchronously
		later (see L{fetch_candidates}).
		@param master_feed: feed containing the <package-implementation> elements
		@type master_feed: L{model.ZeroInstallFeed}
		@rtype: L{model.ZeroInstallFeed}"""

        feed = model.ZeroInstallFeed(None)
        feed.url = 'distribution:' + master_feed.url

        for item, item_attrs in master_feed.get_package_impls(self):
            package = item_attrs.get('package', None)
            if package is None:
                raise model.InvalidInterface(
                    _("Missing 'package' attribute on %s") % item)

            def factory(id, only_if_missing=False, installed=True):
                assert id.startswith('package:')
                if id in feed.implementations:
                    if only_if_missing:
                        return None
                    warn(_("Duplicate ID '%s' for DistributionImplementation"),
                         id)
                impl = model.DistributionImplementation(feed, id, self)
                feed.implementations[id] = impl

                impl.installed = installed
                impl.metadata = item_attrs

                item_main = item_attrs.get('main', None)
                if item_main and not item_main.startswith('/'):
                    raise model.InvalidInterface(
                        _("'main' attribute must be absolute, but '%s' doesn't start with '/'!"
                          ) % item_main)
                impl.main = item_main
                impl.upstream_stability = model.packaged

                return impl

            self.get_package_info(package, factory)

        if master_feed.url == 'http://repo.roscidus.com/python/python' and all(
                not impl.installed for impl in feed.implementations.values()):
            # Hack: we can support Python on platforms with unsupported package managers
            # by adding the implementation of Python running us now to the list.
            python_version = '.'.join(
                [str(v) for v in sys.version_info if isinstance(v, int)])
            impl_id = 'package:host:python:' + python_version
            assert impl_id not in feed.implementations
            impl = model.DistributionImplementation(feed, impl_id, self)
            impl.installed = True
            impl.version = model.parse_version(python_version)
            impl.main = sys.executable
            impl.upstream_stability = model.packaged
            impl.machine = host_machine  # (hopefully)
            feed.implementations[impl_id] = impl

        return feed