aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bersenev <bay@hackerdom.ru>2014-02-17 17:57:05 +0600
committerAlexander Bersenev <bay@hackerdom.ru>2014-02-17 17:57:05 +0600
commit6563293d18daed502ccdb663f3c72b4bae5fe23a (patch)
treed0a7d53a7c137feb4073c963408829f88ea75c92 /portage_with_autodep/pym/_emerge/main.py
parentupdated portage to 2.2.8-r1 (diff)
downloadautodep-master.tar.gz
autodep-master.tar.bz2
autodep-master.zip
updated portage to 2.2.8-r1HEADmaster
Diffstat (limited to 'portage_with_autodep/pym/_emerge/main.py')
-rw-r--r--portage_with_autodep/pym/_emerge/main.py1302
1 files changed, 147 insertions, 1155 deletions
diff --git a/portage_with_autodep/pym/_emerge/main.py b/portage_with_autodep/pym/_emerge/main.py
index c52a3ea..89413a9 100644
--- a/portage_with_autodep/pym/_emerge/main.py
+++ b/portage_with_autodep/pym/_emerge/main.py
@@ -1,52 +1,24 @@
-# Copyright 1999-2012 Gentoo Foundation
+# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from __future__ import print_function
-import logging
-import signal
-import stat
-import subprocess
-import sys
-import textwrap
import platform
+import sys
+
import portage
portage.proxy.lazyimport.lazyimport(globals(),
- 'portage.news:count_unread_news,display_news_notifications',
+ 'logging',
+ 'portage.dep:Atom',
+ 'portage.util:writemsg_level',
+ 'textwrap',
+ '_emerge.actions:load_emerge_config,run_action,' + \
+ 'validate_ebuild_environment',
+ '_emerge.help:help@emerge_help',
+ '_emerge.is_valid_package_atom:insert_category_into_atom'
)
from portage import os
-from portage import _encodings
-from portage import _unicode_decode
-import _emerge.help
-import portage.xpak, errno, re, time
-from portage.output import colorize, xtermTitle, xtermTitleReset
-from portage.output import create_color_func
-good = create_color_func("GOOD")
-bad = create_color_func("BAD")
-
-from portage.const import _ENABLE_DYN_LINK_MAP
-import portage.elog
-import portage.util
-import portage.locks
-import portage.exception
-from portage.data import secpass
-from portage.dbapi.dep_expand import dep_expand
-from portage.util import normalize_path as normpath
-from portage.util import (shlex_split, varexpand,
- writemsg_level, writemsg_stdout)
-from portage._sets import SETPREFIX
-from portage._global_updates import _global_updates
-
-from _emerge.actions import action_config, action_sync, action_metadata, \
- action_regen, action_search, action_uninstall, action_info, action_build, \
- adjust_configs, chk_updated_cfg_files, display_missing_pkg_set, \
- display_news_notification, getportageversion, load_emerge_config
-import _emerge
-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
-from _emerge.userquery import userquery
+from portage.util._argparse import ArgumentParser
if sys.hexversion >= 0x3000000:
long = int
@@ -60,6 +32,7 @@ options=[
"--debug",
"--digest",
"--emptytree",
+"--verbose-conflicts",
"--fetchonly", "--fetch-all-uri",
"--ignore-default-opts",
"--noconfmem",
@@ -75,7 +48,6 @@ options=[
"--tree",
"--unordered-display",
"--update",
-"--verbose",
"--verbose-main-repo-display",
]
@@ -96,7 +68,7 @@ shortmapping={
"s":"--search", "S":"--searchdesc",
"t":"--tree",
"u":"--update",
-"v":"--verbose", "V":"--version"
+"V":"--version"
}
COWSAY_MOO = """
@@ -114,325 +86,6 @@ COWSAY_MOO = """
"""
-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) and \
- not [x for x in os.listdir(inforoot) \
- if x.startswith('.keepinfodir')]:
- infomtime = os.stat(inforoot)[stat.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")
- if portage.util.noiselimit >= 0:
- out.einfo("GNU info directory index is up-to-date.")
- else:
- portage.writemsg_stdout("\n")
- if portage.util.noiselimit >= 0:
- 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 as e:
- if e.errno != errno.ENOENT:
- raise
- del e
- processed_count += 1
- try:
- proc = subprocess.Popen(
- ['/usr/bin/install-info',
- '--dir-file=%s' % os.path.join(inforoot, "dir"),
- os.path.join(inforoot, x)],
- env=dict(os.environ, LANG="C", LANGUAGE="C"),
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- except OSError:
- myso = None
- else:
- myso = _unicode_decode(
- proc.communicate()[0]).rstrip("\n")
- proc.wait()
- 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 as 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 as e:
- if e.errno != errno.ENOENT:
- raise
- del e
-
- #update mtime so we can potentially avoid regenerating.
- prev_mtimes[inforoot] = os.stat(inforoot)[stat.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 and portage.util.noiselimit >= 0:
- out.einfo("Processed %d info files." % (icount,))
-
-def display_preserved_libs(vardbapi, myopts):
- MAX_DISPLAY = 3
-
- if vardbapi._linkmap is None or \
- vardbapi._plib_registry is None:
- # preserve-libs is entirely disabled
- return
-
- # Explicitly load and prune the PreservedLibsRegistry in order
- # to ensure that we do not display stale data.
- vardbapi._plib_registry.load()
-
- if vardbapi._plib_registry.hasEntries():
- if "--quiet" in myopts:
- print()
- print(colorize("WARN", "!!!") + " existing preserved libs found")
- return
- else:
- print()
- print(colorize("WARN", "!!!") + " existing preserved libs:")
-
- plibdata = vardbapi._plib_registry.getPreservedLibs()
- linkmap = vardbapi._linkmap
- consumer_map = {}
- owners = {}
-
- try:
- linkmap.rebuild()
- except portage.exception.CommandNotFound as e:
- writemsg_level("!!! Command Not Found: %s\n" % (e,),
- level=logging.ERROR, noiselevel=-1)
- del e
- 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 = {}
- for f in search_for_owners:
- owner_set = set()
- for owner in linkmap.getOwners(f):
- owner_dblink = vardbapi._dblink(owner)
- if owner_dblink.exists():
- owner_set.add(owner_dblink)
- if owner_set:
- owners[f] = owner_set
-
- 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.values():
- 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(myaction, myopts, myfiles,
- target_root, trees, 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
-
- @param myaction: The action returned from parse_opts()
- @type myaction: String
- @param myopts: emerge options
- @type myopts: dict
- @param myfiles: emerge arguments
- @type myfiles: list
- @param target_root: The target EROOT for myaction
- @type target_root: String
- @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
- """
-
- root_config = trees[target_root]["root_config"]
- 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 = shlex_split(settings.get("CONFIG_PROTECT", ""))
- 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()
-
- if not vardbapi._pkgs_changed:
- # GLEP 42 says to display news *after* an emerge --pretend
- if "--pretend" in myopts:
- display_news_notification(root_config, myopts)
- # If vdb state has not changed then there's nothing else to do.
- return
-
- vdb_path = os.path.join(root_config.settings['EROOT'], 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:
- vardbapi.lock()
- vdb_lock = True
-
- 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:
- vardbapi.unlock()
-
- display_preserved_libs(vardbapi, myopts)
- chk_updated_cfg_files(settings['EROOT'], config_protect)
-
- display_news_notification(root_config, myopts)
-
- postemerge = os.path.join(settings["PORTAGE_CONFIGROOT"],
- portage.USER_CONFIG_PATH, "bin", "post_emerge")
- if os.access(postemerge, os.X_OK):
- hook_retval = portage.process.spawn(
- [postemerge], env=settings.environ())
- if hook_retval != os.EX_OK:
- writemsg_level(
- " %s spawn failed of %s\n" % (bad("*"), postemerge,),
- level=logging.ERROR, noiselevel=-1)
-
- clean_logs(settings)
-
- if "--quiet" not in myopts and \
- myaction is None and "@world" in myfiles:
- show_depclean_suggestion()
-
-def show_depclean_suggestion():
- out = portage.output.EOutput()
- msg = "After world updates, it is important to remove " + \
- "obsolete packages with emerge --depclean. Refer " + \
- "to `man emerge` for more information."
- for line in textwrap.wrap(msg, 72):
- out.ewarn(line)
-
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))
@@ -454,6 +107,16 @@ def insert_optional_args(args):
return False
valid_integers = valid_integers()
+
+ class valid_floats(object):
+ def __contains__(self, s):
+ try:
+ return float(s) >= 0
+ except (ValueError, OverflowError):
+ return False
+
+ valid_floats = valid_floats()
+
y_or_n = ('y', 'n',)
new_args = []
@@ -467,6 +130,7 @@ def insert_optional_args(args):
'--buildpkg' : y_or_n,
'--complete-graph' : y_or_n,
'--deep' : valid_integers,
+ '--depclean-lib-check' : y_or_n,
'--deselect' : y_or_n,
'--binpkg-respect-use' : y_or_n,
'--fail-clean' : y_or_n,
@@ -474,9 +138,12 @@ def insert_optional_args(args):
'--getbinpkgonly' : y_or_n,
'--jobs' : valid_integers,
'--keep-going' : y_or_n,
+ '--load-average' : valid_floats,
'--package-moves' : y_or_n,
'--quiet' : y_or_n,
'--quiet-build' : y_or_n,
+ '--quiet-fail' : y_or_n,
+ '--rebuild-if-new-slot': y_or_n,
'--rebuild-if-new-rev' : y_or_n,
'--rebuild-if-new-ver' : y_or_n,
'--rebuild-if-unbuilt' : y_or_n,
@@ -487,11 +154,9 @@ def insert_optional_args(args):
"--use-ebuild-visibility": y_or_n,
'--usepkg' : y_or_n,
'--usepkgonly' : y_or_n,
+ '--verbose' : y_or_n,
}
- if _ENABLE_DYN_LINK_MAP:
- default_arg_opts['--depclean-lib-check'] = y_or_n
-
short_arg_opts = {
'D' : valid_integers,
'j' : valid_integers,
@@ -507,6 +172,8 @@ def insert_optional_args(args):
'k' : y_or_n,
'K' : y_or_n,
'q' : y_or_n,
+ 'v' : y_or_n,
+ 'w' : y_or_n,
}
arg_stack = args[:]
@@ -595,14 +262,17 @@ def _find_bad_atoms(atoms, less_strict=False):
"""
bad_atoms = []
for x in ' '.join(atoms).split():
+ atom = x
+ if "/" not in x.split(":")[0]:
+ x_cat = insert_category_into_atom(x, 'dummy-category')
+ if x_cat is not None:
+ atom = x_cat
+
bad_atom = False
try:
- atom = portage.dep.Atom(x, allow_wildcard=True, allow_repo=less_strict)
+ atom = Atom(atom, allow_wildcard=True, allow_repo=less_strict)
except portage.exception.InvalidAtom:
- try:
- atom = portage.dep.Atom("*/"+x, allow_wildcard=True, allow_repo=less_strict)
- except portage.exception.InvalidAtom:
- bad_atom = True
+ bad_atom = True
if bad_atom or (atom.operator and not less_strict) or atom.blocker or atom.use:
bad_atoms.append(x)
@@ -630,31 +300,26 @@ def parse_opts(tmpcmdline, silent=False):
"--ask": {
"shortopt" : "-a",
"help" : "prompt before performing any actions",
- "type" : "choice",
"choices" : true_y_or_n
},
"--autounmask": {
"help" : "automatically unmask packages",
- "type" : "choice",
"choices" : true_y_or_n
},
"--autounmask-unrestricted-atoms": {
"help" : "write autounmask changes with >= atoms if possible",
- "type" : "choice",
"choices" : true_y_or_n
},
"--autounmask-keep-masks": {
"help" : "don't add package.unmask entries",
- "type" : "choice",
"choices" : true_y_or_n
},
"--autounmask-write": {
"help" : "write changes made by --autounmask to disk",
- "type" : "choice",
"choices" : true_y_or_n
},
@@ -663,6 +328,11 @@ def parse_opts(tmpcmdline, silent=False):
"action":"store"
},
+ "--accept-restrict": {
+ "help":"temporarily override ACCEPT_RESTRICT",
+ "action":"store"
+ },
+
"--backtrack": {
"help" : "Specifies how many times to backtrack if dependency " + \
@@ -674,7 +344,6 @@ def parse_opts(tmpcmdline, silent=False):
"--buildpkg": {
"shortopt" : "-b",
"help" : "build binary packages",
- "type" : "choice",
"choices" : true_y_or_n
},
@@ -692,19 +361,21 @@ def parse_opts(tmpcmdline, silent=False):
},
"--color": {
"help":"enable or disable color output",
- "type":"choice",
"choices":("y", "n")
},
"--complete-graph": {
"help" : "completely account for all known dependencies",
- "type" : "choice",
"choices" : true_y_or_n
},
+ "--complete-graph-if-new-use": {
+ "help" : "trigger --complete-graph behavior if USE or IUSE will change for an installed package",
+ "choices" : y_or_n
+ },
+
"--complete-graph-if-new-ver": {
"help" : "trigger --complete-graph behavior if an installed package version will change (upgrade or downgrade)",
- "type" : "choice",
"choices" : y_or_n
},
@@ -720,15 +391,18 @@ def parse_opts(tmpcmdline, silent=False):
"action" : "store"
},
+ "--depclean-lib-check": {
+ "help" : "check for consumers of libraries before removing them",
+ "choices" : true_y_or_n
+ },
+
"--deselect": {
"help" : "remove atoms/sets from the world file",
- "type" : "choice",
"choices" : true_y_or_n
},
"--dynamic-deps": {
"help": "substitute the dependencies of installed packages with the dependencies of unbuilt ebuilds",
- "type": "choice",
"choices": y_or_n
},
@@ -742,10 +416,18 @@ def parse_opts(tmpcmdline, silent=False):
"--fail-clean": {
"help" : "clean temp files after build failure",
- "type" : "choice",
"choices" : true_y_or_n
},
+ "--ignore-built-slot-operator-deps": {
+ "help": "Ignore the slot/sub-slot := operator parts of dependencies that have "
+ "been recorded when packages where built. This option is intended "
+ "only for debugging purposes, and it only affects built packages "
+ "that specify slot/sub-slot := operator dependencies using the "
+ "experimental \"4-slot-abi\" EAPI.",
+ "choices": y_or_n
+ },
+
"--jobs": {
"shortopt" : "-j",
@@ -758,7 +440,6 @@ def parse_opts(tmpcmdline, silent=False):
"--keep-going": {
"help" : "continue as much as possible after an error",
- "type" : "choice",
"choices" : true_y_or_n
},
@@ -773,18 +454,15 @@ def parse_opts(tmpcmdline, silent=False):
"--misspell-suggestions": {
"help" : "enable package name misspell suggestions",
- "type" : "choice",
"choices" : ("y", "n")
},
"--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"]
},
@@ -799,21 +477,18 @@ def parse_opts(tmpcmdline, silent=False):
"--binpkg-respect-use": {
"help" : "discard binary packages if their use flags \
don't match the current configuration",
- "type" : "choice",
"choices" : true_y_or_n
},
"--getbinpkg": {
"shortopt" : "-g",
"help" : "fetch binary packages",
- "type" : "choice",
"choices" : true_y_or_n
},
"--getbinpkgonly": {
"shortopt" : "-G",
"help" : "fetch binary packages only",
- "type" : "choice",
"choices" : true_y_or_n
},
@@ -842,29 +517,48 @@ def parse_opts(tmpcmdline, silent=False):
"--package-moves": {
"help" : "perform package moves when necessary",
- "type" : "choice",
"choices" : true_y_or_n
},
+ "--prefix": {
+ "help" : "specify the installation prefix",
+ "action" : "store"
+ },
+
+ "--pkg-format": {
+ "help" : "format of result binary package",
+ "action" : "store",
+ },
+
"--quiet": {
"shortopt" : "-q",
"help" : "reduced or condensed output",
- "type" : "choice",
"choices" : true_y_or_n
},
"--quiet-build": {
"help" : "redirect build output to logs",
- "type" : "choice",
"choices" : true_y_or_n,
},
+ "--quiet-fail": {
+ "help" : "suppresses display of the build log on stdout",
+ "choices" : true_y_or_n,
+ },
+
+ "--rebuild-if-new-slot": {
+ "help" : ("Automatically rebuild or reinstall packages when slot/sub-slot := "
+ "operator dependencies can be satisfied by a newer slot, so that "
+ "older packages slots will become eligible for removal by the "
+ "--depclean action as soon as possible."),
+ "choices" : true_y_or_n
+ },
+
"--rebuild-if-new-rev": {
"help" : "Rebuild packages when dependencies that are " + \
"used at both build-time and run-time are built, " + \
"if the dependency is not already installed with the " + \
"same version and revision.",
- "type" : "choice",
"choices" : true_y_or_n
},
@@ -873,21 +567,18 @@ def parse_opts(tmpcmdline, silent=False):
"used at both build-time and run-time are built, " + \
"if the dependency is not already installed with the " + \
"same version. Revision numbers are ignored.",
- "type" : "choice",
"choices" : true_y_or_n
},
"--rebuild-if-unbuilt": {
"help" : "Rebuild packages when dependencies that are " + \
"used at both build-time and run-time are built.",
- "type" : "choice",
"choices" : true_y_or_n
},
"--rebuilt-binaries": {
"help" : "replace installed packages with binary " + \
"packages that have been rebuilt",
- "type" : "choice",
"choices" : true_y_or_n
},
@@ -904,26 +595,23 @@ def parse_opts(tmpcmdline, silent=False):
"--root-deps": {
"help" : "modify interpretation of depedencies",
- "type" : "choice",
"choices" :("True", "rdeps")
},
"--select": {
+ "shortopt" : "-w",
"help" : "add specified packages to the world set " + \
"(inverse of --oneshot)",
- "type" : "choice",
"choices" : true_y_or_n
},
"--selective": {
"help" : "identical to --noreplace",
- "type" : "choice",
"choices" : true_y_or_n
},
"--use-ebuild-visibility": {
"help" : "use unbuilt ebuild metadata for visibility checks on built packages",
- "type" : "choice",
"choices" : true_y_or_n
},
@@ -937,42 +625,35 @@ def parse_opts(tmpcmdline, silent=False):
"--usepkg": {
"shortopt" : "-k",
"help" : "use binary packages",
- "type" : "choice",
"choices" : true_y_or_n
},
"--usepkgonly": {
"shortopt" : "-K",
"help" : "use only binary packages",
- "type" : "choice",
"choices" : true_y_or_n
},
+ "--verbose": {
+ "shortopt" : "-v",
+ "help" : "verbose output",
+ "choices" : true_y_or_n
+ },
}
- if _ENABLE_DYN_LINK_MAP:
- argument_options["--depclean-lib-check"] = {
- "help" : "check for consumers of libraries before removing them",
- "type" : "choice",
- "choices" : true_y_or_n
- }
-
- from optparse import OptionParser
- parser = OptionParser()
- if parser.has_option("--help"):
- parser.remove_option("--help")
+ parser = ArgumentParser(add_help=False)
for action_opt in actions:
- parser.add_option("--" + action_opt, action="store_true",
+ parser.add_argument("--" + action_opt, action="store_true",
dest=action_opt.replace("-", "_"), default=False)
for myopt in options:
- parser.add_option(myopt, action="store_true",
+ parser.add_argument(myopt, action="store_true",
dest=myopt.lstrip("--").replace("-", "_"), default=False)
for shortopt, longopt in shortmapping.items():
- parser.add_option("-" + shortopt, action="store_true",
+ parser.add_argument("-" + shortopt, action="store_true",
dest=longopt.lstrip("--").replace("-", "_"), default=False)
for myalias, myopt in longopt_aliases.items():
- parser.add_option(myalias, action="store_true",
+ parser.add_argument(myalias, action="store_true",
dest=myopt.lstrip("--").replace("-", "_"), default=False)
for myopt, kwargs in argument_options.items():
@@ -980,12 +661,12 @@ def parse_opts(tmpcmdline, silent=False):
args = [myopt]
if shortopt is not None:
args.append(shortopt)
- parser.add_option(dest=myopt.lstrip("--").replace("-", "_"),
+ parser.add_argument(dest=myopt.lstrip("--").replace("-", "_"),
*args, **kwargs)
tmpcmdline = insert_optional_args(tmpcmdline)
- myoptions, myargs = parser.parse_args(args=tmpcmdline)
+ myoptions, myargs = parser.parse_known_args(args=tmpcmdline)
if myoptions.ask in true_y:
myoptions.ask = True
@@ -1031,9 +712,8 @@ def parse_opts(tmpcmdline, silent=False):
else:
myoptions.complete_graph = None
- if _ENABLE_DYN_LINK_MAP:
- if myoptions.depclean_lib_check in true_y:
- myoptions.depclean_lib_check = True
+ if myoptions.depclean_lib_check in true_y:
+ myoptions.depclean_lib_check = True
if myoptions.exclude:
bad_atoms = _find_bad_atoms(myoptions.exclude)
@@ -1100,6 +780,12 @@ def parse_opts(tmpcmdline, silent=False):
if myoptions.quiet_build in true_y:
myoptions.quiet_build = 'y'
+ if myoptions.quiet_fail in true_y:
+ myoptions.quiet_fail = 'y'
+
+ if myoptions.rebuild_if_new_slot in true_y:
+ myoptions.rebuild_if_new_slot = 'y'
+
if myoptions.rebuild_if_new_ver in true_y:
myoptions.rebuild_if_new_ver = True
else:
@@ -1185,6 +871,9 @@ def parse_opts(tmpcmdline, silent=False):
myoptions.jobs = jobs
+ if myoptions.load_average == "True":
+ myoptions.load_average = None
+
if myoptions.load_average:
try:
load_average = float(myoptions.load_average)
@@ -1229,6 +918,11 @@ def parse_opts(tmpcmdline, silent=False):
else:
myoptions.usepkgonly = None
+ if myoptions.verbose in true_y:
+ myoptions.verbose = True
+ else:
+ myoptions.verbose = None
+
for myopt in options:
v = getattr(myoptions, myopt.lstrip("--").replace("-", "_"))
if v:
@@ -1253,320 +947,10 @@ def parse_opts(tmpcmdline, silent=False):
if myaction is None and myoptions.deselect is True:
myaction = 'deselect'
- if myargs and isinstance(myargs[0], bytes):
- for i in range(len(myargs)):
- myargs[i] = portage._unicode_decode(myargs[i])
-
myfiles += myargs
return myaction, myopts, myfiles
-# Warn about features that may confuse users and
-# lead them to report invalid bugs.
-_emerge_features_warn = frozenset(['keeptemp', 'keepwork'])
-
-def validate_ebuild_environment(trees):
- features_warn = set()
- for myroot in trees:
- settings = trees[myroot]["vartree"].settings
- settings.validate()
- features_warn.update(
- _emerge_features_warn.intersection(settings.features))
-
- if features_warn:
- msg = "WARNING: The FEATURES variable contains one " + \
- "or more values that should be disabled under " + \
- "normal circumstances: %s" % " ".join(features_warn)
- out = portage.output.EOutput()
- for line in textwrap.wrap(msg, 65):
- out.ewarn(line)
-
-def apply_priorities(settings):
- ionice(settings)
- nice(settings)
-
-def nice(settings):
- try:
- os.nice(int(settings.get("PORTAGE_NICENESS", "0")))
- except (OSError, ValueError) as 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 = portage.util.shlex_split(ionice_cmd)
- if not ionice_cmd:
- return
-
- 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 clean_logs(settings):
-
- if "clean-logs" not in settings.features:
- return
-
- clean_cmd = settings.get("PORT_LOGDIR_CLEAN")
- if clean_cmd:
- clean_cmd = shlex_split(clean_cmd)
- if not clean_cmd:
- return
-
- logdir = settings.get("PORT_LOGDIR")
- if logdir is None or not os.path.isdir(logdir):
- return
-
- variables = {"PORT_LOGDIR" : logdir}
- cmd = [varexpand(x, mydict=variables) for x in clean_cmd]
-
- try:
- rval = portage.process.spawn(cmd, env=os.environ)
- except portage.exception.CommandNotFound:
- rval = 127
-
- if rval != os.EX_OK:
- out = portage.output.EOutput()
- out.eerror("PORT_LOGDIR_CLEAN returned %d" % (rval,))
- out.eerror("See the make.conf(5) man page for "
- "PORT_LOGDIR_CLEAN usage instructions.")
-
-def setconfig_fallback(root_config):
- from portage._sets.base import DummyPackageSet
- from portage._sets.files import WorldSelectedSet
- from portage._sets.profiles import PackagesSystemSet
- setconfig = root_config.setconfig
- setconfig.psets['world'] = DummyPackageSet(atoms=['@selected', '@system'])
- setconfig.psets['selected'] = WorldSelectedSet(root_config.settings['EROOT'])
- setconfig.psets['system'] = \
- PackagesSystemSet(root_config.settings.profiles)
- root_config.sets = setconfig.getSets()
-
-def get_missing_sets(root_config):
- # emerge requires existence of "world", "selected", and "system"
- missing_sets = []
-
- for s in ("selected", "system", "world",):
- if s not in root_config.sets:
- missing_sets.append(s)
-
- return missing_sets
-
-def missing_sets_warning(root_config, 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 root_config.sets:
- msg.append(" sets defined: %s" % ", ".join(root_config.sets))
- global_config_path = portage.const.GLOBAL_CONFIG_PATH
- if root_config.settings['EPREFIX']:
- global_config_path = os.path.join(root_config.settings['EPREFIX'],
- portage.const.GLOBAL_CONFIG_PATH.lstrip(os.sep))
- msg.append(" This usually means that '%s'" % \
- (os.path.join(global_config_path, "sets/portage.conf"),))
- msg.append(" is missing or corrupt.")
- msg.append(" Falling back to default world and system set configuration!!!")
- for line in msg:
- writemsg_level(line + "\n", level=logging.ERROR, noiselevel=-1)
-
-def ensure_required_sets(trees):
- warning_shown = False
- for root_trees in trees.values():
- missing_sets = get_missing_sets(root_trees["root_config"])
- if missing_sets and not warning_shown:
- warning_shown = True
- missing_sets_warning(root_trees["root_config"], missing_sets)
- if missing_sets:
- setconfig_fallback(root_trees["root_config"])
-
-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 = "}"
-
- 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 occurred while loading the SetConfig instance
- for e in setconfig.errors:
- print(colorize("BAD", "Error during set creation: %s" % e))
-
- unmerge_actions = ("unmerge", "prune", "clean", "depclean")
-
- for a in myfiles:
- if a.startswith(SETPREFIX):
- 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 as 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_trees in trees.values():
- porttree = root_trees.get("porttree")
- if porttree:
- portdb = porttree.dbapi
- missing_repo_names.update(portdb.getMissingRepoNames())
- 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))
- msg.append("\n")
- 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.items():
- if 'porttree' in root_trees:
- portdb = root_trees['porttree'].dbapi
- if portdb.settings.get('PORTAGE_REPO_DUPLICATE_WARN') != '0':
- for repo_name, paths in portdb.getIgnoredRepos():
- 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' % ", ".join(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."))
- msg.append("\n")
- 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.items():
- settings = root_trees["root_config"].settings
- if not settings.get("CONFIG_PROTECT"):
- msg = "!!! CONFIG_PROTECT is empty"
- if settings["ROOT"] != "/":
- msg += " for '%s'" % root
- msg += "\n"
- writemsg_level(msg, level=logging.WARN, noiselevel=-1)
-
def profile_check(trees, myaction):
if myaction in ("help", "info", "search", "sync", "version"):
return os.EX_OK
@@ -1584,16 +968,6 @@ def profile_check(trees, myaction):
return 1
return os.EX_OK
-def check_procfs():
- procfs_path = '/proc'
- if platform.system() not in ("Linux",) or \
- os.path.ismount(procfs_path):
- return os.EX_OK
- msg = "It seems that %s is not mounted. You have been warned." % procfs_path
- writemsg_level("".join("!!! %s\n" % l for l in textwrap.wrap(msg, 70)),
- level=logging.ERROR, noiselevel=-1)
- return 1
-
def emerge_main(args=None):
"""
@param args: command arguments (default: sys.argv[1:])
@@ -1602,11 +976,12 @@ def emerge_main(args=None):
if args is None:
args = sys.argv[1:]
- portage._disable_legacy_globals()
- portage.dep._internal_warnings = True
+ args = portage._decode_argv(args)
+
# 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
@@ -1618,428 +993,45 @@ def emerge_main(args=None):
os.environ["PORTAGE_CONFIGROOT"] = myopts["--config-root"]
if "--root" in myopts:
os.environ["ROOT"] = myopts["--root"]
+ if "--prefix" in myopts:
+ os.environ["EPREFIX"] = myopts["--prefix"]
if "--accept-properties" in myopts:
os.environ["ACCEPT_PROPERTIES"] = myopts["--accept-properties"]
+ if "--accept-restrict" in myopts:
+ os.environ["ACCEPT_RESTRICT"] = myopts["--accept-restrict"]
+
+ # optimize --help (no need to load config / EMERGE_DEFAULT_OPTS)
+ if myaction == "help":
+ emerge_help()
+ return os.EX_OK
+ elif myaction == "moo":
+ print(COWSAY_MOO % platform.system())
+ return os.EX_OK
# Portage needs to ensure a sane umask for the files it creates.
os.umask(0o22)
- settings, trees, mtimedb = load_emerge_config()
- portdb = trees[settings['EROOT']]['porttree'].dbapi
- rval = profile_check(trees, myaction)
+ if myaction == "sync":
+ portage._sync_disabled_warnings = True
+ emerge_config = load_emerge_config(
+ action=myaction, args=myfiles, opts=myopts)
+ rval = profile_check(emerge_config.trees, emerge_config.action)
if rval != os.EX_OK:
return rval
tmpcmdline = []
if "--ignore-default-opts" not in myopts:
- tmpcmdline.extend(settings["EMERGE_DEFAULT_OPTS"].split())
+ tmpcmdline.extend(portage.util.shlex_split(
+ emerge_config.target_config.settings.get(
+ "EMERGE_DEFAULT_OPTS", "")))
tmpcmdline.extend(args)
- myaction, myopts, myfiles = parse_opts(tmpcmdline)
-
- # skip global updates prior to sync, since it's called after sync
- if myaction not in ('help', 'info', 'sync', 'version') and \
- myopts.get('--package-moves') != 'n' and \
- _global_updates(trees, mtimedb["updates"], quiet=("--quiet" in myopts)):
- mtimedb.commit()
- # Reload the whole config from scratch.
- settings, trees, mtimedb = load_emerge_config(trees=trees)
- portdb = trees[settings['EROOT']]['porttree'].dbapi
-
- xterm_titles = "notitles" not in settings.features
- if xterm_titles:
- xtermTitle("emerge")
-
- 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['EROOT']]['porttree'].dbapi
-
- # NOTE: adjust_configs() can map options to FEATURES, so any relevant
- # options adjustments should be made prior to calling adjust_configs().
- if "--buildpkgonly" in myopts:
- myopts["--buildpkg"] = True
-
- adjust_configs(myopts, trees)
- apply_priorities(settings)
-
- if myaction == 'version':
- writemsg_stdout(getportageversion(
- settings["PORTDIR"], None,
- settings.profile_path, settings["CHOST"],
- trees[settings['EROOT']]['vartree'].dbapi) + '\n', noiselevel=-1)
- return 0
- elif myaction == 'help':
- _emerge.help.help()
- return 0
-
- spinner = stdout_spinner()
- if "candy" in settings.features:
- spinner.update = spinner.update_scroll
-
- if "--quiet" not in myopts:
- portage.deprecated_profile_check(settings=settings)
- if portage.const._ENABLE_REPO_NAME_WARN:
- # Bug #248603 - Disable warnings about missing
- # repo_name entries for stable branch.
- repo_name_check(trees)
- repo_name_duplicate_check(trees)
- config_protect_check(trees)
- check_procfs()
-
- if "getbinpkg" in settings.features:
- myopts["--getbinpkg"] = True
-
- if "--getbinpkgonly" in myopts:
- myopts["--getbinpkg"] = True
-
- if "--getbinpkgonly" in myopts:
- myopts["--usepkgonly"] = True
-
- if "--getbinpkg" in myopts:
- myopts["--usepkg"] = True
-
- if "--usepkgonly" in myopts:
- myopts["--usepkg"] = 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)
-
- for mytrees in trees.values():
- mydb = mytrees["porttree"].dbapi
- # Freeze the portdbapi for performance (memoize all xmatch results).
- mydb.freeze()
-
- if myaction in ('search', None) and \
- "--usepkg" in myopts:
- # Populate the bintree with current --getbinpkg setting.
- # This needs to happen before expand_set_arguments(), in case
- # any sets use the bintree.
- mytrees["bintree"].populate(
- getbinpkgs="--getbinpkg" in myopts)
-
- del mytrees, mydb
-
- if "moo" in myfiles:
- print(COWSAY_MOO % platform.system())
- msg = ("The above `emerge moo` display is deprecated. "
- "Please use `emerge --moo` instead.")
- for line in textwrap.wrap(msg, 50):
- print(" %s %s" % (colorize("WARN", "*"), line))
-
- 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['EROOT']]['root_config']
- if myaction == "moo":
- print(COWSAY_MOO % platform.system())
- return os.EX_OK
- elif myaction == "list-sets":
- writemsg_stdout("".join("%s\n" % s for s in sorted(root_config.sets)))
- return os.EX_OK
- elif myaction == "check-news":
- news_counts = count_unread_news(
- root_config.trees["porttree"].dbapi,
- root_config.trees["vartree"].dbapi)
- if any(news_counts.values()):
- display_news_notifications(news_counts)
- elif "--quiet" not in myopts:
- print("", colorize("GOOD", "*"), "No news items were found.")
- return os.EX_OK
-
- ensure_required_sets(trees)
-
- # 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 '--emptytree' in myopts and '--noreplace' in myopts:
- writemsg_level("emerge: can't specify both of " + \
- "\"--emptytree\" and \"--noreplace\".\n",
- level=logging.ERROR, noiselevel=-1)
- return 1
+ emerge_config.action, emerge_config.opts, emerge_config.args = \
+ parse_opts(tmpcmdline)
- if ("--quiet" in myopts):
- spinner.update = spinner.update_quiet
- portage.util.noiselimit = -1
-
- if "--fetch-all-uri" in myopts:
- myopts["--fetchonly"] = True
-
- if "--skipfirst" in myopts and "--resume" not in myopts:
- myopts["--resume"] = 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.util.noiselimit = 0
- if "python-trace" in settings.features:
- import portage.debug as portage_debug
- portage_debug.set_trace(True)
-
- if not ("--quiet" in myopts):
- if '--nospinner' in myopts or \
- settings.get('TERM') == 'dumb' or \
- not sys.stdout.isatty():
- spinner.update = spinner.update_basic
-
- if "--debug" in myopts:
- print("myaction", myaction)
- print("myopts", myopts)
-
- if not myaction and not myfiles and "--resume" not in myopts:
- _emerge.help.help()
- 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", "sync"))
- 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:
- writemsg_stdout("This action requires %s access...\n" % \
- (access_desc,), noiselevel=-1)
- if portage.secpass < 1 and not need_superuser:
- portage_group_warning()
- if userquery("Would you like to add --pretend to options?",
- "--ask-enter-invalid" in myopts) == "No":
- return 128 + signal.SIGINT
- myopts["--pretend"] = True
- del myopts["--ask"]
- 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 for everything except build or unmerge operations.
- # This helps minimize parallel emerge.log entries that can confuse log
- # parsers like genlop.
- disable_emergelog = False
- for x in ("--pretend", "--fetchonly", "--fetch-all-uri"):
- if x in myopts:
- disable_emergelog = True
- break
- if disable_emergelog:
- pass
- elif myaction in ("search", "info"):
- disable_emergelog = True
- elif portage.data.secpass < 1:
- disable_emergelog = True
-
- _emerge.emergelog._disable = disable_emergelog
-
- if not disable_emergelog:
- 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 as e:
- writemsg_level("!!! Error creating directory for " + \
- "EMERGE_LOG_DIR='%s':\n!!! %s\n" % \
- (settings['EMERGE_LOG_DIR'], e),
- noiselevel=-1, level=logging.ERROR)
- portage.util.ensure_dirs(_emerge.emergelog._emerge_log_dir)
- else:
- _emerge.emergelog._emerge_log_dir = settings["EMERGE_LOG_DIR"]
- else:
- _emerge.emergelog._emerge_log_dir = os.path.join(os.sep,
- settings["EPREFIX"].lstrip(os.sep), "var", "log")
- portage.util.ensure_dirs(_emerge.emergelog._emerge_log_dir)
-
- if not "--pretend" in myopts:
- emergelog(xterm_titles, "Started emerge on: "+\
- _unicode_decode(
- time.strftime("%b %d, %Y %H:%M:%S", time.localtime()),
- encoding=_encodings['content'], errors='replace'))
- myelogstr=""
- if myopts:
- opt_list = []
- for opt, arg in myopts.items():
- if arg is True:
- opt_list.append(opt)
- elif isinstance(arg, list):
- # arguments like --exclude that use 'append' action
- for x in arg:
- opt_list.append("%s=%s" % (opt, x))
- else:
- opt_list.append("%s=%s" % (opt, arg))
- myelogstr=" ".join(opt_list)
- 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(128 + 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 xterm_titles:
- 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['EROOT']]['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(myaction, myopts, myfiles, settings['EROOT'],
- trees, mtimedb, rval)
- return rval
-
- elif myaction == 'info':
-
- # Ensure atoms are valid before calling unmerge().
- vardb = trees[settings['EROOT']]['vartree'].dbapi
- portdb = trees[settings['EROOT']]['porttree'].dbapi
- bindb = trees[settings['EROOT']]["bintree"].dbapi
- valid_atoms = []
- for x in myfiles:
- if is_valid_package_atom(x, allow_repo=True):
- try:
- #look at the installed files first, if there is no match
- #look at the ebuilds, since EAPI 4 allows running pkg_info
- #on non-installed packages
- valid_atom = dep_expand(x, mydb=vardb, settings=settings)
- if valid_atom.cp.split("/")[0] == "null":
- valid_atom = dep_expand(x, mydb=portdb, settings=settings)
- if valid_atom.cp.split("/")[0] == "null" and "--usepkg" in myopts:
- valid_atom = dep_expand(x, mydb=bindb, settings=settings)
- valid_atoms.append(valid_atom)
- except portage.exception.AmbiguousPackageName as 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.args[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, allow_repo=True):
- continue
- if x[:1] == os.sep:
- continue
- try:
- os.lstat(x)
+ try:
+ return run_action(emerge_config)
+ finally:
+ # Call destructors for our portdbapi instances.
+ for x in emerge_config.trees.values():
+ if "porttree" in x.lazy_items:
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
-
- # GLEP 42 says to display news *after* an emerge --pretend
- if "--pretend" not in myopts:
- display_news_notification(root_config, myopts)
- retval = action_build(settings, trees, mtimedb,
- myopts, myaction, myfiles, spinner)
- post_emerge(myaction, myopts, myfiles, settings['EROOT'],
- trees, mtimedb, retval)
-
- return retval
+ x["porttree"].dbapi.close_caches()