示例#1
0
def package_info(pkgname):
    pv = get_db().xmatch("match-all", pkgname)
    if not pv:
        raise IMException("No package named '%s' found" % pkgname)

    bv = get_db().xmatch("bestmatch-visible", pkgname)
    pvsplit = portage.catpkgsplit(bv if bv else pv[-1])
    info = get_db().aux_get(
        bv if bv else pv[-1],
        ["DESCRIPTION", "HOMEPAGE", "LICENSE", "IUSE", "KEYWORDS"])

    return {
        "pkgname": '/'.join(pvsplit[:2]),
        "category": pvsplit[0],
        "shortname": pvsplit[1],
        "lastvers":
        '-'.join(pvsplit[2:]) if pvsplit[3] != "r0" else pvsplit[2],
        "othersvers":
        ['-'.join(portage.catpkgsplit(p)[2:]) for p in pv if p != bv],
        "description": info[0],
        "homepage": info[1],
        "license": info[2],
        "uses": info[3],
        "keywords": info[4],
    }
示例#2
0
def getMinUpgrade(vulnerableList, unaffectedList, minimize=True):
    """
	Checks if the systemstate is matching an atom in
	I{vulnerableList} and returns string describing
	the lowest version for the package that matches an atom in
	I{unaffectedList} and is greater than the currently installed
	version. It will return an empty list if the system is affected,
	and no upgrade is possible or None if the system is not affected.
	Both I{vulnerableList} and I{unaffectedList} should have the
	same base package.

	@type	vulnerableList: List of Strings
	@param	vulnerableList: atoms matching vulnerable package versions
	@type	unaffectedList: List of Strings
	@param	unaffectedList: atoms matching unaffected package versions
	@type	minimize:	Boolean
	@param	minimize:	True for a least-change upgrade, False for emerge-like algorithm

	@rtype:		String | None
	@return:	the lowest unaffected version that is greater than
				the installed version.
	"""
    rValue = ""
    v_installed = reduce(operator.add,
                         [match(v, "vartree") for v in vulnerableList], [])
    u_installed = reduce(operator.add,
                         [match(u, "vartree") for u in unaffectedList], [])

    # remove all unaffected atoms from vulnerable list
    v_installed = list(set(v_installed).difference(set(u_installed)))

    if not v_installed:
        return None

    # this tuple holds all vulnerable atoms, and the related upgrade atom
    vuln_update = []
    avail_updates = set()
    for u in unaffectedList:
        # TODO: This had match_type="match-all" before. I don't think it should
        # since we disregarded masked items later anyway (match(=rValue, "porttree"))
        avail_updates.update(match(u, "porttree"))
    # if an atom is already installed, we should not consider it for upgrades
    avail_updates.difference_update(u_installed)

    for vuln in v_installed:
        update = ""
        for c in avail_updates:
            c_pv = portage.catpkgsplit(c)
            i_pv = portage.catpkgsplit(vuln)
            if portage.pkgcmp(c_pv[1:], i_pv[1:]) > 0 \
              and (update == "" \
               or (minimize ^ (portage.pkgcmp(c_pv[1:], portage.catpkgsplit(update)[1:]) > 0))) \
              and portage.db[portage.root]["porttree"].dbapi.aux_get(c, ["SLOT"]) == portage.db[portage.root]["vartree"].dbapi.aux_get(vuln, ["SLOT"]):
                update = c_pv[0] + "/" + c_pv[1] + "-" + c_pv[2]
                if c_pv[3] != "r0":  # we don't like -r0 for display
                    update += "-" + c_pv[3]
        vuln_update.append([vuln, update])

    return vuln_update
示例#3
0
def getMinUpgrade(vulnerableList, unaffectedList, minimize=True):
	"""
	Checks if the systemstate is matching an atom in
	I{vulnerableList} and returns string describing
	the lowest version for the package that matches an atom in
	I{unaffectedList} and is greater than the currently installed
	version. It will return an empty list if the system is affected,
	and no upgrade is possible or None if the system is not affected.
	Both I{vulnerableList} and I{unaffectedList} should have the
	same base package.

	@type	vulnerableList: List of Strings
	@param	vulnerableList: atoms matching vulnerable package versions
	@type	unaffectedList: List of Strings
	@param	unaffectedList: atoms matching unaffected package versions
	@type	minimize:	Boolean
	@param	minimize:	True for a least-change upgrade, False for emerge-like algorithm

	@rtype:		String | None
	@return:	the lowest unaffected version that is greater than
				the installed version.
	"""
	rValue = ""
	v_installed = reduce(operator.add, [match(v, "vartree") for v in vulnerableList], [])
	u_installed = reduce(operator.add, [match(u, "vartree") for u in unaffectedList], [])

	# remove all unaffected atoms from vulnerable list
	v_installed = list(set(v_installed).difference(set(u_installed)))

	if not v_installed:
		return None

	# this tuple holds all vulnerable atoms, and the related upgrade atom
	vuln_update = []
	avail_updates = set()
	for u in unaffectedList:
		# TODO: This had match_type="match-all" before. I don't think it should
		# since we disregarded masked items later anyway (match(=rValue, "porttree"))
		avail_updates.update(match(u, "porttree"))
	# if an atom is already installed, we should not consider it for upgrades
	avail_updates.difference_update(u_installed)

	for vuln in v_installed:
		update = ""
		for c in avail_updates:
			c_pv = portage.catpkgsplit(c)
			i_pv = portage.catpkgsplit(vuln)
			if portage.pkgcmp(c_pv[1:], i_pv[1:]) > 0 \
					and (update == "" \
						or (minimize ^ (portage.pkgcmp(c_pv[1:], portage.catpkgsplit(update)[1:]) > 0))) \
					and portage.db[portage.root]["porttree"].dbapi.aux_get(c, ["SLOT"]) == portage.db[portage.root]["vartree"].dbapi.aux_get(vuln, ["SLOT"]):
				update = c_pv[0]+"/"+c_pv[1]+"-"+c_pv[2]
				if c_pv[3] != "r0":		# we don't like -r0 for display
					update += "-"+c_pv[3]
		vuln_update.append([vuln, update])

	return vuln_update
