Exemplo n.º 1
0
    def register(self, cpv, slot, counter, paths):
        """ Register new objects in the registry. If there is a record with the
			same packagename (internally derived from cpv) and slot it is 
			overwritten with the new data.
			@param cpv: package instance that owns the objects
			@type cpv: CPV (as String)
			@param slot: the value of SLOT of the given package instance
			@type slot: String
			@param counter: vdb counter value for the package instance
			@type counter: String
			@param paths: absolute paths of objects that got preserved during an update
			@type paths: List
		"""
        cp = cpv_getkey(cpv)
        cps = cp + ":" + slot
        counter = self._normalize_counter(counter)
        if len(paths) == 0 and cps in self._data \
          and self._data[cps][0] == cpv and \
          self._normalize_counter(self._data[cps][1]) == counter:
            del self._data[cps]
        elif len(paths) > 0:
            if isinstance(paths, set):
                # convert set to list, for write with JSONEncoder
                paths = list(paths)
            self._data[cps] = (cpv, counter, paths)
Exemplo n.º 2
0
	def getUseForce(self, pkg=None):
		if pkg is None:
			return frozenset(stack_lists(
				self._useforce_list, incremental=True))

		cp = getattr(pkg, "cp", None)
		if cp is None:
			cp = cpv_getkey(remove_slot(pkg))
		useforce = []
		if hasattr(pkg, "repo") and pkg.repo != Package.UNKNOWN_REPO:
			repos = []
			try:
				repos.extend(repo.name for repo in
					self.repositories[pkg.repo].masters)
			except KeyError:
				pass
			repos.append(pkg.repo)
			for repo in repos:
				useforce.append(self._repo_useforce_dict.get(repo, {}))
				cpdict = self._repo_puseforce_dict.get(repo, {}).get(cp)
				if cpdict:
					pkg_useforce = ordered_by_atom_specificity(cpdict, pkg)
					if pkg_useforce:
						useforce.extend(pkg_useforce)
		for i, puseforce_dict in enumerate(self._puseforce_list):
			if self._useforce_list[i]:
				useforce.append(self._useforce_list[i])
			cpdict = puseforce_dict.get(cp)
			if cpdict:
				pkg_useforce = ordered_by_atom_specificity(cpdict, pkg)
				if pkg_useforce:
					useforce.extend(pkg_useforce)
		return frozenset(stack_lists(useforce, incremental=True))
Exemplo n.º 3
0
	def _getMaskAtom(self, cpv, slot, repo, unmask_atoms=None):
		"""
		Take a package and return a matching package.mask atom, or None if no
		such atom exists or it has been cancelled by package.unmask. PROVIDE
		is not checked, so atoms will not be found for old-style virtuals.

		@param cpv: The package name
		@type cpv: String
		@param slot: The package's slot
		@type slot: String
		@param repo: The package's repository [optional]
		@type repo: String
		@param unmask_atoms: if desired pass in self._punmaskdict.get(cp)
		@type unmask_atoms: list
		@rtype: String
		@return: A matching atom string or None if one is not found.
		"""
		cp = cpv_getkey(cpv)
		mask_atoms = self._pmaskdict.get(cp)
		if mask_atoms:
			pkg = "".join((cpv, _slot_separator, slot))
			if repo and repo != Package.UNKNOWN_REPO:
				pkg = "".join((pkg, _repo_separator, repo))
			pkg_list = [pkg]
			for x in mask_atoms:
				if not match_from_list(x, pkg_list):
					continue
				if unmask_atoms:
					for y in unmask_atoms:
						if match_from_list(y, pkg_list):
							return None
				return x
		return None
Exemplo n.º 4
0
	def add_depgraph_virtuals(self, mycpv, virts):
		"""This updates the preferences for old-style virtuals,
		affecting the behavior of dep_expand() and dep_check()
		calls. It can change dbapi.match() behavior since that
		calls dep_expand(). However, dbapi instances have
		internal match caches that are not invalidated when
		preferences are updated here. This can potentially
		lead to some inconsistency (relevant to bug #1343)."""

		#Ensure that self._virtuals is populated.
		if self._virtuals is None:
			self.getvirtuals()

		modified = False
		cp = Atom(cpv_getkey(mycpv))
		for virt in virts:
			try:
				virt = Atom(virt).cp
			except InvalidAtom:
				continue
			providers = self._virtuals.get(virt)
			if providers and cp in providers:
				continue
			providers = self._depgraphVirtuals.get(virt)
			if providers is None:
				providers = []
				self._depgraphVirtuals[virt] = providers
			if cp not in providers:
				providers.append(cp)
				modified = True

		if modified:
			self._compile_virtuals()
Exemplo n.º 5
0
    def getMaskAtom(self, cpv, slot):
        """
		Take a package and return a matching package.mask atom, or None if no
		such atom exists or it has been cancelled by package.unmask. PROVIDE
		is not checked, so atoms will not be found for old-style virtuals.

		@param cpv: The package name
		@type cpv: String
		@param slot: The package's slot
		@type slot: String
		@rtype: String
		@return: An matching atom string or None if one is not found.
		"""

        cp = cpv_getkey(cpv)
        mask_atoms = self._pmaskdict.get(cp)
        if mask_atoms:
            pkg_list = ["%s:%s" % (cpv, slot)]
            unmask_atoms = self._punmaskdict.get(cp)
            for x in mask_atoms:
                if not match_from_list(x, pkg_list):
                    continue
                if unmask_atoms:
                    for y in unmask_atoms:
                        if match_from_list(y, pkg_list):
                            return None
                return x
        return None
Exemplo n.º 6
0
    def _instance_key_multi_instance(self, cpv, support_string=False):
        try:
            return (cpv, cpv.build_id, cpv.file_size, cpv.build_time,
                    cpv.mtime)
        except AttributeError:
            if not support_string:
                raise

        # Fallback for interfaces such as aux_get where API consumers
        # may pass in a plain string.
        latest = None
        for pkg in self.cp_list(cpv_getkey(cpv)):
            if pkg == cpv and (latest is None
                               or latest.build_time < pkg.build_time):
                latest = pkg

        if latest is not None:
            return (
                latest,
                latest.build_id,
                latest.file_size,
                latest.build_time,
                latest.mtime,
            )

        raise KeyError(cpv)
Exemplo n.º 7
0
	def getMaskAtom(self, cpv, slot):
		"""
		Take a package and return a matching package.mask atom, or None if no
		such atom exists or it has been cancelled by package.unmask. PROVIDE
		is not checked, so atoms will not be found for old-style virtuals.

		@param cpv: The package name
		@type cpv: String
		@param slot: The package's slot
		@type slot: String
		@rtype: String
		@return: An matching atom string or None if one is not found.
		"""

		cp = cpv_getkey(cpv)
		mask_atoms = self._pmaskdict.get(cp)
		if mask_atoms:
			pkg_list = ["%s:%s" % (cpv, slot)]
			unmask_atoms = self._punmaskdict.get(cp)
			for x in mask_atoms:
				if not match_from_list(x, pkg_list):
					continue
				if unmask_atoms:
					for y in unmask_atoms:
						if match_from_list(y, pkg_list):
							return None
				return x
		return None
