Exemplo n.º 1
0
def _get_all_provides(vardb):
    """
	Get all of the sonames provided by all of the installed packages.
	This does not bother to acquire a lock, since its pretty safe to
	assume that any packages merged or unmerged while this function
	is running must be irrelevant.

	@param vardb: an installed package database
	@type vardb: vardbapi
	@rtype: frozenset
	@return: a frozenset od SonameAtom instances provided by all
		installed packages
	"""

    all_provides = []

    for cpv in vardb.cpv_all():
        try:
            provides, = vardb.aux_get(cpv, ['PROVIDES'])
        except KeyError:
            # Since we don't hold a lock, assume this is due to a
            # concurrent unmerge, and PROVIDES from the unmerged package
            # are most likely negligible due to topologically sorted
            # merge order. Also, note that it's possible for aux_get
            # to succeed and return empty PROVIDES metadata if the file
            # disappears (due to unmerge) before it can be read.
            pass
        else:
            if provides:
                all_provides.extend(parse_soname_deps(provides))

    return frozenset(all_provides)
Exemplo n.º 2
0
def _get_unresolved_soname_deps(metadata_dir, all_provides):
    """
	Get files with unresolved soname dependencies.

	@param metadata_dir: directory containing package metadata files
		named REQUIRES and NEEDED.ELF.2
	@type metadata_dir: str
	@param all_provides: a frozenset on SonameAtom instances provided by
		all installed packages
	@type all_provides: frozenset
	@rtype: list
	@return: list of tuple(filename, tuple(unresolved sonames))
	"""
    try:
        with io.open(_unicode_encode(os.path.join(metadata_dir, 'REQUIRES'),
                                     encoding=_encodings['fs'],
                                     errors='strict'),
                     mode='rt',
                     encoding=_encodings['repo.content'],
                     errors='strict') as f:
            requires = frozenset(parse_soname_deps(f.read()))
    except EnvironmentError:
        return []

    unresolved_by_category = {}
    for atom in requires:
        if atom not in all_provides:
            unresolved_by_category.setdefault(atom.multilib_category,
                                              set()).add(atom.soname)

    needed_filename = os.path.join(metadata_dir, "NEEDED.ELF.2")
    with io.open(_unicode_encode(needed_filename,
                                 encoding=_encodings['fs'],
                                 errors='strict'),
                 mode='rt',
                 encoding=_encodings['repo.content'],
                 errors='strict') as f:
        needed = f.readlines()

    unresolved_by_file = []
    for l in needed:
        l = l.rstrip("\n")
        if not l:
            continue
        entry = NeededEntry.parse(needed_filename, l)
        missing = unresolved_by_category.get(entry.multilib_category)
        if not missing:
            continue
        # NOTE: This can contain some false positives in the case of
        # missing DT_RPATH settings, since it's possible that a subset
        # package files have the desired DT_RPATH settings. However,
        # since reported sonames are unresolved for at least some file(s),
        # false positives or this sort should not be not too annoying.
        missing = [soname for soname in entry.needed if soname in missing]
        if missing:
            unresolved_by_file.append((entry.filename, tuple(missing)))

    return unresolved_by_file
Exemplo n.º 3
0
	def _validate_deps(self):
		"""
		Validate deps. This does not trigger USE calculation since that
		is expensive for ebuilds and therefore we want to avoid doing
		it unnecessarily (like for masked packages).
		"""
		eapi = self.eapi
		dep_eapi = eapi
		dep_valid_flag = self.iuse.is_valid_flag
		if self.installed:
			# Ignore EAPI.incompatible and conditionals missing
			# from IUSE for installed packages since these issues
			# aren't relevant now (re-evaluate when new EAPIs are
			# deployed).
			dep_eapi = None
			dep_valid_flag = None

		validated_atoms = []
		for k in self._dep_keys:
			v = self._metadata.get(k)
			if not v:
				continue
			try:
				atoms = use_reduce(v, eapi=dep_eapi,
					matchall=True, is_valid_flag=dep_valid_flag,
					token_class=Atom, flat=True)
			except InvalidDependString as e:
				self._metadata_exception(k, e)
			else:
				validated_atoms.extend(atoms)
				if not self.built:
					for atom in atoms:
						if not isinstance(atom, Atom):
							continue
						if atom.slot_operator_built:
							e = InvalidDependString(
								_("Improper context for slot-operator "
								"\"built\" atom syntax: %s") %
								(atom.unevaluated_atom,))
							self._metadata_exception(k, e)

		self._validated_atoms = tuple(set(atom for atom in
			validated_atoms if isinstance(atom, Atom)))

		for k in self._use_conditional_misc_keys:
			v = self._metadata.get(k)
			if not v:
				continue
			try:
				use_reduce(v, eapi=dep_eapi, matchall=True,
					is_valid_flag=dep_valid_flag)
			except InvalidDependString as e:
				self._metadata_exception(k, e)

		k = 'REQUIRED_USE'
		v = self._metadata.get(k)
		if v and not self.built:
			if not _get_eapi_attrs(eapi).required_use:
				self._invalid_metadata('EAPI.incompatible',
					"REQUIRED_USE set, but EAPI='%s' doesn't allow it" % eapi)
			else:
				try:
					check_required_use(v, (),
						self.iuse.is_valid_flag, eapi=eapi)
				except InvalidDependString as e:
					self._invalid_metadata(k + ".syntax", "%s: %s" % (k, e))

		k = 'SRC_URI'
		v = self._metadata.get(k)
		if v:
			try:
				use_reduce(v, is_src_uri=True, eapi=eapi, matchall=True,
					is_valid_flag=self.iuse.is_valid_flag)
			except InvalidDependString as e:
				if not self.installed:
					self._metadata_exception(k, e)

		if self.built:
			k = 'PROVIDES'
			try:
				self._provides = frozenset(
					parse_soname_deps(self._metadata[k]))
			except InvalidData as e:
				self._invalid_metadata(k + ".syntax", "%s: %s" % (k, e))

			k = 'REQUIRES'
			try:
				self._requires = frozenset(
					parse_soname_deps(self._metadata[k]))
			except InvalidData as e:
				self._invalid_metadata(k + ".syntax", "%s: %s" % (k, e))