示例#4
0
	def __init__(self, **kwargs):
		Task.__init__(self, **kwargs)
		self.root = self.root_config.root
		self._raw_metadata = _PackageMetadataWrapperBase(self.metadata)
		self.metadata = _PackageMetadataWrapper(self, self._raw_metadata)
		if not self.built:
			self.metadata['CHOST'] = self.root_config.settings.get('CHOST', '')
		self.cp = portage.cpv_getkey(self.cpv)
		slot = self.slot
		if _slot_re.match(slot) is None:
			self._invalid_metadata('SLOT.invalid',
				"SLOT: invalid value: '%s'" % slot)
			# Avoid an InvalidAtom exception when creating slot_atom.
			# This package instance will be masked due to empty SLOT.
			slot = '0'
		if (self.iuse.enabled or self.iuse.disabled) and \
			not eapi_has_iuse_defaults(self.metadata["EAPI"]):
			if not self.installed:
				self._invalid_metadata('EAPI.incompatible',
					"IUSE contains defaults, but EAPI doesn't allow them")
		self.slot_atom = portage.dep.Atom("%s:%s" % (self.cp, slot))
		self.category, self.pf = portage.catsplit(self.cpv)
		self.cpv_split = portage.catpkgsplit(self.cpv)
		self.pv_split = self.cpv_split[1:]
		self._validate_deps()
		self.masks = self._masks()
		self.visible = self._visible(self.masks)
示例#5
0
	def __init__(self, filename):
		self.__localinit__()
		
		# check the location
		allportdirs = portdir + overlays
		for d in allportdirs:
			if filename[:len(d)] == d:
				self.location = d
		if len(self.location) <= 1:
			raise Exception("invalid ebuild directory")

		if self.location[-1] == "/":
			self.location = self.location[:-1]
			
		s = string.split(filename, "/")
		self.filename = s[len(s)-1]
		self.package = s[len(s)-2]
		self.category = s[len(s)-3]
		
		# use portage to get the version part
		self.version = portage.catpkgsplit(self.category+"/"+self.filename.replace(".ebuild", ""))
		if self.version[3] == "r0":
			self.version = self.version[2]
		else:
			self.version = self.version[2]+"-"+self.version[3]

		self.path = self.location+"/"+self.category+"/"+self.package+"/"+self.filename
示例#6
0
def split_atom_pkg( pkg ):
    """Extract [category/package, atoms, version] from some ebuild identifier"""
    #debug.dprint("PORTAGELIB: split_atom_pkg(); pkg = " +pkg)
    atoms = []
    version = ''
    ver_suffix = ''
    if pkg.endswith("*"):
        pkg = pkg[:-1]
        ver_suffix = '*'
    while pkg[0] in ["<",">","=","!","*"]:
        #debug.dprint("PORTAGELIB: split_atom_pkg(); pkg = " + str(pkg))
        atoms.append(pkg[0])
        pkg = pkg[1:]
    cplist = portage.catpkgsplit(pkg) or portage.catsplit(pkg)
    #debug.dprint("PORTAGELIB: split_atom_pkg(); cplist = " + str(cplist))
    if not cplist or len(cplist) < 2:
        debug.dprint("PORTAGELIB split_atom_pkg(): issues with '%s'" % pkg)
        return ['', '', '']
    cp = cplist[0] + "/" + cplist[1]
    #debug.dprint("PORTAGELIB: split_atom_pkg(); cplist2 = " + str(cplist))
    if cplist:
        if len(cplist) >2:
            version = cplist[2] + ver_suffix
        if len(cplist) >3 and cplist[3] != 'r0':
            version += '-' + cplist[3]
    return [str(cp), ''.join(atoms), version] # hmm ... unicode keeps appearing :(
示例#7
0
def format_output(cpv, slot, iuse, keyword):
    category, pkgname, version, revision = portage.catpkgsplit(cpv)
    sha1 = hashlib.sha1(open(PORTTREE.dbapi.findname(cpv),
                             'rb').read()).hexdigest()
    print(sha1 + ' ' + \
            category + ' ' + \
            pkgname + ' ' + \
            version + ' ' + \
            revision + ' ' + \
            slot + ' ' + \
            keyword, \
            end=' ')
    if 'ruby_targets_ruby20' in iuse:
        print('ruby20', end=' ')
    else:
        print('nil', end=' ')
    if 'ruby_targets_ruby21' in iuse:
        print('ruby21', end=' ')
    else:
        print('nil', end=' ')
    if 'ruby_targets_ruby22' in iuse:
        print('ruby22', end=' ')
    else:
        print('nil', end=' ')
    if 'ruby_targets_ruby23' in iuse:
        print('ruby23', end=' ')
    else:
        print('nil', end=' ')
    print(get_deps(cpv), end=' ')
    print()
示例#8
0
文件: system.py 项目: Necoro/portato
    def split_cpv (self, cpv):
        try:
            cpv = portage.dep_getcpv(cpv)
        except portage.exception.InvalidAtom:
            pass

        return portage.catpkgsplit(cpv)
示例#9
0
    def __init__(self, filename):
        self.__localinit__()

        # check the location
        allportdirs = portdir + overlays
        for d in allportdirs:
            if filename[:len(d)] == d:
                self.location = d
        if len(self.location) <= 1:
            raise Exception("invalid ebuild directory")

        if self.location[-1] == "/":
            self.location = self.location[:-1]

        s = string.split(filename, "/")
        self.filename = s[len(s) - 1]
        self.package = s[len(s) - 2]
        self.category = s[len(s) - 3]

        # use portage to get the version part
        self.version = portage.catpkgsplit(
            self.category + "/" + self.filename.replace(".ebuild", ""))
        if self.version[3] == "r0":
            self.version = self.version[2]
        else:
            self.version = self.version[2] + "-" + self.version[3]

        self.path = self.location + "/" + self.category + "/" + self.package + "/" + self.filename
示例#10
0
def main(ebuild):
    dict = {}
    db = portage.portdb
    getKeys = lambda x: db.aux_get(ebuild, [x])
    getKey = lambda x: getKeys(x)[0]

    dict["homepage"] = getKey("HOMEPAGE")
    dict["archiveUri"] = getKey("SRC_URI").split()[0]
    dict["archiveType"] = getArchiveType(dict["archiveUri"])
    dict["packagename"] = portage.catpkgsplit(ebuild)[1]
    dict["license"] = getKey("LICENSE")
    dict["description"] = getKey("DESCRIPTION")
    dict["updateDate"] = datetime.date.today()

    # version & release
    if "-" in packageVersion(ebuild):
        (version, release) = packageVersion(ebuild).split("-")
        release = release.replace("r", "")
    else:
        version = packageVersion(ebuild)
        release = ""
    dict["updateVersion"] = version
    dict["updateRelease"] = release

    # buildDep & runDep
    deps = getKeys("DEPEND")
    dict["buildDep"] = getDepString(deps)
    dict["runDep"] = getDepString(getKeys("RDEPEND"))

    # patches
    dict["patches"] = getPatches(db.findname(ebuild), dict["packagename"], dict["updateVersion"])

    print PSPEC_TEMPLATE % dict