Exemplo n.º 8
0
	def applyDelta(self, data):
		packages = self._vardb._aux_cache["packages"]
		added_slots = {}
		for delta in data["deltas"]:
			cpv = delta["package"] + "-" + delta["version"]
			event = delta["event"]
			if event == "add":
				added_slots[cpv] = delta
				# Use aux_get to populate the cache
				# for this cpv.
				if cpv not in packages:
					try:
						self._vardb.aux_get(cpv, ["DESCRIPTION"])
					except KeyError:
						pass
			elif event == "remove":
				packages.pop(cpv, None)

		# Remove replaced versions from updated slots
		for cached_cpv, (mtime, metadata) in list(packages.items()):
			if cached_cpv in added_slots:
				continue
			replaced = False
			for cpv, delta in added_slots.items():
				if (cached_cpv.startswith(delta["package"]) and
					metadata.get("SLOT") == delta["slot"] and
					cpv_getkey(cached_cpv) == delta["package"]):
					replaced = True
					break
			if replaced:
				del packages[cached_cpv]
				del added_slots[cpv]
				if not added_slots:
					break
	def add_depgraph_virtuals(self, mycpv, virts):
		"""This updates the preferences for old-style virtuals,
		affecting the behavior of dep_expand() and dep_check()
		calls. It can change dbapi.match() behavior since that
		calls dep_expand(). However, dbapi instances have
		internal match caches that are not invalidated when
		preferences are updated here. This can potentially
		lead to some inconsistency (relevant to bug #1343)."""

		#Ensure that self._virtuals is populated.
		if self._virtuals is None:
			self.getvirtuals()

		modified = False
		cp = Atom(cpv_getkey(mycpv))
		for virt in virts:
			try:
				virt = Atom(virt).cp
			except InvalidAtom:
				continue
			providers = self._virtuals.get(virt)
			if providers and cp in providers:
				continue
			providers = self._depgraphVirtuals.get(virt)
			if providers is None:
				providers = []
				self._depgraphVirtuals[virt] = providers
			if cp not in providers:
				providers.append(cp)
				modified = True

		if modified:
			self._compile_virtuals()
Exemplo n.º 10
0
    def _getMaskAtom(self, cpv, slot, repo, unmask_atoms=None):
        """
		Take a package and return a matching package.mask atom, or None if no
		such atom exists or it has been cancelled by package.unmask. PROVIDE
		is not checked, so atoms will not be found for old-style virtuals.

		@param cpv: The package name
		@type cpv: String
		@param slot: The package's slot
		@type slot: String
		@param repo: The package's repository [optional]
		@type repo: String
		@param unmask_atoms: if desired pass in self._punmaskdict.get(cp)
		@type unmask_atoms: list
		@rtype: String
		@return: A matching atom string or None if one is not found.
		"""

        cp = cpv_getkey(cpv)
        mask_atoms = self._pmaskdict.get(cp)
        if mask_atoms:
            pkg = "".join((cpv, _slot_separator, slot))
            if repo and repo != Package.UNKNOWN_REPO:
                pkg = "".join((pkg, _repo_separator, repo))
            pkg_list = [pkg]
            for x in mask_atoms:
                if not match_from_list(x, pkg_list):
                    continue
                if unmask_atoms:
                    for y in unmask_atoms:
                        if match_from_list(y, pkg_list):
                            return None
                return x
        return None
Exemplo n.º 11
0
    def iterAtomsForPackage(self, pkg):
        """
		Find all matching atoms for a given package. This matches virtual
		arguments against the PROVIDE metadata.  This will raise an
		InvalidDependString exception if PROVIDE is invalid.
		"""
        cpv_slot_list = [pkg]
        cp = cpv_getkey(pkg.cpv)
        self._load()  # make sure the atoms are loaded

        atoms = self._atommap.get(cp)
        if atoms:
            for atom in atoms:
                if match_from_list(atom, cpv_slot_list):
                    yield atom
        provides = pkg._metadata["PROVIDE"]
        if not provides:
            return
        provides = provides.split()
        for provide in provides:
            try:
                provided_cp = Atom(provide).cp
            except InvalidAtom:
                continue
            atoms = self._atommap.get(provided_cp)
            if atoms:
                for atom in atoms:
                    if match_from_list(atom.replace(provided_cp, cp), cpv_slot_list):
                        yield atom
Exemplo n.º 12
0
    def iterAtomsForPackage(self, pkg):
        """
		Find all matching atoms for a given package. This matches virtual
		arguments against the PROVIDE metadata.  This will raise an
		InvalidDependString exception if PROVIDE is invalid.
		"""
        cpv_slot_list = [pkg]
        cp = cpv_getkey(pkg.cpv)
        self._load()  # make sure the atoms are loaded

        atoms = self._atommap.get(cp)
        if atoms:
            for atom in atoms:
                if match_from_list(atom, cpv_slot_list):
                    yield atom
        provides = pkg._metadata['PROVIDE']
        if not provides:
            return
        provides = provides.split()
        for provide in provides:
            try:
                provided_cp = Atom(provide).cp
            except InvalidAtom:
                continue
            atoms = self._atommap.get(provided_cp)
            if atoms:
                for atom in atoms:
                    if match_from_list(atom.replace(provided_cp, cp),
                                       cpv_slot_list):
                        yield atom
Exemplo n.º 13
0
	def register(self, cpv, slot, counter, paths):
		""" Register new objects in the registry. If there is a record with the
			same packagename (internally derived from cpv) and slot it is 
			overwritten with the new data.
			@param cpv: package instance that owns the objects
			@type cpv: CPV (as String)
			@param slot: the value of SLOT of the given package instance
			@type slot: String
			@param counter: vdb counter value for the package instance
			@type counter: String
			@param paths: absolute paths of objects that got preserved during an update
			@type paths: List
		"""
		cp = cpv_getkey(cpv)
		cps = cp+":"+slot
		counter = self._normalize_counter(counter)
		if len(paths) == 0 and cps in self._data \
				and self._data[cps][0] == cpv and \
				self._normalize_counter(self._data[cps][1]) == counter:
			del self._data[cps]
		elif len(paths) > 0:
			if isinstance(paths, set):
				# convert set to list, for write with JSONEncoder
				paths = list(paths)
			self._data[cps] = (cpv, counter, paths)
Exemplo n.º 14
0
	def cpv_remove(self,mycpv):
		"""Removes a cpv from the list of available packages."""
		self._clear_cache()
		mycp = cpv_getkey(mycpv)
		if mycpv in self.cpvdict:
			del	self.cpvdict[mycpv]
		if mycp not in self.cpdict:
			return
		while mycpv in self.cpdict[mycp]:
			del self.cpdict[mycp][self.cpdict[mycp].index(mycpv)]
		if not len(self.cpdict[mycp]):
			del self.cpdict[mycp]
Exemplo n.º 15
0
 def cpv_remove(self, mycpv):
     """Removes a cpv from the list of available packages."""
     self._clear_cache()
     mycp = cpv_getkey(mycpv)
     if mycpv in self.cpvdict:
         del self.cpvdict[mycpv]
     if mycp not in self.cpdict:
         return
     while mycpv in self.cpdict[mycp]:
         del self.cpdict[mycp][self.cpdict[mycp].index(mycpv)]
     if not len(self.cpdict[mycp]):
         del self.cpdict[mycp]
Exemplo n.º 16
0
 def getKeywords(self, cpv, slot, keywords, repo):
     cp = cpv_getkey(cpv)
     pkg = "".join((cpv, _slot_separator, slot))
     if repo and repo != Package.UNKNOWN_REPO:
         pkg = "".join((pkg, _repo_separator, repo))
     keywords = [[x for x in keywords.split() if x != "-*"]]
     for pkeywords_dict in self._pkeywords_list:
         cpdict = pkeywords_dict.get(cp)
         if cpdict:
             pkg_keywords = ordered_by_atom_specificity(cpdict, pkg)
             if pkg_keywords:
                 keywords.extend(pkg_keywords)
     return stack_lists(keywords, incremental=True)