Exemplo n.º 4
0
	def _validate_deps(self):
		"""
		Validate deps. This does not trigger USE calculation since that
		is expensive for ebuilds and therefore we want to avoid doing
		it unnecessarily (like for masked packages).
		"""
		eapi = self.eapi
		dep_eapi = eapi
		dep_valid_flag = self.iuse.is_valid_flag
		if self.installed:
			# Ignore EAPI.incompatible and conditionals missing
			# from IUSE for installed packages since these issues
			# aren't relevant now (re-evaluate when new EAPIs are
			# deployed).
			dep_eapi = None
			dep_valid_flag = None

		validated_atoms = []
		for k in self._dep_keys:
			v = self._metadata.get(k)
			if not v:
				continue
			try:
				atoms = use_reduce(v, eapi=dep_eapi,
					matchall=True, is_valid_flag=dep_valid_flag,
					token_class=Atom, flat=True)
			except InvalidDependString as e:
				self._metadata_exception(k, e)
			else:
				validated_atoms.extend(atoms)
				if not self.built:
					for atom in atoms:
						if not isinstance(atom, Atom):
							continue
						if atom.slot_operator_built:
							e = InvalidDependString(
								_("Improper context for slot-operator "
								"\"built\" atom syntax: %s") %
								(atom.unevaluated_atom,))
							self._metadata_exception(k, e)

		self._validated_atoms = tuple(set(atom for atom in
			validated_atoms if isinstance(atom, Atom)))

		k = 'PROVIDE'
		v = self._metadata.get(k)
		if v:
			try:
				use_reduce(v, eapi=dep_eapi, matchall=True,
					is_valid_flag=dep_valid_flag, token_class=Atom)
			except InvalidDependString as e:
				self._invalid_metadata("PROVIDE.syntax", "%s: %s" % (k, e))

		for k in self._use_conditional_misc_keys:
			v = self._metadata.get(k)
			if not v:
				continue
			try:
				use_reduce(v, eapi=dep_eapi, matchall=True,
					is_valid_flag=dep_valid_flag)
			except InvalidDependString as e:
				self._metadata_exception(k, e)

		k = 'REQUIRED_USE'
		v = self._metadata.get(k)
		if v and not self.built:
			if not _get_eapi_attrs(eapi).required_use:
				self._invalid_metadata('EAPI.incompatible',
					"REQUIRED_USE set, but EAPI='%s' doesn't allow it" % eapi)
			else:
				try:
					check_required_use(v, (),
						self.iuse.is_valid_flag, eapi=eapi)
				except InvalidDependString as e:
					self._invalid_metadata(k + ".syntax", "%s: %s" % (k, e))

		k = 'SRC_URI'
		v = self._metadata.get(k)
		if v:
			try:
				use_reduce(v, is_src_uri=True, eapi=eapi, matchall=True,
					is_valid_flag=self.iuse.is_valid_flag)
			except InvalidDependString as e:
				if not self.installed:
					self._metadata_exception(k, e)

		if self.built:
			k = 'PROVIDES'
			try:
				self._provides = frozenset(
					parse_soname_deps(self._metadata[k]))
			except InvalidData as e:
				self._invalid_metadata(k + ".syntax", "%s: %s" % (k, e))

			k = 'REQUIRES'
			try:
				self._requires = frozenset(
					parse_soname_deps(self._metadata[k]))
			except InvalidData as e:
				self._invalid_metadata(k + ".syntax", "%s: %s" % (k, e))