def main(): trees = portage.create_trees() trees["/"]["porttree"].settings = portage.settings portdb = trees["/"]["porttree"] portdb.dbapi.settings = portage.settings portdb.dbapi.porttrees = [portage.portdb.porttree_root] # does it make sense to remove _all_ useless stuff or just leave it as it is? #portdb.dbapi._aux_cache_keys.clear() #portdb.dbapi._aux_cache_keys.update(["EAPI", "KEYWORDS", "SLOT"]) res_slots = {} # Loop through all package names for cp in portdb.dbapi.cp_all(): #print(cp) # Get versions cpvrs = portdb.dbapi.xmatch('match-all', cp) # Group by slots slots = {} for cpvr in cpvrs: slot = portdb.dbapi.aux_get(cpvr, ["SLOT"])[0] if slot is None: slot = 0 if not slot in slots: slots[slot] = [] slots[slot].append(cpvr) # XXX: Walk through slots (walk twice for ~arch and arch) for slot in sorted(slots): cpvr = portage.versions.best(slots[slot]) depends = portdb.dbapi.aux_get(cpvr, ['DEPEND', 'RDEPEND', 'PDEPEND']) depends = set( portage.dep.use_reduce(' '.join(depends), matchall=True, flat=True)) depends = [dep for dep in depends if portage.dep.isvalidatom(dep)] #print('DEPEND:') #pprint(depends) for depend in depends: if portage.dep.dep_getkey(depend) == sys.argv[1]: mypkg_slot = portage.dep.dep_getslot(depend) if mypkg_slot is None: mypkg_slot = "unset" if mypkg_slot not in res_slots: res_slots[mypkg_slot] = [(cpvr, depend)] else: res_slots[mypkg_slot].append((cpvr, depend)) #print(portage.dep.dep_getkey(depend) + ' uses ' + sys.argv[1] + ' slot ' + portage.dep.dep_getslot(depend)) for slot in sorted(res_slots): print('%s:%s' % (sys.argv[1], slot)) for rescpv in res_slots[slot]: print(' %s (as %s)' % rescpv)
def PortageTrees(root): """Return the portage trees for a given root.""" if root == '/': return portage.db['/'] # The portage logic requires the path always end in a slash. root = root.rstrip('/') + '/' return portage.create_trees(target_root=root, config_root=root)[root]
def load(self): """(Re)loads the portage settings and sets the variables.""" kwargs = {} for k, envvar in (("config_root", "PORTAGE_CONFIGROOT"), ("target_root", "ROOT")): kwargs[k] = os.environ.get(envvar, None) self.trees = portage.create_trees(trees=self.trees, **kwargs) self.settings = self.trees["/"]["vartree"].settings for myroot in self.trees: if myroot != "/": self.settings = self.trees[myroot]["vartree"].settings break self.settings.unlock() root = self.settings["ROOT"] self.porttree = self.trees[root]["porttree"] self.vartree = self.trees[root]["vartree"] self.virtuals = self.trees[root]["virtuals"] self.global_settings = portage.config(clone=self.settings) self._cpv = None portage.settings = None # we use our own one ...
def validateLogfile(package, config_, target): # pylint: disable=too-many-locals try: my_root = os.path.join('/usr/targets', os.getenv('CURRENT_TARGET', target), 'root/') my_trees = create_trees(config_root=my_root, target_root=my_root) portage_db = my_trees[my_root]['vartree'].dbapi [cpv] = portage_db.match(package) except (InvalidAtom, ValueError): return None if not cpv: return None [license_] = portage_db.aux_get(cpv, ['LICENSE']) if license_.lower() != 'wyplay': return None category, name, version, revision = catpkgsplit(cpv) logfile = '%s:%s-%s%s:' % (category, name, version, str() if revision == 'r0' else '-%s' % revision) try: file_ = next(fname for fname in os.listdir(config_['PORT_LOGDIR']) if fname.startswith(logfile)) except StopIteration: return None filepath = os.path.abspath(os.path.join(config_['PORT_LOGDIR'], file_)) with open(filepath, 'r') as fd: compiler_pattern = r'^\s?%s-g' % config_['CHOST'] try: line = next(l for l in fd if re.match(compiler_pattern, l)) except StopIteration: return None return list(v for k, v in [(' -Wall ', 'NO_WALL'), (' -Wextra ', 'NO_WEXTRA')] if k not in line)
def _load_config(self): portdir_overlay = [] for repo_name in sorted(self.repo_dirs): path = self.repo_dirs[repo_name] if path != self.portdir: portdir_overlay.append(path) env = { "ACCEPT_KEYWORDS": "x86", "DISTDIR" : self.distdir, "PKGDIR": os.path.join(self.eroot, "usr/portage/packages"), "PORTDIR": self.portdir, "PORTDIR_OVERLAY": " ".join(portdir_overlay), 'PORTAGE_TMPDIR' : os.path.join(self.eroot, 'var/tmp'), } if os.environ.get("SANDBOX_ON") == "1": # avoid problems from nested sandbox instances env["FEATURES"] = "-sandbox" # Pass along PORTAGE_USERNAME and PORTAGE_GRPNAME since they # need to be inherited by ebuild subprocesses. if 'PORTAGE_USERNAME' in os.environ: env['PORTAGE_USERNAME'] = os.environ['PORTAGE_USERNAME'] if 'PORTAGE_GRPNAME' in os.environ: env['PORTAGE_GRPNAME'] = os.environ['PORTAGE_GRPNAME'] trees = portage.create_trees(env=env, eprefix=self.eprefix) for root, root_trees in trees.items(): settings = root_trees["vartree"].settings settings._init_dirs() setconfig = load_default_config(settings, root_trees) root_trees["root_config"] = RootConfig(settings, root_trees, setconfig) return settings, trees
def _load_config(self): create_trees_kwargs = {} if self.target_root != os.sep: create_trees_kwargs["target_root"] = self.target_root env = { "PORTAGE_REPOSITORIES": "\n".join("[%s]\n%s" % ( repo_name, "\n".join("%s = %s" % (k, v) for k, v in repo_config.items()), ) for repo_name, repo_config in self._repositories.items()) } if self.debug: env["PORTAGE_DEBUG"] = "1" trees = portage.create_trees(env=env, eprefix=self.eprefix, **create_trees_kwargs) for root, root_trees in trees.items(): settings = root_trees["vartree"].settings settings._init_dirs() setconfig = load_default_config(settings, root_trees) root_trees["root_config"] = RootConfig(settings, root_trees, setconfig) return trees[trees._target_eroot]["vartree"].settings, trees
def main(argv): options = ParseArgs(argv) if not cros_build_lib.IsInsideChroot(): raise commandline.ChrootRequiredError() if os.geteuid() != 0: cros_build_lib.SudoRunCommand(sys.argv) return # sysroot must have a trailing / as the tree dictionary produced by # create_trees in indexed with a trailing /. sysroot = cros_build_lib.GetSysroot(options.board) + '/' trees = create_trees(target_root=sysroot, config_root=sysroot) vartree = trees[sysroot]['vartree'] cache_dir = os.path.join(path_util.FindCacheDir(), 'cros_install_debug_syms-v' + CACHE_VERSION) if options.clearcache: osutils.RmDir(cache_dir, ignore_missing=True) binhost_cache = None if options.cachebinhost: binhost_cache = cache.DiskCache(cache_dir) boto_file = vartree.settings['BOTO_CONFIG'] if boto_file: os.environ['BOTO_CONFIG'] = boto_file gs_context = gs.GSContext() symbols_mapping = RemoteSymbols(vartree, binhost_cache) if options.all: to_install = vartree.dbapi.cpv_all() else: to_install = [GetMatchingCPV(p, vartree.dbapi) for p in options.packages] to_install = [p for p in to_install if ShouldGetSymbols(p, vartree.dbapi, symbols_mapping)] if not to_install: logging.info('nothing to do, exit') return with DebugSymbolsInstaller(vartree, gs_context, sysroot, not options.debug) as installer: args = [(p, symbols_mapping[p]) for p in to_install] parallel.RunTasksInProcessPool(installer.Install, args, processes=options.jobs) logging.debug('installation done, updating packages index file') packages_dir = os.path.join(sysroot, 'packages') packages_file = os.path.join(packages_dir, 'Packages') # binpkg will set DEBUG_SYMBOLS automatically if it detects the debug symbols # in the packages dir. pkgindex = binpkg.GrabLocalPackageIndex(packages_dir) with open(packages_file, 'w') as p: pkgindex.Write(p)
def GetVartree(sysroot): """Get the portage vartree. This must be called in subprocesses only. The vartree is not serializable, and is implemented as a singleton in portage, so it always breaks the parallel call when initialized before it is called. """ trees = create_trees(target_root=sysroot, config_root=sysroot) return trees[sysroot]['vartree']
def reload_config(self): kwargs = {} if self.config_root: kwargs['config_root'] = self.config_root trees = create_trees(**kwargs) tree = trees[max(trees)] self._root = max(trees) self._vardb = tree['vartree'].dbapi self._portdb = tree['porttree'].dbapi
def main(): trees = portage.create_trees() trees["/"]["porttree"].settings = portage.settings portdb = trees["/"]["porttree"] portdb.dbapi.settings = portage.settings portdb.dbapi.porttrees = [portage.portdb.porttree_root] # does it make sense to remove _all_ useless stuff or just leave it as it is? #portdb.dbapi._aux_cache_keys.clear() #portdb.dbapi._aux_cache_keys.update(["EAPI", "KEYWORDS", "SLOT"]) res_slots = {} # Loop through all package names for cp in portdb.dbapi.cp_all(): #print(cp) # Get versions cpvrs = portdb.dbapi.xmatch('match-all', cp) # Group by slots slots = {} for cpvr in cpvrs: slot = portdb.dbapi.aux_get(cpvr, ["SLOT"])[0] if slot is None: slot = 0 if not slot in slots: slots[slot] = [] slots[slot].append(cpvr) # XXX: Walk through slots (walk twice for ~arch and arch) for slot in sorted(slots): cpvr = portage.versions.best(slots[slot]) depends = portdb.dbapi.aux_get(cpvr, ['DEPEND', 'RDEPEND', 'PDEPEND']) depends = set(portage.dep.use_reduce(' '.join(depends), matchall=True, flat=True)) depends = [dep for dep in depends if portage.dep.isvalidatom(dep)] #print('DEPEND:') #pprint(depends) for depend in depends: if portage.dep.dep_getkey(depend) == sys.argv[1]: mypkg_slot = portage.dep.dep_getslot(depend) if mypkg_slot is None: mypkg_slot = "unset" if mypkg_slot not in res_slots: res_slots[mypkg_slot] = [(cpvr, depend)] else: res_slots[mypkg_slot].append((cpvr, depend)) #print(portage.dep.dep_getkey(depend) + ' uses ' + sys.argv[1] + ' slot ' + portage.dep.dep_getslot(depend)) for slot in sorted(res_slots): print('%s:%s' % (sys.argv[1], slot)) for rescpv in res_slots[slot]: print(' %s (as %s)' % rescpv)
def UpdatePackageContents(change_report, package_cp, portage_root=None): """ Add newly created files/directors to package contents. Given an ItemizedChangeReport, add the newly created files and directories to the CONTENTS of an installed portage package, such that these files are considered owned by that package. Arguments: changereport: ItemizedChangeReport object for the changes to be made to the package. package_cp: A string similar to 'chromeos-base/autotest-tests' giving the package category and name of the package to be altered. portage_root: Portage root path, corresponding to the board that we are working on. Defaults to '/' """ if portage_root is None: portage_root = portage.root # pylint: disable-msg=E1101 # Ensure that portage_root ends with trailing slash. portage_root = os.path.join(portage_root, "") # Create vartree object corresponding to portage_root trees = portage.create_trees(portage_root, portage_root) vartree = trees[portage_root]["vartree"] # List matching installed packages in cpv format matching_packages = vartree.dbapi.cp_list(package_cp) if not matching_packages: raise ValueError("No matching package for %s in portage_root %s" % (package_cp, portage_root)) if len(matching_packages) > 1: raise ValueError("Too many matching packages for %s in portage_root " "%s" % (package_cp, portage_root)) # Convert string match to package dblink package_cpv = matching_packages[0] package_split = portage_utilities.SplitCPV(package_cpv) package = portage.dblink( package_split.category, # pylint: disable-msg=E1101 package_split.pv, settings=vartree.settings, vartree=vartree, ) # Append new contents to package contents dictionary contents = package.getcontents().copy() for _, filename in change_report.new_files: contents.setdefault(filename, (u"obj", "0", "0")) for _, dirname in change_report.new_directories: # String trailing slashes if present. dirname = dirname.rstrip("/") contents.setdefault(dirname, (u"dir",)) # Write new contents dictionary to file vartree.dbapi.writeContentsToContentsFile(package, contents)
def load_emerge_config(self, trees = None): # Taken from /usr/bin/emerge portage-2.1.2.2 ...Brian >=portage-2.2* it is import-able kwargs = {} for k, envvar in (("config_root", "PORTAGE_CONFIGROOT"), ("target_root", "ROOT")): kwargs[k] = os.environ.get(envvar, None) trees = portage.create_trees(trees=trees, **kwargs) settings = trees["/"]["vartree"].settings for myroot in trees: if myroot != "/": settings = trees[myroot]["vartree"].settings break mtimedbfile = os.path.join("/", portage.CACHE_PATH.lstrip(os.path.sep), "mtimedb") mtimedb = portage.MtimeDB(mtimedbfile) return settings, trees, mtimedb
def _load_config(self): create_trees_kwargs = {} if self.target_root != os.sep: create_trees_kwargs["target_root"] = self.target_root trees = portage.create_trees(env={}, eprefix=self.eprefix, **create_trees_kwargs) for root, root_trees in trees.items(): settings = root_trees["vartree"].settings settings._init_dirs() setconfig = load_default_config(settings, root_trees) root_trees["root_config"] = RootConfig(settings, root_trees, setconfig) return trees[trees._target_eroot]["vartree"].settings, trees
def _InitBinpkgDB(self, process_rdeps): """Initializes a dictionary of binary packages for updating the target.""" # Get build root trees; portage indexes require a trailing '/'. build_root = os.path.join(self.sysroot, '') trees = portage.create_trees(target_root=build_root, config_root=build_root) bintree = trees[build_root]['bintree'] binpkgs_info = [] for cpv in bintree.dbapi.cpv_all(): slot, rdep_raw, build_time = bintree.dbapi.aux_get( cpv, ['SLOT', 'RDEPEND', 'BUILD_TIME']) binpkgs_info.append((cpv, slot, rdep_raw, build_time)) try: self.binpkgs_db = self._BuildDB(binpkgs_info, process_rdeps, False, installed_db=self.target_db) except ValueError as e: raise self.BintreeError(str(e))
def GetPackageAPI(portage_root, package_cp): """Gets portage API handles for the given package. Arguments: portage_root: Root directory of portage tree. Eg '/' or '/build/lumpy' package_cp: A string similar to 'chromeos-base/autotest-tests'. Returns: Returns (package, vartree) tuple, where package is of type portage.dbapi.vartree.dblink vartree is of type portage.dbapi.vartree.vartree """ if portage_root is None: # pylint: disable-msg=E1101 portage_root = portage.root # Ensure that portage_root ends with trailing slash. portage_root = os.path.join(portage_root, '') # Create a vartree object corresponding to portage_root. trees = portage.create_trees(portage_root, portage_root) vartree = trees[portage_root]['vartree'] # List the matching installed packages in cpv format. matching_packages = vartree.dbapi.cp_list(package_cp) if not matching_packages: raise PortagePackageAPIError( 'No matching package for %s in portage_root ' '%s' % (package_cp, portage_root)) if len(matching_packages) > 1: raise PortagePackageAPIError('Too many matching packages for %s in ' 'portage_root %s' % (package_cp, portage_root)) # Convert string match to package dblink. package_cpv = matching_packages[0] package_split = portage_utilities.SplitCPV(package_cpv) # pylint: disable-msg=E1101 package = portage.dblink(package_split.category, package_split.pv, settings=vartree.settings, vartree=vartree) return package, vartree
def GetPackageAPI(portage_root, package_cp): """Gets portage API handles for the given package. Args: portage_root: Root directory of portage tree. Eg '/' or '/build/lumpy' package_cp: A string similar to 'chromeos-base/autotest-tests'. Returns: Returns (package, vartree) tuple, where package is of type portage.dbapi.vartree.dblink vartree is of type portage.dbapi.vartree.vartree """ if portage_root is None: # pylint: disable=no-member portage_root = portage.root # Ensure that portage_root ends with trailing slash. portage_root = os.path.join(portage_root, '') # Create a vartree object corresponding to portage_root. trees = portage.create_trees(portage_root, portage_root) vartree = trees[portage_root]['vartree'] # List the matching installed packages in cpv format. matching_packages = vartree.dbapi.cp_list(package_cp) if not matching_packages: raise PortagePackageAPIError('No matching package for %s in portage_root ' '%s' % (package_cp, portage_root)) if len(matching_packages) > 1: raise PortagePackageAPIError('Too many matching packages for %s in ' 'portage_root %s' % (package_cp, portage_root)) # Convert string match to package dblink. package_cpv = matching_packages[0] package_split = portage_util.SplitCPV(package_cpv) # pylint: disable=no-member package = portage.dblink(package_split.category, package_split.pv, settings=vartree.settings, vartree=vartree) return package, vartree
def get_settings(conf=None): if not isinstance(conf, dict) and conf: raise TypeError("conf must be dict() or None") if not conf: conf = {} # TODO: maybe we should improve it a bit ;) mysettings = portage.config(config_incrementals=portage.const.INCREMENTALS, local_config=False) if conf["MAIN_ARCH"] == "auto": conf["MAIN_ARCH"] = "%s" % mysettings["ACCEPT_KEYWORDS"].split( " ")[0].lstrip("~") if conf["TARGET_ARCH"] == "auto": conf["TARGET_ARCH"] = "~%s" % mysettings["ACCEPT_KEYWORDS"].split( " ")[0].lstrip("~") # TODO: exclude overlay categories from check if conf["CATEGORIES"]: _mycats = [] for _cat in conf["CATEGORIES"].split(","): _cat = _cat.strip() _mycats.append(_cat) if _cat not in mysettings.categories: raise ValueError("invalid category for -C switch '%s'" % _cat) mysettings.categories = _mycats # maybe thats not necessary because we override porttrees below.. _portage_settings("PORTDIR_OVERLAY", "", mysettings) trees = portage.create_trees() trees["/"]["porttree"].settings = mysettings portdb = trees["/"]["porttree"] portdb.dbapi.settings = mysettings portdb.dbapi.porttrees = [portage.portdb.porttree_root] # does it make sense to remove _all_ useless stuff or just leave it as it is? #portdb.dbapi._aux_cache_keys.clear() #portdb.dbapi._aux_cache_keys.update(["EAPI", "KEYWORDS", "SLOT"]) conf["PORTDIR"] = portage.settings["PORTDIR"] conf["portdb"] = portdb return conf
def _load_config(self): create_trees_kwargs = {} if self.target_root != os.sep: create_trees_kwargs["target_root"] = self.target_root env = { "PORTAGE_REPOSITORIES": "\n".join("[%s]\n%s" % (repo_name, "\n".join("%s = %s" % (k, v) for k, v in repo_config.items())) for repo_name, repo_config in self._repositories.items()) } trees = portage.create_trees(env=env, eprefix=self.eprefix, **create_trees_kwargs) for root, root_trees in trees.items(): settings = root_trees["vartree"].settings settings._init_dirs() setconfig = load_default_config(settings, root_trees) root_trees["root_config"] = RootConfig(settings, root_trees, setconfig) return trees[trees._target_eroot]["vartree"].settings, trees
def __init__(self, config_root: typing.Optional[Path] = None) -> None: """ Instantiate a new instance and load Portage configs Load Portage config from optional `config_root`. If it is not specified, the current Portage configuration is loaded. """ kwargs = {} if config_root is not None: kwargs['config_root'] = config_root trees = create_trees(**kwargs) self.tree = trees[max(trees)] self.dbapi = self.tree['porttree'].dbapi self.vdb = self.tree['vartree'] for r in self.dbapi.repositories: if r.name == 'gentoo': self.repo = r break else: raise GentooRepoNotFound('Unable to find ::gentoo repository')
def get_settings( conf = None ): if not isinstance( conf, dict ) and conf: raise TypeError("conf must be dict() or None") if not conf: conf = {} # TODO: maybe we should improve it a bit ;) mysettings = portage.config( config_incrementals = portage.const.INCREMENTALS, local_config = False ) if conf["MAIN_ARCH"] == "auto": conf["MAIN_ARCH"] = "%s" % mysettings["ACCEPT_KEYWORDS"].split(" ")[0].lstrip("~") if conf["TARGET_ARCH"] == "auto": conf["TARGET_ARCH"] = "~%s" % mysettings["ACCEPT_KEYWORDS"].split(" ")[0].lstrip("~") # TODO: exclude overlay categories from check if conf["CATEGORIES"]: _mycats = [] for _cat in conf["CATEGORIES"].split(","): _cat = _cat.strip() _mycats.append(_cat ) if _cat not in mysettings.categories: raise ValueError("invalid category for -C switch '%s'" % _cat) mysettings.categories = _mycats # maybe thats not necessary because we override porttrees below.. _portage_settings( "PORTDIR_OVERLAY", "", mysettings ) trees = portage.create_trees() trees["/"]["porttree"].settings = mysettings portdb = trees["/"]["porttree"] portdb.dbapi.settings = mysettings portdb.dbapi.porttrees = [portage.portdb.porttree_root] # does it make sense to remove _all_ useless stuff or just leave it as it is? #portdb.dbapi._aux_cache_keys.clear() #portdb.dbapi._aux_cache_keys.update(["EAPI", "KEYWORDS", "SLOT"]) conf["PORTDIR"] = portage.settings["PORTDIR"] conf["portdb"] = portdb return conf
def _load_config(self): portdir_overlay = [] for repo_name in sorted(self.repo_dirs): path = self.repo_dirs[repo_name] if path != self.portdir: portdir_overlay.append(path) env = { "ACCEPT_KEYWORDS": "x86", "DISTDIR": self.distdir, "PKGDIR": self.pkgdir, "PORTDIR": self.portdir, "PORTDIR_OVERLAY": " ".join(portdir_overlay), 'PORTAGE_TMPDIR': os.path.join(self.eroot, 'var/tmp'), } if os.environ.get("NOCOLOR"): env["NOCOLOR"] = os.environ["NOCOLOR"] if os.environ.get("SANDBOX_ON") == "1": # avoid problems from nested sandbox instances env["FEATURES"] = "-sandbox" # Pass along PORTAGE_USERNAME and PORTAGE_GRPNAME since they # need to be inherited by ebuild subprocesses. if 'PORTAGE_USERNAME' in os.environ: env['PORTAGE_USERNAME'] = os.environ['PORTAGE_USERNAME'] if 'PORTAGE_GRPNAME' in os.environ: env['PORTAGE_GRPNAME'] = os.environ['PORTAGE_GRPNAME'] trees = portage.create_trees(env=env, eprefix=self.eprefix) for root, root_trees in trees.items(): settings = root_trees["vartree"].settings settings._init_dirs() setconfig = load_default_config(settings, root_trees) root_trees["root_config"] = RootConfig(settings, root_trees, setconfig) return settings, trees
def _get_legacy_global(name): constructed = portage._legacy_globals_constructed if name in constructed: return getattr(portage, name) if name == 'portdb': portage.portdb = portage.db[portage.root]["porttree"].dbapi constructed.add(name) return getattr(portage, name) elif name in ('mtimedb', 'mtimedbfile'): portage.mtimedbfile = os.path.join(portage.root, CACHE_PATH, "mtimedb") constructed.add('mtimedbfile') portage.mtimedb = portage.MtimeDB(portage.mtimedbfile) constructed.add('mtimedb') return getattr(portage, name) # Portage needs to ensure a sane umask for the files it creates. os.umask(0o22) kwargs = {} for k, envvar in (("config_root", "PORTAGE_CONFIGROOT"), ("target_root", "ROOT")): kwargs[k] = os.environ.get(envvar) portage._initializing_globals = True portage.db = portage.create_trees(**kwargs) constructed.add('db') del portage._initializing_globals settings = portage.db["/"]["vartree"].settings for root in portage.db: if root != "/": settings = portage.db[root]["vartree"].settings break portage.output._init(config_root=settings['PORTAGE_CONFIGROOT']) portage.settings = settings constructed.add('settings') portage.root = root constructed.add('root') # COMPATIBILITY # These attributes should not be used within # Portage under any circumstances. portage.archlist = settings.archlist() constructed.add('archlist') portage.features = settings.features constructed.add('features') portage.groups = settings["ACCEPT_KEYWORDS"].split() constructed.add('groups') portage.pkglines = settings.packages constructed.add('pkglines') portage.selinux_enabled = settings.selinux_enabled() constructed.add('selinux_enabled') portage.thirdpartymirrors = settings.thirdpartymirrors() constructed.add('thirdpartymirrors') profiledir = os.path.join(settings["PORTAGE_CONFIGROOT"], PROFILE_PATH) if not os.path.isdir(profiledir): profiledir = None portage.profiledir = profiledir constructed.add('profiledir') return getattr(portage, name)
def UpdateGmergeBinhost(board, pkg, deep): """Add pkg to our gmerge-specific binhost. Files matching DEFAULT_INSTALL_MASK are not included in the tarball. """ root = '/build/%s/' % board gmerge_pkgdir = os.path.join(root, 'gmerge-packages') stripped_link = os.path.join(root, 'stripped-packages') # Create gmerge pkgdir and give us permission to write to it. subprocess.check_call(['sudo', 'mkdir', '-p', gmerge_pkgdir]) subprocess.check_call(['sudo', 'ln', '-snf', os.path.basename(gmerge_pkgdir), stripped_link]) username = os.environ['PORTAGE_USERNAME'] subprocess.check_call(['sudo', 'chown', username, gmerge_pkgdir]) # Load databases. trees = portage.create_trees(config_root=root, target_root=root) vardb = trees[root]['vartree'].dbapi bintree = trees[root]['bintree'] bintree.populate() gmerge_tree = dbapi.bintree.binarytree(root, gmerge_pkgdir, settings=bintree.settings) gmerge_tree.populate() if deep: # If we're in deep mode, fill in the binhost completely. gmerge_matches = set(gmerge_tree.dbapi.cpv_all()) bindb_matches = set(bintree.dbapi.cpv_all()) installed_matches = set(vardb.cpv_all()) & bindb_matches else: # Otherwise, just fill in the requested package. gmerge_matches = set(gmerge_tree.dbapi.match(pkg)) bindb_matches = set(bintree.dbapi.match(pkg)) installed_matches = set(vardb.match(pkg)) & bindb_matches # Remove any stale packages that exist in the local binhost but are not # installed anymore. if bindb_matches - installed_matches: subprocess.check_call(['eclean-%s' % board, '-d', 'packages']) # Remove any stale packages that exist in the gmerge binhost but are not # installed anymore. changed = False for pkg in gmerge_matches - installed_matches: gmerge_path = gmerge_tree.getname(pkg) if os.path.exists(gmerge_path): os.unlink(gmerge_path) changed = True # Copy any installed packages that have been rebuilt to the gmerge binhost. for pkg in installed_matches: build_time, = bintree.dbapi.aux_get(pkg, ['BUILD_TIME']) build_path = bintree.getname(pkg) gmerge_path = gmerge_tree.getname(pkg) # If a package exists in the gmerge binhost with the same build time, # don't rebuild it. if pkg in gmerge_matches and os.path.exists(gmerge_path): old_build_time, = gmerge_tree.dbapi.aux_get(pkg, ['BUILD_TIME']) if old_build_time == build_time: continue _Log('Filtering install mask from %s' % pkg) _FilterInstallMaskFromPackage(build_path, gmerge_path) changed = True # If the gmerge binhost was changed, update the Packages file to match. if changed: env_copy = os.environ.copy() env_copy['PKGDIR'] = gmerge_pkgdir env_copy['ROOT'] = root env_copy['PORTAGE_CONFIGROOT'] = root cmd = ['/usr/sbin/emaint', '-f', 'binhost'] subprocess.check_call(cmd, env=env_copy) return bool(installed_matches)
def main(argv): argp = argparse.ArgumentParser( description='Test-build specified package with absolutely ' 'minimal number of non-dependency packages installed', epilog='WARNING: This tool will bulldoze your system. Use ' 'in a dedicated chroot only!') argp.add_argument('--emerge-opts', default='--jobs', help='emerge(1) options to use (default: --jobs)') argp.add_argument('-p', '--pretend', action='store_true', help='only print what would be done') argp.add_argument('package', help='package specification to build and install') args = argp.parse_args(argv) def run_command(cmd, env={}): print(' '.join( shlex.quote(x) for x in [f'{k}={v}' for k, v in env.items()] + cmd)) if not args.pretend: kwargs = {} if env: kwargs['env'] = dict(os.environ) kwargs['env'].update(env) subprocess.check_call(cmd, **kwargs) trees = create_trees() tree = trees[max(trees)] repos = tree['porttree'].dbapi vdb = tree['vartree'] emerge_opts = shlex.split(args.emerge_opts) print('[1] Installing build-time dependencies ...\n') run_command( ['emerge', '-v', '--ask=n', '--onlydeps', '--onlydeps-with-rdeps=n'] + emerge_opts + [args.package]) print('\n[2] Updating world file with dependencies ...\n') m = repos.xmatch('bestmatch-visible', args.package) deps = repos.aux_get(m, ['DEPEND', 'BDEPEND']) depset = set() for dep_group in deps: depset.update(x for x in use_reduce(dep_group, matchall=True, flat=True) if x != '||') matches = set(vdb.dep_bestmatch(x) for x in depset) matches.discard('') if args.pretend: print('Note: --pretend mode works correctly only for installed deps') print('New world contents:') print('\n'.join(f'={x}' for x in matches)) else: world_path = '/var/lib/portage/world' backup_path = world_path + '.puremerge-backup' try: if not os.path.exists(backup_path): os.rename(world_path, backup_path) else: os.unlink(world_path) except FileNotFoundError: pass with open(world_path, 'w') as f: f.write(''.join(f'={x}\n' for x in matches)) print('\n[3] Cleaning up remaining packages ...\n') run_command(['emerge', '--depclean', '--ask=n', '--with-bdeps=n']) print('\n[4] Building the package itself\n') run_command(['emerge', '-1v', '--ask=n', '--buildpkgonly'] + emerge_opts + [args.package], env={'FEATURES': 'test'}) print('\n[5] Installing the package\n') run_command(['emerge', '-1v', '--ask=n', '--usepkgonly'] + emerge_opts + [args.package]) return 0
def UpdateGmergeBinhost(board, pkg, deep): """Add pkg to our gmerge-specific binhost. Files matching DEFAULT_INSTALL_MASK are not included in the tarball. """ root = '/build/%s/' % board gmerge_pkgdir = os.path.join(root, 'gmerge-packages') stripped_link = os.path.join(root, 'stripped-packages') # Create gmerge pkgdir and give us permission to write to it. subprocess.check_call(['sudo', 'mkdir', '-p', gmerge_pkgdir]) subprocess.check_call( ['sudo', 'ln', '-snf', os.path.basename(gmerge_pkgdir), stripped_link]) username = os.environ['PORTAGE_USERNAME'] subprocess.check_call(['sudo', 'chown', username, gmerge_pkgdir]) # Load databases. trees = portage.create_trees(config_root=root, target_root=root) vardb = trees[root]['vartree'].dbapi bintree = trees[root]['bintree'] bintree.populate() gmerge_tree = dbapi.bintree.binarytree(root, gmerge_pkgdir, settings=bintree.settings) gmerge_tree.populate() if deep: # If we're in deep mode, fill in the binhost completely. gmerge_matches = set(gmerge_tree.dbapi.cpv_all()) bindb_matches = set(bintree.dbapi.cpv_all()) installed_matches = set(vardb.cpv_all()) & bindb_matches else: # Otherwise, just fill in the requested package. gmerge_matches = set(gmerge_tree.dbapi.match(pkg)) bindb_matches = set(bintree.dbapi.match(pkg)) installed_matches = set(vardb.match(pkg)) & bindb_matches # Remove any stale packages that exist in the local binhost but are not # installed anymore. if bindb_matches - installed_matches: subprocess.check_call(['eclean-%s' % board, '-d', 'packages']) # Remove any stale packages that exist in the gmerge binhost but are not # installed anymore. changed = False for pkg in gmerge_matches - installed_matches: gmerge_path = gmerge_tree.getname(pkg) if os.path.exists(gmerge_path): os.unlink(gmerge_path) changed = True # Copy any installed packages that have been rebuilt to the gmerge binhost. for pkg in installed_matches: build_time, = bintree.dbapi.aux_get(pkg, ['BUILD_TIME']) build_path = bintree.getname(pkg) gmerge_path = gmerge_tree.getname(pkg) # If a package exists in the gmerge binhost with the same build time, # don't rebuild it. if pkg in gmerge_matches and os.path.exists(gmerge_path): old_build_time, = gmerge_tree.dbapi.aux_get(pkg, ['BUILD_TIME']) if old_build_time == build_time: continue _Log('Filtering install mask from %s' % pkg) _FilterInstallMaskFromPackage(build_path, gmerge_path) changed = True # If the gmerge binhost was changed, update the Packages file to match. if changed: env_copy = os.environ.copy() env_copy['PKGDIR'] = gmerge_pkgdir env_copy['ROOT'] = root env_copy['PORTAGE_CONFIGROOT'] = root cmd = ['/usr/sbin/emaint', '-f', 'binhost'] subprocess.check_call(cmd, env=env_copy) return bool(installed_matches)
def main(argv): cleanup_actions = set() quiet = False strict = False locale.setlocale(locale.LC_ALL, '') # Python3 does std{in,out,err} and argv recoding implicitly if not hasattr(argv[0], 'decode'): dataout = sys.stdout output = sys.stderr else: indec = codecs.getdecoder(locale.getpreferredencoding()) argv = [indec(x)[0] for x in argv] dataout = codecs.getwriter(locale.getpreferredencoding())( sys.stderr, 'backslashescape') output = codecs.getwriter(locale.getpreferredencoding())( sys.stderr, 'backslashescape') for a in list(argv[1:]): if a.startswith('--'): if a == '--version': output.write('flaggie %s\n' % PV) return 0 elif a == '--help': output.write('''Synopsis: %s [<options>] [<global-actions>] [<packages> <actions>] [...] Options: --quiet Silence argument errors and warnings --strict Abort if at least a single flag is invalid --drop-ineffective Drop ineffective flags (those which are overriden by later declarations) --sort-entries Sort package.* file entries by package (please note this will drop comments) --sort-flags Sort package.* flags by name --sort Shorthand for --sort-entries and --sort-flags --cleanup Shorthand for --drop-ineffective and --sort --drop-unmatched-pkgs Drop packages which no longer are available in portdb --drop-unmatched-flags Drop flags which are not found in package's IUSE, KEYWORDS and/or LICENSE variables --destructive-cleanup Shorthand for all of the above --migrate-files Migrate the outdated files to newer variants (package.keywords -> package.accept_keywords) Global actions are applied to the make.conf file. Actions are applied to the package.* files, for the packages preceding them. An action can be one of: +arg explicitly enable arg -arg explicitly disable arg %%arg reset arg to the default state (remove it from the file) ?arg print the effective status of arg (due to the file) The action argument must be either a USE flag, a keyword or a license name. For the '%%' and '?' actions, it can be also one of 'use::', 'kw::' or 'lic::' in order to apply the action to all of the flags, keywords or licenses respectively. A package specification can be any atom acceptable for Portage (in the same format as taken by emerge).\n''' % os.path.basename(argv[0])) return 0 elif a == '--quiet': quiet = True elif a == '--strict': strict = True elif a == '--drop-ineffective': cleanup_actions.add(DropIneffective) elif a == '--sort-entries': cleanup_actions.add(SortEntries) elif a == '--sort-flags': cleanup_actions.add(SortFlags) elif a == '--sort': cleanup_actions.add(SortEntries) cleanup_actions.add(SortFlags) elif a == '--cleanup': cleanup_actions.add(DropIneffective) cleanup_actions.add(SortEntries) cleanup_actions.add(SortFlags) elif a == '--drop-unmatched-pkgs': cleanup_actions.add(DropUnmatchedPkgs) elif a == '--drop-unmatched-flags': cleanup_actions.add(DropUnmatchedFlags) elif a == '--destructive-cleanup': cleanup_actions.add(DropIneffective) cleanup_actions.add(SortEntries) cleanup_actions.add(SortFlags) cleanup_actions.add(DropUnmatchedPkgs) cleanup_actions.add(DropUnmatchedFlags) elif a == '--migrate-files': cleanup_actions.add(MigrateFiles) elif a == '--': argv.remove(a) break else: output.write('Error: unknown option: %s\n' % a) return 1 argv.remove(a) trees = create_trees(config_root=os.environ.get('PORTAGE_CONFIGROOT'), target_root=os.environ.get('ROOT')) porttree = trees[max(trees)]['porttree'].dbapi cache = Caches(porttree) act = parse_actions(argv[1:], porttree, cache, quiet=quiet, strict=strict, cleanupact=cleanup_actions, output=output, dataout=dataout) if act is None: return 1 if not act: main([argv[0], '--help']) return 0 confroot = porttree.settings['PORTAGE_CONFIGROOT'] usercpath = os.path.join(confroot, 'etc', 'portage') pfiles = PackageFiles(usercpath, porttree) for actset in act: actset(pfiles) pfiles.write() return 0
High-level interface for delta generation and distfile reconstruction. :copyright: (c) 2011 by Rafael Goncalves Martins :license: GPL-2, see LICENSE for more details. """ import os import portage from collections import OrderedDict from distpatch.diff import Diff, DiffUnsupported from distpatch.ebuild import Distfile, Ebuild from distpatch.patch import Patch dbapi = portage.create_trees()[portage.settings["ROOT"]]["porttree"].dbapi class PackageException(Exception): pass class Package(object): def __init__(self, deltadb): self.deltadb = deltadb def _lineage_identification(self): self.diffs = [] diffs = [] taken = {} for ebuild_id in range(len(self.ebuilds) - 1):
def _get_legacy_global(name): constructed = portage._legacy_globals_constructed if name in constructed: return getattr(portage, name) if name == 'portdb': portage.portdb = portage.db[portage.root]["porttree"].dbapi constructed.add(name) return getattr(portage, name) if name in ('mtimedb', 'mtimedbfile'): portage.mtimedbfile = os.path.join(portage.settings['EROOT'], CACHE_PATH, "mtimedb") constructed.add('mtimedbfile') portage.mtimedb = portage.MtimeDB(portage.mtimedbfile) constructed.add('mtimedb') return getattr(portage, name) # Portage needs to ensure a sane umask for the files it creates. os.umask(0o22) kwargs = {} for k, envvar in (("config_root", "PORTAGE_CONFIGROOT"), ("target_root", "ROOT"), ("sysroot", "SYSROOT"), ("eprefix", "EPREFIX")): kwargs[k] = os.environ.get(envvar) portage._initializing_globals = True portage.db = portage.create_trees(**kwargs) constructed.add('db') del portage._initializing_globals settings = portage.db[portage.db._target_eroot]["vartree"].settings portage.settings = settings constructed.add('settings') # Since portage.db now uses EROOT for keys instead of ROOT, we make # portage.root refer to EROOT such that it continues to work as a key. portage.root = portage.db._target_eroot constructed.add('root') # COMPATIBILITY # These attributes should not be used within # Portage under any circumstances. portage.archlist = settings.archlist() constructed.add('archlist') portage.features = settings.features constructed.add('features') portage.groups = settings.get("ACCEPT_KEYWORDS", "").split() constructed.add('groups') portage.pkglines = settings.packages constructed.add('pkglines') portage.selinux_enabled = settings.selinux_enabled() constructed.add('selinux_enabled') portage.thirdpartymirrors = settings.thirdpartymirrors() constructed.add('thirdpartymirrors') profiledir = os.path.join(settings["PORTAGE_CONFIGROOT"], PROFILE_PATH) if not os.path.isdir(profiledir): profiledir = None portage.profiledir = profiledir constructed.add('profiledir') return getattr(portage, name)
def main(argv): parser = optparse.OptionParser(version=MY_PV, usage='%prog <actions> [options] [packages]') parser.add_option('-U', '--unmask-file', action='store', dest='unmask', help='package.unmask file location') gr = optparse.OptionGroup(parser, 'Actions') gr.add_option('-a', '--add', action='append_const', dest='mode', const='add', help='Unmask specified packages.') gr.add_option('-d', '--delete', action='append_const', dest='mode', const='delete', help='Remove the unmask entries for specified packages.') gr.add_option('-u', '--update', action='append_const', dest='mode', const='update', help='Update unmasks according to the package.mask files and remove the old ones.') gr.add_option('-v', '--vimdiff', action='append_const', dest='mode', const='vimdiff', help='vimdiff the merged package.mask file with package.unmask.') parser.add_option_group(gr) gr = optparse.OptionGroup(parser, 'Options related to vimdiff') gr.add_option('--vimdiffcmd', action='store', dest='vimdiff', default='vimdiff', help='vimdiff command') parser.add_option_group(gr) (opts, args) = parser.parse_args(args=argv[1:]) if not opts.mode: if os.path.basename(argv[0]).startswith('vimdiff'): opts.mode = ('vimdiff') else: parser.print_help() return 2 opts.mode = frozenset(opts.mode) if 'add' in opts.mode and 'delete' in opts.mode: parser.error('--add and --delete arguments are exclusive.') return 2 if not args and ('add' in opts.mode or 'delete' in opts.mode): parser.error('--and and --delete actions require at least a single package') return 2 trees = create_trees( config_root = os.environ.get('PORTAGE_CONFIGROOT'), target_root = os.environ.get('ROOT')) porttree = trees[max(trees)]['porttree'] portdb = porttree.dbapi unmask = opts.unmask if not unmask: unmask = os.path.join(porttree.settings['PORTAGE_CONFIGROOT'], USER_CONFIG_PATH, 'package.unmask') if os.path.isdir(unmask): unmask = os.path.join(unmask, 'diffmask') mask = None if 'add' in opts.mode: (unmask, mask) = add(args, unmask, mask, dbapi = portdb) elif 'delete' in opts.mode: (unmask, mask) = delete(args, unmask, mask, dbapi = portdb) if 'update' in opts.mode: (unmask, mask) = update(unmask, mask, dbapi = portdb) if 'vimdiff' in opts.mode: (unmask, mask) = vimdiff(opts.vimdiff, unmask, mask, dbapi = portdb) if isinstance(unmask, UnmaskFile): unmask.write() return 0
def _get_legacy_global(name): constructed = portage._legacy_globals_constructed if name in constructed: return getattr(portage, name) if name == 'portdb': portage.portdb = portage.db[portage.root]["porttree"].dbapi constructed.add(name) return getattr(portage, name) elif name in ('mtimedb', 'mtimedbfile'): portage.mtimedbfile = os.path.join(portage.root, CACHE_PATH, "mtimedb") constructed.add('mtimedbfile') portage.mtimedb = portage.MtimeDB(portage.mtimedbfile) constructed.add('mtimedb') return getattr(portage, name) # Portage needs to ensure a sane umask for the files it creates. os.umask(0o22) kwargs = {} for k, envvar in (("config_root", "PORTAGE_CONFIGROOT"), ("target_root", "ROOT")): kwargs[k] = os.environ.get(envvar, "/") portage._initializing_globals = True portage.db = portage.create_trees(**kwargs) constructed.add('db') del portage._initializing_globals settings = portage.db["/"]["vartree"].settings for root in portage.db: if root != "/": settings = portage.db[root]["vartree"].settings break portage.output._init(config_root=settings['PORTAGE_CONFIGROOT']) portage.settings = settings constructed.add('settings') portage.root = root constructed.add('root') # COMPATIBILITY # These attributes should not be used within # Portage under any circumstances. portage.archlist = settings.archlist() constructed.add('archlist') portage.features = settings.features constructed.add('features') portage.groups = settings["ACCEPT_KEYWORDS"].split() constructed.add('groups') portage.pkglines = settings.packages constructed.add('pkglines') portage.selinux_enabled = settings.selinux_enabled() constructed.add('selinux_enabled') portage.thirdpartymirrors = settings.thirdpartymirrors() constructed.add('thirdpartymirrors') portage.usedefaults = settings.use_defs constructed.add('usedefaults') profiledir = os.path.join(settings["PORTAGE_CONFIGROOT"], PROFILE_PATH) if not os.path.isdir(profiledir): profiledir = None portage.profiledir = profiledir constructed.add('profiledir') return getattr(portage, name)
def _get_legacy_global(name): constructed = portage._legacy_globals_constructed if name in constructed: return getattr(portage, name) if name == 'portdb': portage.portdb = portage.db[portage.root]["porttree"].dbapi constructed.add(name) return getattr(portage, name) elif name in ('mtimedb', 'mtimedbfile'): portage.mtimedbfile = os.path.join(portage.settings['EROOT'], CACHE_PATH, "mtimedb") constructed.add('mtimedbfile') portage.mtimedb = portage.MtimeDB(portage.mtimedbfile) constructed.add('mtimedb') return getattr(portage, name) # Portage needs to ensure a sane umask for the files it creates. os.umask(0o22) kwargs = {} for k, envvar in (("config_root", "PORTAGE_CONFIGROOT"), ("target_root", "ROOT"), ("eprefix", "EPREFIX")): kwargs[k] = os.environ.get(envvar) portage._initializing_globals = True portage.db = portage.create_trees(**kwargs) constructed.add('db') del portage._initializing_globals settings = portage.db[portage.db._target_eroot]["vartree"].settings portage.settings = settings constructed.add('settings') # Since portage.db now uses EROOT for keys instead of ROOT, we make # portage.root refer to EROOT such that it continues to work as a key. portage.root = portage.db._target_eroot constructed.add('root') # COMPATIBILITY # These attributes should not be used within # Portage under any circumstances. portage.archlist = settings.archlist() constructed.add('archlist') portage.features = settings.features constructed.add('features') portage.groups = settings.get("ACCEPT_KEYWORDS", "").split() constructed.add('groups') portage.pkglines = settings.packages constructed.add('pkglines') portage.selinux_enabled = settings.selinux_enabled() constructed.add('selinux_enabled') portage.thirdpartymirrors = settings.thirdpartymirrors() constructed.add('thirdpartymirrors') profiledir = os.path.join(settings["PORTAGE_CONFIGROOT"], PROFILE_PATH) if not os.path.isdir(profiledir): profiledir = None portage.profiledir = profiledir constructed.add('profiledir') return getattr(portage, name)
import pprint import pylon.base import pylon.gentoo.job import pylon.gentoo.ui import re import sys import time # FIXME configurability cache_base_path = '/tmp' cache_base_name = 'cruft_cache' comment_char = '#' default_pattern_root = '/usr/bin/cruft.d' gtk_check = gentoolkit.equery.check.VerifyContents() trees = portage.create_trees() vardb = trees[portage.settings['EROOT']]["vartree"].dbapi vardb_path = os.path.join(portage.settings['EROOT'], portage.const.VDB_PATH) # portage vartree dict indices po_type = 0 po_timestamp = 1 po_digest = 2 # cruft dict indices co_date = 0 class ui(pylon.gentoo.ui.ui): def __init__(self, owner): super().__init__(owner) self.parser_common.add_argument('-i', '--pattern_root',
def main(argv): parser = OptionParser() parser.add_option('-a', '--add', dest='add', action='store_true', default=False, help='Add paths to INSTALL_MASK') parser.add_option('-d', '--delete', '--remove', dest='remove', action='store_true', default=False, help='Remove paths from INSTALL_MASK') parser.add_option('-i', '--info', dest='info', action='store_true', default=False, help='Print information about INSTALL_MASK flag or INSTALL_MASK in general') parser.add_option('-r', '--rebuild', dest='rebuild', action='store_true', default=False, help='Create rebuild list for packages not matching given (or current) INSTALL_MASK') (opts, args) = parser.parse_args(argv[1:]) acts = opts.add + opts.remove + opts.info + opts.rebuild if acts > 1: parser.error('Actions (-a, -d, -i, -r) are mutually exclusive.') elif acts < 1: parser.error('No action specified (-a, -d, -i, -r).') if not args and not opts.info + opts.rebuild: parser.error('No paths specified') trees = create_trees( config_root = os.environ.get('PORTAGE_CONFIGROOT'), target_root = os.environ.get('ROOT')) porttree = trees[max(trees)]['porttree'].dbapi vartree = trees[max(trees)]['vartree'].dbapi confroot = porttree.settings['PORTAGE_CONFIGROOT'] mkconf = MakeConf( (os.path.join(confroot, 'etc', 'make.conf'), os.path.join(confroot, 'etc', 'portage', 'make.conf')), porttree) # .cp_list() should be potentially faster than .match() for m in reversed(porttree.cp_list('app-portage/install-mask')): d = os.path.dirname(porttree.findname(m)) dbf = os.path.join(d, 'files', 'location-db.conf') if os.path.exists(dbf): break else: dbf = None ldb = LocationDB(dbf) try: installmask = mkconf.variables['INSTALL_MASK'] except KeyError: installmask = NewVariable('INSTALL_MASK') mkconf.newvars.append(installmask) try: if opts.add: add(installmask, args, ldb = ldb) elif opts.remove: remove(installmask, args, ldb = ldb) elif opts.info: info(installmask, args, ldb = ldb) elif opts.rebuild: rebuild(installmask, args, ldb = ldb, dbapi = vartree) except Exception as e: parser.error(str(e)) mkconf.write()
Module to abstract ebuild/distfile interfaces. :copyright: (c) 2011 by Rafael Goncalves Martins :license: GPL-2, see LICENSE for more details. """ import os import portage from collections import OrderedDict from portage.dbapi.porttree import _parse_uri_map from portage.package.ebuild.fetch import fetch dbapi = portage.create_trees()[portage.settings['ROOT']]['porttree'].dbapi class EbuildException(Exception): pass class DistfileException(Exception): pass class Ebuild(object): def __init__(self, cpv): if not dbapi.cpv_exists(cpv): raise EbuildException('Invalid CPV: %s' % cpv)