Exemplo n.º 17
0
	def getKeywords(self, cpv, slot, keywords, repo):
		cp = cpv_getkey(cpv)
		pkg = "".join((cpv, _slot_separator, slot))
		if repo and repo != Package.UNKNOWN_REPO:
			pkg = "".join((pkg, _repo_separator, repo))
		keywords = [[x for x in keywords.split() if x != "-*"]]
		for pkeywords_dict in self._pkeywords_list:
			cpdict = pkeywords_dict.get(cp)
			if cpdict:
				pkg_keywords = ordered_by_atom_specificity(cpdict, pkg)
				if pkg_keywords:
					keywords.extend(pkg_keywords)
		return stack_lists(keywords, incremental=True)
Exemplo n.º 18
0
	def mapPathsToAtoms(self, paths):
		rValue = set()
		for p in paths:
			for cpv in self.dbapi._linkmap.getOwners(p):
				try:
					slot, = self.dbapi.aux_get(cpv, ["SLOT"])
				except KeyError:
					# This is expected for preserved libraries
					# of packages that have been uninstalled
					# without replacement.
					pass
				else:
					rValue.add("%s:%s" % (cpv_getkey(cpv), slot))
		return rValue
Exemplo n.º 19
0
 def mapPathsToAtoms(self, paths):
     rValue = set()
     for p in paths:
         for cpv in self.dbapi._linkmap.getOwners(p):
             try:
                 slot, = self.dbapi.aux_get(cpv, ["SLOT"])
             except KeyError:
                 # This is expected for preserved libraries
                 # of packages that have been uninstalled
                 # without replacement.
                 pass
             else:
                 rValue.add("%s:%s" % (cpv_getkey(cpv), slot))
     return rValue
Exemplo n.º 20
0
	def getPUSE(self, pkg):
		cp = getattr(pkg, "cp", None)
		if cp is None:
			cp = cpv_getkey(remove_slot(pkg))
		ret = ""
		cpdict = self._pusedict.get(cp)
		if cpdict:
			puse_matches = ordered_by_atom_specificity(cpdict, pkg)
			if puse_matches:
				puse_list = []
				for x in puse_matches:
					puse_list.extend(x)
				ret = " ".join(puse_list)
		return ret
Exemplo n.º 21
0
	def cpv_remove(self,mycpv):
		"""Removes a cpv from the list of available packages."""
		self._clear_cache()
		mycp = cpv_getkey(mycpv)
		instance_key = self._instance_key(mycpv)
		self.cpvdict.pop(instance_key, None)
		cp_list = self.cpdict.get(mycp)
		if cp_list is not None:
			cp_list = [x for x in cp_list
				if self._instance_key(x) != instance_key]
			if cp_list:
				self.cpdict[mycp] = cp_list
			else:
				del self.cpdict[mycp]
Exemplo n.º 22
0
 def getPUSE(self, pkg):
     cp = getattr(pkg, "cp", None)
     if cp is None:
         cp = cpv_getkey(remove_slot(pkg))
     ret = ""
     cpdict = self._pusedict.get(cp)
     if cpdict:
         puse_matches = ordered_by_atom_specificity(cpdict, pkg)
         if puse_matches:
             puse_list = []
             for x in puse_matches:
                 puse_list.extend(x)
             ret = " ".join(puse_list)
     return ret
Exemplo n.º 23
0
	def cpv_remove(self,mycpv):
		"""Removes a cpv from the list of available packages."""
		self._clear_cache()
		mycp = cpv_getkey(mycpv)
		instance_key = self._instance_key(mycpv)
		self.cpvdict.pop(instance_key, None)
		cp_list = self.cpdict.get(mycp)
		if cp_list is not None:
			cp_list = [x for x in cp_list
				if self._instance_key(x) != instance_key]
			if cp_list:
				self.cpdict[mycp] = cp_list
			else:
				del self.cpdict[mycp]
Exemplo n.º 24
0
    def iterAtomsForPackage(self, pkg):
        """
		Find all matching atoms for a given package. This matches virtual
		arguments against the PROVIDE metadata.  This will raise an
		InvalidDependString exception if PROVIDE is invalid.
		"""
        cpv_slot_list = [pkg]
        cp = cpv_getkey(pkg.cpv)
        self._load()  # make sure the atoms are loaded

        atoms = self._atommap.get(cp)
        if atoms:
            for atom in atoms:
                if match_from_list(atom, cpv_slot_list):
                    yield atom
Exemplo n.º 25
0
    def _getPkgAcceptLicense(self, cpv, slot):
        """
		Get an ACCEPT_LICENSE list, accounting for package.license.
		"""
        accept_license = self._accept_license
        cp = cpv_getkey(cpv)
        cpdict = self._plicensedict.get(cp)
        if cpdict:
            cpv_slot = "%s:%s" % (cpv, slot)
            plicence_list = ordered_by_atom_specificity(cpdict, cpv_slot)
            if plicence_list:
                accept_license = list(self._accept_license)
                for x in plicence_list:
                    accept_license.extend(x)
        return accept_license
Exemplo n.º 26
0
	def _getPkgAcceptLicense(self, cpv, slot):
		"""
		Get an ACCEPT_LICENSE list, accounting for package.license.
		"""
		accept_license = self._accept_license
		cp = cpv_getkey(cpv)
		cpdict = self._plicensedict.get(cp)
		if cpdict:
			cpv_slot = "%s:%s" % (cpv, slot)
			plicence_list = ordered_by_atom_specificity(cpdict, cpv_slot)
			if plicence_list:
				accept_license = list(self._accept_license)
				for x in plicence_list:
					accept_license.extend(x)
		return accept_license
Exemplo n.º 27
0
	def iterAtomsForPackage(self, pkg):
		"""
		Find all matching atoms for a given package. This matches virtual
		arguments against the PROVIDE metadata.  This will raise an
		InvalidDependString exception if PROVIDE is invalid.
		"""
		cpv_slot_list = [pkg]
		cp = cpv_getkey(pkg.cpv)
		self._load() # make sure the atoms are loaded

		atoms = self._atommap.get(cp)
		if atoms:
			for atom in atoms:
				if match_from_list(atom, cpv_slot_list):
					yield atom
Exemplo n.º 28
0
	def _getPkgAcceptLicense(self, cpv, slot, repo):
		"""
		Get an ACCEPT_LICENSE list, accounting for package.license.
		"""
		accept_license = self._accept_license
		cp = cpv_getkey(cpv)
		cpdict = self._plicensedict.get(cp)
		if cpdict:
			if not hasattr(cpv, "slot"):
				cpv = _pkg_str(cpv, slot=slot, repo=repo)
			plicence_list = ordered_by_atom_specificity(cpdict, cpv)
			if plicence_list:
				accept_license = list(self._accept_license)
				for x in plicence_list:
					accept_license.extend(x)
		return accept_license
Exemplo n.º 29
0
    def _getPkgAcceptLicense(self, cpv, slot, repo):
        """
		Get an ACCEPT_LICENSE list, accounting for package.license.
		"""
        accept_license = self._accept_license
        cp = cpv_getkey(cpv)
        cpdict = self._plicensedict.get(cp)
        if cpdict:
            if not hasattr(cpv, "slot"):
                cpv = _pkg_str(cpv, slot=slot, repo=repo)
            plicence_list = ordered_by_atom_specificity(cpdict, cpv)
            if plicence_list:
                accept_license = list(self._accept_license)
                for x in plicence_list:
                    accept_license.extend(x)
        return accept_license
Exemplo n.º 30
0
	def _populate_treeVirtuals(self, vartree):
		"""
		Initialize _treeVirtuals from the given vartree.
		It must not have been initialized already, otherwise
		our assumptions about immutability don't hold.
		"""
		assert self._treeVirtuals is None, "treeVirtuals must not be reinitialized"

		self._treeVirtuals = {}

		for provide, cpv_list in vartree.get_all_provides().items():
			try:
				provide = Atom(provide)
			except InvalidAtom:
				continue
			self._treeVirtuals[provide.cp] = \
				[Atom(cpv_getkey(cpv)) for cpv in cpv_list]
Exemplo n.º 31
0
	def getMaskAtom(self, cpv, slot, repo):
		"""
		Take a package and return a matching package.mask atom, or None if no
		such atom exists or it has been cancelled by package.unmask. PROVIDE
		is not checked, so atoms will not be found for old-style virtuals.

		@param cpv: The package name
		@type cpv: String
		@param slot: The package's slot
		@type slot: String
		@param repo: The package's repository [optional]
		@type repo: String
		@rtype: String
		@return: A matching atom string or None if one is not found.
		"""
		cp = cpv_getkey(cpv)
		return self._getMaskAtom(cpv, slot, repo, self._punmaskdict.get(cp))
Exemplo n.º 32
0
	def getPKeywords(self, cpv, slot, repo, global_accept_keywords):
		"""Gets any package.keywords settings for cp for the given
		cpv, slot and repo

		@param cpv: The package name (for package.keywords support)
		@type cpv: String
		@param slot: The 'SLOT' key from the raw package metadata
		@type slot: String
		@param keywords: The 'KEYWORDS' key from the raw package metadata
		@type keywords: String
		@param global_accept_keywords: The current value of ACCEPT_KEYWORDS
		@type global_accept_keywords: String
		@param backuped_accept_keywords: ACCEPT_KEYWORDS from the backup env
		@type backuped_accept_keywords: String
		@rtype: List
		@return: list of KEYWORDS that have been accepted
		"""

		pgroups = global_accept_keywords.split()
		cp = cpv_getkey(cpv)

		unmaskgroups = []
		if self._p_accept_keywords:
			cpv_slot = "%s:%s" % (cpv, slot)
			accept_keywords_defaults = tuple('~' + keyword for keyword in \
				pgroups if keyword[:1] not in "~-")
			for d in self._p_accept_keywords:
				cpdict = d.get(cp)
				if cpdict:
					pkg_accept_keywords = \
						ordered_by_atom_specificity(cpdict, cpv_slot)
					if pkg_accept_keywords:
						for x in pkg_accept_keywords:
							if not x:
								x = accept_keywords_defaults
							unmaskgroups.extend(x)

		pkgdict = self.pkeywordsdict.get(cp)
		if pkgdict:
			cpv_slot = "%s:%s" % (cpv, slot)
			pkg_accept_keywords = \
				ordered_by_atom_specificity(pkgdict, cpv_slot, repo=repo)
			if pkg_accept_keywords:
				for x in pkg_accept_keywords:
					unmaskgroups.extend(x)
		return unmaskgroups
Exemplo n.º 33
0
	def _populate_treeVirtuals(self, vartree):
		"""
		Initialize _treeVirtuals from the given vartree.
		It must not have been initialized already, otherwise
		our assumptions about immutability don't hold.
		"""
		assert self._treeVirtuals is None, "treeVirtuals must not be reinitialized"

		self._treeVirtuals = {}

		for provide, cpv_list in vartree.get_all_provides().items():
			try:
				provide = Atom(provide)
			except InvalidAtom:
				continue
			self._treeVirtuals[provide.cp] = \
				[Atom(cpv_getkey(cpv)) for cpv in cpv_list]
Exemplo n.º 34
0
    def getPKeywords(self, cpv, slot, repo, global_accept_keywords):
        """Gets any package.keywords settings for cp for the given
		cpv, slot and repo

		@param cpv: The package name (for package.keywords support)
		@type cpv: String
		@param slot: The 'SLOT' key from the raw package metadata
		@type slot: String
		@param keywords: The 'KEYWORDS' key from the raw package metadata
		@type keywords: String
		@param global_accept_keywords: The current value of ACCEPT_KEYWORDS
		@type global_accept_keywords: String
		@param backuped_accept_keywords: ACCEPT_KEYWORDS from the backup env
		@type backuped_accept_keywords: String
		@rtype: List
		@return: list of KEYWORDS that have been accepted
		"""

        pgroups = global_accept_keywords.split()
        cp = cpv_getkey(cpv)

        unmaskgroups = []
        if self._p_accept_keywords:
            cpv_slot = "%s:%s" % (cpv, slot)
            accept_keywords_defaults = tuple('~' + keyword for keyword in \
             pgroups if keyword[:1] not in "~-")
            for d in self._p_accept_keywords:
                cpdict = d.get(cp)
                if cpdict:
                    pkg_accept_keywords = \
                     ordered_by_atom_specificity(cpdict, cpv_slot)
                    if pkg_accept_keywords:
                        for x in pkg_accept_keywords:
                            if not x:
                                x = accept_keywords_defaults
                            unmaskgroups.extend(x)

        pkgdict = self.pkeywordsdict.get(cp)
        if pkgdict:
            cpv_slot = "%s:%s" % (cpv, slot)
            pkg_accept_keywords = \
             ordered_by_atom_specificity(pkgdict, cpv_slot, repo=repo)
            if pkg_accept_keywords:
                for x in pkg_accept_keywords:
                    unmaskgroups.extend(x)
        return unmaskgroups
Exemplo n.º 35
0
    def getUseMask(self, pkg=None):
        if pkg is None:
            return frozenset(stack_lists(self._usemask_list, incremental=True))

        cp = getattr(pkg, "cp", None)
        if cp is None:
            cp = cpv_getkey(remove_slot(pkg))
        usemask = []
        for i, pusemask_dict in enumerate(self._pusemask_list):
            if self._usemask_list[i]:
                usemask.append(self._usemask_list[i])
            cpdict = pusemask_dict.get(cp)
            if cpdict:
                pkg_usemask = ordered_by_atom_specificity(cpdict, pkg)
                if pkg_usemask:
                    usemask.extend(pkg_usemask)
        return frozenset(stack_lists(usemask, incremental=True))
Exemplo n.º 36
0
	def getUseForce(self, pkg=None):
		if pkg is None:
			return frozenset(stack_lists(
				self._useforce_list, incremental=True))

		cp = getattr(pkg, "cp", None)
		if cp is None:
			cp = cpv_getkey(remove_slot(pkg))
		useforce = []
		for i, puseforce_dict in enumerate(self._puseforce_list):
			if self._useforce_list[i]:
				useforce.append(self._useforce_list[i])
			cpdict = puseforce_dict.get(cp)
			if cpdict:
				pkg_useforce = ordered_by_atom_specificity(cpdict, pkg)
				if pkg_useforce:
					useforce.extend(pkg_useforce)
		return frozenset(stack_lists(useforce, incremental=True))
Exemplo n.º 37
0
    def getMaskAtom(self, cpv, slot, repo):
        """
		Take a package and return a matching package.mask atom, or None if no
		such atom exists or it has been cancelled by package.unmask. PROVIDE
		is not checked, so atoms will not be found for old-style virtuals.

		@param cpv: The package name
		@type cpv: String
		@param slot: The package's slot
		@type slot: String
		@param repo: The package's repository [optional]
		@type repo: String
		@rtype: String
		@return: A matching atom string or None if one is not found.
		"""

        cp = cpv_getkey(cpv)
        return self._getMaskAtom(cpv, slot, repo, self._punmaskdict.get(cp))
Exemplo n.º 38
0
def rebuild(instmask, args, ldb, dbapi):
	def _get_enabled(instmask):
		ret = set()
		for t in instmask:
			for d in t:
				ret.add(d.toString())
		return frozenset(ret)

	def _output_status(cur, length):
		sys.stderr.write('\rScanning packages: %4d of %4d...' % (cur, length))

	def _match_path(vpath, args, enabled):
		for p in args:
			ps = p.rstrip(os.path.sep)
			if vpath == ps or vpath.startswith(ps + os.path.sep):
				if bool(os.path.exists(vpath)) == bool(p in enabled):
					return True
		return False

	enabled = _get_enabled(instmask)
	if args:
		paths = frozenset(expand_ldb(args, ldb))
	else:
		paths = enabled

	cpvs = dbapi.cpv_all()
	cpvl = len(cpvs)
	rebuilds = set()
	for i, cpv in enumerate(cpvs):
		_output_status(i, cpvl)
		dblink = dbapi._dblink(cpv)

		for f in dblink.getcontents():
			if _match_path(f, paths, enabled):
				key = cpv_getkey(cpv)
				slot = dbapi.aux_get(cpv, ('SLOT',))[0]
				rebuilds.add('%s:%s' % (key, slot))
				break

	_output_status(cpvl, cpvl)
	sys.stderr.write(' done.\n')

	for r in rebuilds:
		print(r)
Exemplo n.º 39
0
	def register(self, cpv, slot, counter, paths):
		""" Register new objects in the registry. If there is a record with the
			same packagename (internally derived from cpv) and slot it is 
			overwritten with the new data.
			@param cpv: package instance that owns the objects
			@type cpv: CPV (as String)
			@param slot: the value of SLOT of the given package instance
			@type slot: String
			@param counter: vdb counter value for the package instace
			@type counter: Integer
			@param paths: absolute paths of objects that got preserved during an update
			@type paths: List
		"""
		cp = cpv_getkey(cpv)
		cps = cp+":"+slot
		if len(paths) == 0 and cps in self._data \
				and self._data[cps][0] == cpv and int(self._data[cps][1]) == int(counter):
			del self._data[cps]
		elif len(paths) > 0:
			self._data[cps] = (cpv, counter, paths)
		if self._autocommit:
			self.store()
Exemplo n.º 40
0
    def applyDelta(self, data):
        packages = self._vardb._aux_cache["packages"]
        deltas = {}
        for delta in data["deltas"]:
            cpv = delta["package"] + "-" + delta["version"]
            deltas[cpv] = delta
            event = delta["event"]
            if event == "add":
                # Use aux_get to populate the cache
                # for this cpv.
                if cpv not in packages:
                    try:
                        self._vardb.aux_get(cpv, ["DESCRIPTION"])
                    except KeyError:
                        pass
            elif event == "remove":
                packages.pop(cpv, None)

        if deltas:
            # Delete removed or replaced versions from affected slots
            for cached_cpv, (mtime, metadata) in list(packages.items()):
                if cached_cpv in deltas:
                    continue

                removed = False
                for cpv, delta in deltas.items():
                    if (
                        cached_cpv.startswith(delta["package"])
                        and metadata.get("SLOT") == delta["slot"]
                        and cpv_getkey(cached_cpv) == delta["package"]
                    ):
                        removed = True
                        break

                if removed:
                    del packages[cached_cpv]
                    del deltas[cpv]
                    if not deltas:
                        break
Exemplo n.º 41
0
    def register(self, cpv, slot, counter, paths):
        """ Register new objects in the registry. If there is a record with the
			same packagename (internally derived from cpv) and slot it is 
			overwritten with the new data.
			@param cpv: package instance that owns the objects
			@type cpv: CPV (as String)
			@param slot: the value of SLOT of the given package instance
			@type slot: String
			@param counter: vdb counter value for the package instace
			@type counter: Integer
			@param paths: absolute paths of objects that got preserved during an update
			@type paths: List
		"""
        cp = cpv_getkey(cpv)
        cps = cp + ":" + slot
        if len(paths) == 0 and cps in self._data \
          and self._data[cps][0] == cpv and int(self._data[cps][1]) == int(counter):
            del self._data[cps]
        elif len(paths) > 0:
            self._data[cps] = (cpv, counter, paths)
        if self._autocommit:
            self.store()
Exemplo n.º 42
0
	def _instance_key_multi_instance(self, cpv, support_string=False):
		try:
			return (cpv, cpv.build_id, cpv.file_size, cpv.build_time,
				cpv.mtime)
		except AttributeError:
			if not support_string:
				raise

		# Fallback for interfaces such as aux_get where API consumers
		# may pass in a plain string.
		latest = None
		for pkg in self.cp_list(cpv_getkey(cpv)):
			if pkg == cpv and (
				latest is None or
				latest.build_time < pkg.build_time):
				latest = pkg

		if latest is not None:
			return (latest, latest.build_id, latest.file_size,
				latest.build_time, latest.mtime)

		raise KeyError(cpv)
def getmaskingstatus(mycpv, settings=None, portdb=None):
	if settings is None:
		settings = config(clone=portage.settings)
	if portdb is None:
		portdb = portage.portdb

	metadata = None
	installed = False
	if not isinstance(mycpv, basestring):
		# emerge passed in a Package instance
		pkg = mycpv
		mycpv = pkg.cpv
		metadata = pkg.metadata
		installed = pkg.installed

	mysplit = catpkgsplit(mycpv)
	if not mysplit:
		raise ValueError(_("invalid CPV: %s") % mycpv)
	if metadata is None:
		db_keys = list(portdb._aux_cache_keys)
		try:
			metadata = dict(zip(db_keys, portdb.aux_get(mycpv, db_keys)))
		except KeyError:
			if not portdb.cpv_exists(mycpv):
				raise
			return ["corruption"]
		if "?" in metadata["LICENSE"]:
			settings.setcpv(mycpv, mydb=metadata)
			metadata["USE"] = settings["PORTAGE_USE"]
		else:
			metadata["USE"] = ""

	rValue = []

	# profile checking
	if settings._getProfileMaskAtom(mycpv, metadata):
		rValue.append("profile")

	# package.mask checking
	if settings._getMaskAtom(mycpv, metadata):
		rValue.append("package.mask")

	# keywords checking
	eapi = metadata["EAPI"]
	mygroups = settings._getKeywords(mycpv, metadata)
	licenses = metadata["LICENSE"]
	properties = metadata["PROPERTIES"]
	if eapi.startswith("-"):
		eapi = eapi[1:]
	if not eapi_is_supported(eapi):
		return ["EAPI %s" % eapi]
	elif _eapi_is_deprecated(eapi) and not installed:
		return ["EAPI %s" % eapi]
	egroups = settings.configdict["backupenv"].get(
		"ACCEPT_KEYWORDS", "").split()
	pgroups = settings["ACCEPT_KEYWORDS"].split()
	myarch = settings["ARCH"]
	if pgroups and myarch not in pgroups:
		"""For operating systems other than Linux, ARCH is not necessarily a
		valid keyword."""
		myarch = pgroups[0].lstrip("~")

	cp = cpv_getkey(mycpv)
	pkgdict = settings.pkeywordsdict.get(cp)
	matches = False
	if pkgdict:
		cpv_slot_list = ["%s:%s" % (mycpv, metadata["SLOT"])]
		for atom, pkgkeywords in pkgdict.items():
			if match_from_list(atom, cpv_slot_list):
				matches = True
				pgroups.extend(pkgkeywords)
	if matches or egroups:
		pgroups.extend(egroups)
		inc_pgroups = set()
		for x in pgroups:
			if x.startswith("-"):
				if x == "-*":
					inc_pgroups.clear()
				else:
					inc_pgroups.discard(x[1:])
			else:
				inc_pgroups.add(x)
		pgroups = inc_pgroups
		del inc_pgroups

	kmask = "missing"

	if '**' in pgroups:
		kmask = None
	else:
		for keyword in pgroups:
			if keyword in mygroups:
				kmask = None
				break

	if kmask:
		for gp in mygroups:
			if gp=="*":
				kmask=None
				break
			elif gp=="-"+myarch and myarch in pgroups:
				kmask="-"+myarch
				break
			elif gp=="~"+myarch and myarch in pgroups:
				kmask="~"+myarch
				break

	try:
		missing_licenses = settings._getMissingLicenses(mycpv, metadata)
		if missing_licenses:
			allowed_tokens = set(["||", "(", ")"])
			allowed_tokens.update(missing_licenses)
			license_split = licenses.split()
			license_split = [x for x in license_split \
				if x in allowed_tokens]
			msg = license_split[:]
			msg.append("license(s)")
			rValue.append(" ".join(msg))
	except portage.exception.InvalidDependString as e:
		rValue.append("LICENSE: "+str(e))

	try:
		missing_properties = settings._getMissingProperties(mycpv, metadata)
		if missing_properties:
			allowed_tokens = set(["||", "(", ")"])
			allowed_tokens.update(missing_properties)
			properties_split = properties.split()
			properties_split = [x for x in properties_split \
					if x in allowed_tokens]
			msg = properties_split[:]
			msg.append("properties")
			rValue.append(" ".join(msg))
	except portage.exception.InvalidDependString as e:
		rValue.append("PROPERTIES: "+str(e))

	# Only show KEYWORDS masks for installed packages
	# if they're not masked for any other reason.
	if kmask and (not installed or not rValue):
		rValue.append(kmask+" keyword")

	return rValue
