# Interactively process remaining
#
- for conf in confs:
- count = count + 1
+ valid_input = "qhtnmlezu"
+
+ for conf in confs:
+ count = count + 1
newconf = conf['new']
mrgconf = re.sub(r'\._cfg', '._mrg', newconf)
print '>> (%i of %i) -- %s' % (count, len(confs), conf ['current'])
print '>> q quit, h help, n next, e edit-new, z zap-new, u use-new\n m merge, t toggle-merge, l look-merge: ',
- c = getch ()
-
- if c == 'q':
- sys.exit (0)
- if c == 'h':
- self.do_help ()
- continue
- elif c == 't':
- if newconf == mrgconf:
- newconf = conf['new']
- elif os.path.exists(mrgconf):
- newconf = mrgconf
- continue
- elif c == 'n':
- break
- elif c == 'm':
- merged = SCRATCH_DIR+"/"+os.path.basename(conf['current'])
- print
- ret = os.system (self.options['merge'] % (merged, conf ['current'], newconf))
- if ret:
- print "Failure running 'merge' command"
- continue
- shutil.copyfile(merged, mrgconf)
- os.remove(merged)
- mystat = os.lstat(conf['new'])
- os.chmod(mrgconf, mystat[ST_MODE])
- os.chown(mrgconf, mystat[ST_UID], mystat[ST_GID])
- newconf = mrgconf
- continue
- elif c == 'l':
- show_new_diff = 1
- continue
- elif c == 'e':
- if not os.environ.has_key('EDITOR'):
- os.environ['EDITOR']='nano'
- os.system(os.environ['EDITOR'] + ' ' + newconf)
- continue
- elif c == 'z':
- os.unlink(conf['new'])
- if os.path.exists(mrgconf):
- os.unlink(mrgconf)
- break
- elif c == 'u':
- self.replace(newconf, conf ['current'])
- self.post_process(conf['current'])
- if newconf == mrgconf:
- os.unlink(conf['new'])
- elif os.path.exists(mrgconf):
- os.unlink(mrgconf)
- break
- else:
- continue
+ # In some cases getch() will return some spurious characters
+ # that do not represent valid input. If we don't validate the
+ # input then the spurious characters can cause us to jump
+ # back into the above "diff" command immediatly after the user
+ # has exited it (which can be quite confusing and gives an
+ # "out of control" feeling).
+ while True:
+ c = getch()
+ if c in valid_input:
+ break
+
+ if c == 'q':
+ sys.exit (0)
+ if c == 'h':
+ self.do_help ()
+ continue
+ elif c == 't':
+ if newconf == mrgconf:
+ newconf = conf['new']
+ elif os.path.exists(mrgconf):
+ newconf = mrgconf
+ continue
+ elif c == 'n':
+ break
+ elif c == 'm':
+ merged = SCRATCH_DIR+"/"+os.path.basename(conf['current'])
+ print
+ ret = os.system (self.options['merge'] % (merged, conf ['current'], newconf))
+ if ret:
+ print "Failure running 'merge' command"
+ continue
+ shutil.copyfile(merged, mrgconf)
+ os.remove(merged)
+ mystat = os.lstat(conf['new'])
+ os.chmod(mrgconf, mystat[ST_MODE])
+ os.chown(mrgconf, mystat[ST_UID], mystat[ST_GID])
+ newconf = mrgconf
+ continue
+ elif c == 'l':
+ show_new_diff = 1
+ continue
+ elif c == 'e':
+ if not os.environ.has_key('EDITOR'):
+ os.environ['EDITOR']='nano'
+ os.system(os.environ['EDITOR'] + ' ' + newconf)
+ continue
+ elif c == 'z':
+ os.unlink(conf['new'])
+ if os.path.exists(mrgconf):
+ os.unlink(mrgconf)
+ break
+ elif c == 'u':
+ self.replace(newconf, conf ['current'])
+ self.post_process(conf['current'])
+ if newconf == mrgconf:
+ os.unlink(conf['new'])
+ elif os.path.exists(mrgconf):
+ os.unlink(mrgconf)
+ break
+ else:
+ raise AssertionError("Invalid Input: %s" % c)
if auto_zapped:
print
tmpsettings["FEATURES"] = " ".join(tmpsettings.features)
tmpsettings.backup_changes("FEATURES")
+build_dir_phases = set(["setup", "unpack", "compile",
+ "test", "install", "package", "rpm"])
+
+def stale_env_warning():
+ if "clean" not in pargs and \
+ "noauto" not in tmpsettings.features and \
+ tmpsettings.get("PORTAGE_QUIET") != "1" and \
+ build_dir_phases.intersection(pargs):
+ portage.doebuild_environment(ebuild, "setup", portage.root,
+ tmpsettings, debug, 1, portage.portdb)
+ env_filename = os.path.join(tmpsettings["T"], "environment")
+ if os.path.exists(env_filename):
+ msg = ("Existing ${T}/environment for '%s' will be sourced. " + \
+ "Run 'clean' to start with a fresh environment.") % \
+ (tmpsettings["PF"], )
+ from textwrap import wrap
+ msg = wrap(msg, 70)
+ for x in msg:
+ portage.writemsg(">>> %s\n" % x)
+
+checked_for_stale_env = False
+
for arg in pargs:
try:
+ if not checked_for_stale_env and arg not in ("digest","manifest"):
+ # This has to go after manifest generation since otherwise
+ # aux_get() might fail due to invalid ebuild digests.
+ stale_env_warning()
+ checked_for_stale_env = True
+
if arg == "digest" and force:
discard_digests(ebuild, tmpsettings, portage.portdb)
a = portage.doebuild(ebuild, arg, portage.root, tmpsettings,
# delete it so that the compressor doesn't whine (bzip2 will
# complain and skip, gzip will prompt for input)
suffix=$(ecompress --suffix)
- [[ -n ${suffix} ]] && rm -f "${@/%/${suffix}}"
+ [[ -n ${suffix} ]] && echo -n "${@/%/${suffix}$'\001'}" | \
+ tr '\001' '\000' | ${XARGS} -0 rm -f
# Finally, let's actually do some real work
exec "${PORTAGE_COMPRESS}" ${PORTAGE_COMPRESS_FLAGS} "$@"
;;
shopt -s extdebug
-# usage- first arg is the number of funcs on the stack to ignore.
-# defaults to 1 (ignoring dump_trace)
+# dump_trace([number of funcs on stack to skip],
+# [whitespacing for filenames],
+# [whitespacing for line numbers])
dump_trace() {
- local funcname="" sourcefile="" lineno="" n e s="yes"
-
- declare -i strip=1
-
- if [[ -n $1 ]]; then
- strip=$(( $1 ))
- fi
-
- eerror "Call stack:"
- for (( n = ${#FUNCNAME[@]} - 1, p = ${#BASH_ARGV[@]} ; n > $strip ; n-- )) ; do
- funcname=${FUNCNAME[${n} - 1]}
- sourcefile=$(basename ${BASH_SOURCE[${n}]})
- lineno=${BASH_LINENO[${n} - 1]}
- # Display function arguments
- args=
- if [[ -n "${BASH_ARGV[@]}" ]]; then
- for (( j = 1 ; j <= ${BASH_ARGC[${n} - 1]} ; ++j )); do
- newarg=${BASH_ARGV[$(( p - j - 1 ))]}
- args="${args:+${args} }'${newarg}'"
- done
- (( p -= ${BASH_ARGC[${n} - 1]} ))
- fi
- eerror " ${sourcefile}, line ${lineno}: Called ${funcname}${args:+ ${args}}"
- done
+ local funcname="" sourcefile="" lineno="" n e s="yes"
+ declare -i strip=${1:-1}
+ local filespacing=$2 linespacing=$3
+
+ eerror "Call stack:"
+ for (( n = ${#FUNCNAME[@]} - 1, p = ${#BASH_ARGV[@]} ; n > ${strip} ; n-- )) ; do
+ funcname=${FUNCNAME[${n} - 1]}
+ sourcefile=$(basename ${BASH_SOURCE[${n}]})
+ lineno=${BASH_LINENO[${n} - 1]}
+ # Display function arguments
+ args=
+ if [[ -n "${BASH_ARGV[@]}" ]]; then
+ for (( j = 1 ; j <= ${BASH_ARGC[${n} - 1]} ; ++j )); do
+ newarg=${BASH_ARGV[$(( p - j - 1 ))]}
+ args="${args:+${args} }'${newarg}'"
+ done
+ (( p -= ${BASH_ARGC[${n} - 1]} ))
+ fi
+ eerror " $(printf "%${filespacing}s" "${sourcefile}"), line $(printf "%${linespacing}s" "${lineno}"): Called ${funcname}${args:+ ${args}}"
+ done
}
diefunc() {
- local funcname="$1" lineno="$2" exitcode="$3"
- shift 3
- eerror
- eerror "ERROR: $CATEGORY/$PF failed."
- dump_trace 2
- eerror " ${BASH_SOURCE[1]##*/}, line ${BASH_LINENO[0]}: Called die"
- eerror
- eerror "${*:-(no error message)}"
- eerror "If you need support, post the topmost build error, and the call stack if relevant."
- [ -n "${PORTAGE_LOG_FILE}" ] && \
- eerror "A complete build log is located at '${PORTAGE_LOG_FILE}'."
- if [ -n "${EBUILD_OVERLAY_ECLASSES}" ] ; then
- eerror "This ebuild used the following eclasses from overlays:"
- local x
- for x in ${EBUILD_OVERLAY_ECLASSES} ; do
- eerror " ${x}"
- done
- fi
- if [ "${EBUILD#${PORTDIR}/}" == "${EBUILD}" ] ; then
- local overlay=${EBUILD%/*}
- overlay=${overlay%/*}
- overlay=${overlay%/*}
- eerror "This ebuild is from an overlay: '${overlay}/'"
- fi
- eerror
-
- if [ "${EBUILD_PHASE/depend}" == "${EBUILD_PHASE}" ]; then
- local x
- for x in $EBUILD_DEATH_HOOKS; do
- ${x} "$@" >&2 1>&2
- done
- fi
-
- # subshell die support
- kill -s SIGTERM ${EBUILD_MASTER_PID}
- exit 1
+ local funcname="$1" lineno="$2" exitcode="$3"
+ shift 3
+
+ local n filespacing=0 linespacing=0
+ # setup spacing to make output easier to read
+ for ((n = ${#FUNCNAME[@]} - 1; n >= 0; --n)); do
+ sourcefile=${BASH_SOURCE[${n}]} sourcefile=${sourcefile##*/}
+ lineno=${BASH_LINENO[${n}]}
+ ((filespacing < ${#sourcefile})) && filespacing=${#sourcefile}
+ ((linespacing < ${#lineno})) && linespacing=${#lineno}
+ done
+
+ eerror
+ eerror "ERROR: $CATEGORY/$PF failed."
+ dump_trace 2 ${filespacing} ${linespacing}
+ eerror " $(printf "%${filespacing}s" "${BASH_SOURCE[1]##*/}"), line $(printf "%${linespacing}s" "${BASH_LINENO[0]}"): Called die"
+ eerror "The specific snippet of code:"
+ # This scans the file that called die and prints out the logic that
+ # ended in the call to die. This really only handles lines that end
+ # with '|| die' and any preceding lines with line continuations (\).
+ # This tends to be the most common usage though, so let's do it.
+ # Due to the usage of appending to the hold space (even when empty),
+ # we always end up with the first line being a blank (thus the 2nd sed).
+ sed -n \
+ -e "# When we get to the line that failed, append it to the
+ # hold space, move the hold space to the pattern space,
+ # then print out the pattern space and quit immediately
+ ${BASH_LINENO[0]}{H;g;p;q}" \
+ -e '# If this line ends with a line continuation, append it
+ # to the hold space
+ /\\$/H' \
+ -e '# If this line does not end with a line continuation,
+ # erase the line and set the hold buffer to it (thus
+ # erasing the hold buffer in the process)
+ /[^\]$/{s:^.*$::;h}' \
+ ${BASH_SOURCE[1]} \
+ | sed -e '1d' -e 's:^:RETAIN-LEADING-SPACE:' \
+ | while read -r n ; do eerror " ${n#RETAIN-LEADING-SPACE}" ; done
+ eerror " The die message:"
+ eerror " ${*:-(no error message)}"
+ eerror
+ eerror "If you need support, post the topmost build error, and the call stack if relevant."
+ [[ -n ${PORTAGE_LOG_FILE} ]] \
+ && eerror "A complete build log is located at '${PORTAGE_LOG_FILE}'."
+ if [[ -n ${EBUILD_OVERLAY_ECLASSES} ]] ; then
+ eerror "This ebuild used the following eclasses from overlays:"
+ local x
+ for x in ${EBUILD_OVERLAY_ECLASSES} ; do
+ eerror " ${x}"
+ done
+ fi
+ if [[ "${EBUILD#${PORTDIR}/}" == "${EBUILD}" ]] ; then
+ local overlay=${EBUILD%/*}
+ overlay=${overlay%/*}
+ overlay=${overlay%/*}
+ eerror "This ebuild is from an overlay: '${overlay}/'"
+ fi
+ eerror
+
+ if [[ "${EBUILD_PHASE/depend}" == "${EBUILD_PHASE}" ]] ; then
+ local x
+ for x in $EBUILD_DEATH_HOOKS; do
+ ${x} "$@" >&2 1>&2
+ done
+ fi
+
+ # subshell die support
+ kill -s SIGTERM ${EBUILD_MASTER_PID}
+ exit 1
}
quiet_mode() {
# Adjust COLS so that eend works properly on a standard BSD console.
[ "${TERM}" = "cons25" ] && COLS=$((${COLS} - 1))
- ENDCOL=$'\e[A\e['${COLS}'C' # Now, ${ENDCOL} will move us to the end of the
- # column; irregardless of character width
+ # Now, ${ENDCOL} will move us to the end of the
+ # column; irregardless of character width
+ ENDCOL=$'\e[A\e['${COLS}'C'
if [ -n "${PORTAGE_COLORMAP}" ] ; then
eval ${PORTAGE_COLORMAP}
else
\fIdigest\fR feature is enabled). Existing digests for files that do not exist
in ${DISTDIR} will be automatically assumed even when \fIassume\-digests\fR is
not enabled. If a file exists in ${DISTDIR} but it's size does not match the
-existing digest, the digest will be regenerated regardless of the whether or
+existing digest, the digest will be regenerated regardless of whether or
not \fIassume\-digests\fR is enabled. The \fBebuild\fR(1) \fBdigest\fR command
has a \fB\-\-force\fR option that can be used to force regeneration of digests.
.TP
print "For more information, see MASKED PACKAGES section in the emerge man page or "
print "refer to the Gentoo Handbook."
else:
+ print
alleb = bindb.match(x)
if alleb:
chost = pkgsettings["CHOST"]
if chost != pkg_chost:
mreasons.append("CHOST: %s" % pkg_chost)
print "- "+p+" (masked by: "+", ".join(mreasons)+")"
- print "\n!!! "+red("There are no packages available to satisfy: ")+green(xinfo)
+ print "!!! "+red("There are no packages available to satisfy: ")+green(xinfo)
print "!!! Either add a suitable binary package or compile from an ebuild."
else:
print "\nemerge: there are no ebuilds to satisfy "+green(xinfo)+"."
else:
mod_echo.finalize()
- if "noinfo" not in settings.features:
- chk_updated_info_files(normalize_path(target_root + EPREFIX), infodirs, info_mtimes, retval)
- chk_updated_cfg_files(normalize_path(target_root + EPREFIX), config_protect)
+ vdb_path = os.path.join(target_root, portage.VDB_PATH)
+ portage.util.ensure_dirs(vdb_path)
+ vdb_lock = portage.locks.lockdir(vdb_path)
+ try:
+ if "noinfo" not in settings.features:
+ chk_updated_info_files(target_root + EPREFIX, infodirs, info_mtimes, retval)
+ mtimedb.commit()
+ finally:
+ portage.locks.unlockdir(vdb_lock)
+
+ chk_updated_cfg_files(target_root + EPREFIX, config_protect)
display_news_notification(trees)
print colorize("WARN", " * ") + " - %s" % f
print "Use " + colorize("GOOD", "revdep-rebuild") + " to rebuild packages using these libraries"
print "and then remerge the packages listed above."
-
- mtimedb.commit()
+
sys.exit(retval)
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' -iname '._cfg????_*'" % x
else:
mycommand = "find '%s' -maxdepth 1 -iname '._cfg????_%s'" % \
os.path.split(x.rstrip(os.path.sep))
- a = commands.getstatusoutput(mycommand + \
- " ! -iname '.*~' ! -iname '.*.bak' -print0")
+ mycommand += " ! -iname '.*~' ! -iname '.*.bak' -print0"
+ a = commands.getstatusoutput(mycommand)
if a[0] != 0:
- print >> sys.stderr, " " + bad("*")+ " error scanning '%s'" % x
+ 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
import tempfile
import portage.exception
import portage.process
-import portage.locks
import commands
import md5, sha
global prelink_capable
myfilename = filename[:]
prelink_tmpfile = None
- mylock = None
try:
if calc_prelink and prelink_capable:
# Create non-prelinked temporary file to checksum.
if e.errno == errno.ENOENT:
raise portage.exception.FileNotFound(myfilename)
raise
+ return myhash, mysize
+ finally:
if prelink_tmpfile:
try:
os.unlink(prelink_tmpfile)
if e.errno != errno.ENOENT:
raise
del e
- return myhash, mysize
- finally:
- if mylock:
- portage.locks.unlockfile(mylock)
def perform_multiple_checksums(filename, hashes=["MD5"], calc_prelink=0):
"""
#process symlinks second-to-last, directories last.
mydirs = []
- ignored_unlink_errnos = (errno.ENOENT, errno.EISDIR)
+ ignored_unlink_errnos = (
+ errno.EBUSY, errno.ENOENT,
+ errno.ENOTDIR, errno.EISDIR)
+ ignored_rmdir_errnos = (
+ errno.EEXIST, errno.ENOTEMPTY,
+ errno.EBUSY, errno.ENOENT,
+ errno.ENOTDIR, errno.EISDIR)
modprotect = os.path.join(self.vartree.root, "lib/modules/")
def unlink(file_name, lstatobj):
bsd_chflags.chflags(parent_name, pflags)
show_unmerge("<<<", "", "dir", obj)
except EnvironmentError, e:
- if e.errno not in (errno.ENOENT,
- errno.EEXIST, errno.ENOTEMPTY,
- errno.ENOTDIR):
+ if e.errno not in ignored_rmdir_errnos:
raise
if e.errno != errno.ENOENT:
show_unmerge("---", "!empty", "dir", obj)
self.eclasses = {}
self._eclass_locations = {}
eclass_len = len(".eclass")
+ ignored_listdir_errnos = (errno.ENOENT, errno.ENOTDIR)
for x in [normalize_path(os.path.join(y,"eclass")) for y in self.porttrees]:
- eclass_filenames = []
try:
- for y in os.listdir(x):
- if y.endswith(".eclass"):
- eclass_filenames.append(y)
+ eclass_filenames = os.listdir(x)
except OSError, e:
- if e.errno == errno.ENOENT:
- del e
- continue
- elif e.errno == errno.ENOTDIR:
+ if e.errno in ignored_listdir_errnos:
del e
continue
elif e.errno == PermissionDenied.errno:
raise PermissionDenied(x)
raise
for y in eclass_filenames:
+ if not y.endswith(".eclass"):
+ continue
try:
mtime = long(os.stat(os.path.join(x, y)).st_mtime)
except OSError: