summaryrefslogtreecommitdiffstats
path: root/pym/_emerge/__init__.py
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2009-06-23 18:52:20 +0000
committerZac Medico <zmedico@gentoo.org>2009-06-23 18:52:20 +0000
commitd00f9c88bc5ccd132d8bd8ee858dad2ac8aab8df (patch)
treea86d7fc39d3ad35d2a5698e8bfbd2cb2fc8eaf8e /pym/_emerge/__init__.py
parent6ca0735178ef51c087f35c2bbf2bca415bd4ab55 (diff)
downloadportage-d00f9c88bc5ccd132d8bd8ee858dad2ac8aab8df.tar.gz
portage-d00f9c88bc5ccd132d8bd8ee858dad2ac8aab8df.tar.bz2
portage-d00f9c88bc5ccd132d8bd8ee858dad2ac8aab8df.zip
Bug #275047 - Split _emerge/__init__.py into smaller pieces (part 6).
Thanks to Sebastian Mingramm (few) <s.mingramm@gmx.de> for this patch. svn path=/main/trunk/; revision=13673
Diffstat (limited to 'pym/_emerge/__init__.py')
-rw-r--r--pym/_emerge/__init__.py2714
1 files changed, 10 insertions, 2704 deletions
diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py
index 47c20a2f3..622c1c6e1 100644
--- a/pym/_emerge/__init__.py
+++ b/pym/_emerge/__init__.py
@@ -4,12 +4,11 @@
# $Id$
import logging
-import pwd
import shlex
import signal
import sys
import textwrap
-import os, stat
+import os
import platform
try:
@@ -19,13 +18,9 @@ except ImportError:
sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
import portage
-from portage import digraph
-from portage.const import NEWS_LIB_PATH
-
import _emerge.help
-import portage.xpak, commands, errno, re, socket, time
-from portage.output import blue, bold, colorize, darkgreen, \
- red, xtermTitleReset, yellow
+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")
@@ -36,37 +31,19 @@ portage.dep._dep_check_strict = True
import portage.util
import portage.locks
import portage.exception
-from portage.cache.cache_errors import CacheError
from portage.data import secpass
from portage.util import normalize_path as normpath
-from portage.util import cmp_sort_key, writemsg, writemsg_level
-from portage.sets import load_default_config, SETPREFIX
-from portage.sets.base import InternalPackageSet
-
-from itertools import chain, izip
-
-from _emerge.clear_caches import clear_caches
-from _emerge.countdown import countdown
-from _emerge.create_depgraph_params import create_depgraph_params
-from _emerge.Dependency import Dependency
-from _emerge.depgraph import depgraph, resume_depgraph
-from _emerge.DepPrioritySatisfiedRange import DepPrioritySatisfiedRange
+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.MetadataRegen import MetadataRegen
-from _emerge.Package import Package
-from _emerge.ProgressHandler import ProgressHandler
-from _emerge.RootConfig import RootConfig
-from _emerge.Scheduler import Scheduler
-from _emerge.search import search
-from _emerge.SetArg import SetArg
-from _emerge.show_invalid_depstring_notice import show_invalid_depstring_notice
from _emerge.stdout_spinner import stdout_spinner
-from _emerge.unmerge import unmerge
-from _emerge.UnmergeDepPriority import UnmergeDepPriority
-from _emerge.UseFlagDisplay import UseFlagDisplay
-from _emerge.userquery import userquery
actions = frozenset([
@@ -123,69 +100,6 @@ shortmapping={
"v":"--verbose", "V":"--version"
}
-def getgccversion(chost):
- """
- rtype: C{str}
- return: the current in-use gcc version
- """
-
- gcc_ver_command = 'gcc -dumpversion'
- gcc_ver_prefix = 'gcc-'
-
- gcc_not_found_error = red(
- "!!! No gcc found. You probably need to 'source /etc/profile'\n" +
- "!!! to update the environment of this terminal and possibly\n" +
- "!!! other terminals also.\n"
- )
-
- mystatus, myoutput = commands.getstatusoutput("gcc-config -c")
- if mystatus == os.EX_OK and myoutput.startswith(chost + "-"):
- return myoutput.replace(chost + "-", gcc_ver_prefix, 1)
-
- mystatus, myoutput = commands.getstatusoutput(
- chost + "-" + gcc_ver_command)
- if mystatus == os.EX_OK:
- return gcc_ver_prefix + myoutput
-
- mystatus, myoutput = commands.getstatusoutput(gcc_ver_command)
- if mystatus == os.EX_OK:
- return gcc_ver_prefix + myoutput
-
- portage.writemsg(gcc_not_found_error, noiselevel=-1)
- return "[unavailable]"
-
-def getportageversion(portdir, target_root, profile, chost, vardb):
- profilever = "unavailable"
- if profile:
- realpath = os.path.realpath(profile)
- basepath = os.path.realpath(os.path.join(portdir, "profiles"))
- if realpath.startswith(basepath):
- profilever = realpath[1 + len(basepath):]
- else:
- try:
- profilever = "!" + os.readlink(profile)
- except (OSError):
- pass
- del realpath, basepath
-
- libcver=[]
- libclist = vardb.match("virtual/libc")
- libclist += vardb.match("virtual/glibc")
- libclist = portage.util.unique_array(libclist)
- for x in libclist:
- xs=portage.catpkgsplit(x)
- if libcver:
- libcver+=","+"-".join(xs[1:])
- else:
- libcver="-".join(xs[1:])
- if libcver==[]:
- libcver="unavailable"
-
- gccver = getgccversion(chost)
- unameout=platform.release()+" "+platform.machine()
-
- return "Portage " + portage.VERSION +" ("+profilever+", "+gccver+", "+libcver+", "+unameout+")"
-
def chk_updated_info_files(root, infodirs, prev_mtimes, retval):
if os.path.exists("/usr/bin/install-info"):
@@ -297,33 +211,6 @@ def chk_updated_info_files(root, infodirs, prev_mtimes, retval):
out.einfo("Processed %d info files." % (icount,))
-def display_news_notification(root_config, myopts):
- target_root = root_config.root
- trees = root_config.trees
- settings = trees["vartree"].settings
- portdb = trees["porttree"].dbapi
- vardb = trees["vartree"].dbapi
- NEWS_PATH = os.path.join("metadata", "news")
- UNREAD_PATH = os.path.join(target_root, NEWS_LIB_PATH, "news")
- newsReaderDisplay = False
- update = "--pretend" not in myopts
-
- for repo in portdb.getRepositories():
- unreadItems = checkUpdatedNewsItems(
- portdb, vardb, NEWS_PATH, UNREAD_PATH, repo, update=update)
- if unreadItems:
- if not newsReaderDisplay:
- newsReaderDisplay = True
- print
- print colorize("WARN", " * IMPORTANT:"),
- print "%s news items need reading for repository '%s'." % (unreadItems, repo)
-
-
- if newsReaderDisplay:
- print colorize("WARN", " *"),
- print "Use " + colorize("GOOD", "eselect news") + " to read news items."
- print
-
def display_preserved_libs(vardbapi):
MAX_DISPLAY = 3
@@ -475,2458 +362,6 @@ def post_emerge(root_config, myopts, mtimedb, retval):
sys.exit(retval)
-def chk_updated_cfg_files(target_root, config_protect):
- if config_protect:
- #number of directories with some protect files in them
- procount=0
- for x in config_protect:
- x = os.path.join(target_root, x.lstrip(os.path.sep))
- if not os.access(x, os.W_OK):
- # Avoid Permission denied errors generated
- # later by `find`.
- continue
- try:
- mymode = os.lstat(x).st_mode
- except OSError:
- continue
- if stat.S_ISLNK(mymode):
- # We want to treat it like a directory if it
- # is a symlink to an existing directory.
- try:
- real_mode = os.stat(x).st_mode
- if stat.S_ISDIR(real_mode):
- mymode = real_mode
- except OSError:
- pass
- if stat.S_ISDIR(mymode):
- mycommand = "find '%s' -name '.*' -type d -prune -o -name '._cfg????_*'" % x
- else:
- mycommand = "find '%s' -maxdepth 1 -name '._cfg????_%s'" % \
- os.path.split(x.rstrip(os.path.sep))
- mycommand += " ! -name '.*~' ! -iname '.*.bak' -print0"
- a = commands.getstatusoutput(mycommand)
- if a[0] != 0:
- sys.stderr.write(" %s error scanning '%s': " % (bad("*"), x))
- sys.stderr.flush()
- # Show the error message alone, sending stdout to /dev/null.
- os.system(mycommand + " 1>/dev/null")
- else:
- files = a[1].split('\0')
- # split always produces an empty string as the last element
- if files and not files[-1]:
- del files[-1]
- if files:
- procount += 1
- print "\n"+colorize("WARN", " * IMPORTANT:"),
- if stat.S_ISDIR(mymode):
- print "%d config files in '%s' need updating." % \
- (len(files), x)
- else:
- print "config file '%s' needs updating." % x
-
- if procount:
- print " "+yellow("*")+" See the "+colorize("INFORM","CONFIGURATION FILES")+ \
- " section of the " + bold("emerge")
- print " "+yellow("*")+" man page to learn how to update config files."
-
-def checkUpdatedNewsItems(portdb, vardb, NEWS_PATH, UNREAD_PATH, repo_id,
- update=False):
- """
- Examines news items in repodir + '/' + NEWS_PATH and attempts to find unread items
- Returns the number of unread (yet relevent) items.
-
- @param portdb: a portage tree database
- @type portdb: pordbapi
- @param vardb: an installed package database
- @type vardb: vardbapi
- @param NEWS_PATH:
- @type NEWS_PATH:
- @param UNREAD_PATH:
- @type UNREAD_PATH:
- @param repo_id:
- @type repo_id:
- @rtype: Integer
- @returns:
- 1. The number of unread but relevant news items.
-
- """
- from portage.news import NewsManager
- manager = NewsManager(portdb, vardb, NEWS_PATH, UNREAD_PATH)
- return manager.getUnreadItems( repo_id, update=update )
-
-def action_sync(settings, trees, mtimedb, myopts, myaction):
- xterm_titles = "notitles" not in settings.features
- emergelog(xterm_titles, " === sync")
- portdb = trees[settings["ROOT"]]["porttree"].dbapi
- myportdir = portdb.porttree_root
- out = portage.output.EOutput()
- if not myportdir:
- sys.stderr.write("!!! PORTDIR is undefined. Is /etc/make.globals missing?\n")
- sys.exit(1)
- if myportdir[-1]=="/":
- myportdir=myportdir[:-1]
- try:
- st = os.stat(myportdir)
- except OSError:
- st = None
- if st is None:
- print ">>>",myportdir,"not found, creating it."
- os.makedirs(myportdir,0755)
- st = os.stat(myportdir)
-
- spawn_kwargs = {}
- spawn_kwargs["env"] = settings.environ()
- if 'usersync' in settings.features and \
- portage.data.secpass >= 2 and \
- (st.st_uid != os.getuid() and st.st_mode & 0700 or \
- st.st_gid != os.getgid() and st.st_mode & 0070):
- try:
- homedir = pwd.getpwuid(st.st_uid).pw_dir
- except KeyError:
- pass
- else:
- # Drop privileges when syncing, in order to match
- # existing uid/gid settings.
- spawn_kwargs["uid"] = st.st_uid
- spawn_kwargs["gid"] = st.st_gid
- spawn_kwargs["groups"] = [st.st_gid]
- spawn_kwargs["env"]["HOME"] = homedir
- umask = 0002
- if not st.st_mode & 0020:
- umask = umask | 0020
- spawn_kwargs["umask"] = umask
-
- syncuri = settings.get("SYNC", "").strip()
- if not syncuri:
- writemsg_level("!!! SYNC is undefined. Is /etc/make.globals missing?\n",
- noiselevel=-1, level=logging.ERROR)
- return 1
-
- vcs_dirs = frozenset([".git", ".svn", "CVS", ".hg"])
- vcs_dirs = vcs_dirs.intersection(os.listdir(myportdir))
-
- os.umask(0022)
- dosyncuri = syncuri
- updatecache_flg = False
- if myaction == "metadata":
- print "skipping sync"
- updatecache_flg = True
- elif ".git" in vcs_dirs:
- # Update existing git repository, and ignore the syncuri. We are
- # going to trust the user and assume that the user is in the branch
- # that he/she wants updated. We'll let the user manage branches with
- # git directly.
- if portage.process.find_binary("git") is None:
- msg = ["Command not found: git",
- "Type \"emerge dev-util/git\" to enable git support."]
- for l in msg:
- writemsg_level("!!! %s\n" % l,
- level=logging.ERROR, noiselevel=-1)
- return 1
- msg = ">>> Starting git pull in %s..." % myportdir
- emergelog(xterm_titles, msg )
- writemsg_level(msg + "\n")
- exitcode = portage.process.spawn_bash("cd %s ; git pull" % \
- (portage._shell_quote(myportdir),), **spawn_kwargs)
- if exitcode != os.EX_OK:
- msg = "!!! git pull error in %s." % myportdir
- emergelog(xterm_titles, msg)
- writemsg_level(msg + "\n", level=logging.ERROR, noiselevel=-1)
- return exitcode
- msg = ">>> Git pull in %s successful" % myportdir
- emergelog(xterm_titles, msg)
- writemsg_level(msg + "\n")
- exitcode = git_sync_timestamps(settings, myportdir)
- if exitcode == os.EX_OK:
- updatecache_flg = True
- elif syncuri[:8]=="rsync://":
- for vcs_dir in vcs_dirs:
- writemsg_level(("!!! %s appears to be under revision " + \
- "control (contains %s).\n!!! Aborting rsync sync.\n") % \
- (myportdir, vcs_dir), level=logging.ERROR, noiselevel=-1)
- return 1
- if not os.path.exists("/usr/bin/rsync"):
- print "!!! /usr/bin/rsync does not exist, so rsync support is disabled."
- print "!!! Type \"emerge net-misc/rsync\" to enable rsync support."
- sys.exit(1)
- mytimeout=180
-
- rsync_opts = []
- if settings["PORTAGE_RSYNC_OPTS"] == "":
- portage.writemsg("PORTAGE_RSYNC_OPTS empty or unset, using hardcoded defaults\n")
- rsync_opts.extend([
- "--recursive", # Recurse directories
- "--links", # Consider symlinks
- "--safe-links", # Ignore links outside of tree
- "--perms", # Preserve permissions
- "--times", # Preserive mod times
- "--compress", # Compress the data transmitted
- "--force", # Force deletion on non-empty dirs
- "--whole-file", # Don't do block transfers, only entire files
- "--delete", # Delete files that aren't in the master tree
- "--stats", # Show final statistics about what was transfered
- "--timeout="+str(mytimeout), # IO timeout if not done in X seconds
- "--exclude=/distfiles", # Exclude distfiles from consideration
- "--exclude=/local", # Exclude local from consideration
- "--exclude=/packages", # Exclude packages from consideration
- ])
-
- else:
- # The below validation is not needed when using the above hardcoded
- # defaults.
-
- portage.writemsg("Using PORTAGE_RSYNC_OPTS instead of hardcoded defaults\n", 1)
- rsync_opts.extend(
- shlex.split(settings.get("PORTAGE_RSYNC_OPTS","")))
- for opt in ("--recursive", "--times"):
- if opt not in rsync_opts:
- portage.writemsg(yellow("WARNING:") + " adding required option " + \
- "%s not included in PORTAGE_RSYNC_OPTS\n" % opt)
- rsync_opts.append(opt)
-
- for exclude in ("distfiles", "local", "packages"):
- opt = "--exclude=/%s" % exclude
- if opt not in rsync_opts:
- portage.writemsg(yellow("WARNING:") + \
- " adding required option %s not included in " % opt + \
- "PORTAGE_RSYNC_OPTS (can be overridden with --exclude='!')\n")
- rsync_opts.append(opt)
-
- if syncuri.rstrip("/").endswith(".gentoo.org/gentoo-portage"):
- def rsync_opt_startswith(opt_prefix):
- for x in rsync_opts:
- if x.startswith(opt_prefix):
- return True
- return False
-
- if not rsync_opt_startswith("--timeout="):
- rsync_opts.append("--timeout=%d" % mytimeout)
-
- for opt in ("--compress", "--whole-file"):
- if opt not in rsync_opts:
- portage.writemsg(yellow("WARNING:") + " adding required option " + \
- "%s not included in PORTAGE_RSYNC_OPTS\n" % opt)
- rsync_opts.append(opt)
-
- if "--quiet" in myopts:
- rsync_opts.append("--quiet") # Shut up a lot
- else:
- rsync_opts.append("--verbose") # Print filelist
-
- if "--verbose" in myopts:
- rsync_opts.append("--progress") # Progress meter for each file
-
- if "--debug" in myopts:
- rsync_opts.append("--checksum") # Force checksum on all files
-
- # Real local timestamp file.
- servertimestampfile = os.path.join(
- myportdir, "metadata", "timestamp.chk")
-
- content = portage.util.grabfile(servertimestampfile)
- mytimestamp = 0
- if content:
- try:
- mytimestamp = time.mktime(time.strptime(content[0],
- "%a, %d %b %Y %H:%M:%S +0000"))
- except (OverflowError, ValueError):
- pass
- del content
-
- try:
- rsync_initial_timeout = \
- int(settings.get("PORTAGE_RSYNC_INITIAL_TIMEOUT", "15"))
- except ValueError:
- rsync_initial_timeout = 15
-
- try:
- maxretries=int(settings["PORTAGE_RSYNC_RETRIES"])
- except SystemExit, e:
- raise # Needed else can't exit
- except:
- maxretries=3 #default number of retries
-
- retries=0
- user_name, hostname, port = re.split(
- "rsync://([^:/]+@)?([^:/]*)(:[0-9]+)?", syncuri, maxsplit=3)[1:4]
- if port is None:
- port=""
- if user_name is None:
- user_name=""
- updatecache_flg=True
- all_rsync_opts = set(rsync_opts)
- extra_rsync_opts = shlex.split(
- settings.get("PORTAGE_RSYNC_EXTRA_OPTS",""))
- all_rsync_opts.update(extra_rsync_opts)
- family = socket.AF_INET
- if "-4" in all_rsync_opts or "--ipv4" in all_rsync_opts:
- family = socket.AF_INET
- elif socket.has_ipv6 and \
- ("-6" in all_rsync_opts or "--ipv6" in all_rsync_opts):
- family = socket.AF_INET6
- ips=[]
- SERVER_OUT_OF_DATE = -1
- EXCEEDED_MAX_RETRIES = -2
- while (1):
- if ips:
- del ips[0]
- if ips==[]:
- try:
- for addrinfo in socket.getaddrinfo(
- hostname, None, family, socket.SOCK_STREAM):
- if socket.has_ipv6 and addrinfo[0] == socket.AF_INET6:
- # IPv6 addresses need to be enclosed in square brackets
- ips.append("[%s]" % addrinfo[4][0])
- else:
- ips.append(addrinfo[4][0])
- from random import shuffle
- shuffle(ips)
- except SystemExit, e:
- raise # Needed else can't exit
- except Exception, e:
- print "Notice:",str(e)
- dosyncuri=syncuri
-
- if ips:
- try:
- dosyncuri = syncuri.replace(
- "//" + user_name + hostname + port + "/",
- "//" + user_name + ips[0] + port + "/", 1)
- except SystemExit, e:
- raise # Needed else can't exit
- except Exception, e:
- print "Notice:",str(e)
- dosyncuri=syncuri
-
- if (retries==0):
- if "--ask" in myopts:
- if userquery("Do you want to sync your Portage tree with the mirror at\n" + blue(dosyncuri) + bold("?"))=="No":
- print
- print "Quitting."
- print
- sys.exit(0)
- emergelog(xterm_titles, ">>> Starting rsync with " + dosyncuri)
- if "--quiet" not in myopts:
- print ">>> Starting rsync with "+dosyncuri+"..."
- else:
- emergelog(xterm_titles,
- ">>> Starting retry %d of %d with %s" % \
- (retries,maxretries,dosyncuri))
- print "\n\n>>> Starting retry %d of %d with %s" % (retries,maxretries,dosyncuri)
-
- if mytimestamp != 0 and "--quiet" not in myopts:
- print ">>> Checking server timestamp ..."
-
- rsynccommand = ["/usr/bin/rsync"] + rsync_opts + extra_rsync_opts
-
- if "--debug" in myopts:
- print rsynccommand
-
- exitcode = os.EX_OK
- servertimestamp = 0
- # Even if there's no timestamp available locally, fetch the
- # timestamp anyway as an initial probe to verify that the server is
- # responsive. This protects us from hanging indefinitely on a
- # connection attempt to an unresponsive server which rsync's
- # --timeout option does not prevent.
- if True:
- # Temporary file for remote server timestamp comparison.
- from tempfile import mkstemp
- fd, tmpservertimestampfile = mkstemp()
- os.close(fd)
- mycommand = rsynccommand[:]
- mycommand.append(dosyncuri.rstrip("/") + \
- "/metadata/timestamp.chk")
- mycommand.append(tmpservertimestampfile)
- content = None
- mypids = []
- try:
- def timeout_handler(signum, frame):
- raise portage.exception.PortageException("timed out")
- signal.signal(signal.SIGALRM, timeout_handler)
- # Timeout here in case the server is unresponsive. The
- # --timeout rsync option doesn't apply to the initial
- # connection attempt.
- if rsync_initial_timeout:
- signal.alarm(rsync_initial_timeout)
- try:
- mypids.extend(portage.process.spawn(
- mycommand, env=settings.environ(), returnpid=True))
- exitcode = os.waitpid(mypids[0], 0)[1]
- content = portage.grabfile(tmpservertimestampfile)
- finally:
- if rsync_initial_timeout:
- signal.alarm(0)
- try:
- os.unlink(tmpservertimestampfile)
- except OSError:
- pass
- except portage.exception.PortageException, e:
- # timed out
- print e
- del e
- if mypids and os.waitpid(mypids[0], os.WNOHANG) == (0,0):
- os.kill(mypids[0], signal.SIGTERM)
- os.waitpid(mypids[0], 0)
- # This is the same code rsync uses for timeout.
- exitcode = 30
- else:
- if exitcode != os.EX_OK:
- if exitcode & 0xff:
- exitcode = (exitcode & 0xff) << 8
- else:
- exitcode = exitcode >> 8
- if mypids:
- portage.process.spawned_pids.remove(mypids[0])
- if content:
- try:
- servertimestamp = time.mktime(time.strptime(
- content[0], "%a, %d %b %Y %H:%M:%S +0000"))
- except (OverflowError, ValueError):
- pass
- del mycommand, mypids, content
- if exitcode == os.EX_OK:
- if (servertimestamp != 0) and (servertimestamp == mytimestamp):
- emergelog(xterm_titles,
- ">>> Cancelling sync -- Already current.")
- print
- print ">>>"
- print ">>> Timestamps on the server and in the local repository are the same."
- print ">>> Cancelling all further sync action. You are already up to date."
- print ">>>"
- print ">>> In order to force sync, remove '%s'." % servertimestampfile
- print ">>>"
- print
- sys.exit(0)
- elif (servertimestamp != 0) and (servertimestamp < mytimestamp):
- emergelog(xterm_titles,
- ">>> Server out of date: %s" % dosyncuri)
- print
- print ">>>"
- print ">>> SERVER OUT OF DATE: %s" % dosyncuri
- print ">>>"
- print ">>> In order to force sync, remove '%s'." % servertimestampfile
- print ">>>"
- print
- exitcode = SERVER_OUT_OF_DATE
- elif (servertimestamp == 0) or (servertimestamp > mytimestamp):
- # actual sync
- mycommand = rsynccommand + [dosyncuri+"/", myportdir]
- exitcode = portage.process.spawn(mycommand, **spawn_kwargs)
- if exitcode in [0,1,3,4,11,14,20,21]:
- break
- elif exitcode in [1,3,4,11,14,20,21]:
- break
- else:
- # Code 2 indicates protocol incompatibility, which is expected
- # for servers with protocol < 29 that don't support
- # --prune-empty-directories. Retry for a server that supports
- # at least rsync protocol version 29 (>=rsync-2.6.4).
- pass
-
- retries=retries+1
-
- if retries<=maxretries:
- print ">>> Retrying..."
- time.sleep(11)
- else:
- # over retries
- # exit loop
- updatecache_flg=False
- exitcode = EXCEEDED_MAX_RETRIES
- break
-
- if (exitcode==0):
- emergelog(xterm_titles, "=== Sync completed with %s" % dosyncuri)
- elif exitcode == SERVER_OUT_OF_DATE:
- sys.exit(1)
- elif exitcode == EXCEEDED_MAX_RETRIES:
- sys.stderr.write(
- ">>> Exceeded PORTAGE_RSYNC_RETRIES: %s\n" % maxretries)
- sys.exit(1)
- elif (exitcode>0):
- msg = []
- if exitcode==1:
- msg.append("Rsync has reported that there is a syntax error. Please ensure")
- msg.append("that your SYNC statement is proper.")
- msg.append("SYNC=" + settings["SYNC"])
- elif exitcode==11:
- msg.append("Rsync has reported that there is a File IO error. Normally")
- msg.append("this means your disk is full, but can be caused by corruption")
- msg.append("on the filesystem that contains PORTDIR. Please investigate")
- msg.append("and try again after the problem has been fixed.")
- msg.append("PORTDIR=" + settings["PORTDIR"])
- elif exitcode==20:
- msg.append("Rsync was killed before it finished.")
- else:
- msg.append("Rsync has not successfully finished. It is recommended that you keep")
- msg.append("trying or that you use the 'emerge-webrsync' option if you are unable")
- msg.append("to use rsync due to firewall or other restrictions. This should be a")
- msg.append("temporary problem unless complications exist with your network")
- msg.append("(and possibly your system's filesystem) configuration.")
- for line in msg:
- out.eerror(line)
- sys.exit(exitcode)
- elif syncuri[:6]=="cvs://":
- if not os.path.exists("/usr/bin/cvs"):
- print "!!! /usr/bin/cvs does not exist, so CVS support is disabled."
- print "!!! Type \"emerge dev-util/cvs\" to enable CVS support."
- sys.exit(1)
- cvsroot=syncuri[6:]
- cvsdir=os.path.dirname(myportdir)
- if not os.path.exists(myportdir+"/CVS"):
- #initial checkout
- print ">>> Starting initial cvs checkout with "+syncuri+"..."
- if os.path.exists(cvsdir+"/gentoo-x86"):
- print "!!! existing",cvsdir+"/gentoo-x86 directory; exiting."
- sys.exit(1)
- try:
- os.rmdir(myportdir)
- except OSError, e:
- if e.errno != errno.ENOENT:
- sys.stderr.write(
- "!!! existing '%s' directory; exiting.\n" % myportdir)
- sys.exit(1)
- del e
- if portage.spawn("cd "+cvsdir+"; cvs -z0 -d "+cvsroot+" co -P gentoo-x86",settings,free=1):
- print "!!! cvs checkout error; exiting."
- sys.exit(1)
- os.rename(os.path.join(cvsdir, "gentoo-x86"), myportdir)
- else:
- #cvs update
- print ">>> Starting cvs update with "+syncuri+"..."
- retval = portage.process.spawn_bash(
- "cd %s; cvs -z0 -q update -dP" % \
- (portage._shell_quote(myportdir),), **spawn_kwargs)
- if retval != os.EX_OK:
- sys.exit(retval)
- dosyncuri = syncuri
- else:
- writemsg_level("!!! Unrecognized protocol: SYNC='%s'\n" % (syncuri,),
- noiselevel=-1, level=logging.ERROR)
- return 1
-
- if updatecache_flg and \
- myaction != "metadata" and \
- "metadata-transfer" not in settings.features:
- updatecache_flg = False
-
- # Reload the whole config from scratch.
- settings, trees, mtimedb = load_emerge_config(trees=trees)
- root_config = trees[settings["ROOT"]]["root_config"]
- portdb = trees[settings["ROOT"]]["porttree"].dbapi
-
- if updatecache_flg and \
- os.path.exists(os.path.join(myportdir, 'metadata', 'cache')):
-
- # Only update cache for myportdir since that's
- # the only one that's been synced here.
- action_metadata(settings, portdb, myopts, porttrees=[myportdir])
-
- 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
- root_config = trees[settings["ROOT"]]["root_config"]
-
- mybestpv = portdb.xmatch("bestmatch-visible",
- portage.const.PORTAGE_PACKAGE_ATOM)
- mypvs = portage.best(
- trees[settings["ROOT"]]["vartree"].dbapi.match(
- portage.const.PORTAGE_PACKAGE_ATOM))
-
- chk_updated_cfg_files("/", settings.get("CONFIG_PROTECT","").split())
-
- if myaction != "metadata":
- if os.access(portage.USER_CONFIG_PATH + "/bin/post_sync", os.X_OK):
- retval = portage.process.spawn(
- [os.path.join(portage.USER_CONFIG_PATH, "bin", "post_sync"),
- dosyncuri], env=settings.environ())
- if retval != os.EX_OK:
- print red(" * ")+bold("spawn failed of "+ portage.USER_CONFIG_PATH + "/bin/post_sync")
-
- if(mybestpv != mypvs) and not "--quiet" in myopts:
- print
- print red(" * ")+bold("An update to portage is available.")+" It is _highly_ recommended"
- print red(" * ")+"that you update portage now, before any other packages are updated."
- print
- print red(" * ")+"To update portage, run 'emerge portage' now."
- print
-
- display_news_notification(root_config, myopts)
- return os.EX_OK
-
-def git_sync_timestamps(settings, portdir):
- """
- Since git doesn't preserve timestamps, synchronize timestamps between
- entries and ebuilds/eclasses. Assume the cache has the correct timestamp
- for a given file as long as the file in the working tree is not modified
- (relative to HEAD).
- """
- cache_dir = os.path.join(portdir, "metadata", "cache")
- if not os.path.isdir(cache_dir):
- return os.EX_OK
- writemsg_level(">>> Synchronizing timestamps...\n")
-
- from portage.cache.cache_errors import CacheError
- try:
- cache_db = settings.load_best_module("portdbapi.metadbmodule")(
- portdir, "metadata/cache", portage.auxdbkeys[:], readonly=True)
- except CacheError, e:
- writemsg_level("!!! Unable to instantiate cache: %s\n" % (e,),
- level=logging.ERROR, noiselevel=-1)
- return 1
-
- ec_dir = os.path.join(portdir, "eclass")
- try:
- ec_names = set(f[:-7] for f in os.listdir(ec_dir) \
- if f.endswith(".eclass"))
- except OSError, e:
- writemsg_level("!!! Unable to list eclasses: %s\n" % (e,),
- level=logging.ERROR, noiselevel=-1)
- return 1
-
- args = [portage.const.BASH_BINARY, "-c",
- "cd %s && git diff-index --name-only --diff-filter=M HEAD" % \
- portage._shell_quote(portdir)]
- import subprocess
- proc = subprocess.Popen(args, stdout=subprocess.PIPE)
- modified_files = set(l.rstrip("\n") for l in proc.stdout)
- rval = proc.wait()
- if rval != os.EX_OK:
- return rval
-
- modified_eclasses = set(ec for ec in ec_names \
- if os.path.join("eclass", ec + ".eclass") in modified_files)
-
- updated_ec_mtimes = {}
-
- for cpv in cache_db:
- cpv_split = portage.catpkgsplit(cpv)
- if cpv_split is None:
- writemsg_level("!!! Invalid cache entry: %s\n" % (cpv,),
- level=logging.ERROR, noiselevel=-1)
- continue
-
- cat, pn, ver, rev = cpv_split
- cat, pf = portage.catsplit(cpv)
- relative_eb_path = os.path.join(cat, pn, pf + ".ebuild")
- if relative_eb_path in modified_files:
- continue
-
- try:
- cache_entry = cache_db[cpv]
- eb_mtime = cache_entry.get("_mtime_")
- ec_mtimes = cache_entry.get("_eclasses_")
- except KeyError:
- writemsg_level("!!! Missing cache entry: %s\n" % (cpv,),
- level=logging.ERROR, noiselevel=-1)
- continue
- except CacheError, e:
- writemsg_level("!!! Unable to access cache entry: %s %s\n" % \
- (cpv, e), level=logging.ERROR, noiselevel=-1)
- continue
-
- if eb_mtime is None:
- writemsg_level("!!! Missing ebuild mtime: %s\n" % (cpv,),
- level=logging.ERROR, noiselevel=-1)
- continue
-
- try:
- eb_mtime = long(eb_mtime)
- except ValueError:
- writemsg_level("!!! Invalid ebuild mtime: %s %s\n" % \
- (cpv, eb_mtime), level=logging.ERROR, noiselevel=-1)
- continue
-
- if ec_mtimes is None:
- writemsg_level("!!! Missing eclass mtimes: %s\n" % (cpv,),
- level=logging.ERROR, noiselevel=-1)
- continue
-
- if modified_eclasses.intersection(ec_mtimes):
- continue
-
- missing_eclasses = set(ec_mtimes).difference(ec_names)
- if missing_eclasses:
- writemsg_level("!!! Non-existent eclass(es): %s %s\n" % \
- (cpv, sorted(missing_eclasses)), level=logging.ERROR,
- noiselevel=-1)
- continue
-
- eb_path = os.path.join(portdir, relative_eb_path)
- try:
- current_eb_mtime = os.stat(eb_path)
- except OSError:
- writemsg_level("!!! Missing ebuild: %s\n" % \
- (cpv,), level=logging.ERROR, noiselevel=-1)
- continue
-
- inconsistent = False
- for ec, (ec_path, ec_mtime) in ec_mtimes.iteritems():
- updated_mtime = updated_ec_mtimes.get(ec)
- if updated_mtime is not None and updated_mtime != ec_mtime:
- writemsg_level("!!! Inconsistent eclass mtime: %s %s\n" % \
- (cpv, ec), level=logging.ERROR, noiselevel=-1)
- inconsistent = True
- break
-
- if inconsistent:
- continue
-
- if current_eb_mtime != eb_mtime:
- os.utime(eb_path, (eb_mtime, eb_mtime))
-
- for ec, (ec_path, ec_mtime) in ec_mtimes.iteritems():
- if ec in updated_ec_mtimes:
- continue
- ec_path = os.path.join(ec_dir, ec + ".eclass")
- current_mtime = long(os.stat(ec_path).st_mtime)
- if current_mtime != ec_mtime:
- os.utime(ec_path, (ec_mtime, ec_mtime))
- updated_ec_mtimes[ec] = ec_mtime
-
- return os.EX_OK
-
-def action_metadata(settings, portdb, myopts, porttrees=None):
- if porttrees is None:
- porttrees = portdb.porttrees
- portage.writemsg_stdout("\n>>> Updating Portage cache\n")
- old_umask = os.umask(0002)
- cachedir = os.path.normpath(settings.depcachedir)
- if cachedir in ["/", "/bin", "/dev", "/etc", "/home",
- "/lib", "/opt", "/proc", "/root", "/sbin",
- "/sys", "/tmp", "/usr", "/var"]:
- print >> sys.stderr, "!!! PORTAGE_DEPCACHEDIR IS SET TO A PRIMARY " + \
- "ROOT DIRECTORY ON YOUR SYSTEM."
- print >> sys.stderr, \
- "!!! This is ALMOST CERTAINLY NOT what you want: '%s'" % cachedir
- sys.exit(73)
- if not os.path.exists(cachedir):
- os.makedirs(cachedir)
-
- auxdbkeys = [x for x in portage.auxdbkeys if not x.startswith("UNUSED_0")]
- auxdbkeys = tuple(auxdbkeys)
-
- class TreeData(object):
- __slots__ = ('dest_db', 'eclass_db', 'path', 'src_db', 'valid_nodes')
- def __init__(self, dest_db, eclass_db, path, src_db):
- self.dest_db = dest_db
- self.eclass_db = eclass_db
- self.path = path
- self.src_db = src_db
- self.valid_nodes = set()
-
- porttrees_data = []
- for path in porttrees:
- src_db = portdb._pregen_auxdb.get(path)
- if src_db is None and \
- os.path.isdir(os.path.join(path, 'metadata', 'cache')):
- src_db = portdb.metadbmodule(
- path, 'metadata/cache', auxdbkeys, readonly=True)
- try:
- src_db.ec = portdb._repo_info[path].eclass_db
- except AttributeError:
- pass
-
- if src_db is not None:
- porttrees_data.append(TreeData(portdb.auxdb[path],
- portdb._repo_info[path].eclass_db, path, src_db))
-
- porttrees = [tree_data.path for tree_data in porttrees_data]
-
- isatty = sys.stdout.isatty()
- quiet = not isatty or '--quiet' in myopts
- onProgress = None
- if not quiet:
- progressBar = portage.output.TermProgressBar()
- progressHandler = ProgressHandler()
- onProgress = progressHandler.onProgress
- def display():
- progressBar.set(progressHandler.curval, progressHandler.maxval)
- progressHandler.display = display
- def sigwinch_handler(signum, frame):
- lines, progressBar.term_columns = \
- portage.output.get_term_size()
- signal.signal(signal.SIGWINCH, sigwinch_handler)
-
- # Temporarily override portdb.porttrees so portdb.cp_all()
- # will only return the relevant subset.
- portdb_porttrees = portdb.porttrees
- portdb.porttrees = porttrees
- try:
- cp_all = portdb.cp_all()
- finally:
- portdb.porttrees = portdb_porttrees
-
- curval = 0
- maxval = len(cp_all)
- if onProgress is not None:
- onProgress(maxval, curval)
-
- from portage.cache.util import quiet_mirroring
- from portage import eapi_is_supported, \
- _validate_cache_for_unsupported_eapis
-
- # TODO: Display error messages, but do not interfere with the progress bar.
- # Here's how:
- # 1) erase the progress bar
- # 2) show the error message
- # 3) redraw the progress bar on a new line
- noise = quiet_mirroring()
-
- for cp in cp_all:
- for tree_data in porttrees_data:
- for cpv in portdb.cp_list(cp, mytree=tree_data.path):
- tree_data.valid_nodes.add(cpv)
- try:
- src = tree_data.src_db[cpv]
- except KeyError, e:
- noise.missing_entry(cpv)
- del e
- continue
- except CacheError, ce:
- noise.exception(cpv, ce)
- del ce
- continue
-
- eapi = src.get('EAPI')
- if not eapi:
- eapi = '0'
- eapi = eapi.lstrip('-')
- eapi_supported = eapi_is_supported(eapi)
- if not eapi_supported:
- if not _validate_cache_for_unsupported_eapis:
- noise.misc(cpv, "unable to validate " + \
- "cache for EAPI='%s'" % eapi)
- continue
-
- dest = None
- try:
- dest = tree_data.dest_db[cpv]
- except (KeyError, CacheError):
- pass
-
- for d in (src, dest):
- if d is not None and d.get('EAPI') in ('', '0'):
- del d['EAPI']
-
- if dest is not None:
- if not (dest['_mtime_'] == src['_mtime_'] and \
- tree_data.eclass_db.is_eclass_data_valid(
- dest['_eclasses_']) and \
- set(dest['_eclasses_']) == set(src['_eclasses_'])):
- dest = None
- else:
- # We don't want to skip the write unless we're really
- # sure that the existing cache is identical, so don't
- # trust _mtime_ and _eclasses_ alone.
- for k in set(chain(src, dest)).difference(
- ('_mtime_', '_eclasses_')):
- if dest.get(k, '') != src.get(k, ''):
- dest = None
- break
-
- if dest is not None:
- # The existing data is valid and identical,
- # so there's no need to overwrite it.
- continue
-
- try:
- inherited = src.get('INHERITED', '')
- eclasses = src.get('_eclasses_')
- except CacheError, ce:
- noise.exception(cpv, ce)
- del ce
- continue
-
- if eclasses is not None:
- if not tree_data.eclass_db.is_eclass_data_valid(
- src['_eclasses_']):
- noise.eclass_stale(cpv)
- continue
- inherited = eclasses
- else:
- inherited = inherited.split()
-
- if tree_data.src_db.complete_eclass_entries and \
- eclasses is None:
- noise.corruption(cpv, "missing _eclasses_ field")
- continue
-
- if inherited:
- # Even if _eclasses_ already exists, replace it with data from
- # eclass_cache, in order to insert local eclass paths.
- try:
- eclasses = tree_data.eclass_db.get_eclass_data(inherited)
- except KeyError:
- # INHERITED contains a non-existent eclass.
- noise.eclass_stale(cpv)
- continue
-
- if eclasses is None:
- noise.eclass_stale(cpv)
- continue
- src['_eclasses_'] = eclasses
- else:
- src['_eclasses_'] = {}
-
- if not eapi_supported:
- src = {
- 'EAPI' : '-' + eapi,
- '_mtime_' : src['_mtime_'],
- '_eclasses_' : src['_eclasses_'],
- }
-
- try:
- tree_data.dest_db[cpv] = src
- except CacheError, ce:
- noise.exception(cpv, ce)
- del ce
-
- curval += 1
- if onProgress is not None:
- onProgress(maxval, curval)
-
- if onProgress is not None:
- onProgress(maxval, curval)
-
- for tree_data in porttrees_data:
- try:
- dead_nodes = set(tree_data.dest_db.iterkeys())
- except CacheError, e:
- writemsg_level("Error listing cache entries for " + \
- "'%s': %s, continuing...\n" % (tree_data.path, e),
- level=logging.ERROR, noiselevel=-1)
- del e
- else:
- dead_nodes.difference_update(tree_data.valid_nodes)
- for cpv in dead_nodes:
- try:
- del tree_data.dest_db[cpv]
- except (KeyError, CacheError):
- pass
-
- if not quiet:
- # make sure the final progress is displayed
- progressHandler.display()
- print
- signal.signal(signal.SIGWINCH, signal.SIG_DFL)
-
- sys.stdout.flush()
- os.umask(old_umask)
-
-def action_regen(settings, portdb, max_jobs, max_load):
- xterm_titles = "notitles" not in settings.features
- emergelog(xterm_titles, " === regen")
- #regenerate cache entries
- portage.writemsg_stdout("Regenerating cache entries...\n")
- try:
- os.close(sys.stdin.fileno())
- except SystemExit, e:
- raise # Needed else can't exit
- except:
- pass
- sys.stdout.flush()
-
- regen = MetadataRegen(portdb, max_jobs=max_jobs, max_load=max_load)
- regen.run()
-
- portage.writemsg_stdout("done!\n")
- return regen.returncode
-
-def action_config(settings, trees, myopts, myfiles):
- if len(myfiles) != 1:
- print red("!!! config can only take a single package atom at this time\n")
- sys.exit(1)
- if not is_valid_package_atom(myfiles[0]):
- portage.writemsg("!!! '%s' is not a valid package atom.\n" % myfiles[0],
- noiselevel=-1)
- portage.writemsg("!!! Please check ebuild(5) for full details.\n")
- portage.writemsg("!!! (Did you specify a version but forget to prefix with '='?)\n")
- sys.exit(1)
- print
- try:
- pkgs = trees[settings["ROOT"]]["vartree"].dbapi.match(myfiles[0])
- except portage.exception.AmbiguousPackageName, e:
- # Multiple matches thrown from cpv_expand
- pkgs = e.args[0]
- if len(pkgs) == 0:
- print "No packages found.\n"
- sys.exit(0)
- elif len(pkgs) > 1:
- if "--ask" in myopts:
- options = []
- print "Please select a package to configure:"
- idx = 0
- for pkg in pkgs:
- idx += 1
- options.append(str(idx))
- print options[-1]+") "+pkg
- print "X) Cancel"
- options.append("X")
- idx = userquery("Selection?", options)
- if idx == "X":
- sys.exit(0)
- pkg = pkgs[int(idx)-1]
- else:
- print "The following packages available:"
- for pkg in pkgs:
- print "* "+pkg
- print "\nPlease use a specific atom or the --ask option."
- sys.exit(1)
- else:
- pkg = pkgs[0]
-
- print
- if "--ask" in myopts:
- if userquery("Ready to configure "+pkg+"?") == "No":
- sys.exit(0)
- else:
- print "Configuring pkg..."
- print
- ebuildpath = trees[settings["ROOT"]]["vartree"].dbapi.findname(pkg)
- mysettings = portage.config(clone=settings)
- vardb = trees[mysettings["ROOT"]]["vartree"].dbapi
- debug = mysettings.get("PORTAGE_DEBUG") == "1"
- retval = portage.doebuild(ebuildpath, "config", mysettings["ROOT"],
- mysettings,
- debug=(settings.get("PORTAGE_DEBUG", "") == 1), cleanup=True,
- mydbapi=trees[settings["ROOT"]]["vartree"].dbapi, tree="vartree")
- if retval == os.EX_OK:
- portage.doebuild(ebuildpath, "clean", mysettings["ROOT"],
- mysettings, debug=debug, mydbapi=vardb, tree="vartree")
- print
-
-def action_info(settings, trees, myopts, myfiles):
- print getportageversion(settings["PORTDIR"], settings["ROOT"],
- settings.profile_path, settings["CHOST"],
- trees[settings["ROOT"]]["vartree"].dbapi)
- header_width = 65
- header_title = "System Settings"
- if myfiles:
- print header_width * "="
- print header_title.rjust(int(header_width/2 + len(header_title)/2))
- print header_width * "="
- print "System uname: "+platform.platform(aliased=1)
-
- lastSync = portage.grabfile(os.path.join(
- settings["PORTDIR"], "metadata", "timestamp.chk"))
- print "Timestamp of tree:",
- if lastSync:
- print lastSync[0]
- else:
- print "Unknown"
-
- output=commands.getstatusoutput("distcc --version")
- if not output[0]:
- print str(output[1].split("\n",1)[0]),
- if "distcc" in settings.features:
- print "[enabled]"
- else:
- print "[disabled]"
-
- output=commands.getstatusoutput("ccache -V")
- if not output[0]:
- print str(output[1].split("\n",1)[0]),
- if "ccache" in settings.features:
- print "[enabled]"
- else:
- print "[disabled]"
-
- myvars = ["sys-devel/autoconf", "sys-devel/automake", "virtual/os-headers",
- "sys-devel/binutils", "sys-devel/libtool", "dev-lang/python"]
- myvars += portage.util.grabfile(settings["PORTDIR"]+"/profiles/info_pkgs")
- myvars = portage.util.unique_array(myvars)
- myvars.sort()
-
- for x in myvars:
- if portage.isvalidatom(x):
- pkg_matches = trees["/"]["vartree"].dbapi.match(x)
- pkg_matches = [portage.catpkgsplit(cpv)[1:] for cpv in pkg_matches]
- pkg_matches.sort(key=cmp_sort_key(portage.pkgcmp))
- pkgs = []
- for pn, ver, rev in pkg_matches:
- if rev != "r0":
- pkgs.append(ver + "-" + rev)
- else:
- pkgs.append(ver)
- if pkgs:
- pkgs = ", ".join(pkgs)
- print "%-20s %s" % (x+":", pkgs)
- else:
- print "%-20s %s" % (x+":", "[NOT VALID]")
-
- libtool_vers = ",".join(trees["/"]["vartree"].dbapi.match("sys-devel/libtool"))
-
- if "--verbose" in myopts:
- myvars=settings.keys()
- else:
- myvars = ['GENTOO_MIRRORS', 'CONFIG_PROTECT', 'CONFIG_PROTECT_MASK',
- 'PORTDIR', 'DISTDIR', 'PKGDIR', 'PORTAGE_TMPDIR',
- 'PORTDIR_OVERLAY', 'USE', 'CHOST', 'CFLAGS', 'CXXFLAGS',
- 'ACCEPT_KEYWORDS', 'SYNC', 'FEATURES', 'EMERGE_DEFAULT_OPTS']
-
- myvars.extend(portage.util.grabfile(settings["PORTDIR"]+"/profiles/info_vars"))
-
- myvars = portage.util.unique_array(myvars)
- use_expand = settings.get('USE_EXPAND', '').split()
- use_expand.sort()
- use_expand_hidden = set(
- settings.get('USE_EXPAND_HIDDEN', '').upper().split())
- alphabetical_use = '--alphabetical' in myopts
- root_config = trees[settings["ROOT"]]['root_config']
- unset_vars = []
- myvars.sort()
- for x in myvars:
- if x in settings:
- if x != "USE":
- print '%s="%s"' % (x, settings[x])
- else:
- use = set(settings["USE"].split())
- for varname in use_expand:
- flag_prefix = varname.lower() + "_"
- for f in list(use):
- if f.startswith(flag_prefix):
- use.remove(f)
- use = list(use)
- use.sort()
- print 'USE="%s"' % " ".join(use),
- for varname in use_expand:
- myval = settings.get(varname)
- if myval:
- print '%s="%s"' % (varname, myval),
- print
- else:
- unset_vars.append(x)
- if unset_vars:
- print "Unset: "+", ".join(unset_vars)
- print
-
- if "--debug" in myopts:
- for x in dir(portage):
- module = getattr(portage, x)
- if "cvs_id_string" in dir(module):
- print "%s: %s" % (str(x), str(module.cvs_id_string))
-
- # See if we can find any packages installed matching the strings
- # passed on the command line
- mypkgs = []
- vardb = trees[settings["ROOT"]]["vartree"].dbapi
- portdb = trees[settings["ROOT"]]["porttree"].dbapi
- for x in myfiles:
- mypkgs.extend(vardb.match(x))
-
- # If some packages were found...
- if mypkgs:
- # Get our global settings (we only print stuff if it varies from
- # the current config)
- mydesiredvars = [ 'CHOST', 'CFLAGS', 'CXXFLAGS', 'LDFLAGS' ]
- auxkeys = mydesiredvars + list(vardb._aux_cache_keys)
- auxkeys.append('DEFINED_PHASES')
- global_vals = {}
- pkgsettings = portage.config(clone=settings)
-
- # Loop through each package
- # Only print settings if they differ from global settings
- header_title = "Package Settings"
- print header_width * "="
- print header_title.rjust(int(header_width/2 + len(header_title)/2))
- print header_width * "="
- from portage.output import EOutput
- out = EOutput()
- for cpv in mypkgs:
- # Get all package specific variables
- metadata = dict(izip(auxkeys, vardb.aux_get(cpv, auxkeys)))
- pkg = Package(built=True, cpv=cpv,
- installed=True, metadata=izip(Package.metadata_keys,
- (metadata.get(x, '') for x in Package.metadata_keys)),
- root_config=root_config, type_name='installed')
-
- print "\n%s was built with the following:" % \
- colorize("INFORM", str(pkg.cpv))
-
- pkgsettings.setcpv(pkg)
- forced_flags = set(chain(pkgsettings.useforce,
- pkgsettings.usemask))
- use = set(pkg.use.enabled)
- use.discard(pkgsettings.get('ARCH'))
- use_expand_flags = set()
- use_enabled = {}
- use_disabled = {}
- for varname in use_expand:
- flag_prefix = varname.lower() + "_"
- for f in use:
- if f.startswith(flag_prefix):
- use_expand_flags.add(f)
- use_enabled.setdefault(
- varname.upper(), []).append(f[len(flag_prefix):])
-
- for f in pkg.iuse.all:
- if f.startswith(flag_prefix):
- use_expand_flags.add(f)
- if f not in use:
- use_disabled.setdefault(
- varname.upper(), []).append(f[len(flag_prefix):])
-
- var_order = set(use_enabled)
- var_order.update(use_disabled)
- var_order = sorted(var_order)
- var_order.insert(0, 'USE')
- use.difference_update(use_expand_flags)
- use_enabled['USE'] = list(use)
- use_disabled['USE'] = []
-
- for f in pkg.iuse.all:
- if f not in use and \
- f not in use_expand_flags:
- use_disabled['USE'].append(f)
-
- for varname in var_order:
- if varname in use_expand_hidden:
- continue
- flags = []
- for f in use_enabled.get(varname, []):
- flags.append(UseFlagDisplay(f, True, f in forced_flags))
- for f in use_disabled.get(varname, []):
- flags.append(UseFlagDisplay(f, False, f in forced_flags))
- if alphabetical_use:
- flags.sort(key=UseFlagDisplay.sort_combined)
- else:
- flags.sort(key=UseFlagDisplay.sort_separated)
- print '%s="%s"' % (varname, ' '.join(str(f) for f in flags)),
- print
-
- for myvar in mydesiredvars:
- if metadata[myvar].split() != settings.get(myvar, '').split():
- print "%s=\"%s\"" % (myvar, metadata[myvar])
- print
-
- if metadata['DEFINED_PHASES']:
- if 'info' not in metadata['DEFINED_PHASES'].split():
- continue
-
- print ">>> Attempting to run pkg_info() for '%s'" % pkg.cpv
- ebuildpath = vardb.findname(pkg.cpv)
- if not ebuildpath or not os.path.exists(ebuildpath):
- out.ewarn("No ebuild found for '%s'" % pkg.cpv)
- continue
- portage.doebuild(ebuildpath, "info", pkgsettings["ROOT"],
- pkgsettings, debug=(settings.get("PORTAGE_DEBUG", "") == 1),
- mydbapi=trees[settings["ROOT"]]["vartree"].dbapi,
- tree="vartree")
-
-def action_search(root_config, myopts, myfiles, spinner):
- if not myfiles:
- print "emerge: no search terms provided."
- else:
- searchinstance = search(root_config,
- spinner, "--searchdesc" in myopts,
- "--quiet" not in myopts, "--usepkg" in myopts,
- "--usepkgonly" in myopts)
- for mysearch in myfiles:
- try:
- searchinstance.execute(mysearch)
- except re.error, comment:
- print "\n!!! Regular expression error in \"%s\": %s" % ( mysearch, comment )
- sys.exit(1)
- searchinstance.output()
-
-def action_uninstall(settings, trees, ldpath_mtimes,
- opts, action, files, spinner):
-
- # For backward compat, some actions do not require leading '='.
- ignore_missing_eq = action in ('clean', 'unmerge')
- root = settings['ROOT']
- vardb = trees[root]['vartree'].dbapi
- valid_atoms = []
- lookup_owners = []
-
- # Ensure atoms are valid before calling unmerge().
- # For backward compat, leading '=' is not required.
- for x in files:
- if is_valid_package_atom(x) or \
- (ignore_missing_eq and 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
-
- elif x.startswith(os.sep):
- if not x.startswith(root):
- writemsg_level(("!!! '%s' does not start with" + \
- " $ROOT.\n") % x, level=logging.ERROR, noiselevel=-1)
- return 1
- # Queue these up since it's most efficient to handle
- # multiple files in a single iter_owners() call.
- lookup_owners.append(x)
-
- else:
- 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 lookup_owners:
- relative_paths = []
- search_for_multiple = False
- if len(lookup_owners) > 1:
- search_for_multiple = True
-
- for x in lookup_owners:
- if not search_for_multiple and os.path.isdir(x):
- search_for_multiple = True
- relative_paths.append(x[len(root):])
-
- owners = set()
- for pkg, relative_path in \
- vardb._owners.iter_owners(relative_paths):
- owners.add(pkg.mycpv)
- if not search_for_multiple:
- break
-
- if owners:
- for cpv in owners:
- slot = vardb.aux_get(cpv, ['SLOT'])[0]
- if not slot:
- # portage now masks packages with missing slot, but it's
- # possible that one was installed by an older version
- atom = portage.cpv_getkey(cpv)
- else:
- atom = '%s:%s' % (portage.cpv_getkey(cpv), slot)
- valid_atoms.append(portage.dep.Atom(atom))
- else:
- writemsg_level(("!!! '%s' is not claimed " + \
- "by any package.\n") % lookup_owners[0],
- level=logging.WARNING, noiselevel=-1)
-
- if files and not valid_atoms:
- return 1
-
- if action in ('clean', 'unmerge') or \
- (action == 'prune' and "--nodeps" in opts):
- # When given a list of atoms, unmerge them in the order given.
- ordered = action == 'unmerge'
- unmerge(trees[settings["ROOT"]]['root_config'], opts, action,
- valid_atoms, ldpath_mtimes, ordered=ordered)
- rval = os.EX_OK
- elif action == 'deselect':
- rval = action_deselect(settings, trees, opts, valid_atoms)
- else:
- rval = action_depclean(settings, trees, ldpath_mtimes,
- opts, action, valid_atoms, spinner)
-
- return rval
-
-def action_deselect(settings, trees, opts, atoms):
- root_config = trees[settings['ROOT']]['root_config']
- world_set = root_config.sets['world']
- if not hasattr(world_set, 'update'):
- writemsg_level("World set does not appear to be mutable.\n",
- level=logging.ERROR, noiselevel=-1)
- return 1
-
- vardb = root_config.trees['vartree'].dbapi
- expanded_atoms = set(atoms)
- from portage.dep import Atom
- for atom in atoms:
- for cpv in vardb.match(atom):
- slot, = vardb.aux_get(cpv, ['SLOT'])
- if not slot:
- slot = '0'
- expanded_atoms.add(Atom('%s:%s' % (portage.cpv_getkey(cpv), slot)))
-
- pretend = '--pretend' in opts
- locked = False
- if not pretend and hasattr(world_set, 'lock'):
- world_set.lock()
- locked = True
- try:
- discard_atoms = set()
- world_set.load()
- for atom in world_set:
- if not isinstance(atom, Atom):
- # nested set
- continue
- for arg_atom in expanded_atoms:
- if arg_atom.intersects(atom) and \
- not (arg_atom.slot and not atom.slot):
- discard_atoms.add(atom)
- break
- if discard_atoms:
- for atom in sorted(discard_atoms):
- print ">>> Removing %s from \"world\" favorites file..." % \
- colorize("INFORM", str(atom))
-
- if '--ask' in opts:
- prompt = "Would you like to remove these " + \
- "packages from your world favorites?"
- if userquery(prompt) == 'No':
- return os.EX_OK
-
- remaining = set(world_set)
- remaining.difference_update(discard_atoms)
- if not pretend:
- world_set.replace(remaining)
- else:
- print ">>> No matching atoms found in \"world\" favorites file..."
- finally:
- if locked:
- world_set.unlock()
- return os.EX_OK
-
-def action_depclean(settings, trees, ldpath_mtimes,
- myopts, action, myfiles, spinner):
- # Kill packages that aren't explicitly merged or are required as a
- # dependency of another package. World file is explicit.
-
- # Global depclean or prune operations are not very safe when there are
- # missing dependencies since it's unknown how badly incomplete
- # the dependency graph is, and we might accidentally remove packages
- # that should have been pulled into the graph. On the other hand, it's
- # relatively safe to ignore missing deps when only asked to remove
- # specific packages.
- allow_missing_deps = len(myfiles) > 0
-
- msg = []
- msg.append("Always study the list of packages to be cleaned for any obvious\n")
- msg.append("mistakes. Packages that are part of the world set will always\n")
- msg.append("be kept. They can be manually added to this set with\n")
- msg.append(good("`emerge --noreplace <atom>`") + ". Packages that are listed in\n")
- msg.append("package.provided (see portage(5)) will be removed by\n")
- msg.append("depclean, even if they are part of the world set.\n")
- msg.append("\n")
- msg.append("As a safety measure, depclean will not remove any packages\n")
- msg.append("unless *all* required dependencies have been resolved. As a\n")
- msg.append("consequence, it is often necessary to run %s\n" % \
- good("`emerge --update"))
- msg.append(good("--newuse --deep @system @world`") + \
- " prior to depclean.\n")
-
- if action == "depclean" and "--quiet" not in myopts and not myfiles:
- portage.writemsg_stdout("\n")
- for x in msg:
- portage.writemsg_stdout(colorize("WARN", " * ") + x)
-
- xterm_titles = "notitles" not in settings.features
- myroot = settings["ROOT"]
- root_config = trees[myroot]["root_config"]
- getSetAtoms = root_config.setconfig.getSetAtoms
- vardb = trees[myroot]["vartree"].dbapi
- deselect = myopts.get('--deselect') != 'n'
-
- required_set_names = ("system", "world")
- required_sets = {}
- set_args = []
-
- for s in required_set_names:
- required_sets[s] = InternalPackageSet(
- initial_atoms=getSetAtoms(s))
-
-
- # When removing packages, use a temporary version of world
- # which excludes packages that are intended to be eligible for
- # removal.
- world_temp_set = required_sets["world"]
- system_set = required_sets["system"]
-
- if not system_set or not world_temp_set:
-
- if not system_set:
- writemsg_level("!!! You have no system list.\n",
- level=logging.ERROR, noiselevel=-1)
-
- if not world_temp_set:
- writemsg_level("!!! You have no world file.\n",
- level=logging.WARNING, noiselevel=-1)
-
- writemsg_level("!!! Proceeding is likely to " + \
- "break your installation.\n",
- level=logging.WARNING, noiselevel=-1)
- if "--pretend" not in myopts:
- countdown(int(settings["EMERGE_WARNING_DELAY"]), ">>> Depclean")
-
- if action == "depclean":
- emergelog(xterm_titles, " >>> depclean")
-
- import textwrap
- args_set = InternalPackageSet()
- if myfiles:
- args_set.update(myfiles)
- matched_packages = False
- for x in args_set:
- if vardb.match(x):
- matched_packages = True
- break
- if not matched_packages:
- writemsg_level(">>> No packages selected for removal by %s\n" % \
- action)
- return
-
- writemsg_level("\nCalculating dependencies ")
- resolver_params = create_depgraph_params(myopts, "remove")
- resolver = depgraph(settings, trees, myopts, resolver_params, spinner)
- vardb = resolver.trees[myroot]["vartree"].dbapi
-
- if action == "depclean":
-
- if args_set:
-
- if deselect:
- world_temp_set.clear()
-
- # Pull in everything that's installed but not matched
- # by an argument atom since we don't want to clean any
- # package if something depends on it.
- for pkg in vardb:
- spinner.update()
-
- try:
- if args_set.findAtomForPackage(pkg) is None:
- world_temp_set.add("=" + pkg.cpv)
- continue
- except portage.exception.InvalidDependString, e:
- show_invalid_depstring_notice(pkg,
- pkg.metadata["PROVIDE"], str(e))
- del e
- world_temp_set.add("=" + pkg.cpv)
- continue
-
- elif action == "prune":
-
- if deselect:
- world_temp_set.clear()
-
- # Pull in everything that's installed since we don't
- # to prune a package if something depends on it.
- world_temp_set.update(vardb.cp_all())
-
- if not args_set:
-
- # Try to prune everything that's slotted.
- for cp in vardb.cp_all():
- if len(vardb.cp_list(cp)) > 1:
- args_set.add(cp)
-
- # Remove atoms from world that match installed packages
- # that are also matched by argument atoms, but do not remove
- # them if they match the highest installed version.
- for pkg in vardb:
- spinner.update()
- pkgs_for_cp = vardb.match_pkgs(pkg.cp)
- if not pkgs_for_cp or pkg not in pkgs_for_cp:
- raise AssertionError("package expected in matches: " + \
- "cp = %s, cpv = %s matches = %s" % \
- (pkg.cp, pkg.cpv, [str(x) for x in pkgs_for_cp]))
-
- highest_version = pkgs_for_cp[-1]
- if pkg == highest_version:
- # pkg is the highest version
- world_temp_set.add("=" + pkg.cpv)
- continue
-
- if len(pkgs_for_cp) <= 1:
- raise AssertionError("more packages expected: " + \
- "cp = %s, cpv = %s matches = %s" % \
- (pkg.cp, pkg.cpv, [str(x) for x in pkgs_for_cp]))
-
- try:
- if args_set.findAtomForPackage(pkg) is None:
- world_temp_set.add("=" + pkg.cpv)
- continue
- except portage.exception.InvalidDependString, e:
- show_invalid_depstring_notice(pkg,
- pkg.metadata["PROVIDE"], str(e))
- del e
- world_temp_set.add("=" + pkg.cpv)
- continue
-
- set_args = {}
- for s, package_set in required_sets.iteritems():
- set_atom = SETPREFIX + s
- set_arg = SetArg(arg=set_atom, set=package_set,
- root_config=resolver.roots[myroot])
- set_args[s] = set_arg
- for atom in set_arg.set:
- resolver._dep_stack.append(
- Dependency(atom=atom, root=myroot, parent=set_arg))
- resolver.digraph.add(set_arg, None)
-
- success = resolver._complete_graph()
- writemsg_level("\b\b... done!\n")
-
- resolver.display_problems()
-
- if not success:
- return 1
-
- def unresolved_deps():
-
- unresolvable = set()
- for dep in resolver._initially_unsatisfied_deps:
- if isinstance(dep.parent, Package) and \
- (dep.priority > UnmergeDepPriority.SOFT):
- unresolvable.add((dep.atom, dep.parent.cpv))
-
- if not unresolvable:
- return False
-
- if unresolvable and not allow_missing_deps:
- prefix = bad(" * ")
- msg = []
- msg.append("Dependencies could not be completely resolved due to")
- msg.append("the following required packages not being installed:")
- msg.append("")
- for atom, parent in unresolvable:
- msg.append(" %s pulled in by:" % (atom,))
- msg.append(" %s" % (parent,))
- msg.append("")
- msg.append("Have you forgotten to run " + \
- good("`emerge --update --newuse --deep @system @world`") + " prior")
- msg.append(("to %s? It may be necessary to manually " + \
- "uninstall packages that no longer") % action)
- msg.append("exist in the portage tree since " + \
- "it may not be possible to satisfy their")
- msg.append("dependencies. Also, be aware of " + \
- "the --with-bdeps option that is documented")
- msg.append("in " + good("`man emerge`") + ".")
- if action == "prune":
- msg.append("")
- msg.append("If you would like to ignore " + \
- "dependencies then use %s." % good("--nodeps"))
- writemsg_level("".join("%s%s\n" % (prefix, line) for line in msg),
- level=logging.ERROR, noiselevel=-1)
- return True
- return False
-
- if unresolved_deps():
- return 1
-
- graph = resolver.digraph.copy()
- required_pkgs_total = 0
- for node in graph:
- if isinstance(node, Package):
- required_pkgs_total += 1
-
- def show_parents(child_node):
- parent_nodes = graph.parent_nodes(child_node)
- if not parent_nodes:
- # With --prune, the highest version can be pulled in without any
- # real parent since all installed packages are pulled in. In that
- # case there's nothing to show here.
- return
- parent_strs = []
- for node in parent_nodes:
- parent_strs.append(str(getattr(node, "cpv", node)))
- parent_strs.sort()
- msg = []
- msg.append(" %s pulled in by:\n" % (child_node.cpv,))
- for parent_str in parent_strs:
- msg.append(" %s\n" % (parent_str,))
- msg.append("\n")
- portage.writemsg_stdout("".join(msg), noiselevel=-1)
-
- def cmp_pkg_cpv(pkg1, pkg2):
- """Sort Package instances by cpv."""
- if pkg1.cpv > pkg2.cpv:
- return 1
- elif pkg1.cpv == pkg2.cpv:
- return 0
- else:
- return -1
-
- def create_cleanlist():
- pkgs_to_remove = []
-
- if action == "depclean":
- if args_set:
-
- for pkg in sorted(vardb, key=cmp_sort_key(cmp_pkg_cpv)):
- arg_atom = None
- try:
- arg_atom = args_set.findAtomForPackage(pkg)
- except portage.exception.InvalidDependString:
- # this error has already been displayed by now
- continue
-
- if arg_atom:
- if pkg not in graph:
- pkgs_to_remove.append(pkg)
- elif "--verbose" in myopts:
- show_parents(pkg)
-
- else:
- for pkg in sorted(vardb, key=cmp_sort_key(cmp_pkg_cpv)):
- if pkg not in graph:
- pkgs_to_remove.append(pkg)
- elif "--verbose" in myopts:
- show_parents(pkg)
-
- elif action == "prune":
- # Prune really uses all installed instead of world. It's not
- # a real reverse dependency so don't display it as such.
- graph.remove(set_args["world"])
-
- for atom in args_set:
- for pkg in vardb.match_pkgs(atom):
- if pkg not in graph:
- pkgs_to_remove.append(pkg)
- elif "--verbose" in myopts:
- show_parents(pkg)
-
- if not pkgs_to_remove:
- writemsg_level(
- ">>> No packages selected for removal by %s\n" % action)
- if "--verbose" not in myopts:
- writemsg_level(
- ">>> To see reverse dependencies, use %s\n" % \
- good("--verbose"))
- if action == "prune":
- writemsg_level(
- ">>> To ignore dependencies, use %s\n" % \
- good("--nodeps"))
-
- return pkgs_to_remove
-
- cleanlist = create_cleanlist()
-
- if len(cleanlist):
- clean_set = set(cleanlist)
-
- # Check if any of these package are the sole providers of libraries
- # with consumers that have not been selected for removal. If so, these
- # packages and any dependencies need to be added to the graph.
- real_vardb = trees[myroot]["vartree"].dbapi
- linkmap = real_vardb.linkmap
- liblist = linkmap.listLibraryObjects()
- consumer_cache = {}
- provider_cache = {}
- soname_cache = {}
- consumer_map = {}
-
- writemsg_level(">>> Checking for lib consumers...\n")
-
- for pkg in cleanlist:
- pkg_dblink = real_vardb._dblink(pkg.cpv)
- provided_libs = set()
-
- for lib in liblist:
- if pkg_dblink.isowner(lib, myroot):
- provided_libs.add(lib)
-
- if not provided_libs:
- continue
-
- consumers = {}
- for lib in provided_libs:
- lib_consumers = consumer_cache.get(lib)
- if lib_consumers is None:
- lib_consumers = linkmap.findConsumers(lib)
- consumer_cache[lib] = lib_consumers
- if lib_consumers:
- consumers[lib] = lib_consumers
-
- if not consumers:
- continue
-
- for lib, lib_consumers in consumers.items():
- for consumer_file in list(lib_consumers):
- if pkg_dblink.isowner(consumer_file, myroot):
- lib_consumers.remove(consumer_file)
- if not lib_consumers:
- del consumers[lib]
-
- if not consumers:
- continue
-
- for lib, lib_consumers in consumers.iteritems():
-
- soname = soname_cache.get(lib)
- if soname is None:
- soname = linkmap.getSoname(lib)
- soname_cache[lib] = soname
-
- consumer_providers = []
- for lib_consumer in lib_consumers:
- providers = provider_cache.get(lib)
- if providers is None:
- providers = linkmap.findProviders(lib_consumer)
- provider_cache[lib_consumer] = providers
- if soname not in providers:
- # Why does this happen?
- continue
- consumer_providers.append(
- (lib_consumer, providers[soname]))
-
- consumers[lib] = consumer_providers
-
- consumer_map[pkg] = consumers
-
- if consumer_map:
-
- search_files = set()
- for consumers in consumer_map.itervalues():
- for lib, consumer_providers in consumers.iteritems():
- for lib_consumer, providers in consumer_providers:
- search_files.add(lib_consumer)
- search_files.update(providers)
-
- writemsg_level(">>> Assigning files to packages...\n")
- file_owners = real_vardb._owners.getFileOwnerMap(search_files)
-
- for pkg, consumers in consumer_map.items():
- for lib, consumer_providers in consumers.items():
- lib_consumers = set()
-
- for lib_consumer, providers in consumer_providers:
- owner_set = file_owners.get(lib_consumer)
- provider_dblinks = set()
- provider_pkgs = set()
-
- if len(providers) > 1:
- for provider in providers:
- provider_set = file_owners.get(provider)
- if provider_set is not None:
- provider_dblinks.update(provider_set)
-
- if len(provider_dblinks) > 1:
- for provider_dblink in provider_dblinks:
- pkg_key = ("installed", myroot,
- provider_dblink.mycpv, "nomerge")
- if pkg_key not in clean_set:
- provider_pkgs.add(vardb.get(pkg_key))
-
- if provider_pkgs:
- continue
-
- if owner_set is not None:
- lib_consumers.update(owner_set)
-
- for consumer_dblink in list(lib_consumers):
- if ("installed", myroot, consumer_dblink.mycpv,
- "nomerge") in clean_set:
- lib_consumers.remove(consumer_dblink)
- continue
-
- if lib_consumers:
- consumers[lib] = lib_consumers
- else:
- del consumers[lib]
- if not consumers:
- del consumer_map[pkg]
-
- if consumer_map:
- # TODO: Implement a package set for rebuilding consumer packages.
-
- msg = "In order to avoid breakage of link level " + \
- "dependencies, one or more packages will not be removed. " + \
- "This can be solved by rebuilding " + \
- "the packages that pulled them in."
-
- prefix = bad(" * ")
- from textwrap import wrap
- writemsg_level("".join(prefix + "%s\n" % line for \
- line in wrap(msg, 70)), level=logging.WARNING, noiselevel=-1)
-
- msg = []
- for pkg, consumers in consumer_map.iteritems():
- unique_consumers = set(chain(*consumers.values()))
- unique_consumers = sorted(consumer.mycpv \
- for consumer in unique_consumers)
- msg.append("")
- msg.append(" %s pulled in by:" % (pkg.cpv,))
- for consumer in unique_consumers:
- msg.append(" %s" % (consumer,))
- msg.append("")
- writemsg_level("".join(prefix + "%s\n" % line for line in msg),
- level=logging.WARNING, noiselevel=-1)
-
- # Add lib providers to the graph as children of lib consumers,
- # and also add any dependencies pulled in by the provider.
- writemsg_level(">>> Adding lib providers to graph...\n")
-
- for pkg, consumers in consumer_map.iteritems():
- for consumer_dblink in set(chain(*consumers.values())):
- consumer_pkg = vardb.get(("installed", myroot,
- consumer_dblink.mycpv, "nomerge"))
- if not resolver._add_pkg(pkg,
- Dependency(parent=consumer_pkg,
- priority=UnmergeDepPriority(runtime=True),
- root=pkg.root)):
- resolver.display_problems()
- return 1
-
- writemsg_level("\nCalculating dependencies ")
- success = resolver._complete_graph()
- writemsg_level("\b\b... done!\n")
- resolver.display_problems()
- if not success:
- return 1
- if unresolved_deps():
- return 1
-
- graph = resolver.digraph.copy()
- required_pkgs_total = 0
- for node in graph:
- if isinstance(node, Package):
- required_pkgs_total += 1
- cleanlist = create_cleanlist()
- if not cleanlist:
- return 0
- clean_set = set(cleanlist)
-
- # Use a topological sort to create an unmerge order such that
- # each package is unmerged before it's dependencies. This is
- # necessary to avoid breaking things that may need to run
- # during pkg_prerm or pkg_postrm phases.
-
- # Create a new graph to account for dependencies between the
- # packages being unmerged.
- graph = digraph()
- del cleanlist[:]
-
- dep_keys = ["DEPEND", "RDEPEND", "PDEPEND"]
- runtime = UnmergeDepPriority(runtime=True)
- runtime_post = UnmergeDepPriority(runtime_post=True)
- buildtime = UnmergeDepPriority(buildtime=True)
- priority_map = {
- "RDEPEND": runtime,
- "PDEPEND": runtime_post,
- "DEPEND": buildtime,
- }
-
- for node in clean_set:
- graph.add(node, None)
- mydeps = []
- node_use = node.metadata["USE"].split()
- for dep_type in dep_keys:
- depstr = node.metadata[dep_type]
- if not depstr:
- continue
- try:
- portage.dep._dep_check_strict = False
- success, atoms = portage.dep_check(depstr, None, settings,
- myuse=node_use, trees=resolver._graph_trees,
- myroot=myroot)
- finally:
- portage.dep._dep_check_strict = True
- if not success:
- # Ignore invalid deps of packages that will
- # be uninstalled anyway.
- continue
-
- priority = priority_map[dep_type]
- for atom in atoms:
- if not isinstance(atom, portage.dep.Atom):
- # Ignore invalid atoms returned from dep_check().
- continue
- if atom.blocker:
- continue
- matches = vardb.match_pkgs(atom)
- if not matches:
- continue
- for child_node in matches:
- if child_node in clean_set:
- graph.add(child_node, node, priority=priority)
-
- ordered = True
- if len(graph.order) == len(graph.root_nodes()):
- # If there are no dependencies between packages
- # let unmerge() group them by cat/pn.
- ordered = False
- cleanlist = [pkg.cpv for pkg in graph.order]
- else:
- # Order nodes from lowest to highest overall reference count for
- # optimal root node selection.
- node_refcounts = {}
- for node in graph.order:
- node_refcounts[node] = len(graph.parent_nodes(node))
- def cmp_reference_count(node1, node2):
- return node_refcounts[node1] - node_refcounts[node2]
- graph.order.sort(key=cmp_sort_key(cmp_reference_count))
-
- ignore_priority_range = [None]
- ignore_priority_range.extend(
- xrange(UnmergeDepPriority.MIN, UnmergeDepPriority.MAX + 1))
- while not graph.empty():
- for ignore_priority in ignore_priority_range:
- nodes = graph.root_nodes(ignore_priority=ignore_priority)
- if nodes:
- break
- if not nodes:
- raise AssertionError("no root nodes")
- if ignore_priority is not None:
- # Some deps have been dropped due to circular dependencies,
- # so only pop one node in order do minimize the number that
- # are dropped.
- del nodes[1:]
- for node in nodes:
- graph.remove(node)
- cleanlist.append(node.cpv)
-
- unmerge(root_config, myopts, "unmerge", cleanlist,
- ldpath_mtimes, ordered=ordered)
-
- if action == "prune":
- return
-
- if not cleanlist and "--quiet" in myopts:
- return
-
- print "Packages installed: "+str(len(vardb.cpv_all()))
- print "Packages in world: " + \
- str(len(root_config.sets["world"].getAtoms()))
- print "Packages in system: " + \
- str(len(root_config.sets["system"].getAtoms()))
- print "Required packages: "+str(required_pkgs_total)
- if "--pretend" in myopts:
- print "Number to remove: "+str(len(cleanlist))
- else:
- print "Number removed: "+str(len(cleanlist))
-
-def action_build(settings, trees, mtimedb,
- myopts, myaction, myfiles, spinner):
-
- # validate the state of the resume data
- # so that we can make assumptions later.
- for k in ("resume", "resume_backup"):
- if k not in mtimedb:
- continue
- resume_data = mtimedb[k]
- if not isinstance(resume_data, dict):
- del mtimedb[k]
- continue
- mergelist = resume_data.get("mergelist")
- if not isinstance(mergelist, list):
- del mtimedb[k]
- continue
- for x in mergelist:
- if not (isinstance(x, list) and len(x) == 4):
- continue
- pkg_type, pkg_root, pkg_key, pkg_action = x
- if pkg_root not in trees:
- # Current $ROOT setting differs,
- # so the list must be stale.
- mergelist = None
- break
- if not mergelist:
- del mtimedb[k]
- continue
- resume_opts = resume_data.get("myopts")
- if not isinstance(resume_opts, (dict, list)):
- del mtimedb[k]
- continue
- favorites = resume_data.get("favorites")
- if not isinstance(favorites, list):
- del mtimedb[k]
- continue
-
- resume = False
- if "--resume" in myopts and \
- ("resume" in mtimedb or
- "resume_backup" in mtimedb):
- resume = True
- if "resume" not in mtimedb:
- mtimedb["resume"] = mtimedb["resume_backup"]
- del mtimedb["resume_backup"]
- mtimedb.commit()
- # "myopts" is a list for backward compatibility.
- resume_opts = mtimedb["resume"].get("myopts", [])
- if isinstance(resume_opts, list):
- resume_opts = dict((k,True) for k in resume_opts)
- for opt in ("--ask", "--color", "--skipfirst", "--tree"):
- resume_opts.pop(opt, None)
-
- # Current options always override resume_opts.
- resume_opts.update(myopts)
- myopts.clear()
- myopts.update(resume_opts)
-
- if "--debug" in myopts:
- writemsg_level("myopts %s\n" % (myopts,))
-
- # Adjust config according to options of the command being resumed.
- for myroot in trees:
- mysettings = trees[myroot]["vartree"].settings
- mysettings.unlock()
- adjust_config(myopts, mysettings)
- mysettings.lock()
- del myroot, mysettings
-
- ldpath_mtimes = mtimedb["ldpath"]
- favorites=[]
- merge_count = 0
- buildpkgonly = "--buildpkgonly" in myopts
- pretend = "--pretend" in myopts
- fetchonly = "--fetchonly" in myopts or "--fetch-all-uri" in myopts
- ask = "--ask" in myopts
- nodeps = "--nodeps" in myopts
- oneshot = "--oneshot" in myopts or "--onlydeps" in myopts
- tree = "--tree" in myopts
- if nodeps and tree:
- tree = False
- del myopts["--tree"]
- portage.writemsg(colorize("WARN", " * ") + \
- "--tree is broken with --nodeps. Disabling...\n")
- debug = "--debug" in myopts
- verbose = "--verbose" in myopts
- quiet = "--quiet" in myopts
- if pretend or fetchonly:
- # make the mtimedb readonly
- mtimedb.filename = None
- if '--digest' in myopts or 'digest' in settings.features:
- if '--digest' in myopts:
- msg = "The --digest option"
- else:
- msg = "The FEATURES=digest setting"
-
- msg += " can prevent corruption from being" + \
- " noticed. The `repoman manifest` command is the preferred" + \
- " way to generate manifests and it is capable of doing an" + \
- " entire repository or category at once."
- prefix = bad(" * ")
- writemsg(prefix + "\n")
- from textwrap import wrap
- for line in wrap(msg, 72):
- writemsg("%s%s\n" % (prefix, line))
- writemsg(prefix + "\n")
-
- if "--quiet" not in myopts and \
- ("--pretend" in myopts or "--ask" in myopts or \
- "--tree" in myopts or "--verbose" in myopts):
- action = ""
- if "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
- action = "fetched"
- elif "--buildpkgonly" in myopts:
- action = "built"
- else:
- action = "merged"
- if "--tree" in myopts and action != "fetched": # Tree doesn't work with fetching
- print
- print darkgreen("These are the packages that would be %s, in reverse order:") % action
- print
- else:
- print
- print darkgreen("These are the packages that would be %s, in order:") % action
- print
-
- show_spinner = "--quiet" not in myopts and "--nodeps" not in myopts
- if not show_spinner:
- spinner.update = spinner.update_quiet
-
- if resume:
- favorites = mtimedb["resume"].get("favorites")
- if not isinstance(favorites, list):
- favorites = []
-
- if show_spinner:
- print "Calculating dependencies ",
- myparams = create_depgraph_params(myopts, myaction)
-
- resume_data = mtimedb["resume"]
- mergelist = resume_data["mergelist"]
- if mergelist and "--skipfirst" in myopts:
- for i, task in enumerate(mergelist):
- if isinstance(task, list) and \
- task and task[-1] == "merge":
- del mergelist[i]
- break
-
- success = False
- mydepgraph = None
- try:
- success, mydepgraph, dropped_tasks = resume_depgraph(
- settings, trees, mtimedb, myopts, myparams, spinner)
- except (portage.exception.PackageNotFound,
- depgraph.UnsatisfiedResumeDep), e:
- if isinstance(e, depgraph.UnsatisfiedResumeDep):
- mydepgraph = e.depgraph
- if show_spinner:
- print
- from textwrap import wrap
- from portage.output import EOutput
- out = EOutput()
-
- resume_data = mtimedb["resume"]
- mergelist = resume_data.get("mergelist")
- if not isinstance(mergelist, list):
- mergelist = []
- if mergelist and debug or (verbose and not quiet):
- out.eerror("Invalid resume list:")
- out.eerror("")
- indent = " "
- for task in mergelist:
- if isinstance(task, list):
- out.eerror(indent + str(tuple(task)))
- out.eerror("")
-
- if isinstance(e, depgraph.UnsatisfiedResumeDep):
- out.eerror("One or more packages are either masked or " + \
- "have missing dependencies:")
- out.eerror("")
- indent = " "
- for dep in e.value:
- if dep.atom is None:
- out.eerror(indent + "Masked package:")
- out.eerror(2 * indent + str(dep.parent))
- out.eerror("")
- else:
- out.eerror(indent + str(dep.atom) + " pulled in by:")
- out.eerror(2 * indent + str(dep.parent))
- out.eerror("")
- msg = "The resume list contains packages " + \
- "that are either masked or have " + \
- "unsatisfied dependencies. " + \
- "Please restart/continue " + \
- "the operation manually, or use --skipfirst " + \
- "to skip the first package in the list and " + \
- "any other packages that may be " + \
- "masked or have missing dependencies."
- for line in wrap(msg, 72):
- out.eerror(line)
- elif isinstance(e, portage.exception.PackageNotFound):
- out.eerror("An expected package is " + \
- "not available: %s" % str(e))
- out.eerror("")
- msg = "The resume list contains one or more " + \
- "packages that are no longer " + \
- "available. Please restart/continue " + \
- "the operation manually."
- for line in wrap(msg, 72):
- out.eerror(line)
- else:
- if show_spinner:
- print "\b\b... done!"
-
- if success:
- if dropped_tasks:
- portage.writemsg("!!! One or more packages have been " + \
- "dropped due to\n" + \
- "!!! masking or unsatisfied dependencies:\n\n",
- noiselevel=-1)
- for task in dropped_tasks:
- portage.writemsg(" " + str(task) + "\n", noiselevel=-1)
- portage.writemsg("\n", noiselevel=-1)
- del dropped_tasks
- else:
- if mydepgraph is not None:
- mydepgraph.display_problems()
- if not (ask or pretend):
- # delete the current list and also the backup
- # since it's probably stale too.
- for k in ("resume", "resume_backup"):
- mtimedb.pop(k, None)
- mtimedb.commit()
-
- return 1
- else:
- if ("--resume" in myopts):
- print darkgreen("emerge: It seems we have nothing to resume...")
- return os.EX_OK
-
- myparams = create_depgraph_params(myopts, myaction)
- if "--quiet" not in myopts and "--nodeps" not in myopts:
- print "Calculating dependencies ",
- sys.stdout.flush()
- mydepgraph = depgraph(settings, trees, myopts, myparams, spinner)
- try:
- retval, favorites = mydepgraph.select_files(myfiles)
- except portage.exception.PackageNotFound, e:
- portage.writemsg("\n!!! %s\n" % str(e), noiselevel=-1)
- return 1
- except portage.exception.PackageSetNotFound, e:
- root_config = trees[settings["ROOT"]]["root_config"]
- display_missing_pkg_set(root_config, e.value)
- return 1
- if show_spinner:
- print "\b\b... done!"
- if not retval:
- mydepgraph.display_problems()
- return 1
-
- if "--pretend" not in myopts and \
- ("--ask" in myopts or "--tree" in myopts or \
- "--verbose" in myopts) and \
- not ("--quiet" in myopts and "--ask" not in myopts):
- if "--resume" in myopts:
- mymergelist = mydepgraph.altlist()
- if len(mymergelist) == 0:
- print colorize("INFORM", "emerge: It seems we have nothing to resume...")
- return os.EX_OK
- favorites = mtimedb["resume"]["favorites"]
- retval = mydepgraph.display(
- mydepgraph.altlist(reversed=tree),
- favorites=favorites)
- mydepgraph.display_problems()
- if retval != os.EX_OK:
- return retval
- prompt="Would you like to resume merging these packages?"
- else:
- retval = mydepgraph.display(
- mydepgraph.altlist(reversed=("--tree" in myopts)),
- favorites=favorites)
- mydepgraph.display_problems()
- if retval != os.EX_OK:
- return retval
- mergecount=0
- for x in mydepgraph.altlist():
- if isinstance(x, Package) and x.operation == "merge":
- mergecount += 1
-
- if mergecount==0:
- sets = trees[settings["ROOT"]]["root_config"].sets
- world_candidates = None
- if "--noreplace" in myopts and \
- not oneshot and favorites:
- # Sets that are not world candidates are filtered
- # out here since the favorites list needs to be
- # complete for depgraph.loadResumeCommand() to
- # operate correctly.
- world_candidates = [x for x in favorites \
- if not (x.startswith(SETPREFIX) and \
- not sets[x[1:]].world_candidate)]
- if "--noreplace" in myopts and \
- not oneshot and world_candidates:
- print
- for x in world_candidates:
- print " %s %s" % (good("*"), x)
- prompt="Would you like to add these packages to your world favorites?"
- elif settings["AUTOCLEAN"] and "yes"==settings["AUTOCLEAN"]:
- prompt="Nothing to merge; would you like to auto-clean packages?"
- else:
- print
- print "Nothing to merge; quitting."
- print
- return os.EX_OK
- elif "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
- prompt="Would you like to fetch the source files for these packages?"
- else:
- prompt="Would you like to merge these packages?"
- print
- if "--ask" in myopts and userquery(prompt) == "No":
- print
- print "Quitting."
- print
- return os.EX_OK
- # Don't ask again (e.g. when auto-cleaning packages after merge)
- myopts.pop("--ask", None)
-
- if ("--pretend" in myopts) and not ("--fetchonly" in myopts or "--fetch-all-uri" in myopts):
- if ("--resume" in myopts):
- mymergelist = mydepgraph.altlist()
- if len(mymergelist) == 0:
- print colorize("INFORM", "emerge: It seems we have nothing to resume...")
- return os.EX_OK
- favorites = mtimedb["resume"]["favorites"]
- retval = mydepgraph.display(
- mydepgraph.altlist(reversed=tree),
- favorites=favorites)
- mydepgraph.display_problems()
- if retval != os.EX_OK:
- return retval
- else:
- retval = mydepgraph.display(
- mydepgraph.altlist(reversed=("--tree" in myopts)),
- favorites=favorites)
- mydepgraph.display_problems()
- if retval != os.EX_OK:
- return retval
- if "--buildpkgonly" in myopts:
- graph_copy = mydepgraph.digraph.clone()
- removed_nodes = set()
- for node in graph_copy:
- if not isinstance(node, Package) or \
- node.operation == "nomerge":
- removed_nodes.add(node)
- graph_copy.difference_update(removed_nodes)
- if not graph_copy.hasallzeros(ignore_priority = \
- DepPrioritySatisfiedRange.ignore_medium):
- print "\n!!! --buildpkgonly requires all dependencies to be merged."
- print "!!! You have to merge the dependencies before you can build this package.\n"
- return 1
- else:
- if "--buildpkgonly" in myopts:
- graph_copy = mydepgraph.digraph.clone()
- removed_nodes = set()
- for node in graph_copy:
- if not isinstance(node, Package) or \
- node.operation == "nomerge":
- removed_nodes.add(node)
- graph_copy.difference_update(removed_nodes)
- if not graph_copy.hasallzeros(ignore_priority = \
- DepPrioritySatisfiedRange.ignore_medium):
- print "\n!!! --buildpkgonly requires all dependencies to be merged."
- print "!!! Cannot merge requested packages. Merge deps and try again.\n"
- return 1
-
- if ("--resume" in myopts):
- favorites=mtimedb["resume"]["favorites"]
- mymergelist = mydepgraph.altlist()
- mydepgraph.break_refs(mymergelist)
- mergetask = Scheduler(settings, trees, mtimedb, myopts,
- spinner, mymergelist, favorites, mydepgraph.schedulerGraph())
- del mydepgraph, mymergelist
- clear_caches(trees)
-
- retval = mergetask.merge()
- merge_count = mergetask.curval
- else:
- if "resume" in mtimedb and \
- "mergelist" in mtimedb["resume"] and \
- len(mtimedb["resume"]["mergelist"]) > 1:
- mtimedb["resume_backup"] = mtimedb["resume"]
- del mtimedb["resume"]
- mtimedb.commit()
- mtimedb["resume"]={}
- # Stored as a dict starting with portage-2.1.6_rc1, and supported
- # by >=portage-2.1.3_rc8. Versions <portage-2.1.3_rc8 only support
- # a list type for options.
- mtimedb["resume"]["myopts"] = myopts.copy()
-
- # Convert Atom instances to plain str.
- mtimedb["resume"]["favorites"] = [str(x) for x in favorites]
-
- pkglist = mydepgraph.altlist()
- mydepgraph.saveNomergeFavorites()
- mydepgraph.break_refs(pkglist)
- mergetask = Scheduler(settings, trees, mtimedb, myopts,
- spinner, pkglist, favorites, mydepgraph.schedulerGraph())
- del mydepgraph, pkglist
- clear_caches(trees)
-
- retval = mergetask.merge()
- merge_count = mergetask.curval
-
- if retval == os.EX_OK and not (buildpkgonly or fetchonly or pretend):
- if "yes" == settings.get("AUTOCLEAN"):
- portage.writemsg_stdout(">>> Auto-cleaning packages...\n")
- unmerge(trees[settings["ROOT"]]["root_config"],
- myopts, "clean", [],
- ldpath_mtimes, autoclean=1)
- else:
- portage.writemsg_stdout(colorize("WARN", "WARNING:")
- + " AUTOCLEAN is disabled. This can cause serious"
- + " problems due to overlapping packages.\n")
- trees[settings["ROOT"]]["vartree"].dbapi.plib_registry.pruneNonExisting()
-
- return 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))
@@ -3165,120 +600,6 @@ def validate_ebuild_environment(trees):
settings = trees[myroot]["vartree"].settings
settings.validate()
-def load_emerge_config(trees=None):
- kwargs = {}
- for k, envvar in (("config_root", "PORTAGE_CONFIGROOT"), ("target_root", "ROOT")):
- v = os.environ.get(envvar, None)
- if v and v.strip():
- kwargs[k] = v
- trees = portage.create_trees(trees=trees, **kwargs)
-
- for root, root_trees in trees.iteritems():
- settings = root_trees["vartree"].settings
- setconfig = load_default_config(settings, root_trees)
- root_trees["root_config"] = RootConfig(settings, root_trees, setconfig)
-
- 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 adjust_config(myopts, settings):
- """Make emerge specific adjustments to the config."""
-
- # To enhance usability, make some vars case insensitive by forcing them to
- # lower case.
- for myvar in ("AUTOCLEAN", "NOCOLOR"):
- if myvar in settings:
- settings[myvar] = settings[myvar].lower()
- settings.backup_changes(myvar)
- del myvar
-
- # Kill noauto as it will break merges otherwise.
- if "noauto" in settings.features:
- settings.features.remove('noauto')
- settings['FEATURES'] = ' '.join(sorted(settings.features))
- settings.backup_changes("FEATURES")
-
- CLEAN_DELAY = 5
- try:
- CLEAN_DELAY = int(settings.get("CLEAN_DELAY", str(CLEAN_DELAY)))
- except ValueError, e:
- portage.writemsg("!!! %s\n" % str(e), noiselevel=-1)
- portage.writemsg("!!! Unable to parse integer: CLEAN_DELAY='%s'\n" % \
- settings["CLEAN_DELAY"], noiselevel=-1)
- settings["CLEAN_DELAY"] = str(CLEAN_DELAY)
- settings.backup_changes("CLEAN_DELAY")
-
- EMERGE_WARNING_DELAY = 10
- try:
- EMERGE_WARNING_DELAY = int(settings.get(
- "EMERGE_WARNING_DELAY", str(EMERGE_WARNING_DELAY)))
- except ValueError, e:
- portage.writemsg("!!! %s\n" % str(e), noiselevel=-1)
- portage.writemsg("!!! Unable to parse integer: EMERGE_WARNING_DELAY='%s'\n" % \
- settings["EMERGE_WARNING_DELAY"], noiselevel=-1)
- settings["EMERGE_WARNING_DELAY"] = str(EMERGE_WARNING_DELAY)
- settings.backup_changes("EMERGE_WARNING_DELAY")
-
- if "--quiet" in myopts:
- settings["PORTAGE_QUIET"]="1"
- settings.backup_changes("PORTAGE_QUIET")
-
- if "--verbose" in myopts:
- settings["PORTAGE_VERBOSE"] = "1"
- settings.backup_changes("PORTAGE_VERBOSE")
-
- # Set so that configs will be merged regardless of remembered status
- if ("--noconfmem" in myopts):
- settings["NOCONFMEM"]="1"
- settings.backup_changes("NOCONFMEM")
-
- # Set various debug markers... They should be merged somehow.
- PORTAGE_DEBUG = 0
- try:
- PORTAGE_DEBUG = int(settings.get("PORTAGE_DEBUG", str(PORTAGE_DEBUG)))
- if PORTAGE_DEBUG not in (0, 1):
- portage.writemsg("!!! Invalid value: PORTAGE_DEBUG='%i'\n" % \
- PORTAGE_DEBUG, noiselevel=-1)
- portage.writemsg("!!! PORTAGE_DEBUG must be either 0 or 1\n",
- noiselevel=-1)
- PORTAGE_DEBUG = 0
- except ValueError, e:
- portage.writemsg("!!! %s\n" % str(e), noiselevel=-1)
- portage.writemsg("!!! Unable to parse integer: PORTAGE_DEBUG='%s'\n" %\
- settings["PORTAGE_DEBUG"], noiselevel=-1)
- del e
- if "--debug" in myopts:
- PORTAGE_DEBUG = 1
- settings["PORTAGE_DEBUG"] = str(PORTAGE_DEBUG)
- settings.backup_changes("PORTAGE_DEBUG")
-
- if settings.get("NOCOLOR") not in ("yes","true"):
- portage.output.havecolor = 1
-
- """The explicit --color < y | n > option overrides the NOCOLOR environment
- variable and stdout auto-detection."""
- if "--color" in myopts:
- if "y" == myopts["--color"]:
- portage.output.havecolor = 1
- settings["NOCOLOR"] = "false"
- else:
- portage.output.havecolor = 0
- settings["NOCOLOR"] = "true"
- settings.backup_changes("NOCOLOR")
- elif not sys.stdout.isatty() and settings.get("NOCOLOR") != "no":
- portage.output.havecolor = 0
- settings["NOCOLOR"] = "true"
- settings.backup_changes("NOCOLOR")
-
def apply_priorities(settings):
ionice(settings)
nice(settings)
@@ -3316,21 +637,6 @@ def ionice(settings):
out.eerror("PORTAGE_IONICE_COMMAND returned %d" % (rval,))
out.eerror("See the make.conf(5) man page for PORTAGE_IONICE_COMMAND usage instructions.")
-def display_missing_pkg_set(root_config, set_name):
-
- msg = []
- msg.append(("emerge: There are no sets to satisfy '%s'. " + \
- "The following sets exist:") % \
- colorize("INFORM", set_name))
- msg.append("")
-
- for s in sorted(root_config.sets):
- msg.append(" %s" % s)
- msg.append("")
-
- writemsg_level("".join("%s\n" % l for l in msg),
- level=logging.ERROR, noiselevel=-1)
-
def expand_set_arguments(myfiles, myaction, root_config):
retval = os.EX_OK
setconfig = root_config.setconfig