Exemplo n.º 44
0
def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None):
	"""
	Takes an unreduced and reduced deplist and removes satisfied dependencies.
	Returned deplist contains steps that must be taken to satisfy dependencies.
	"""
	if trees is None:
		trees = portage.db
	writemsg("ZapDeps -- %s\n" % (use_binaries), 2)
	if not reduced or unreduced == ["||"] or dep_eval(reduced):
		return []

	if unreduced[0] != "||":
		unresolved = []
		for x, satisfied in zip(unreduced, reduced):
			if isinstance(x, list):
				unresolved += dep_zapdeps(x, satisfied, myroot,
					use_binaries=use_binaries, trees=trees)
			elif not satisfied:
				unresolved.append(x)
		return unresolved

	# We're at a ( || atom ... ) type level and need to make a choice
	deps = unreduced[1:]
	satisfieds = reduced[1:]

	# Our preference order is for an the first item that:
	# a) contains all unmasked packages with the same key as installed packages
	# b) contains all unmasked packages
	# c) contains masked installed packages
	# d) is the first item

	preferred_installed = []
	preferred_in_graph = []
	preferred_any_slot = []
	preferred_non_installed = []
	unsat_use_in_graph = []
	unsat_use_installed = []
	unsat_use_non_installed = []
	other = []

	# unsat_use_* must come after preferred_non_installed
	# for correct ordering in cases like || ( foo[a] foo[b] ).
	choice_bins = (
		preferred_in_graph,
		preferred_installed,
		preferred_any_slot,
		preferred_non_installed,
		unsat_use_in_graph,
		unsat_use_installed,
		unsat_use_non_installed,
		other,
	)

	# Alias the trees we'll be checking availability against
	parent   = trees[myroot].get("parent")
	priority = trees[myroot].get("priority")
	graph_db = trees[myroot].get("graph_db")
	vardb = None
	if "vartree" in trees[myroot]:
		vardb = trees[myroot]["vartree"].dbapi
	if use_binaries:
		mydbapi = trees[myroot]["bintree"].dbapi
	else:
		mydbapi = trees[myroot]["porttree"].dbapi

	# Sort the deps into installed, not installed but already 
	# in the graph and other, not installed and not in the graph
	# and other, with values of [[required_atom], availablility]
	for x, satisfied in zip(deps, satisfieds):
		if isinstance(x, list):
			atoms = dep_zapdeps(x, satisfied, myroot,
				use_binaries=use_binaries, trees=trees)
		else:
			atoms = [x]
		if vardb is None:
			# When called by repoman, we can simply return the first choice
			# because dep_eval() handles preference selection.
			return atoms

		all_available = True
		all_use_satisfied = True
		slot_map = {}
		cp_map = {}
		for atom in atoms:
			if atom.blocker:
				continue
			# Ignore USE dependencies here since we don't want USE
			# settings to adversely affect || preference evaluation.
			avail_pkg = mydbapi.match(atom.without_use)
			if avail_pkg:
				avail_pkg = avail_pkg[-1] # highest (ascending order)
				avail_slot = Atom("%s:%s" % (atom.cp,
					mydbapi.aux_get(avail_pkg, ["SLOT"])[0]))
			if not avail_pkg:
				all_available = False
				all_use_satisfied = False
				break

			if atom.use:
				avail_pkg_use = mydbapi.match(atom)
				if not avail_pkg_use:
					all_use_satisfied = False
				else:
					# highest (ascending order)
					avail_pkg_use = avail_pkg_use[-1]
					if avail_pkg_use != avail_pkg:
						avail_pkg = avail_pkg_use
						avail_slot = Atom("%s:%s" % (atom.cp,
							mydbapi.aux_get(avail_pkg, ["SLOT"])[0]))

			slot_map[avail_slot] = avail_pkg
			pkg_cp = cpv_getkey(avail_pkg)
			highest_cpv = cp_map.get(pkg_cp)
			if highest_cpv is None or \
				pkgcmp(catpkgsplit(avail_pkg)[1:],
				catpkgsplit(highest_cpv)[1:]) > 0:
				cp_map[pkg_cp] = avail_pkg

		this_choice = (atoms, slot_map, cp_map, all_available)
		if all_available:
			# The "all installed" criterion is not version or slot specific.
			# If any version of a package is already in the graph then we
			# assume that it is preferred over other possible packages choices.
			all_installed = True
			for atom in set(Atom(atom.cp) for atom in atoms \
				if not atom.blocker):
				# New-style virtuals have zero cost to install.
				if not vardb.match(atom) and not atom.startswith("virtual/"):
					all_installed = False
					break
			all_installed_slots = False
			if all_installed:
				all_installed_slots = True
				for slot_atom in slot_map:
					# New-style virtuals have zero cost to install.
					if not vardb.match(slot_atom) and \
						not slot_atom.startswith("virtual/"):
						all_installed_slots = False
						break
			if graph_db is None:
				if all_use_satisfied:
					if all_installed:
						if all_installed_slots:
							preferred_installed.append(this_choice)
						else:
							preferred_any_slot.append(this_choice)
					else:
						preferred_non_installed.append(this_choice)
				else:
					if all_installed_slots:
						unsat_use_installed.append(this_choice)
					else:
						unsat_use_non_installed.append(this_choice)
			else:
				all_in_graph = True
				for slot_atom in slot_map:
					# New-style virtuals have zero cost to install.
					if not graph_db.match(slot_atom) and \
						not slot_atom.startswith("virtual/"):
						all_in_graph = False
						break
				circular_atom = None
				if all_in_graph:
					if parent is None or priority is None:
						pass
					elif priority.buildtime:
						# Check if the atom would result in a direct circular
						# dependency and try to avoid that if it seems likely
						# to be unresolvable. This is only relevant for
						# buildtime deps that aren't already satisfied by an
						# installed package.
						cpv_slot_list = [parent]
						for atom in atoms:
							if atom.blocker:
								continue
							if vardb.match(atom):
								# If the atom is satisfied by an installed
								# version then it's not a circular dep.
								continue
							if atom.cp != parent.cp:
								continue
							if match_from_list(atom, cpv_slot_list):
								circular_atom = atom
								break
				if circular_atom is not None:
					other.append(this_choice)
				else:
					if all_use_satisfied:
						if all_in_graph:
							preferred_in_graph.append(this_choice)
						elif all_installed:
							if all_installed_slots:
								preferred_installed.append(this_choice)
							else:
								preferred_any_slot.append(this_choice)
						else:
							preferred_non_installed.append(this_choice)
					else:
						if all_in_graph:
							unsat_use_in_graph.append(this_choice)
						elif all_installed_slots:
							unsat_use_installed.append(this_choice)
						else:
							unsat_use_non_installed.append(this_choice)
		else:
			other.append(this_choice)

	# Prefer choices which contain upgrades to higher slots. This helps
	# for deps such as || ( foo:1 foo:2 ), where we want to prefer the
	# atom which matches the higher version rather than the atom furthest
	# to the left. Sorting is done separately for each of choice_bins, so
	# as not to interfere with the ordering of the bins. Because of the
	# bin separation, the main function of this code is to allow
	# --depclean to remove old slots (rather than to pull in new slots).
	for choices in choice_bins:
		if len(choices) < 2:
			continue
		for choice_1 in choices[1:]:
			atoms_1, slot_map_1, cp_map_1, all_available_1 = choice_1
			cps = set(cp_map_1)
			for choice_2 in choices:
				if choice_1 is choice_2:
					# choice_1 will not be promoted, so move on
					break
				atoms_2, slot_map_2, cp_map_2, all_available_2 = choice_2
				intersecting_cps = cps.intersection(cp_map_2)
				if not intersecting_cps:
					continue
				has_upgrade = False
				has_downgrade = False
				for cp in intersecting_cps:
					version_1 = cp_map_1[cp]
					version_2 = cp_map_2[cp]
					difference = pkgcmp(catpkgsplit(version_1)[1:],
						catpkgsplit(version_2)[1:])
					if difference != 0:
						if difference > 0:
							has_upgrade = True
						else:
							has_downgrade = True
							break
				if has_upgrade and not has_downgrade:
					# promote choice_1 in front of choice_2
					choices.remove(choice_1)
					index_2 = choices.index(choice_2)
					choices.insert(index_2, choice_1)
					break

	for allow_masked in (False, True):
		for choices in choice_bins:
			for atoms, slot_map, cp_map, all_available in choices:
				if all_available or allow_masked:
					return atoms

	assert(False) # This point should not be reachable
