From 2801d985efc89ea124489b8b4b5d8452e40615a7 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Fri, 26 Jun 2009 20:06:08 +0000 Subject: Move __init__.py to main.py. svn path=/main/trunk/; revision=13697 --- pym/_emerge/__init__.py | 1282 ----------------------------------------------- 1 file changed, 1282 deletions(-) delete mode 100644 pym/_emerge/__init__.py (limited to 'pym/_emerge/__init__.py') diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py deleted file mode 100644 index f73bc6db4..000000000 --- a/pym/_emerge/__init__.py +++ /dev/null @@ -1,1282 +0,0 @@ -# Copyright 1999-2009 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Id$ - -import logging -import shlex -import signal -import sys -import textwrap -import os -import platform - -try: - import portage -except ImportError: - from os import path as osp - sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")) - import portage - -import _emerge.help -import portage.xpak, commands, errno, re, time -from portage.output import colorize, xtermTitleReset -from portage.output import create_color_func -good = create_color_func("GOOD") -bad = create_color_func("BAD") - -import portage.elog -import portage.dep -portage.dep._dep_check_strict = True -import portage.util -import portage.locks -import portage.exception -from portage.data import secpass -from portage.util import normalize_path as normpath -from portage.util import writemsg, writemsg_level -from portage.sets import SETPREFIX - -from _emerge.actions import action_config, action_sync, action_metadata, \ - action_regen, action_search, action_uninstall, action_info, action_build, \ - adjust_config, chk_updated_cfg_files, display_missing_pkg_set, \ - display_news_notification, getportageversion, load_emerge_config -from _emerge.emergelog import emergelog -from _emerge._flush_elog_mod_echo import _flush_elog_mod_echo -from _emerge.is_valid_package_atom import is_valid_package_atom -from _emerge.stdout_spinner import stdout_spinner - -options=[ -"--ask", "--alphabetical", -"--buildpkg", "--buildpkgonly", -"--changelog", "--columns", -"--complete-graph", -"--debug", "--deep", -"--digest", -"--emptytree", -"--fetchonly", "--fetch-all-uri", -"--getbinpkg", "--getbinpkgonly", -"--help", "--ignore-default-opts", -"--keep-going", -"--noconfmem", -"--newuse", -"--nodeps", "--noreplace", -"--nospinner", "--oneshot", -"--onlydeps", "--pretend", -"--quiet", "--resume", -"--searchdesc", "--selective", -"--skipfirst", -"--tree", -"--update", -"--usepkg", "--usepkgonly", -"--verbose", -] - -shortmapping={ -"1":"--oneshot", -"a":"--ask", -"b":"--buildpkg", "B":"--buildpkgonly", -"c":"--clean", "C":"--unmerge", -"d":"--debug", "D":"--deep", -"e":"--emptytree", -"f":"--fetchonly", "F":"--fetch-all-uri", -"g":"--getbinpkg", "G":"--getbinpkgonly", -"h":"--help", -"k":"--usepkg", "K":"--usepkgonly", -"l":"--changelog", -"n":"--noreplace", "N":"--newuse", -"o":"--onlydeps", "O":"--nodeps", -"p":"--pretend", "P":"--prune", -"q":"--quiet", -"s":"--search", "S":"--searchdesc", -"t":"--tree", -"u":"--update", -"v":"--verbose", "V":"--version" -} - -def chk_updated_info_files(root, infodirs, prev_mtimes, retval): - - if os.path.exists("/usr/bin/install-info"): - out = portage.output.EOutput() - regen_infodirs=[] - for z in infodirs: - if z=='': - continue - inforoot=normpath(root+z) - if os.path.isdir(inforoot): - infomtime = long(os.stat(inforoot).st_mtime) - if inforoot not in prev_mtimes or \ - prev_mtimes[inforoot] != infomtime: - regen_infodirs.append(inforoot) - - if not regen_infodirs: - portage.writemsg_stdout("\n") - out.einfo("GNU info directory index is up-to-date.") - else: - portage.writemsg_stdout("\n") - out.einfo("Regenerating GNU info directory index...") - - dir_extensions = ("", ".gz", ".bz2") - icount=0 - badcount=0 - errmsg = "" - for inforoot in regen_infodirs: - if inforoot=='': - continue - - if not os.path.isdir(inforoot) or \ - not os.access(inforoot, os.W_OK): - continue - - file_list = os.listdir(inforoot) - file_list.sort() - dir_file = os.path.join(inforoot, "dir") - moved_old_dir = False - processed_count = 0 - for x in file_list: - if x.startswith(".") or \ - os.path.isdir(os.path.join(inforoot, x)): - continue - if x.startswith("dir"): - skip = False - for ext in dir_extensions: - if x == "dir" + ext or \ - x == "dir" + ext + ".old": - skip = True - break - if skip: - continue - if processed_count == 0: - for ext in dir_extensions: - try: - os.rename(dir_file + ext, dir_file + ext + ".old") - moved_old_dir = True - except EnvironmentError, e: - if e.errno != errno.ENOENT: - raise - del e - processed_count += 1 - myso=commands.getstatusoutput("LANG=C LANGUAGE=C /usr/bin/install-info --dir-file="+inforoot+"/dir "+inforoot+"/"+x)[1] - existsstr="already exists, for file `" - if myso!="": - if re.search(existsstr,myso): - # Already exists... Don't increment the count for this. - pass - elif myso[:44]=="install-info: warning: no info dir entry in ": - # This info file doesn't contain a DIR-header: install-info produces this - # (harmless) warning (the --quiet switch doesn't seem to work). - # Don't increment the count for this. - pass - else: - badcount=badcount+1 - errmsg += myso + "\n" - icount=icount+1 - - if moved_old_dir and not os.path.exists(dir_file): - # We didn't generate a new dir file, so put the old file - # back where it was originally found. - for ext in dir_extensions: - try: - os.rename(dir_file + ext + ".old", dir_file + ext) - except EnvironmentError, e: - if e.errno != errno.ENOENT: - raise - del e - - # Clean dir.old cruft so that they don't prevent - # unmerge of otherwise empty directories. - for ext in dir_extensions: - try: - os.unlink(dir_file + ext + ".old") - except EnvironmentError, e: - if e.errno != errno.ENOENT: - raise - del e - - #update mtime so we can potentially avoid regenerating. - prev_mtimes[inforoot] = long(os.stat(inforoot).st_mtime) - - if badcount: - out.eerror("Processed %d info files; %d errors." % \ - (icount, badcount)) - writemsg_level(errmsg, level=logging.ERROR, noiselevel=-1) - else: - if icount > 0: - out.einfo("Processed %d info files." % (icount,)) - - -def display_preserved_libs(vardbapi): - MAX_DISPLAY = 3 - - # Ensure the registry is consistent with existing files. - vardbapi.plib_registry.pruneNonExisting() - - if vardbapi.plib_registry.hasEntries(): - print - print colorize("WARN", "!!!") + " existing preserved libs:" - plibdata = vardbapi.plib_registry.getPreservedLibs() - linkmap = vardbapi.linkmap - consumer_map = {} - owners = {} - linkmap_broken = False - - try: - linkmap.rebuild() - except portage.exception.CommandNotFound, e: - writemsg_level("!!! Command Not Found: %s\n" % (e,), - level=logging.ERROR, noiselevel=-1) - del e - linkmap_broken = True - else: - search_for_owners = set() - for cpv in plibdata: - internal_plib_keys = set(linkmap._obj_key(f) \ - for f in plibdata[cpv]) - for f in plibdata[cpv]: - if f in consumer_map: - continue - consumers = [] - for c in linkmap.findConsumers(f): - # Filter out any consumers that are also preserved libs - # belonging to the same package as the provider. - if linkmap._obj_key(c) not in internal_plib_keys: - consumers.append(c) - consumers.sort() - consumer_map[f] = consumers - search_for_owners.update(consumers[:MAX_DISPLAY+1]) - - owners = vardbapi._owners.getFileOwnerMap(search_for_owners) - - for cpv in plibdata: - print colorize("WARN", ">>>") + " package: %s" % cpv - samefile_map = {} - for f in plibdata[cpv]: - obj_key = linkmap._obj_key(f) - alt_paths = samefile_map.get(obj_key) - if alt_paths is None: - alt_paths = set() - samefile_map[obj_key] = alt_paths - alt_paths.add(f) - - for alt_paths in samefile_map.itervalues(): - alt_paths = sorted(alt_paths) - for p in alt_paths: - print colorize("WARN", " * ") + " - %s" % (p,) - f = alt_paths[0] - consumers = consumer_map.get(f, []) - for c in consumers[:MAX_DISPLAY]: - print colorize("WARN", " * ") + " used by %s (%s)" % \ - (c, ", ".join(x.mycpv for x in owners.get(c, []))) - if len(consumers) == MAX_DISPLAY + 1: - print colorize("WARN", " * ") + " used by %s (%s)" % \ - (consumers[MAX_DISPLAY], ", ".join(x.mycpv \ - for x in owners.get(consumers[MAX_DISPLAY], []))) - elif len(consumers) > MAX_DISPLAY: - print colorize("WARN", " * ") + " used by %d other files" % (len(consumers) - MAX_DISPLAY) - print "Use " + colorize("GOOD", "emerge @preserved-rebuild") + " to rebuild packages using these libraries" - - -def post_emerge(root_config, myopts, mtimedb, retval): - """ - Misc. things to run at the end of a merge session. - - Update Info Files - Update Config Files - Update News Items - Commit mtimeDB - Display preserved libs warnings - Exit Emerge - - @param trees: A dictionary mapping each ROOT to it's package databases - @type trees: dict - @param mtimedb: The mtimeDB to store data needed across merge invocations - @type mtimedb: MtimeDB class instance - @param retval: Emerge's return value - @type retval: Int - @rype: None - @returns: - 1. Calls sys.exit(retval) - """ - - target_root = root_config.root - trees = { target_root : root_config.trees } - vardbapi = trees[target_root]["vartree"].dbapi - settings = vardbapi.settings - info_mtimes = mtimedb["info"] - - # Load the most current variables from ${ROOT}/etc/profile.env - settings.unlock() - settings.reload() - settings.regenerate() - settings.lock() - - config_protect = settings.get("CONFIG_PROTECT","").split() - infodirs = settings.get("INFOPATH","").split(":") + \ - settings.get("INFODIR","").split(":") - - os.chdir("/") - - if retval == os.EX_OK: - exit_msg = " *** exiting successfully." - else: - exit_msg = " *** exiting unsuccessfully with status '%s'." % retval - emergelog("notitles" not in settings.features, exit_msg) - - _flush_elog_mod_echo() - - counter_hash = settings.get("PORTAGE_COUNTER_HASH") - if "--pretend" in myopts or (counter_hash is not None and \ - counter_hash == vardbapi._counter_hash()): - display_news_notification(root_config, myopts) - # If vdb state has not changed then there's nothing else to do. - sys.exit(retval) - - vdb_path = os.path.join(target_root, portage.VDB_PATH) - portage.util.ensure_dirs(vdb_path) - vdb_lock = None - if os.access(vdb_path, os.W_OK) and not "--pretend" in myopts: - vdb_lock = portage.locks.lockdir(vdb_path) - - if vdb_lock: - try: - if "noinfo" not in settings.features: - chk_updated_info_files(target_root, - infodirs, info_mtimes, retval) - mtimedb.commit() - finally: - if vdb_lock: - portage.locks.unlockdir(vdb_lock) - - chk_updated_cfg_files(target_root, config_protect) - - display_news_notification(root_config, myopts) - if retval in (None, os.EX_OK) or (not "--pretend" in myopts): - display_preserved_libs(vardbapi) - - sys.exit(retval) - - -def multiple_actions(action1, action2): - sys.stderr.write("\n!!! Multiple actions requested... Please choose one only.\n") - sys.stderr.write("!!! '%s' or '%s'\n\n" % (action1, action2)) - sys.exit(1) - -def insert_optional_args(args): - """ - Parse optional arguments and insert a value if one has - not been provided. This is done before feeding the args - to the optparse parser since that parser does not support - this feature natively. - """ - - new_args = [] - jobs_opts = ("-j", "--jobs") - default_arg_opts = { - '--deselect' : ('n',), - '--root-deps' : ('rdeps',), - } - arg_stack = args[:] - arg_stack.reverse() - while arg_stack: - arg = arg_stack.pop() - - default_arg_choices = default_arg_opts.get(arg) - if default_arg_choices is not None: - new_args.append(arg) - if arg_stack and arg_stack[-1] in default_arg_choices: - new_args.append(arg_stack.pop()) - else: - # insert default argument - new_args.append('True') - continue - - short_job_opt = bool("j" in arg and arg[:1] == "-" and arg[:2] != "--") - if not (short_job_opt or arg in jobs_opts): - new_args.append(arg) - continue - - # Insert an empty placeholder in order to - # satisfy the requirements of optparse. - - new_args.append("--jobs") - job_count = None - saved_opts = None - if short_job_opt and len(arg) > 2: - if arg[:2] == "-j": - try: - job_count = int(arg[2:]) - except ValueError: - saved_opts = arg[2:] - else: - job_count = "True" - saved_opts = arg[1:].replace("j", "") - - if job_count is None and arg_stack: - try: - job_count = int(arg_stack[-1]) - except ValueError: - pass - else: - # Discard the job count from the stack - # since we're consuming it here. - arg_stack.pop() - - if job_count is None: - # unlimited number of jobs - new_args.append("True") - else: - new_args.append(str(job_count)) - - if saved_opts is not None: - new_args.append("-" + saved_opts) - - return new_args - -def parse_opts(tmpcmdline, silent=False): - myaction=None - myopts = {} - myfiles=[] - - global options, shortmapping - - actions = frozenset([ - "clean", "config", "depclean", - "info", "list-sets", "metadata", - "prune", "regen", "search", - "sync", "unmerge", "version", - ]) - - longopt_aliases = {"--cols":"--columns", "--skip-first":"--skipfirst"} - argument_options = { - "--config-root": { - "help":"specify the location for portage configuration files", - "action":"store" - }, - "--color": { - "help":"enable or disable color output", - "type":"choice", - "choices":("y", "n") - }, - - "--deselect": { - "help" : "remove atoms from the world file", - "type" : "choice", - "choices" : ("True", "n") - }, - - "--jobs": { - - "help" : "Specifies the number of packages to build " + \ - "simultaneously.", - - "action" : "store" - }, - - "--load-average": { - - "help" :"Specifies that no new builds should be started " + \ - "if there are other builds running and the load average " + \ - "is at least LOAD (a floating-point number).", - - "action" : "store" - }, - - "--with-bdeps": { - "help":"include unnecessary build time dependencies", - "type":"choice", - "choices":("y", "n") - }, - "--reinstall": { - "help":"specify conditions to trigger package reinstallation", - "type":"choice", - "choices":["changed-use"] - }, - "--root": { - "help" : "specify the target root filesystem for merging packages", - "action" : "store" - }, - - "--root-deps": { - "help" : "modify interpretation of depedencies", - "type" : "choice", - "choices" :("True", "rdeps") - }, - } - - from optparse import OptionParser - parser = OptionParser() - if parser.has_option("--help"): - parser.remove_option("--help") - - for action_opt in actions: - parser.add_option("--" + action_opt, action="store_true", - dest=action_opt.replace("-", "_"), default=False) - for myopt in options: - parser.add_option(myopt, action="store_true", - dest=myopt.lstrip("--").replace("-", "_"), default=False) - for shortopt, longopt in shortmapping.iteritems(): - parser.add_option("-" + shortopt, action="store_true", - dest=longopt.lstrip("--").replace("-", "_"), default=False) - for myalias, myopt in longopt_aliases.iteritems(): - parser.add_option(myalias, action="store_true", - dest=myopt.lstrip("--").replace("-", "_"), default=False) - - for myopt, kwargs in argument_options.iteritems(): - parser.add_option(myopt, - dest=myopt.lstrip("--").replace("-", "_"), **kwargs) - - tmpcmdline = insert_optional_args(tmpcmdline) - - myoptions, myargs = parser.parse_args(args=tmpcmdline) - - if myoptions.deselect == "True": - myoptions.deselect = True - - if myoptions.root_deps == "True": - myoptions.root_deps = True - - if myoptions.jobs: - jobs = None - if myoptions.jobs == "True": - jobs = True - else: - try: - jobs = int(myoptions.jobs) - except ValueError: - jobs = -1 - - if jobs is not True and \ - jobs < 1: - jobs = None - if not silent: - writemsg("!!! Invalid --jobs parameter: '%s'\n" % \ - (myoptions.jobs,), noiselevel=-1) - - myoptions.jobs = jobs - - if myoptions.load_average: - try: - load_average = float(myoptions.load_average) - except ValueError: - load_average = 0.0 - - if load_average <= 0.0: - load_average = None - if not silent: - writemsg("!!! Invalid --load-average parameter: '%s'\n" % \ - (myoptions.load_average,), noiselevel=-1) - - myoptions.load_average = load_average - - for myopt in options: - v = getattr(myoptions, myopt.lstrip("--").replace("-", "_")) - if v: - myopts[myopt] = True - - for myopt in argument_options: - v = getattr(myoptions, myopt.lstrip("--").replace("-", "_"), None) - if v is not None: - myopts[myopt] = v - - if myoptions.searchdesc: - myoptions.search = True - - for action_opt in actions: - v = getattr(myoptions, action_opt.replace("-", "_")) - if v: - if myaction: - multiple_actions(myaction, action_opt) - sys.exit(1) - myaction = action_opt - - if myaction is None and myoptions.deselect is True: - myaction = 'deselect' - - myfiles += myargs - - return myaction, myopts, myfiles - -def validate_ebuild_environment(trees): - for myroot in trees: - settings = trees[myroot]["vartree"].settings - settings.validate() - -def apply_priorities(settings): - ionice(settings) - nice(settings) - -def nice(settings): - try: - os.nice(int(settings.get("PORTAGE_NICENESS", "0"))) - except (OSError, ValueError), e: - out = portage.output.EOutput() - out.eerror("Failed to change nice value to '%s'" % \ - settings["PORTAGE_NICENESS"]) - out.eerror("%s\n" % str(e)) - -def ionice(settings): - - ionice_cmd = settings.get("PORTAGE_IONICE_COMMAND") - if ionice_cmd: - ionice_cmd = shlex.split(ionice_cmd) - if not ionice_cmd: - return - - from portage.util import varexpand - variables = {"PID" : str(os.getpid())} - cmd = [varexpand(x, mydict=variables) for x in ionice_cmd] - - try: - rval = portage.process.spawn(cmd, env=os.environ) - except portage.exception.CommandNotFound: - # The OS kernel probably doesn't support ionice, - # so return silently. - return - - if rval != os.EX_OK: - out = portage.output.EOutput() - out.eerror("PORTAGE_IONICE_COMMAND returned %d" % (rval,)) - out.eerror("See the make.conf(5) man page for PORTAGE_IONICE_COMMAND usage instructions.") - -def expand_set_arguments(myfiles, myaction, root_config): - retval = os.EX_OK - setconfig = root_config.setconfig - - sets = setconfig.getSets() - - # In order to know exactly which atoms/sets should be added to the - # world file, the depgraph performs set expansion later. It will get - # confused about where the atoms came from if it's not allowed to - # expand them itself. - do_not_expand = (None, ) - newargs = [] - for a in myfiles: - if a in ("system", "world"): - newargs.append(SETPREFIX+a) - else: - newargs.append(a) - myfiles = newargs - del newargs - newargs = [] - - # separators for set arguments - ARG_START = "{" - ARG_END = "}" - - # WARNING: all operators must be of equal length - IS_OPERATOR = "/@" - DIFF_OPERATOR = "-@" - UNION_OPERATOR = "+@" - - for i in range(0, len(myfiles)): - if myfiles[i].startswith(SETPREFIX): - start = 0 - end = 0 - x = myfiles[i][len(SETPREFIX):] - newset = "" - while x: - start = x.find(ARG_START) - end = x.find(ARG_END) - if start > 0 and start < end: - namepart = x[:start] - argpart = x[start+1:end] - - # TODO: implement proper quoting - args = argpart.split(",") - options = {} - for a in args: - if "=" in a: - k, v = a.split("=", 1) - options[k] = v - else: - options[a] = "True" - setconfig.update(namepart, options) - newset += (x[:start-len(namepart)]+namepart) - x = x[end+len(ARG_END):] - else: - newset += x - x = "" - myfiles[i] = SETPREFIX+newset - - sets = setconfig.getSets() - - # display errors that occured while loading the SetConfig instance - for e in setconfig.errors: - print colorize("BAD", "Error during set creation: %s" % e) - - # emerge relies on the existance of sets with names "world" and "system" - required_sets = ("world", "system") - missing_sets = [] - - for s in required_sets: - if s not in sets: - missing_sets.append(s) - if missing_sets: - if len(missing_sets) > 2: - missing_sets_str = ", ".join('"%s"' % s for s in missing_sets[:-1]) - missing_sets_str += ', and "%s"' % missing_sets[-1] - elif len(missing_sets) == 2: - missing_sets_str = '"%s" and "%s"' % tuple(missing_sets) - else: - missing_sets_str = '"%s"' % missing_sets[-1] - msg = ["emerge: incomplete set configuration, " + \ - "missing set(s): %s" % missing_sets_str] - if sets: - msg.append(" sets defined: %s" % ", ".join(sets)) - msg.append(" This usually means that '%s'" % \ - (os.path.join(portage.const.GLOBAL_CONFIG_PATH, "sets.conf"),)) - msg.append(" is missing or corrupt.") - for line in msg: - writemsg_level(line + "\n", level=logging.ERROR, noiselevel=-1) - return (None, 1) - unmerge_actions = ("unmerge", "prune", "clean", "depclean") - - for a in myfiles: - if a.startswith(SETPREFIX): - # support simple set operations (intersection, difference and union) - # on the commandline. Expressions are evaluated strictly left-to-right - if IS_OPERATOR in a or DIFF_OPERATOR in a or UNION_OPERATOR in a: - expression = a[len(SETPREFIX):] - expr_sets = [] - expr_ops = [] - while IS_OPERATOR in expression or DIFF_OPERATOR in expression or UNION_OPERATOR in expression: - is_pos = expression.rfind(IS_OPERATOR) - diff_pos = expression.rfind(DIFF_OPERATOR) - union_pos = expression.rfind(UNION_OPERATOR) - op_pos = max(is_pos, diff_pos, union_pos) - s1 = expression[:op_pos] - s2 = expression[op_pos+len(IS_OPERATOR):] - op = expression[op_pos:op_pos+len(IS_OPERATOR)] - if not s2 in sets: - display_missing_pkg_set(root_config, s2) - return (None, 1) - expr_sets.insert(0, s2) - expr_ops.insert(0, op) - expression = s1 - if not expression in sets: - display_missing_pkg_set(root_config, expression) - return (None, 1) - expr_sets.insert(0, expression) - result = set(setconfig.getSetAtoms(expression)) - for i in range(0, len(expr_ops)): - s2 = setconfig.getSetAtoms(expr_sets[i+1]) - if expr_ops[i] == IS_OPERATOR: - result.intersection_update(s2) - elif expr_ops[i] == DIFF_OPERATOR: - result.difference_update(s2) - elif expr_ops[i] == UNION_OPERATOR: - result.update(s2) - else: - raise NotImplementedError("unknown set operator %s" % expr_ops[i]) - newargs.extend(result) - else: - s = a[len(SETPREFIX):] - if s not in sets: - display_missing_pkg_set(root_config, s) - return (None, 1) - setconfig.active.append(s) - try: - set_atoms = setconfig.getSetAtoms(s) - except portage.exception.PackageSetNotFound, e: - writemsg_level(("emerge: the given set '%s' " + \ - "contains a non-existent set named '%s'.\n") % \ - (s, e), level=logging.ERROR, noiselevel=-1) - return (None, 1) - if myaction in unmerge_actions and \ - not sets[s].supportsOperation("unmerge"): - sys.stderr.write("emerge: the given set '%s' does " % s + \ - "not support unmerge operations\n") - retval = 1 - elif not set_atoms: - print "emerge: '%s' is an empty set" % s - elif myaction not in do_not_expand: - newargs.extend(set_atoms) - else: - newargs.append(SETPREFIX+s) - for e in sets[s].errors: - print e - else: - newargs.append(a) - return (newargs, retval) - -def repo_name_check(trees): - missing_repo_names = set() - for root, root_trees in trees.iteritems(): - if "porttree" in root_trees: - portdb = root_trees["porttree"].dbapi - missing_repo_names.update(portdb.porttrees) - repos = portdb.getRepositories() - for r in repos: - missing_repo_names.discard(portdb.getRepositoryPath(r)) - if portdb.porttree_root in missing_repo_names and \ - not os.path.exists(os.path.join( - portdb.porttree_root, "profiles")): - # This is normal if $PORTDIR happens to be empty, - # so don't warn about it. - missing_repo_names.remove(portdb.porttree_root) - - if missing_repo_names: - msg = [] - msg.append("WARNING: One or more repositories " + \ - "have missing repo_name entries:") - msg.append("") - for p in missing_repo_names: - msg.append("\t%s/profiles/repo_name" % (p,)) - msg.append("") - msg.extend(textwrap.wrap("NOTE: Each repo_name entry " + \ - "should be a plain text file containing a unique " + \ - "name for the repository on the first line.", 70)) - writemsg_level("".join("%s\n" % l for l in msg), - level=logging.WARNING, noiselevel=-1) - - return bool(missing_repo_names) - -def repo_name_duplicate_check(trees): - ignored_repos = {} - for root, root_trees in trees.iteritems(): - if 'porttree' in root_trees: - portdb = root_trees['porttree'].dbapi - if portdb.mysettings.get('PORTAGE_REPO_DUPLICATE_WARN') != '0': - for repo_name, paths in portdb._ignored_repos: - k = (root, repo_name, portdb.getRepositoryPath(repo_name)) - ignored_repos.setdefault(k, []).extend(paths) - - if ignored_repos: - msg = [] - msg.append('WARNING: One or more repositories ' + \ - 'have been ignored due to duplicate') - msg.append(' profiles/repo_name entries:') - msg.append('') - for k in sorted(ignored_repos): - msg.append(' %s overrides' % (k,)) - for path in ignored_repos[k]: - msg.append(' %s' % (path,)) - msg.append('') - msg.extend(' ' + x for x in textwrap.wrap( - "All profiles/repo_name entries must be unique in order " + \ - "to avoid having duplicates ignored. " + \ - "Set PORTAGE_REPO_DUPLICATE_WARN=\"0\" in " + \ - "/etc/make.conf if you would like to disable this warning.")) - writemsg_level(''.join('%s\n' % l for l in msg), - level=logging.WARNING, noiselevel=-1) - - return bool(ignored_repos) - -def config_protect_check(trees): - for root, root_trees in trees.iteritems(): - if not root_trees["root_config"].settings.get("CONFIG_PROTECT"): - msg = "!!! CONFIG_PROTECT is empty" - if root != "/": - msg += " for '%s'" % root - writemsg_level(msg, level=logging.WARN, noiselevel=-1) - -def profile_check(trees, myaction, myopts): - if myaction in ("info", "sync"): - return os.EX_OK - elif "--version" in myopts or "--help" in myopts: - return os.EX_OK - for root, root_trees in trees.iteritems(): - if root_trees["root_config"].settings.profiles: - continue - # generate some profile related warning messages - validate_ebuild_environment(trees) - msg = "If you have just changed your profile configuration, you " + \ - "should revert back to the previous configuration. Due to " + \ - "your current profile being invalid, allowed actions are " + \ - "limited to --help, --info, --sync, and --version." - writemsg_level("".join("!!! %s\n" % l for l in textwrap.wrap(msg, 70)), - level=logging.ERROR, noiselevel=-1) - return 1 - return os.EX_OK - -def emerge_main(): - global portage # NFC why this is necessary now - genone - portage._disable_legacy_globals() - # Disable color until we're sure that it should be enabled (after - # EMERGE_DEFAULT_OPTS has been parsed). - portage.output.havecolor = 0 - # This first pass is just for options that need to be known as early as - # possible, such as --config-root. They will be parsed again later, - # together with EMERGE_DEFAULT_OPTS (which may vary depending on the - # the value of --config-root). - myaction, myopts, myfiles = parse_opts(sys.argv[1:], silent=True) - if "--debug" in myopts: - os.environ["PORTAGE_DEBUG"] = "1" - if "--config-root" in myopts: - os.environ["PORTAGE_CONFIGROOT"] = myopts["--config-root"] - if "--root" in myopts: - os.environ["ROOT"] = myopts["--root"] - - # Portage needs to ensure a sane umask for the files it creates. - os.umask(022) - settings, trees, mtimedb = load_emerge_config() - portdb = trees[settings["ROOT"]]["porttree"].dbapi - rval = profile_check(trees, myaction, myopts) - if rval != os.EX_OK: - return rval - - if portage._global_updates(trees, mtimedb["updates"]): - mtimedb.commit() - # Reload the whole config from scratch. - settings, trees, mtimedb = load_emerge_config(trees=trees) - portdb = trees[settings["ROOT"]]["porttree"].dbapi - - xterm_titles = "notitles" not in settings.features - - tmpcmdline = [] - if "--ignore-default-opts" not in myopts: - tmpcmdline.extend(settings["EMERGE_DEFAULT_OPTS"].split()) - tmpcmdline.extend(sys.argv[1:]) - myaction, myopts, myfiles = parse_opts(tmpcmdline) - - if "--digest" in myopts: - os.environ["FEATURES"] = os.environ.get("FEATURES","") + " digest" - # Reload the whole config from scratch so that the portdbapi internal - # config is updated with new FEATURES. - settings, trees, mtimedb = load_emerge_config(trees=trees) - portdb = trees[settings["ROOT"]]["porttree"].dbapi - - for myroot in trees: - mysettings = trees[myroot]["vartree"].settings - mysettings.unlock() - adjust_config(myopts, mysettings) - if '--pretend' not in myopts and myaction in \ - (None, 'clean', 'depclean', 'prune', 'unmerge'): - mysettings["PORTAGE_COUNTER_HASH"] = \ - trees[myroot]["vartree"].dbapi._counter_hash() - mysettings.backup_changes("PORTAGE_COUNTER_HASH") - mysettings.lock() - del myroot, mysettings - - apply_priorities(settings) - - spinner = stdout_spinner() - if "candy" in settings.features: - spinner.update = spinner.update_scroll - - if "--quiet" not in myopts: - portage.deprecated_profile_check(settings=settings) - repo_name_check(trees) - repo_name_duplicate_check(trees) - config_protect_check(trees) - - for mytrees in trees.itervalues(): - mydb = mytrees["porttree"].dbapi - # Freeze the portdbapi for performance (memoize all xmatch results). - mydb.freeze() - del mytrees, mydb - - if "moo" in myfiles: - print """ - - Larry loves Gentoo (""" + platform.system() + """) - - _______________________ -< Have you mooed today? > - ----------------------- - \ ^__^ - \ (oo)\_______ - (__)\ )\/\ - ||----w | - || || - -""" - - for x in myfiles: - ext = os.path.splitext(x)[1] - if (ext == ".ebuild" or ext == ".tbz2") and os.path.exists(os.path.abspath(x)): - print colorize("BAD", "\n*** emerging by path is broken and may not always work!!!\n") - break - - root_config = trees[settings["ROOT"]]["root_config"] - if myaction == "list-sets": - sys.stdout.write("".join("%s\n" % s for s in sorted(root_config.sets))) - sys.stdout.flush() - return os.EX_OK - - # only expand sets for actions taking package arguments - oldargs = myfiles[:] - if myaction in ("clean", "config", "depclean", "info", "prune", "unmerge", None): - myfiles, retval = expand_set_arguments(myfiles, myaction, root_config) - if retval != os.EX_OK: - return retval - - # Need to handle empty sets specially, otherwise emerge will react - # with the help message for empty argument lists - if oldargs and not myfiles: - print "emerge: no targets left after set expansion" - return 0 - - if ("--tree" in myopts) and ("--columns" in myopts): - print "emerge: can't specify both of \"--tree\" and \"--columns\"." - return 1 - - if ("--quiet" in myopts): - spinner.update = spinner.update_quiet - portage.util.noiselimit = -1 - - # Always create packages if FEATURES=buildpkg - # Imply --buildpkg if --buildpkgonly - if ("buildpkg" in settings.features) or ("--buildpkgonly" in myopts): - if "--buildpkg" not in myopts: - myopts["--buildpkg"] = True - - # Always try and fetch binary packages if FEATURES=getbinpkg - if ("getbinpkg" in settings.features): - myopts["--getbinpkg"] = True - - if "--buildpkgonly" in myopts: - # --buildpkgonly will not merge anything, so - # it cancels all binary package options. - for opt in ("--getbinpkg", "--getbinpkgonly", - "--usepkg", "--usepkgonly"): - myopts.pop(opt, None) - - if "--fetch-all-uri" in myopts: - myopts["--fetchonly"] = True - - if "--skipfirst" in myopts and "--resume" not in myopts: - myopts["--resume"] = True - - if ("--getbinpkgonly" in myopts) and not ("--usepkgonly" in myopts): - myopts["--usepkgonly"] = True - - if ("--getbinpkgonly" in myopts) and not ("--getbinpkg" in myopts): - myopts["--getbinpkg"] = True - - if ("--getbinpkg" in myopts) and not ("--usepkg" in myopts): - myopts["--usepkg"] = True - - # Also allow -K to apply --usepkg/-k - if ("--usepkgonly" in myopts) and not ("--usepkg" in myopts): - myopts["--usepkg"] = True - - # Allow -p to remove --ask - if "--pretend" in myopts: - myopts.pop("--ask", None) - - # forbid --ask when not in a terminal - # note: this breaks `emerge --ask | tee logfile`, but that doesn't work anyway. - if ("--ask" in myopts) and (not sys.stdin.isatty()): - portage.writemsg("!!! \"--ask\" should only be used in a terminal. Exiting.\n", - noiselevel=-1) - return 1 - - if settings.get("PORTAGE_DEBUG", "") == "1": - spinner.update = spinner.update_quiet - portage.debug=1 - if "python-trace" in settings.features: - import portage.debug - portage.debug.set_trace(True) - - if not ("--quiet" in myopts): - if not sys.stdout.isatty() or ("--nospinner" in myopts): - spinner.update = spinner.update_basic - - if myaction == 'version': - print getportageversion(settings["PORTDIR"], settings["ROOT"], - settings.profile_path, settings["CHOST"], - trees[settings["ROOT"]]["vartree"].dbapi) - return 0 - elif "--help" in myopts: - _emerge.help.help(myaction, myopts, portage.output.havecolor) - return 0 - - if "--debug" in myopts: - print "myaction", myaction - print "myopts", myopts - - if not myaction and not myfiles and "--resume" not in myopts: - _emerge.help.help(myaction, myopts, portage.output.havecolor) - return 1 - - pretend = "--pretend" in myopts - fetchonly = "--fetchonly" in myopts or "--fetch-all-uri" in myopts - buildpkgonly = "--buildpkgonly" in myopts - - # check if root user is the current user for the actions where emerge needs this - if portage.secpass < 2: - # We've already allowed "--version" and "--help" above. - if "--pretend" not in myopts and myaction not in ("search","info"): - need_superuser = myaction in ('clean', 'depclean', 'deselect', - 'prune', 'unmerge') or not \ - (fetchonly or \ - (buildpkgonly and secpass >= 1) or \ - myaction in ("metadata", "regen") or \ - (myaction == "sync" and os.access(settings["PORTDIR"], os.W_OK))) - if portage.secpass < 1 or \ - need_superuser: - if need_superuser: - access_desc = "superuser" - else: - access_desc = "portage group" - # Always show portage_group_warning() when only portage group - # access is required but the user is not in the portage group. - from portage.data import portage_group_warning - if "--ask" in myopts: - myopts["--pretend"] = True - del myopts["--ask"] - print ("%s access is required... " + \ - "adding --pretend to options\n") % access_desc - if portage.secpass < 1 and not need_superuser: - portage_group_warning() - else: - sys.stderr.write(("emerge: %s access is required\n") \ - % access_desc) - if portage.secpass < 1 and not need_superuser: - portage_group_warning() - return 1 - - disable_emergelog = False - for x in ("--pretend", "--fetchonly", "--fetch-all-uri"): - if x in myopts: - disable_emergelog = True - break - if myaction in ("search", "info"): - disable_emergelog = True - if disable_emergelog: - """ Disable emergelog for everything except build or unmerge - operations. This helps minimize parallel emerge.log entries that can - confuse log parsers. We especially want it disabled during - parallel-fetch, which uses --resume --fetchonly.""" - global emergelog - def emergelog(*pargs, **kargs): - pass - - else: - if 'EMERGE_LOG_DIR' in settings: - try: - # At least the parent needs to exist for the lock file. - portage.util.ensure_dirs(settings['EMERGE_LOG_DIR']) - except portage.exception.PortageException, e: - writemsg_level("!!! Error creating directory for " + \ - "EMERGE_LOG_DIR='%s':\n!!! %s\n" % \ - (settings['EMERGE_LOG_DIR'], e), - noiselevel=-1, level=logging.ERROR) - else: - global _emerge_log_dir - _emerge_log_dir = settings['EMERGE_LOG_DIR'] - - if not "--pretend" in myopts: - emergelog(xterm_titles, "Started emerge on: "+\ - time.strftime("%b %d, %Y %H:%M:%S", time.localtime())) - myelogstr="" - if myopts: - myelogstr=" ".join(myopts) - if myaction: - myelogstr+=" "+myaction - if myfiles: - myelogstr += " " + " ".join(oldargs) - emergelog(xterm_titles, " *** emerge " + myelogstr) - del oldargs - - def emergeexitsig(signum, frame): - signal.signal(signal.SIGINT, signal.SIG_IGN) - signal.signal(signal.SIGTERM, signal.SIG_IGN) - portage.util.writemsg("\n\nExiting on signal %(signal)s\n" % {"signal":signum}) - sys.exit(100+signum) - signal.signal(signal.SIGINT, emergeexitsig) - signal.signal(signal.SIGTERM, emergeexitsig) - - def emergeexit(): - """This gets out final log message in before we quit.""" - if "--pretend" not in myopts: - emergelog(xterm_titles, " *** terminating.") - if "notitles" not in settings.features: - xtermTitleReset() - portage.atexit_register(emergeexit) - - if myaction in ("config", "metadata", "regen", "sync"): - if "--pretend" in myopts: - sys.stderr.write(("emerge: The '%s' action does " + \ - "not support '--pretend'.\n") % myaction) - return 1 - - if "sync" == myaction: - return action_sync(settings, trees, mtimedb, myopts, myaction) - elif "metadata" == myaction: - action_metadata(settings, portdb, myopts) - elif myaction=="regen": - validate_ebuild_environment(trees) - return action_regen(settings, portdb, myopts.get("--jobs"), - myopts.get("--load-average")) - # HELP action - elif "config"==myaction: - validate_ebuild_environment(trees) - action_config(settings, trees, myopts, myfiles) - - # SEARCH action - elif "search"==myaction: - validate_ebuild_environment(trees) - action_search(trees[settings["ROOT"]]["root_config"], - myopts, myfiles, spinner) - - elif myaction in ('clean', 'depclean', 'deselect', 'prune', 'unmerge'): - validate_ebuild_environment(trees) - rval = action_uninstall(settings, trees, mtimedb["ldpath"], - myopts, myaction, myfiles, spinner) - if not (myaction == 'deselect' or buildpkgonly or fetchonly or pretend): - post_emerge(root_config, myopts, mtimedb, rval) - return rval - - elif myaction == 'info': - - # Ensure atoms are valid before calling unmerge(). - vardb = trees[settings["ROOT"]]["vartree"].dbapi - valid_atoms = [] - for x in myfiles: - if is_valid_package_atom(x): - try: - valid_atoms.append( - portage.dep_expand(x, mydb=vardb, settings=settings)) - except portage.exception.AmbiguousPackageName, e: - msg = "The short ebuild name \"" + x + \ - "\" is ambiguous. Please specify " + \ - "one of the following " + \ - "fully-qualified ebuild names instead:" - for line in textwrap.wrap(msg, 70): - writemsg_level("!!! %s\n" % (line,), - level=logging.ERROR, noiselevel=-1) - for i in e[0]: - writemsg_level(" %s\n" % colorize("INFORM", i), - level=logging.ERROR, noiselevel=-1) - writemsg_level("\n", level=logging.ERROR, noiselevel=-1) - return 1 - continue - msg = [] - msg.append("'%s' is not a valid package atom." % (x,)) - msg.append("Please check ebuild(5) for full details.") - writemsg_level("".join("!!! %s\n" % line for line in msg), - level=logging.ERROR, noiselevel=-1) - return 1 - - return action_info(settings, trees, myopts, valid_atoms) - - # "update", "system", or just process files: - else: - validate_ebuild_environment(trees) - - for x in myfiles: - if x.startswith(SETPREFIX) or \ - is_valid_package_atom(x): - continue - if x[:1] == os.sep: - continue - try: - os.lstat(x) - continue - except OSError: - pass - msg = [] - msg.append("'%s' is not a valid package atom." % (x,)) - msg.append("Please check ebuild(5) for full details.") - writemsg_level("".join("!!! %s\n" % line for line in msg), - level=logging.ERROR, noiselevel=-1) - return 1 - - if "--pretend" not in myopts: - display_news_notification(root_config, myopts) - retval = action_build(settings, trees, mtimedb, - myopts, myaction, myfiles, spinner) - root_config = trees[settings["ROOT"]]["root_config"] - post_emerge(root_config, myopts, mtimedb, retval) - - return retval -- cgit v1.2.3-1-g7c22