示例#11
0
def split_atom_pkg(pkg):
    """Extract [category/package, atoms, version] from some ebuild identifier"""
    #debug.dprint("PORTAGELIB: split_atom_pkg(); pkg = " + pkg)
    atoms = []
    cp = ''
    version = ''
    ver_suffix = ''
    try:  # ignores failures, but output the erroring pkg
        _pkg = pkg
        if pkg.endswith("*"):
            _pkg = pkg[:-1]
            ver_suffix = '*'
        while _pkg[0] in ["<", ">", "=", "!", "*"]:
            #debug.dprint("PORTAGELIB: split_atom_pkg(); pkg = " + str(_pkg))
            atoms.append(_pkg[0])
            _pkg = _pkg[1:]
        cplist = portage.catpkgsplit(_pkg) or portage.catsplit(_pkg)
        #debug.dprint("PORTAGELIB: split_atom_pkg(); cplist = " + str(cplist))
        if not cplist or len(cplist) < 2:
            debug.dprint("PORTAGELIB: split_atom_pkg(): issues with '%s'" %
                         _pkg)
            return ['', '', '']
        cp = cplist[0] + "/" + cplist[1]
        #debug.dprint("PORTAGE_2_2.LIB: split_atom_pkg(); cplist2 = " + str(cplist))
        if cplist:
            if len(cplist) > 2:
                version = cplist[2] + ver_suffix
            if len(cplist) > 3 and cplist[3] != 'r0':
                version += '-' + cplist[3]
    except:
        debug.dprint("PORTAGELIB: split_atom_pkg(); Error splitting pkg = " +
                     pkg)
        return ['', '', '']
    return [cp, ''.join(atoms), version]  # hmm ... unicode keeps appearing :(
示例#12
0
def downgrade_version(line):
    split = portage.catpkgsplit(package_name(line))
    if len(split)>=4:
        return '{}-{}'.format(split[2], split[3])
    else:
        logging.getLogger("oam.fact.downgrades").log(logging.ERROR, 'downgrade_version failed to parse line: %s', line)
        return ''
示例#13
0
def format_output(cpv, slot, iuse, keyword):
    category, pkgname, version, revision = portage.catpkgsplit(cpv)
    sha1 = hashlib.sha1(open(PORTTREE.dbapi.findname(cpv), 'rb').read()).hexdigest()
    print(sha1 + ' ' + \
            category + ' ' + \
            pkgname + ' ' + \
            version + ' ' + \
            revision + ' ' + \
            slot + ' ' + \
            keyword, \
            end=' ')
    if 'ruby_targets_ruby19' in iuse:
        print('ruby19', end=' ')
    else:
        print('nil', end=' ')
    if 'ruby_targets_ruby20' in iuse:
        print('ruby20', end=' ')
    else:
        print('nil', end=' ')
    if 'ruby_targets_ruby21' in iuse:
        print('ruby21', end=' ')
    else:
        print('nil', end=' ')
    if 'ruby_targets_ruby22' in iuse:
        print('ruby22', end=' ')
    else:
        print('nil', end=' ')
    print(get_deps(cpv), end=' ')
    print()
示例#14
0
    def split_cpv(self, cpv):
        try:
            cpv = portage.dep_getcpv(cpv)
        except portage.exception.InvalidAtom:
            pass

        return portage.catpkgsplit(cpv)
示例#15
0
    def scan(self, options, query=None):
        env = os.environ
        env['MY'] = "<category>/<name>-<version>:<slot> [<overlaynum>]\n"

	cmd = ['eix', '--format', '<availableversions:MY>', '--pure-packages', '-x']
	if query:
		cmd.extend(['--exact', query])

        output = subprocess.Popen(cmd, stdout=subprocess.PIPE, env=env).communicate()[0]
        output = output.strip().strip('\n')

        if len(output) == 0:
            if not query:
                return
            if options['purge-packages']:
                if not options['quiet']:
                    sys.stdout.write('- [p] %s\n' % (query))
                if '/' in query:
                    cat, pkg = portage.catsplit(query)
                    Package.objects.filter(category=cat, name=pkg).delete()
                else:
                    Package.objects.filter(name=query).delete()
            else:
                sys.stderr.write(self.style.ERROR("Unknown package '%s'\n" % query))
            return

	output = output.split('\n')
        packages = {}

        line_re = re.compile(r'^(?P<cpv>.*?):(?P<slot>.*?) \[(?P<overlay>.*?)\]$')

        package = None

	for line in output:
            match = line_re.match(line)

            if not match:
                continue

            cpv = match.group('cpv')
            slot = match.group('slot')
            overlay = match.group('overlay')

            cat, pkg, ver, rev = portage.catpkgsplit(cpv)

            packages['%s/%s' % (cat, pkg)] = True

            if not package or not (cat == package.category and pkg == package.name):
                package = self.store_package(options, cat, pkg)

            self.store_version(options, package, cpv, slot, overlay)

        if options['purge-packages'] and not query:
            for package in Package.objects.all():
                cp = "%s/%s" % (package.category, package.name)
                if cp not in packages:
                    if not options['quiet']:
                        sys.stdout.write('- [p] %s\n' % (package))
                    package.delete()
示例#16
0
def extract_package(ebuild):
    """Returns cat/package from cat/package-ebuild,
       or None if input is not in that format.  """
    result = None
    parts = portage.catpkgsplit(ebuild)
    if parts:
        result = "/".join(parts[0:2])
    return result
示例#17
0
def get_version(ebuild):
    """Extract version number from ebuild name"""
    result = ''
    parts = portage.catpkgsplit(ebuild)
    if parts:
        result = parts[2]
        if parts[3] != 'r0':
            result += '-' + parts[3]
    return result
示例#18
0
def get_full_name(ebuild):
    """Extract category/package from some ebuild identifier"""
    if ebuild.endswith("*"): ebuild = ebuild[:-1]
    cplist = portage.catpkgsplit(ebuild) or portage.catsplit(ebuild)
    if not cplist or len(cplist) < 2:
        dprint("PKGCORE_LIB get_full_name(): issues with '%s'" % ebuild)
        return ''
    cp = cplist[0] + "/" + cplist[1]
    while cp[0] in ["<",">","=","!","*"]: cp = cp[1:]
    return str(cp) # hmm ... unicode keeps appearing :(
示例#19
0
 def getVersion(self, full_package, detail):
     if len(full_package) > 1:
         package_parts = portage.catpkgsplit(full_package)
         if detail == search.VERSION_RELEASE and package_parts[3] != 'r0':
             result = package_parts[2] + "-" + package_parts[3]
         else:
             result = package_parts[2]
     else:
         result = ""
     return result