Exemplo n.º 45
0
def getmaskingstatus(mycpv, settings=None, portdb=None):
    if settings is None:
        settings = config(clone=portage.settings)
    if portdb is None:
        portdb = portage.portdb

    metadata = None
    installed = False
    if not isinstance(mycpv, basestring):
        # emerge passed in a Package instance
        pkg = mycpv
        mycpv = pkg.cpv
        metadata = pkg.metadata
        installed = pkg.installed

    mysplit = catpkgsplit(mycpv)
    if not mysplit:
        raise ValueError(_("invalid CPV: %s") % mycpv)
    if metadata is None:
        db_keys = list(portdb._aux_cache_keys)
        try:
            metadata = dict(zip(db_keys, portdb.aux_get(mycpv, db_keys)))
        except KeyError:
            if not portdb.cpv_exists(mycpv):
                raise
            return ["corruption"]
        if "?" in metadata["LICENSE"]:
            settings.setcpv(mycpv, mydb=metadata)
            metadata["USE"] = settings["PORTAGE_USE"]
        else:
            metadata["USE"] = ""

    rValue = []

    # profile checking
    if settings._getProfileMaskAtom(mycpv, metadata):
        rValue.append("profile")

    # package.mask checking
    if settings._getMaskAtom(mycpv, metadata):
        rValue.append("package.mask")

    # keywords checking
    eapi = metadata["EAPI"]
    mygroups = settings._getKeywords(mycpv, metadata)
    licenses = metadata["LICENSE"]
    properties = metadata["PROPERTIES"]
    if eapi.startswith("-"):
        eapi = eapi[1:]
    if not eapi_is_supported(eapi):
        return ["EAPI %s" % eapi]
    elif _eapi_is_deprecated(eapi) and not installed:
        return ["EAPI %s" % eapi]
    egroups = settings.configdict["backupenv"].get("ACCEPT_KEYWORDS",
                                                   "").split()
    pgroups = settings["ACCEPT_KEYWORDS"].split()
    myarch = settings["ARCH"]
    if pgroups and myarch not in pgroups:
        """For operating systems other than Linux, ARCH is not necessarily a
		valid keyword."""
        myarch = pgroups[0].lstrip("~")

    cp = cpv_getkey(mycpv)
    pkgdict = settings.pkeywordsdict.get(cp)
    matches = False
    if pkgdict:
        cpv_slot_list = ["%s:%s" % (mycpv, metadata["SLOT"])]
        for atom, pkgkeywords in pkgdict.items():
            if match_from_list(atom, cpv_slot_list):
                matches = True
                pgroups.extend(pkgkeywords)
    if matches or egroups:
        pgroups.extend(egroups)
        inc_pgroups = set()
        for x in pgroups:
            if x.startswith("-"):
                if x == "-*":
                    inc_pgroups.clear()
                else:
                    inc_pgroups.discard(x[1:])
            else:
                inc_pgroups.add(x)
        pgroups = inc_pgroups
        del inc_pgroups

    kmask = "missing"

    if '**' in pgroups:
        kmask = None
    else:
        for keyword in pgroups:
            if keyword in mygroups:
                kmask = None
                break

    if kmask:
        for gp in mygroups:
            if gp == "*":
                kmask = None
                break
            elif gp == "-" + myarch and myarch in pgroups:
                kmask = "-" + myarch
                break
            elif gp == "~" + myarch and myarch in pgroups:
                kmask = "~" + myarch
                break

    try:
        missing_licenses = settings._getMissingLicenses(mycpv, metadata)
        if missing_licenses:
            allowed_tokens = set(["||", "(", ")"])
            allowed_tokens.update(missing_licenses)
            license_split = licenses.split()
            license_split = [x for x in license_split \
             if x in allowed_tokens]
            msg = license_split[:]
            msg.append("license(s)")
            rValue.append(" ".join(msg))
    except portage.exception.InvalidDependString as e:
        rValue.append("LICENSE: " + str(e))

    try:
        missing_properties = settings._getMissingProperties(mycpv, metadata)
        if missing_properties:
            allowed_tokens = set(["||", "(", ")"])
            allowed_tokens.update(missing_properties)
            properties_split = properties.split()
            properties_split = [x for x in properties_split \
              if x in allowed_tokens]
            msg = properties_split[:]
            msg.append("properties")
            rValue.append(" ".join(msg))
    except portage.exception.InvalidDependString as e:
        rValue.append("PROPERTIES: " + str(e))

    # Only show KEYWORDS masks for installed packages
    # if they're not masked for any other reason.
    if kmask and (not installed or not rValue):
        rValue.append(kmask + " keyword")

    return rValue
Exemplo n.º 46
0
 def key(self):
     return PortageBoundPackageKey(cpv_getkey(self._cpv), self)
Exemplo n.º 47
0
def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None):
    """
	Takes an unreduced and reduced deplist and removes satisfied dependencies.
	Returned deplist contains steps that must be taken to satisfy dependencies.
	"""
    if trees is None:
        trees = portage.db
    writemsg("ZapDeps -- %s\n" % (use_binaries), 2)
    if not reduced or unreduced == ["||"] or dep_eval(reduced):
        return []

    if unreduced[0] != "||":
        unresolved = []
        for x, satisfied in zip(unreduced, reduced):
            if isinstance(x, list):
                unresolved += dep_zapdeps(x,
                                          satisfied,
                                          myroot,
                                          use_binaries=use_binaries,
                                          trees=trees)
            elif not satisfied:
                unresolved.append(x)
        return unresolved

    # We're at a ( || atom ... ) type level and need to make a choice
    deps = unreduced[1:]
    satisfieds = reduced[1:]

    # Our preference order is for an the first item that:
    # a) contains all unmasked packages with the same key as installed packages
    # b) contains all unmasked packages
    # c) contains masked installed packages
    # d) is the first item

    preferred_installed = []
    preferred_in_graph = []
    preferred_any_slot = []
    preferred_non_installed = []
    unsat_use_in_graph = []
    unsat_use_installed = []
    unsat_use_non_installed = []
    other = []

    # unsat_use_* must come after preferred_non_installed
    # for correct ordering in cases like || ( foo[a] foo[b] ).
    choice_bins = (
        preferred_in_graph,
        preferred_installed,
        preferred_any_slot,
        preferred_non_installed,
        unsat_use_in_graph,
        unsat_use_installed,
        unsat_use_non_installed,
        other,
    )

    # Alias the trees we'll be checking availability against
    parent = trees[myroot].get("parent")
    priority = trees[myroot].get("priority")
    graph_db = trees[myroot].get("graph_db")
    vardb = None
    if "vartree" in trees[myroot]:
        vardb = trees[myroot]["vartree"].dbapi
    if use_binaries:
        mydbapi = trees[myroot]["bintree"].dbapi
    else:
        mydbapi = trees[myroot]["porttree"].dbapi

    # Sort the deps into installed, not installed but already
    # in the graph and other, not installed and not in the graph
    # and other, with values of [[required_atom], availablility]
    for x, satisfied in zip(deps, satisfieds):
        if isinstance(x, list):
            atoms = dep_zapdeps(x,
                                satisfied,
                                myroot,
                                use_binaries=use_binaries,
                                trees=trees)
        else:
            atoms = [x]
        if vardb is None:
            # When called by repoman, we can simply return the first choice
            # because dep_eval() handles preference selection.
            return atoms

        all_available = True
        all_use_satisfied = True
        slot_map = {}
        cp_map = {}
        for atom in atoms:
            if atom.blocker:
                continue
            # Ignore USE dependencies here since we don't want USE
            # settings to adversely affect || preference evaluation.
            avail_pkg = mydbapi.match(atom.without_use)
            if avail_pkg:
                avail_pkg = avail_pkg[-1]  # highest (ascending order)
                avail_slot = Atom(
                    "%s:%s" %
                    (atom.cp, mydbapi.aux_get(avail_pkg, ["SLOT"])[0]))
            if not avail_pkg:
                all_available = False
                all_use_satisfied = False
                break

            if atom.use:
                avail_pkg_use = mydbapi.match(atom)
                if not avail_pkg_use:
                    all_use_satisfied = False
                else:
                    # highest (ascending order)
                    avail_pkg_use = avail_pkg_use[-1]
                    if avail_pkg_use != avail_pkg:
                        avail_pkg = avail_pkg_use
                        avail_slot = Atom(
                            "%s:%s" %
                            (atom.cp, mydbapi.aux_get(avail_pkg, ["SLOT"])[0]))

            slot_map[avail_slot] = avail_pkg
            pkg_cp = cpv_getkey(avail_pkg)
            highest_cpv = cp_map.get(pkg_cp)
            if highest_cpv is None or \
             pkgcmp(catpkgsplit(avail_pkg)[1:],
             catpkgsplit(highest_cpv)[1:]) > 0:
                cp_map[pkg_cp] = avail_pkg

        this_choice = (atoms, slot_map, cp_map, all_available)
        if all_available:
            # The "all installed" criterion is not version or slot specific.
            # If any version of a package is already in the graph then we
            # assume that it is preferred over other possible packages choices.
            all_installed = True
            for atom in set(Atom(atom.cp) for atom in atoms \
             if not atom.blocker):
                # New-style virtuals have zero cost to install.
                if not vardb.match(atom) and not atom.startswith("virtual/"):
                    all_installed = False
                    break
            all_installed_slots = False
            if all_installed:
                all_installed_slots = True
                for slot_atom in slot_map:
                    # New-style virtuals have zero cost to install.
                    if not vardb.match(slot_atom) and \
                     not slot_atom.startswith("virtual/"):
                        all_installed_slots = False
                        break
            if graph_db is None:
                if all_use_satisfied:
                    if all_installed:
                        if all_installed_slots:
                            preferred_installed.append(this_choice)
                        else:
                            preferred_any_slot.append(this_choice)
                    else:
                        preferred_non_installed.append(this_choice)
                else:
                    if all_installed_slots:
                        unsat_use_installed.append(this_choice)
                    else:
                        unsat_use_non_installed.append(this_choice)
            else:
                all_in_graph = True
                for slot_atom in slot_map:
                    # New-style virtuals have zero cost to install.
                    if not graph_db.match(slot_atom) and \
                     not slot_atom.startswith("virtual/"):
                        all_in_graph = False
                        break
                circular_atom = None
                if all_in_graph:
                    if parent is None or priority is None:
                        pass
                    elif priority.buildtime:
                        # Check if the atom would result in a direct circular
                        # dependency and try to avoid that if it seems likely
                        # to be unresolvable. This is only relevant for
                        # buildtime deps that aren't already satisfied by an
                        # installed package.
                        cpv_slot_list = [parent]
                        for atom in atoms:
                            if atom.blocker:
                                continue
                            if vardb.match(atom):
                                # If the atom is satisfied by an installed
                                # version then it's not a circular dep.
                                continue
                            if atom.cp != parent.cp:
                                continue
                            if match_from_list(atom, cpv_slot_list):
                                circular_atom = atom
                                break
                if circular_atom is not None:
                    other.append(this_choice)
                else:
                    if all_use_satisfied:
                        if all_in_graph:
                            preferred_in_graph.append(this_choice)
                        elif all_installed:
                            if all_installed_slots:
                                preferred_installed.append(this_choice)
                            else:
                                preferred_any_slot.append(this_choice)
                        else:
                            preferred_non_installed.append(this_choice)
                    else:
                        if all_in_graph:
                            unsat_use_in_graph.append(this_choice)
                        elif all_installed_slots:
                            unsat_use_installed.append(this_choice)
                        else:
                            unsat_use_non_installed.append(this_choice)
        else:
            other.append(this_choice)

    # Prefer choices which contain upgrades to higher slots. This helps
    # for deps such as || ( foo:1 foo:2 ), where we want to prefer the
    # atom which matches the higher version rather than the atom furthest
    # to the left. Sorting is done separately for each of choice_bins, so
    # as not to interfere with the ordering of the bins. Because of the
    # bin separation, the main function of this code is to allow
    # --depclean to remove old slots (rather than to pull in new slots).
    for choices in choice_bins:
        if len(choices) < 2:
            continue
        for choice_1 in choices[1:]:
            atoms_1, slot_map_1, cp_map_1, all_available_1 = choice_1
            cps = set(cp_map_1)
            for choice_2 in choices:
                if choice_1 is choice_2:
                    # choice_1 will not be promoted, so move on
                    break
                atoms_2, slot_map_2, cp_map_2, all_available_2 = choice_2
                intersecting_cps = cps.intersection(cp_map_2)
                if not intersecting_cps:
                    continue
                has_upgrade = False
                has_downgrade = False
                for cp in intersecting_cps:
                    version_1 = cp_map_1[cp]
                    version_2 = cp_map_2[cp]
                    difference = pkgcmp(
                        catpkgsplit(version_1)[1:],
                        catpkgsplit(version_2)[1:])
                    if difference != 0:
                        if difference > 0:
                            has_upgrade = True
                        else:
                            has_downgrade = True
                            break
                if has_upgrade and not has_downgrade:
                    # promote choice_1 in front of choice_2
                    choices.remove(choice_1)
                    index_2 = choices.index(choice_2)
                    choices.insert(index_2, choice_1)
                    break

    for allow_masked in (False, True):
        for choices in choice_bins:
            for atoms, slot_map, cp_map, all_available in choices:
                if all_available or allow_masked:
                    return atoms

    assert (False)  # This point should not be reachable