# local variables can leak into the saved environment.
unset f
- (
- # To avoid environment.bz2 bloat, cleanse variables that are
- # are no longer needed after src_install(). Don't cleanse from
- # the global environment though, in case the user wants to repeat
- # this phase (like with FEATURES=noauto and the ebuild command).
- unset S _E_DOCDESTTREE_ _E_EXEDESTTREE_
- save_ebuild_env | filter_readonly_variables \
- --filter-sandbox --allow-extra-vars > environment
- )
+ save_ebuild_env --exclude-init-phases | filter_readonly_variables \
+ --filter-sandbox --allow-extra-vars > environment
+
bzip2 -f9 environment
cp "${EBUILD}" "${PF}.ebuild"
PATH="${stripped_path}"
}
-# @FUNCTION: source_all_bashrcs
+# @FUNCTION: _ebuild_arg_to_phase
# @DESCRIPTION:
-# Source a relevant bashrc files and perform other miscellaneous
-# environment initialization when appropriate:
-#
-# * If EAPI is set, define default_* functions provided by the current EAPI.
-#
-source_all_bashrcs() {
- [ -n "$EBUILD_PHASE" ] || return
- local x
+# Translate a known ebuild(1) argument into the precise
+# name of it's corresponding ebuild phase.
+_ebuild_arg_to_phase() {
+ [ $# -ne 2 ] && die "expected exactly 2 args, got $#: $*"
+ local eapi=$1
+ local arg=$2
+ local phase_func=""
+
+ case "$arg" in
+ setup)
+ phase_func=pkg_setup
+ ;;
+ nofetch)
+ phase_func=pkg_nofetch
+ ;;
+ unpack)
+ phase_func=src_unpack
+ ;;
+ configure)
+ ! hasq $eapi 0 1 2_pre1 && \
+ phase_func=src_configure
+ ;;
+ compile)
+ phase_func=src_compile
+ ;;
+ test)
+ phase_func=src_test
+ ;;
+ install)
+ phase_func=src_install
+ ;;
+ preinst)
+ phase_func=pkg_preinst
+ ;;
+ postinst)
+ phase_func=pkg_postinst
+ ;;
+ prerm)
+ phase_func=pkg_prerm
+ ;;
+ postrm)
+ phase_func=pkg_postrm
+ ;;
+ esac
+
+ [[ -z $phase_func ]] && return 1
+ echo "$phase_func"
+ return 0
+}
+
+_ebuild_phase_funcs() {
+ [ $# -ne 2 ] && die "expected exactly 2 args, got $#: $*"
+ local eapi=$1
+ local phase_func=$2
+ local eapi_has_default_fns=$(hasq $eapi 0 1 2_pre1 && echo 0 || echo 1)
local default_phases="pkg_nofetch src_unpack src_configure
src_compile src_test"
+ local x default_func=""
- if [[ -n $EAPI ]] && ! hasq "$EAPI" 0 1 2_pre1 ; then
- for x in $default_phases ; do
- eval "default_$x() { _default_$x \"\$@\" ; }"
- done
+ [[ $eapi_has_default_fns = 1 ]] && \
+ hasq $phase_func $default_phases && \
+ default_func=$phase_func
+
+ if [[ $eapi_has_default_fns = 1 ]] ; then
- [[ $(type -t src_configure) = function ]] || \
- src_configure() { _default_src_configure "$@" ; }
+ if [[ -n $default_func ]] ; then
+
+ for x in $default_phases ; do
+ eval "default_$x() { _default_$x \"\$@\" ; }"
+ done
+
+ [[ $(type -t src_configure) = function ]] || \
+ src_configure() { _default_src_configure "$@" ; }
+
+ eval "default() {
+ _default_$default_func "$@"
+ }"
+
+ else
+
+ for x in $default_phases ; do
+ eval "default_$x() {
+ die \"default_$x() is not supported in phase $default_func\"
+ }"
+ done
+
+ eval "default() {
+ die \"default() is not supported with EAPI='$eapi' during phase $phase_func\"
+ }"
+
+ fi
else
+
for x in $default_phases ; do
eval "default_$x() {
- die \"default_$x() is not supported with EAPI='$EAPI'\"
+ die \"default_$x() is not supported with EAPI='$eapi' during phase $phase_func\"
}"
done
+
+ default() {
+ die "default() is not supported with EAPI='$eapi' during phase $phase_func"
+ }
+
+ fi
+}
+
+# @FUNCTION: source_all_bashrcs
+# @DESCRIPTION:
+# Source a relevant bashrc files and perform other miscellaneous
+# environment initialization when appropriate.
+#
+# If EAPI is set then define functions provided by the current EAPI:
+#
+# * default_* aliases for the current EAPI phase functions
+# * A "default" function which is an alias for the default phase
+# function for the current phase.
+#
+source_all_bashrcs() {
+ [ -n "$EBUILD_PHASE" ] || return
+ local x
+
+ if [[ -n $EAPI ]] ; then
+ local phase_func=$(_ebuild_arg_to_phase "$EAPI" $EBUILD_PHASE)
+ [[ -n $phase_func ]] && _ebuild_phase_funcs "$EAPI" $phase_func
fi
local OCC="${CC}" OCXX="${CXX}"
if [[ $EBUILD_PHASE == postinst ]] && [[ -n $PORTAGE_UPDATE_ENV ]]; then
# Update environment.bz2 in case installation phases
# need to pass some variables to uninstallation phases.
- (
- unset S _E_DOCDESTTREE_ _E_EXEDESTTREE_
- save_ebuild_env | filter_readonly_variables \
- --filter-sandbox --allow-extra-vars | \
- bzip2 -c -f9 > "$PORTAGE_UPDATE_ENV"
- )
+ save_ebuild_env --exclude-init-phases | \
+ filter_readonly_variables --filter-sandbox --allow-extra-vars \
+ | bzip2 -c -f9 > "$PORTAGE_UPDATE_ENV"
fi
;;
unpack|configure|compile|test|clean|install)
# Internal logging function, don't use this in ebuilds
elog_base() {
- local line messagetype
+ local line lines=0 messagetype
[ -z "${1}" -o -z "${T}" -o ! -d "${T}/logging" ] && return 1
case "${1}" in
INFO|WARN|ERROR|LOG|QA)
save_IFS
IFS=$'\n'
for line in $* ; do
+ (( lines++ ))
echo -ne "${messagetype} ${line}\n\0" >> \
"${T}/logging/${EBUILD_PHASE:-other}"
done
restore_IFS
+
+ # This is needed in case a blank line is being shown.
+ [ $lines -eq 0 ] && \
+ echo -ne "${messagetype} $*\n\0" >> \
+ "${T}/logging/${EBUILD_PHASE:-other}"
+
return 0
}
eqawarn() {
elog_base QA "$*"
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
+ local line lines=0
save_IFS
IFS=$'\n'
- local line
for line in $* ; do
+ (( lines++ ))
vecho -e " ${WARN}*${NORMAL} ${line}" >&2
done
restore_IFS
+
+ # This is needed in case a blank line is being shown.
+ [ $lines -eq 0 ] && \
+ vecho -e " ${WARN}*${NORMAL} $*" >&2
+
LAST_E_CMD="eqawarn"
return 0
}
elog() {
elog_base LOG "$*"
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
+ local line lines=0
save_IFS
IFS=$'\n'
- local line
for line in $* ; do
+ (( lines++ ))
echo -e " ${GOOD}*${NORMAL} ${line}"
done
restore_IFS
+
+ # This is needed in case a blank line is being shown.
+ [ $lines -eq 0 ] && \
+ echo -e " ${GOOD}*${NORMAL} $*"
+
LAST_E_CMD="elog"
return 0
}
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
save_IFS
IFS=$'\n'
- local line
+ local line lines=0
for line in $* ; do
+ (( lines++ ))
echo -e " ${GOOD}*${NORMAL} ${line}"
done
restore_IFS
+
+ # This is needed in case a blank line is being shown.
+ [ $lines -eq 0 ] && \
+ echo -e " ${GOOD}*${NORMAL} $*"
+
LAST_E_CMD="einfo"
return 0
}
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
save_IFS
IFS=$'\n'
- local line
+ local line lines=0
for line in $* ; do
+ (( lines++ ))
echo -e " ${WARN}*${NORMAL} ${RC_INDENTATION}${line}" >&2
done
restore_IFS
+
+ # This is needed in case a blank line is being shown.
+ [ $lines -eq 0 ] && \
+ echo -e " ${WARN}*${NORMAL} ${RC_INDENTATION}$*" >&2
+
LAST_E_CMD="ewarn"
return 0
}
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
save_IFS
IFS=$'\n'
- local line
+ local line lines=0
for line in $* ; do
+ (( lines++ ))
echo -e " ${BAD}*${NORMAL} ${RC_INDENTATION}${line}" >&2
done
restore_IFS
+
+ # This is needed in case a blank line is being shown.
+ [ $lines -eq 0 ] && \
+ echo -e " ${BAD}*${NORMAL} ${RC_INDENTATION}$*" >&2
+
LAST_E_CMD="eerror"
return 0
}
# @FUNCTION: save_ebuild_env
# @DESCRIPTION:
# echo the current environment to stdout, filtering out redundant info.
+#
+# --exclude-init-phases causes pkg_nofetch and src_* phase functions to
+# be excluded from the output. These function are not needed for installation
+# or removal of the packages, and can therefore be safely excluded.
+#
save_ebuild_env() {
(
+ if hasq --exclude-init-phases $* ; then
+ unset S _E_DOCDESTTREE_ _E_EXEDESTTREE_
+ unset -f pkg_nofetch src_unpack src_configure \
+ src_compile src_test src_install
+ if [[ -n $PYTHONPATH ]] ; then
+ export PYTHONPATH=${PYTHONPATH/${PORTAGE_PYM_PATH}:}
+ [[ -z $PYTHONPATH ]] && unset PYTHONPATH
+ fi
+ fi
+
# misc variables set by bash
unset BASH HOSTTYPE IFS MACHTYPE OLDPWD \
OPTERR OPTIND OSTYPE PS4 PWD SHELL SHLVL
# There's no need to bloat environment.bz2 with internally defined
# functions and variables, so filter them out if possible.
+ for x in pkg_setup pkg_nofetch src_unpack src_configure \
+ src_compile src_test src_install pkg_preinst pkg_postinst \
+ pkg_prerm pkg_postrm ; do
+ unset -f {,_}default_$x
+ done
+ unset x
+
unset -f dump_trace die diefunc quiet_mode vecho elog_base eqawarn elog \
esyslog einfo einfon ewarn eerror ebegin _eend eend KV_major \
KV_minor KV_micro KV_to_int get_KV unset_colors set_colors has \
save_ebuild_env filter_readonly_variables preprocess_ebuild_env \
source_all_bashrcs ebuild_main \
ebuild_phase ebuild_phase_with_hooks \
+ _ebuild_arg_to_phase _ebuild_phase_funcs default \
${QA_INTERCEPTORS}
# portage config variables and variables set directly by portage
"ebuild.invalidname":"Ebuild files with a non-parseable or syntactically incorrect name (or using 2.1 versioning extensions)",
"ebuild.namenomatch":"Ebuild files that do not have the same name as their parent directory",
"changelog.missing":"Missing ChangeLog files",
- "ebuild.disjointed":"Ebuilds not added to cvs when the matching digest has been added",
"ebuild.notadded":"Ebuilds that exist but have not been added to cvs",
"ebuild.patches":"PATCHES variable should be a bash array to ensure white space safety",
"changelog.notadded":"ChangeLogs that exist but have not been added to cvs",
shared_xmatch_caches = {"cp-list":{}}
# Disable the "ebuild.notadded" check when not in commit mode and
-# running `svn list` and `svn status` calls in every package dir
-# will be too expensive.
+# running `svn status` in every package dir will be too expensive.
+
check_ebuild_notadded = not \
(vcs == "svn" and repolevel < 3 and options.mode != "commit")
#ebuilds and digests added to cvs respectively.
logging.info("checking package %s" % x)
eadded=[]
- dadded=[]
catdir,pkgdir=x.split("/")
checkdir=repodir+"/"+x
s = s[s.rfind("\n") + 1:]
fails["file.UTF8"].append("%s/%s: line %i, just after: '%s'" % (checkdir, y, line, s))
- has_filesdir = True
- if not os.path.isdir(os.path.join(checkdir, "files")):
- has_filesdir = False
-
if vcs and check_ebuild_notadded:
try:
if vcs == "cvs":
myf=open(checkdir+"/CVS/Entries","r")
if vcs == "svn":
- myf = os.popen("svn list " + checkdir)
- myl=myf.readlines()
+ myf = os.popen("svn status --depth=files --verbose " + checkdir)
+ myl = myf.readlines()
myf.close()
for l in myl:
if vcs == "cvs":
if splitl[0][-7:]==".ebuild":
eadded.append(splitl[0][:-7])
if vcs == "svn":
- l = l.rstrip();
- if l[-1:] == "/":
+ if l[:1] == "?":
continue
+ l = l.split()[-1]
if l[-7:] == ".ebuild":
eadded.append(os.path.basename(l[:-7]))
if vcs == "svn":
fails["svn.IO_error"].append(checkdir+"svn info")
continue
- if vcs and has_filesdir:
- try:
- if vcs == "cvs":
- myf=open(checkdir+"/files/CVS/Entries","r")
- if vcs == "svn":
- myf=os.popen("svn list "+os.path.normpath(checkdir+"/files"))
- myl=myf.readlines()
- myf.close()
- for l in myl:
- if vcs == "cvs":
- if l[0]!="/":
- continue
- splitl=l[1:].split("/")
- if not len(splitl):
- continue
- if splitl[0][:7]=="digest-":
- dadded.append(splitl[0][7:])
- if vcs == "svn":
- l = l.rstrip();
- if l[-1:] == "/":
- continue
- if l[:7] == "digest-":
- dadded.append(l[7:])
- if vcs == "svn":
- myf=os.popen("svn status "+os.path.normpath(checkdir+"/files"))
- myl=myf.readlines()
- myf.close()
- for l in myl:
- if l[0] == "A":
- l = l.rstrip().split(' ')[-1]
- if l[:7] == "digest-":
- dadded.append(l[7:])
- except IOError:
- if options.mode == 'commit' and vcs == "cvs":
- stats["CVS/Entries.IO_error"] += 1
- fails["CVS/Entries.IO_error"].append(checkdir+"/files/CVS/Entries")
- if options.mode == 'commit' and vcs == "svn":
- stats["svn.IO_error"] += 1
- fails["svn.IO_error"].append(checkdir+"/files svn info")
- continue
-
mf = Manifest(checkdir, repoman_settings["DISTDIR"])
mydigests=mf.getTypeDigests("DIST")
#ebuild not added to vcs
stats["ebuild.notadded"]=stats["ebuild.notadded"]+1
fails["ebuild.notadded"].append(x+"/"+y+".ebuild")
- if y in dadded:
- stats["ebuild.disjointed"]=stats["ebuild.disjointed"]+1
- fails["ebuild.disjointed"].append(x+"/"+y+".ebuild")
+
myesplit=portage.pkgsplit(y)
if myesplit is None or myesplit[0] != x.split("/")[-1]:
stats["ebuild.invalidname"]=stats["ebuild.invalidname"]+1
if vcs == "svn":
svnstatus = os.popen("svn status").readlines()
- mychanged = [ elem.rstrip()[7:] for elem in svnstatus if elem.startswith("M") ]
+ mychanged = [ elem.rstrip()[7:] for elem in svnstatus if elem and elem[:1] in "MR" ]
mynew = [ elem.rstrip()[7:] for elem in svnstatus if elem.startswith("A") ]
myremoved = [ elem.rstrip()[7:] for elem in svnstatus if elem.startswith("D") ]
# in contrast to CVS, SVN expands nothing by default.
implementation.
</para>
</sect3>
+ <sect3 id='package-ebuild-eapi-2-phases-default-function-alias'>
+ <title>Default Phase Function Alias</title>
+ <para>
+ A function named "default" is redefined for each phase so that it
+ will call the default_* function corresponding to the current phase.
+ For example, a call to the function named "default" during the
+ src_compile phase is equivalent to a call to the function named
+ default_src_compile.
+ </para>
+ </sect3>
</sect2>
</sect1>
.B ebuild.badheader
This ebuild has a malformed header
.TP
-.B ebuild.disjointed
-Ebuilds not added to cvs when the matching digest has been added
-.TP
.B ebuild.invalidname
Ebuild files with a non-parseable or syntactically incorrect name (or using 2.1 versioning extensions)
.TP
f.add_literal_data(load_avg_str)
self._update(color_output.getvalue())
- xtermTitle(plain_output.getvalue())
+ xtermTitle(" ".join(plain_output.getvalue().split()))
class Scheduler(PollScheduler):
for opt in ("--skipfirst", "--ask", "--tree"):
resume_opts.pop(opt, None)
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
del mtimedb["resume"]
mtimedb.commit()
mtimedb["resume"]={}
- # XXX: Stored as a list for backward compatibility.
- mtimedb["resume"]["myopts"] = \
- [k for k in myopts if myopts[k] is True]
+ # Stored as a dict starting with portage-2.2_rc7, 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 since the mtimedb loader
# sets unpickler.find_global = None which causes unpickler.load()
"ebuild's files must be downloaded"
print "!!! manually. See the comments in" + \
" the ebuild for more information.\n"
- mysettings["EBUILD_PHASE"] = "unpack"
- spawn(EBUILD_SH_BINARY + " nofetch", mysettings)
+ ebuild_phase = mysettings.get("EBUILD_PHASE")
+ try:
+ mysettings["EBUILD_PHASE"] = "nofetch"
+ spawn(_shell_quote(EBUILD_SH_BINARY) + \
+ " nofetch", mysettings)
+ finally:
+ if ebuild_phase is None:
+ mysettings.pop("EBUILD_PHASE", None)
+ else:
+ mysettings["EBUILD_PHASE"] = ebuild_phase
elif listonly:
continue
elif not filedict[myfile]:
raise cache_errors.CacheCorruption(cpv, e)
for k, v in values.iteritems():
+ if not v:
+ continue
if k != "_mtime_" and (k == "_eclasses_" or k in self._known_keys):
myf.write("%s=%s\n" % (k, v))
EBUILD_PHASES = ["setup", "unpack", "configure",
"compile", "test", "install",
"package", "preinst", "postinst","prerm", "postrm",
- "other"]
+ "nofetch", "other"]
EAPI = 1
root = self.root
root_len = len(root) - 1
new_contents = pkg.getcontents().copy()
- contents_key = None
+ removed = 0
for filename in paths:
filename = normalize_path(filename)
contents_key = pkg._match_contents(relative_filename, root)
if contents_key:
del new_contents[contents_key]
+ removed += 1
- if contents_key:
+ if removed:
f = atomic_ofstream(os.path.join(pkg.dbdir, "CONTENTS"))
write_contents(new_contents, root, f)
f.close()