示例#20
0
文件: out.py 项目: oxr463/euscan
def to_ebuild_uri(cpv, url):
    cat, pkg, ver, rev = portage.catpkgsplit(cpv)
    p = '%s-%s' % (pkg, ver)
    pvr = '%s%s' % (ver, '-%s' % rev if rev != 'r0' else '')
    pf = '%s-%s' % (pkg, pvr)
    evars = ((p, 'P'), (pkg, 'PN'), (ver, 'PV'), (rev, 'PR'), (pvr, 'PVR'),
             (pf, 'PF'), (cat, 'CATEGORY'))
    for src, dst in evars:
        url = url.replace(src, '${%s}' % dst)
    return url
示例#21
0
	def getVersion(self,full_package,detail):
		if len(full_package) > 1:
			package_parts = portage.catpkgsplit(full_package)
			if detail == search.VERSION_RELEASE and package_parts[3] != 'r0':
				result = package_parts[2]+ "-" + package_parts[3]
			else:
				result = package_parts[2]
		else:
			result = ""
		return result
示例#22
0
    def store_version(self, package, cpv, slot, overlay):
        cat, pkg, ver, rev = portage.catpkgsplit(cpv)

        overlays = self.overlays()

        if overlay in overlays:
            overlay = overlays[overlay]
        else:
            overlay = 'gentoo'

        created = False
        obj = self.cache_get_version(
            package.category, package.name, ver, rev, slot, overlay
        )
        if not obj:
            obj, created = Version.objects.get_or_create(
                package=package, slot=slot,
                revision=rev, version=ver,
                overlay=overlay,
                defaults={"alive": True, "packaged": True}
            )
        if not created: # Created objects have defaults values
            obj.alive = True
            obj.packaged = True
            obj.save()

        if created:
            self.cache_store_version(obj)

        # nothing to do (note: it can't be an upstream version because
        # overlay can't be empty here)
        if not created:
            return

        if not self.options['quiet']:
            sys.stdout.write('+ [v] %s \n' % (obj))

        if overlay == 'gentoo':
            package.n_packaged += 1
        else:
            package.n_overlay += 1
        package.n_versions += 1
        package.save()

        if self.options['no-log']:
            return

        VersionLog.objects.create(
            package=obj.package,
            action=VersionLog.VERSION_ADDED,
            slot=obj.slot,
            revision=obj.revision,
            version=obj.version,
            overlay=obj.overlay
        )
示例#23
0
def doit(a):
	# ['x11-terms', 'wterm', '6.2.9', 'r2']
	cpv = portage.catpkgsplit(a)
	# input -> CATEGORY / [P] PN - PVR [PV] [PR_int]
	CATEGORY = cpv[0]
	PN = cpv[1]
	PV = cpv[2]
	PR_int = cpv[3]
	P = PN + "-" + PV
	PVR = PV + "-" + cpv[3]
	print(a+" -> "+CATEGORY+" / ["+P+"] "+PN+" - "+PVR+" ["+PV+"] ["+PR_int+"]")
示例#24
0
    def _set_cpv(self, cpv):
        splitv = portage.catpkgsplit(cpv)  # pylint: disable=E1101

        if splitv is None:
            # this is super unlikely since all cpvs processed by
            # kernelconfig originate from portage
            raise ValueError(cpv)
        # --

        self.cpv = cpv
        self.category = splitv[0]
        self.name = splitv[1]
示例#25
0
    def store_package(self, options, cpv):
        cat, pkg, ver, rev = portage.catpkgsplit(cpv)

        obj, created = Package.objects.get_or_create(category=cat, name=pkg)

        if created and not options['quiet']:
            sys.stdout.write('+ [p] %s/%s\n' % (cat, pkg))

        ' Set all versions dead, then set found versions alive and delete old versions '
        Version.objects.filter(package=obj, packaged=False).update(alive=False)

        return obj
示例#26
0
def doit(a):
    # ['x11-terms', 'wterm', '6.2.9', 'r2']
    cpv = portage.catpkgsplit(a)
    # input -> CATEGORY / [P] PN - PVR [PV] [PR_int]
    CATEGORY = cpv[0]
    PN = cpv[1]
    PV = cpv[2]
    PR_int = cpv[3]
    P = PN + "-" + PV
    PVR = PV + "-" + cpv[3]
    print(a + " -> " + CATEGORY + " / [" + P + "] " + PN + " - " + PVR + " [" +
          PV + "] [" + PR_int + "]")
示例#27
0
文件: pkgs.py 项目: nbr23/nemubot
def package_info(pkgname):
    pv = get_db().xmatch("match-all", pkgname)
    if not pv:
        raise IMException("No package named '%s' found" % pkgname)

    bv = get_db().xmatch("bestmatch-visible", pkgname)
    pvsplit = portage.catpkgsplit(bv if bv else pv[-1])
    info = get_db().aux_get(bv if bv else pv[-1], ["DESCRIPTION", "HOMEPAGE", "LICENSE", "IUSE", "KEYWORDS"])

    return {
        "pkgname": '/'.join(pvsplit[:2]),
        "category": pvsplit[0],
        "shortname": pvsplit[1],
        "lastvers": '-'.join(pvsplit[2:]) if pvsplit[3] != "r0" else pvsplit[2],
        "othersvers": ['-'.join(portage.catpkgsplit(p)[2:]) for p in pv if p != bv],
        "description": info[0],
        "homepage": info[1],
        "license": info[2],
        "uses": info[3],
        "keywords": info[4],
    }
示例#28
0
    def __init__(self, **kwargs):
        Task.__init__(self, **kwargs)
        # the SlotObject constructor assigns self.root_config from keyword args
        # and is an instance of a '_emerge.RootConfig.RootConfig class
        self.root = self.root_config.root
        self._raw_metadata = _PackageMetadataWrapperBase(self.metadata)
        self.metadata = _PackageMetadataWrapper(self, self._raw_metadata)
        if not self.built:
            self.metadata['CHOST'] = self.root_config.settings.get('CHOST', '')
        self.cp = portage.cpv_getkey(self.cpv)
        slot = self.slot
        if _slot_re.match(slot) is None:
            self._invalid_metadata('SLOT.invalid',
                                   "SLOT: invalid value: '%s'" % slot)
            # Avoid an InvalidAtom exception when creating slot_atom.
            # This package instance will be masked due to empty SLOT.
            slot = '0'
        if (self.iuse.enabled or self.iuse.disabled) and \
         not eapi_has_iuse_defaults(self.metadata["EAPI"]):
            if not self.installed:
                self._invalid_metadata(
                    'EAPI.incompatible',
                    "IUSE contains defaults, but EAPI doesn't allow them")
        self.slot_atom = portage.dep.Atom("%s%s%s" %
                                          (self.cp, _slot_separator, slot))
        self.category, self.pf = portage.catsplit(self.cpv)
        self.cpv_split = portage.catpkgsplit(self.cpv)
        self.pv_split = self.cpv_split[1:]
        if self.inherited is None:
            self.inherited = frozenset()
        repo = _gen_valid_repo(self.metadata.get('repository', ''))
        if not repo:
            repo = self.UNKNOWN_REPO
        self.metadata['repository'] = repo

        self._validate_deps()
        self.masks = self._masks()
        self.visible = self._visible(self.masks)
        if self.operation is None:
            if self.onlydeps or self.installed:
                self.operation = "nomerge"
            else:
                self.operation = "merge"

        self._hash_key = Package._gen_hash_key(cpv=self.cpv,
                                               installed=self.installed,
                                               onlydeps=self.onlydeps,
                                               operation=self.operation,
                                               repo_name=repo,
                                               root_config=self.root_config,
                                               type_name=self.type_name)
        self._hash_value = hash(self._hash_key)
示例#29
0
    def store_package(self, cpv):
        cat, pkg, ver, rev = portage.catpkgsplit(cpv)

        obj, created = Package.objects.get_or_create(category=cat, name=pkg)

        if created:
            self.logger.info('+ [p] %s/%s' % (cat, pkg))

        versions = Version.objects.filter(package=obj, packaged=False)
        for version in versions:
            self._versions.add(version)

        return obj
示例#30
0
	def cp_list(self, package):
		#print(self._cp_list)
		if self._cp_list is None or self._cp_list==[]:
			cplist = []
			for cpv in self._cpv_all:
				parts = portage.catpkgsplit(cpv)
				cp='/'.join(parts[:2])
				if cp == package:
					cplist.append(cpv)
			#print("package = %s, cplist = %s" %(package, cplist))
			return cplist
		else:
			return self._cp_list
示例#31
0
def packageVersion(pkg):
    if len(pkg) > 1:
        parts = portage.catpkgsplit(pkg)
        if parts == None:
            return ""

        if parts[3] != "r0":
            version = parts[2] + "-" + parts[3]
        else:
            version = parts[2]
        return version
    else:
        return False
示例#32
0
 def cp_list(self, package):
     #print(self._cp_list)
     if self._cp_list is None or self._cp_list == []:
         cplist = []
         for cpv in self._cpv_all:
             parts = portage.catpkgsplit(cpv)
             cp = '/'.join(parts[:2])
             if cp == package:
                 cplist.append(cpv)
         #print("package = %s, cplist = %s" %(package, cplist))
         return cplist
     else:
         return self._cp_list
示例#33
0
def calc_changelog(ebuildpath, current, next):
    if ebuildpath == None or not os.path.exists(ebuildpath):
        return []
    current = '-'.join(portage.catpkgsplit(current)[1:])
    if current.endswith('-r0'):
        current = current[:-3]
    next = '-'.join(portage.catpkgsplit(next)[1:])
    if next.endswith('-r0'):
        next = next[:-3]
    changelogpath = os.path.join(os.path.split(ebuildpath)[0], 'ChangeLog')
    try:
        changelog = codecs.open(_unicode_encode(changelogpath,
                                                encoding=_encodings['fs'],
                                                errors='strict'),
                                mode='r',
                                encoding=_encodings['repo.content'],
                                errors='replace').read()
    except SystemExit as e:
        raise  # Needed else can't exit
    except:
        return []
    divisions = _find_changelog_tags(changelog)
    #print 'XX from',current,'to',next
    #for div,text in divisions: print 'XX',div
    # skip entries for all revisions above the one we are about to emerge
    for i in range(len(divisions)):
        if divisions[i][0] == next:
            divisions = divisions[i:]
            break
    # find out how many entries we are going to display
    for i in range(len(divisions)):
        if divisions[i][0] == current:
            divisions = divisions[:i]
            break
    else:
        # couldnt find the current revision in the list. display nothing
        return []
    return divisions
示例#34
0
def match_cpv_to_ebuild(categ, pkg, ver):
    """Matches cpv to an ebuild, and returns a correspondinglyadjusted version.
    Returns (None, None) if no matching ebuild found"""
    pv = "%s-%s" % (pkg, ver)
    overlay_path = "%s/%s/%s" % (GNOME_OVERLAY, categ, pkg)
    overlay_ebuilds = [i for i in os.listdir(overlay_path) if i.endswith(".ebuild")]

    for ebuild in overlay_ebuilds:
        if ebuild.find(pv) != -1:
            ebuild_path = "%s/%s" % (overlay_path, ebuild)
            parts = portage.catpkgsplit(ebuild.split(".ebuild")[0])[-2:]
            version = "%s-%s" % (parts[-2], parts[-1])
            return (ebuild_path, version.replace("-r0", ""))
    return (None, None)
示例#35
0
def pkg_version(pkg):
    # from /usr/bin/emerge
    if len(pkg) > 1:
        parts = catpkgsplit(pkg)
        if parts == None:
            return ""

        if parts[3] != 'r0':
            version = parts[2] + "-" + parts[3]
        else:
            version = parts[2]
        return version
    else:
        return False
示例#36
0
def match_cpv_to_ebuild(categ, pkg, ver):
    """Matches cpv to an ebuild, and returns a correspondinglyadjusted version.
    Returns (None, None) if no matching ebuild found"""
    pv = "%s-%s" % (pkg, ver)
    overlay_path = "%s/%s/%s" % (GNOME_OVERLAY, categ, pkg)
    overlay_ebuilds = [i for i in os.listdir(overlay_path) if i.endswith('.ebuild')]

    for ebuild in overlay_ebuilds:
        if ebuild.find(pv) != -1:
            ebuild_path = "%s/%s" % (overlay_path, ebuild)
            parts = portage.catpkgsplit(ebuild.split('.ebuild')[0])[-2:]
            version = "%s-%s" % (parts[-2], parts[-1])
            return (ebuild_path, version.replace('-r0', ''))
    return (None, None)
示例#37
0
def split_package_name(name):
    """Returns a list on the form [category, name, version, revision]. Revision will
    be 'r0' if none can be inferred. Category and version will be empty, if none can
    be inferred."""
    r = portage.catpkgsplit(name)
    if not r:
        r=name.split("/")
        if len(r) == 1:
            return ["",name,"","r0"]
        else:
            return r + ["","r0"]
    if r[0] == 'null':
        r[0] = ''
    return r
示例#38
0
def split_package_name(name):
    """Returns a list on the form [category, name, version, revision]. Revision will
    be 'r0' if none can be inferred. Category and version will be empty, if none can
    be inferred."""
    r = portage.catpkgsplit(name)
    if not r:
        r = name.split("/")
        if len(r) == 1:
            return ["", name, "", "r0"]
        else:
            return r + ["", "r0"]
    if r[0] == 'null':
        r[0] = ''
    return r
示例#39
0
def pkg_version(pkg):
    # from /usr/bin/emerge
    if len(pkg) > 1:
        parts = catpkgsplit(pkg)
        if parts == None:
            return ""

        if parts[3] != 'r0':
            version = parts[2] + "-" + parts[3]
        else:
            version = parts[2]
        return version
    else:
        return False
示例#40
0
    def store_package(self, cpv):
        cat, pkg, ver, rev = portage.catpkgsplit(cpv)

        obj, created = Package.objects.get_or_create(category=cat, name=pkg)

        if created:
            self.logger.info('+ [p] %s/%s' % (cat, pkg))

        versions = Version.objects.filter(
            package=obj, packaged=False
        )
        for version in versions:
            self._versions.add(version)

        return obj
示例#41
0
def split_package_name(name): # lifted from gentoolkit, handles vituals for find_best_match()
    """Returns a list on the form [category, name, version, revision]. Revision will
    be 'r0' if none can be inferred. Category and version will be empty, if none can
    be inferred."""
    debug.dprint(" * PORTAGELIB: split_package_name() name = " + name)
    r = portage.catpkgsplit(name)
    if not r:
        r = name.split("/")
        if len(r) == 1:
            return ["", name, "", "r0"]
        else:
            return r + ["", "r0"]
    if r[0] == 'null':
        r[0] = ''
    return r
示例#42
0
def doit(a):
    # ['x11-terms', 'wterm', '6.2.9', 'r2']
    cpv = portage.catpkgsplit(a)
    if not cpv:
        print("Portage could not match " + a + " to a package")
        return
    # input -> CATEGORY / [P] PN - PVR [PV] [PR_int]
    CATEGORY = cpv[0]
    PN = cpv[1]
    PV = cpv[2]
    PR_int = cpv[3]
    P = PN + "-" + PV
    PVR = PV + "-" + cpv[3]
    print(a + " -> " + CATEGORY + " / [" + P + "] " + PN + " - " + PVR + " [" +
          PV + "] [" + PR_int + "]")
示例#43
0
def calc_changelog(ebuildpath,current,next):
	if ebuildpath == None or not os.path.exists(ebuildpath):
		return []
	current = '-'.join(portage.catpkgsplit(current)[1:])
	if current.endswith('-r0'):
		current = current[:-3]
	next = '-'.join(portage.catpkgsplit(next)[1:])
	if next.endswith('-r0'):
		next = next[:-3]
	changelogpath = os.path.join(os.path.split(ebuildpath)[0],'ChangeLog')
	try:
		changelog = codecs.open(_unicode_encode(changelogpath,
			encoding=_encodings['fs'], errors='strict'),
			mode='r', encoding=_encodings['repo.content'], errors='replace'
		).read()
	except SystemExit as e:
		raise # Needed else can't exit
	except:
		return []
	divisions = _find_changelog_tags(changelog)
	#print 'XX from',current,'to',next
	#for div,text in divisions: print 'XX',div
	# skip entries for all revisions above the one we are about to emerge
	for i in range(len(divisions)):
		if divisions[i][0]==next:
			divisions = divisions[i:]
			break
	# find out how many entries we are going to display
	for i in range(len(divisions)):
		if divisions[i][0]==current:
			divisions = divisions[:i]
			break
	else:
	    # couldnt find the current revision in the list. display nothing
		return []
	return divisions
示例#44
0
	def __init__(self, **kwargs):
		Task.__init__(self, **kwargs)
		# the SlotObject constructor assigns self.root_config from keyword args
		# and is an instance of a '_emerge.RootConfig.RootConfig class
		self.root = self.root_config.root
		self._raw_metadata = _PackageMetadataWrapperBase(self.metadata)
		self.metadata = _PackageMetadataWrapper(self, self._raw_metadata)
		if not self.built:
			self.metadata['CHOST'] = self.root_config.settings.get('CHOST', '')
		self.cp = portage.cpv_getkey(self.cpv)
		slot = self.slot
		if _slot_re.match(slot) is None:
			self._invalid_metadata('SLOT.invalid',
				"SLOT: invalid value: '%s'" % slot)
			# Avoid an InvalidAtom exception when creating slot_atom.
			# This package instance will be masked due to empty SLOT.
			slot = '0'
		if (self.iuse.enabled or self.iuse.disabled) and \
			not eapi_has_iuse_defaults(self.metadata["EAPI"]):
			if not self.installed:
				self._invalid_metadata('EAPI.incompatible',
					"IUSE contains defaults, but EAPI doesn't allow them")
		self.slot_atom = portage.dep.Atom("%s%s%s" % (self.cp, _slot_separator, slot))
		self.category, self.pf = portage.catsplit(self.cpv)
		self.cpv_split = portage.catpkgsplit(self.cpv)
		self.pv_split = self.cpv_split[1:]
		if self.inherited is None:
			self.inherited = frozenset()
		repo = _gen_valid_repo(self.metadata.get('repository', ''))
		if not repo:
			repo = self.UNKNOWN_REPO
		self.metadata['repository'] = repo

		self._validate_deps()
		self.masks = self._masks()
		self.visible = self._visible(self.masks)
		if self.operation is None:
			if self.onlydeps or self.installed:
				self.operation = "nomerge"
			else:
				self.operation = "merge"

		self._hash_key = Package._gen_hash_key(cpv=self.cpv,
			installed=self.installed, onlydeps=self.onlydeps,
			operation=self.operation, repo_name=repo,
			root_config=self.root_config,
			type_name=self.type_name)
		self._hash_value = hash(self._hash_key)
示例#45
0
文件: out.py 项目: EvaSDK/euscan
def to_ebuild_uri(cpv, url):
    cat, pkg, ver, rev = portage.catpkgsplit(cpv)
    p = '%s-%s' % (pkg, ver)
    pvr = '%s%s' % (ver, '-%s' % rev if rev != 'r0' else '')
    pf = '%s-%s' % (pkg, pvr)
    evars = (
        (p, 'P'),
        (pkg, 'PN'),
        (ver, 'PV'),
        (rev, 'PR'),
        (pvr, 'PVR'),
        (pf, 'PF'),
        (cat, 'CATEGORY')
    )
    for src, dst in evars:
        url = url.replace(src, '${%s}' % dst)
    return url
示例#46
0
def fix_nesting(nested_list):
    """Takes a list of unknown nesting depth, and gives a nice list with each
    element of the form [cpv, [kws]]"""
    index = 0
    cpv_index = -1
    nice_list = []
    # Has an unpredictable nesting of lists; so we flatten it...
    flat_list = portage.flatten(nested_list)
    # ... and re-create a nice list for us to use
    while index < len(flat_list):
        if portage.catpkgsplit(flat_list[index]):
            cpv_index += 1
            nice_list.append([flat_list[index], []])
        else:
            nice_list[cpv_index][1].append(flat_list[index])
        index += 1
    return nice_list
示例#47
0
def split_atom_pkg( pkg ):
    """Extract [category/package, atoms, version] from some ebuild identifier"""
    atoms = []
    version = ''
    if pkg.endswith("*"): pkg = pkg[:-1]
    cplist = portage.catpkgsplit(pkg) or portage.catsplit(pkg)
    if not cplist or len(cplist) < 2:
        dprint("PKGCORE_LIB split_pkg(): issues with '%s'" % pkg)
        return ['', '', '']
    cp = cplist[0] + "/" + cplist[1]
    while cp[0] in ["<",">","=","!","*"]:
        atoms.append(cp[0])
        cp = cp[1:]
    if cplist:
        version = cplist[2]
        if cplist[3] != 'r0':
            version += '-' + cplist[3]
    return [str(cp), atoms.join(), version] # hmm ... unicode keeps appearing :(
示例#48
0
def split_package_name(name):
	"""Returns a list on the form [category, name, version, revision]. Revision will
	be 'r0' if none can be inferred. Category and version will be empty, if none can
	be inferred."""
	warnings.warn("Deprecated. Just use portage.catpkgsplit or apply "
		"gentoolkit.package.Package to access pkg.category, pkg.revision, etc.",
		DeprecationWarning)
	r = portage.catpkgsplit(name)
	if not r:
		r = name.split("/")
		if len(r) == 1:
			return ["", name, "", "r0"]
		else:
			return r + ["", "r0"]
	else:
		r = list(r)
	if r[0] == 'null':
		r[0] = ''
	return r
示例#49
0
    def get_package(self, query):
        try:
            return Package.objects.get(name=query)
        except Package.DoesNotExist:
            pass

        try:
            category, package = portage.catsplit(query)
            return Package.objects.get(category=category, name=package)
        except Package.DoesNotExist:
            pass

        try:
            category, package, ver, rev = portage.catpkgsplit(query)
            return Package.objects.get(category=category, name=package)
        except Package.DoesNotExist:
            pass

        return None
示例#50
0
    def get_package(self, query):
        try:
            return Package.objects.get(name=query)
        except Package.DoesNotExist:
            pass

        try:
            category, package = portage.catsplit(query)
            return Package.objects.get(category=category, name=package)
        except Package.DoesNotExist:
            pass

        try:
            category, package, ver, rev = portage.catpkgsplit(query)
            return Package.objects.get(category=category, name=package)
        except Package.DoesNotExist:
            pass

        return None
示例#51
0
def split_package_name(name):
	"""Returns a list on the form [category, name, version, revision]. Revision will
	be 'r0' if none can be inferred. Category and version will be empty, if none can
	be inferred."""
	warnings.warn("Deprecated. Just use portage.catpkgsplit or apply "
		"gentoolkit.package.Package to access pkg.category, pkg.revision, etc.",
		DeprecationWarning)
	r = portage.catpkgsplit(name)
	if not r:
		r = name.split("/")
		if len(r) == 1:
			return ["", name, "", "r0"]
		else:
			return r + ["", "r0"]
	else:
		r = list(r)
	if r[0] == 'null':
		r[0] = ''
	return r
示例#52
0
 def __init__(self, **kwargs):
     Task.__init__(self, **kwargs)
     self.root = self.root_config.root
     self.metadata = _PackageMetadataWrapper(self, self.metadata)
     if not self.built:
         self.metadata['CHOST'] = self.root_config.settings.get('CHOST', '')
     self.cp = portage.cpv_getkey(self.cpv)
     slot = self.slot
     if _slot_re.match(slot) is None:
         self._invalid_metadata('SLOT.invalid',
                                "SLOT: invalid value: '%s'" % slot)
         # Avoid an InvalidAtom exception when creating slot_atom.
         # This package instance will be masked due to empty SLOT.
         slot = '0'
     self.slot_atom = portage.dep.Atom("%s:%s" % (self.cp, slot))
     self.category, self.pf = portage.catsplit(self.cpv)
     self.cpv_split = portage.catpkgsplit(self.cpv)
     self.pv_split = self.cpv_split[1:]
     self.masks = self._masks()
     self.visible = self._visible(self.masks)
示例#53
0
	def __init__(self, **kwargs):
		Task.__init__(self, **kwargs)
		self.root = self.root_config.root
		self.metadata = _PackageMetadataWrapper(self, self.metadata)
		if not self.built:
			self.metadata['CHOST'] = self.root_config.settings.get('CHOST', '')
		self.cp = portage.cpv_getkey(self.cpv)
		slot = self.slot
		if _slot_re.match(slot) is None:
			self._invalid_metadata('SLOT.invalid',
				"SLOT: invalid value: '%s'" % slot)
			# Avoid an InvalidAtom exception when creating slot_atom.
			# This package instance will be masked due to empty SLOT.
			slot = '0'
		self.slot_atom = portage.dep.Atom("%s:%s" % (self.cp, slot))
		self.category, self.pf = portage.catsplit(self.cpv)
		self.cpv_split = portage.catpkgsplit(self.cpv)
		self.pv_split = self.cpv_split[1:]
		self.masks = self._masks()
		self.visible = self._visible(self.masks)
示例#54
0
def findpackagedepslotops(porttree, cpv):
    depstr = porttree.dbapi.aux_get(cpv, ["RDEPEND"])[0]
    cleandeps = portage.dep.paren_reduce(depstr)
    for indep in portage.dep.flatten(cleandeps):
        if (portage.dep.isvalidatom(indep)): 
            indepslot = portage.dep.dep_getslot(indep)
            if indepslot == None or not indepslot.endswith("="):
                allavail = porttree.dep_match(indep)
                for inallavail in portage.dep.flatten(allavail):
                    slot = porttree.dbapi.aux_get(inallavail, ["SLOT"])[0]
                    if slot.find("/") > 0:
                        category, pkgname, version, rev = portage.catpkgsplit(cpv)
                        ebuild, path = porttree.dbapi.findname2(cpv)
                        metxml = path+"/"+category+"/"+pkgname+"/metadata.xml"
                        maints=[]
                        try:
                            pkg_md = MetaDataXML(metxml,"/usr/portage/metadata/herds.xml")
                            for maint in pkg_md.maintainers():
                                maints.append(maint.email)
                        except IOError: pass                        
                        print cpv + " - " + inallavail + " - " + slot + " - " + ', '.join(maints)
示例#55
0
  def __init__(self):
    self.vartree   = portage.db[portage.root]['vartree']
    self.porttree  = portage.db[portage.root]['porttree']
    self.varPkgDb = {}
    self.worldList = open('/var/lib/portage/world').read().splitlines()

    listPropKey   = ["DESCRIPTION", "CATEGORY","BUILD_TIME","KEYWORDS","HOMEPAGE","FEATURES",\
                 "DEPEND", "RDEPEND", "IUSE", "USE"]

    for cpvName in self.vartree.getallcpv():
      category, pkgName, version, rev = portage.catpkgsplit(cpvName)  
      cpName = category +'/'+ pkgName
      self.varPkgDb[cpName] = {}
      self.varPkgDb[cpName][version] = {}
      inWorld = cpName in self.worldList
      self.varPkgDb[cpName][version]['inWorld'] = inWorld
      listPropVal = self.vartree.dbapi.aux_get(cpvName, listPropKey)
      cpt = 0
      for propKey in listPropKey:
        self.varPkgDb[cpName][version][propKey] = listPropVal[cpt]
        cpt += 1
    self.varList = list(self.varPkgDb.keys())
示例#56
0
    def store_version(self, options, package, cpv, slot, overlay):
        cat, pkg, ver, rev = portage.catpkgsplit(cpv)

        overlays = self.overlays()

        if overlay in overlays:
            overlay = overlays[overlay]
        else:
            overlay = 'gentoo'

        obj, created = Version.objects.get_or_create(package=package, slot=slot,
                                                     revision=rev, version=ver,
                                                     overlay=overlay)
        obj.alive = True
        obj.packaged = True
        obj.save()

        ''' nothing to do (note: it can't be an upstream version because overlay can't be empty here) '''
        if not created:
            return

        if not options['quiet']:
            sys.stdout.write('+ [v] %s \n' % (obj))

        if overlay == 'gentoo':
            package.n_packaged += 1
        else:
            package.n_overlay += 1
        package.n_versions += 1
        package.save()

        entry = VersionLog.objects.create(package=obj.package, action=VersionLog.VERSION_ADDED)
        entry.slot = obj.slot
        entry.revision = obj.revision
        entry.version = obj.version
        entry.overlay = obj.overlay
        entry.save()
示例#57
0

def pkg_sort_key(data):
    c, p, v, r = portage.versions.catpkgsplit(data[0])
    # Format version string so that 0.11 sorts greater than 0.9
    v = list(["%05s" % s for s in v.split('.')])
    return [c, p, v, r]


if not os.path.isdir("doc/packages"):
    os.mkdir("doc/packages")

output = []
cat = pkg = ''
for package, meta in sorted(CACHE.items(), key=pkg_sort_key):
    c, p, v, r = portage.catpkgsplit(package)
    atom = portage.dep.Atom('=' + package)
    meta['NAME'] = p
    if not c == cat:
        if output:
            write_cat_doc(cat, output)

        output = []
        cat = c

        output.append("``%s``" % cat)
        output.append("--" + "-" * len(cat) + "--")
    if not p == pkg:
        if not meta.get("HOMEPAGE") in ("DEAD", None):
            output.append('\n* ``%(NAME)s`` - %(HOMEPAGE)s' % meta)
        else:
示例#58
0
文件: ebuild.py 项目: voyageur/euscan
def package_from_ebuild(ebuild):
    pf = None
    if ebuild.endswith(".ebuild"):
        pf = os.path.basename(ebuild)[:-7]
    else:
        return False

    if not os.path.isabs(ebuild):
        mycwd = os.getcwd()
        # Try to get the non-canonical path from the PWD evironment variable,
        # since the canonical path returned from os.getcwd() may may be
        # unusable in cases where the directory stucture is built from
        # symlinks.
        pwd = os.environ.get('PWD', '')
        if sys.hexversion < 0x3000000:
            pwd = _unicode_decode(pwd,
                                  encoding=_encodings['content'],
                                  errors='strict')
        if pwd and pwd != mycwd and \
            os.path.realpath(pwd) == mycwd:
            mycwd = portage.normalize_path(pwd)
        ebuild = os.path.join(mycwd, ebuild)

    ebuild = portage.normalize_path(ebuild)
    # portdbapi uses the canonical path for the base of the portage tree, but
    # subdirectories of the base can be built from symlinks (like crossdev
    # does).
    ebuild_portdir = os.path.realpath(
        os.path.dirname(os.path.dirname(os.path.dirname(ebuild))))
    ebuild = os.path.join(ebuild_portdir, *ebuild.split(os.path.sep)[-3:])
    vdb_path = os.path.join(portage.settings['ROOT'], VDB_PATH)

    # Make sure that portdb.findname() returns the correct ebuild.
    if ebuild_portdir != vdb_path and \
        ebuild_portdir not in portage.portdb.porttrees:
        if sys.hexversion >= 0x3000000:
            os.environ["PORTDIR_OVERLAY"] = \
                os.environ.get("PORTDIR_OVERLAY", "") + \
                " " + _shell_quote(ebuild_portdir)
        else:
            os.environ["PORTDIR_OVERLAY"] = \
                os.environ.get("PORTDIR_OVERLAY", "") + \
                " " + _unicode_encode(_shell_quote(ebuild_portdir),
                encoding=_encodings['content'], errors='strict')

        portage.close_portdbapi_caches()
        imp.reload(portage)
    del portage.portdb.porttrees[1:]
    if ebuild_portdir != portage.portdb.porttree_root:
        portage.portdb.porttrees.append(ebuild_portdir)

    if not os.path.exists(ebuild):
        return False

    ebuild_split = ebuild.split("/")
    cpv = "%s/%s" % (ebuild_split[-3], pf)

    if not portage.catpkgsplit(cpv):
        return False

    if ebuild.startswith(os.path.join(portage.root, portage.const.VDB_PATH)):
        mytree = "vartree"

        portage_ebuild = portage.db[portage.root][mytree].dbapi.findname(cpv)

        if os.path.realpath(portage_ebuild) != ebuild:
            return False

    else:
        mytree = "porttree"

        portage_ebuild = portage.portdb.findname(cpv)

        if not portage_ebuild or portage_ebuild != ebuild:
            return False

    return cpv