From b42ad34b96c811373dbf719dd4b3ceb3c5bd201c Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Sat, 11 Apr 2009 11:38:43 +0000 Subject: [PATCH] Due to too many conflicts, I have dropped support for EAPI=prefix sooner than originally planned. This commit removes the bits from ebuild.sh. Merged from trunk -r13296:13305 | 13297 | Make emerge --info display USE similarly to how they are | | zmedico | displayed in the merge list. | | 13298 | Make RecursiveFileLoader skip hidden directories, and only | | zmedico | use a single stat call to check for existence and file type. | | 13299 | Move the ebuild sourcing code into a new _source_ebuild() | | zmedico | function. | | 13300 | - Move DEFINED_PHASES code into _source_ebuild() and add it | | zmedico | to the list of readonly variables. - Save DEFINED_PHASES in | | | the vdb entries, as requested by lxnay. | | 13301 | Call _ebuild_phase_funcs() from ebuild_main() since it needs | | zmedico | to be called for every phase (for EAPI 2 default() phase | | | function setup). | | 13302 | Bug #265111 - Make current options override older options | | zmedico | for --resume. | | 13303 | Add UseFlagDisplay.sort_combined and sort_separated | | zmedico | attributes that can be passed directly as key parameters to | | | list.sort(). | | 13304 | Reorganize emerge --info display, and make sure that the | | zmedico | "cpv was built with the following" line is shown for every | | | package. | | 13305 | Don't try to execut the pkg_info phase if DEFINED_PHASES is | | zmedico | available and it shows that the phase is undefined. | svn path=/main/branches/prefix/; revision=13320 --- bin/ebuild.sh | 102 ++++++++++++------------- bin/isolated-functions.sh | 1 + pym/_emerge/__init__.py | 153 ++++++++++++++++++++++++++++++------- pym/portage/env/loaders.py | 15 ++-- 4 files changed, 187 insertions(+), 84 deletions(-) diff --git a/bin/ebuild.sh b/bin/ebuild.sh index 17b602b87..c7026a410 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -465,8 +465,7 @@ econf() { local phase_func=$(_ebuild_arg_to_phase "$EAPI" "$EBUILD_PHASE") if [[ -n $phase_func ]] ; then - local eapi=${EAPI/prefix/} ; eapi=${eapi# } - if hasq "$eapi" 0 1 ; then + if hasq "$EAPI" 0 1 ; then [[ $phase_func != src_compile ]] && \ eqawarn "QA Notice: econf called in" \ "$phase_func instead of src_compile" @@ -630,7 +629,7 @@ _eapi2_src_compile() { } src_install() { - if hasq prefix ${EAPI}; then + if use prefix ; then # this avoids misc errors in prefix because it doesn't exist # by default mkdir -p "${ED}" @@ -1018,7 +1017,7 @@ dyn_install() { local f x IFS=$' \t\n\r' for f in ASFLAGS CATEGORY CBUILD CC CFLAGS CHOST CTARGET CXX \ - CXXFLAGS DEPEND EXTRA_ECONF EXTRA_EINSTALL EXTRA_MAKE \ + CXXFLAGS DEFINED_PHASES DEPEND EXTRA_ECONF EXTRA_EINSTALL EXTRA_MAKE \ FEATURES INHERITED IUSE LDFLAGS LIBCFLAGS LIBCXXFLAGS \ LICENSE PDEPEND PF PKGUSE PROPERTIES PROVIDE RDEPEND RESTRICT SLOT \ KEYWORDS HOMEPAGE SRC_URI DESCRIPTION; do @@ -1540,14 +1539,6 @@ source_all_bashrcs() { PORTAGE_BASHRCS_SOURCED=1 local x - if [[ -n $EBUILD_PHASE && -n ${EAPI/prefix/} ]] ; then - # PREFIX HACK: just remove "prefix" from EAPI here, this file - # currently assumes EAPI to contain a single token, and "prefix" - # is ortogonal to all supported EAPIs here. - local phase_func=$(_ebuild_arg_to_phase ${EAPI/prefix/} $EBUILD_PHASE) - [[ -n $phase_func ]] && _ebuild_phase_funcs ${EAPI/prefix/} $phase_func - fi - local OCC="${CC}" OCXX="${CXX}" if [[ $EBUILD_PHASE != depend ]] ; then @@ -1584,7 +1575,7 @@ source_all_bashrcs() { # of ebuild.sh will work for pkg_postinst, pkg_prerm, and pkg_postrm # when portage is upgrading itself. -READONLY_EBUILD_METADATA="DEPEND DESCRIPTION +READONLY_EBUILD_METADATA="DEFINED_PHASES DEPEND DESCRIPTION EAPI HOMEPAGE INHERITED IUSE KEYWORDS LICENSE PDEPEND PROVIDE RDEPEND RESTRICT SLOT SRC_URI" @@ -1814,13 +1805,10 @@ if ! hasq "$EBUILD_PHASE" clean cleanrm depend && \ unset x y export SANDBOX_ON=${PORTAGE_SANDBOX_ON} unset PORTAGE_SANDBOX_ON + [[ -n $EAPI ]] || EAPI=0 fi -if ! hasq "$EBUILD_PHASE" clean cleanrm ; then -if [[ $EBUILD_PHASE = depend || ! -f $T/environment || \ - -f $PORTAGE_BUILDDIR/.ebuild_changed ]] || \ - hasq noauto $FEATURES ; then - +_source_ebuild() { # The bashrcs get an opportunity here to set aliases that will be expanded # during sourcing of ebuilds and eclasses. source_all_bashrcs @@ -1857,15 +1845,43 @@ if [[ $EBUILD_PHASE = depend || ! -f $T/environment || \ unset ECLASS E_IUSE E_DEPEND E_RDEPEND E_PDEPEND set +f + [[ -n $EAPI ]] || EAPI=0 + + # alphabetically ordered by $EBUILD_PHASE value + local valid_phases + case "$EAPI" in + 0|1) + valid_phases="src_compile pkg_config pkg_info src_install + pkg_nofetch pkg_postinst pkg_postrm pkg_preinst pkg_prerm + pkg_setup src_test src_unpack" + ;; + *) + valid_phases="src_compile pkg_config src_configure pkg_info + src_install pkg_nofetch pkg_postinst pkg_postrm pkg_preinst + src_prepare pkg_prerm pkg_setup src_test src_unpack" + ;; + esac + + DEFINED_PHASES= + for f in $valid_phases ; do + if [[ $(type -t $f) = function ]] ; then + f=${f#pkg_} + DEFINED_PHASES+=" ${f#src_}" + fi + done + [[ -n $DEFINED_PHASES ]] || DEFINED_PHASES=- + # This needs to be exported since prepstrip is a separate shell script. [[ -n $QA_PRESTRIPPED ]] && export QA_PRESTRIPPED -fi -fi +} -# Set default EAPI if necessary, so that most -# code can simply assume that it's defined. -# PREFIX HACK: ignore prefix, and then respect it again -[[ -n ${EAPI/prefix/} ]] || EAPI="${EAPI}${EAPI:+ }0" +if ! hasq "$EBUILD_PHASE" clean cleanrm ; then + if [[ $EBUILD_PHASE = depend || ! -f $T/environment || \ + -f $PORTAGE_BUILDDIR/.ebuild_changed ]] || \ + hasq noauto $FEATURES ; then + _source_ebuild + fi +fi # unset USE_EXPAND variables that contain only the special "*" token for x in ${USE_EXPAND} ; do @@ -1895,8 +1911,6 @@ fi ebuild_main() { local f x - local export_vars="ASFLAGS CCACHE_DIR CCACHE_SIZE - CFLAGS CXXFLAGS LDFLAGS LIBCFLAGS LIBCXXFLAGS" if ! hasq $EBUILD_SH_ARGS clean depend help info nofetch ; then @@ -1922,6 +1936,12 @@ ebuild_main() { fi fi + if [[ $EBUILD_PHASE != depend ]] ; then + local phase_func=$(_ebuild_arg_to_phase "$EAPI" "$EBUILD_PHASE") + [[ -n $phase_func ]] && _ebuild_phase_funcs "$EAPI" "$phase_func" + unset phase_func + fi + source_all_bashrcs case ${EBUILD_SH_ARGS} in @@ -1960,7 +1980,8 @@ ebuild_main() { case "$EBUILD_SH_ARGS" in configure|compile) - for x in $export_vars ; do + for x in ASFLAGS CCACHE_DIR CCACHE_SIZE \ + CFLAGS CXXFLAGS LDFLAGS LIBCFLAGS LIBCXXFLAGS ; do [[ ${!x-unset} != unset ]] && export $x done @@ -2056,34 +2077,9 @@ ebuild_main() { #the extra $(echo) commands remove newlines unset CDEPEND - # PREFIX HACK: ignore prefix, and then respect it again - [[ -n ${EAPI/prefix/} ]] || EAPI="${EAPI}${EAPI:+ }0" + [ -n "${EAPI}" ] || EAPI=0 local eapi=$EAPI - # alphabetically ordered by $EBUILD_PHASE value - local valid_phases - case ${eapi/prefix/} in - 0|1) - valid_phases="src_compile pkg_config pkg_info src_install - pkg_nofetch pkg_postinst pkg_postrm pkg_preinst pkg_prerm - pkg_setup src_test src_unpack" - ;; - *) - valid_phases="src_compile pkg_config src_configure pkg_info - src_install pkg_nofetch pkg_postinst pkg_postrm pkg_preinst - src_prepare pkg_prerm pkg_setup src_test src_unpack" - ;; - esac - - DEFINED_PHASES= - for f in $valid_phases ; do - if [[ $(type -t $f) = function ]] ; then - f=${f#pkg_} - DEFINED_PHASES+=" ${f#src_}" - fi - done - [[ -n $DEFINED_PHASES ]] || DEFINED_PHASES=- - if [ -n "${dbkey}" ] ; then > "${dbkey}" for f in ${auxdbkeys} ; do diff --git a/bin/isolated-functions.sh b/bin/isolated-functions.sh index 3f3ef6f4d..49f4e3d59 100755 --- a/bin/isolated-functions.sh +++ b/bin/isolated-functions.sh @@ -520,6 +520,7 @@ save_ebuild_env() { source_all_bashrcs ebuild_main \ ebuild_phase ebuild_phase_with_hooks \ _ebuild_arg_to_phase _ebuild_phase_funcs default \ + _source_ebuild \ ${QA_INTERCEPTORS} # portage config variables and variables set directly by portage diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index 41beb32f3..f889ed0b0 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -9268,6 +9268,47 @@ class PackageCounters(object): (self.blocks - self.blocks_satisfied)) return "".join(myoutput) +class UseFlagDisplay(object): + + __slots__ = ('name', 'enabled', 'forced') + + def __init__(self, name, enabled, forced): + self.name = name + self.enabled = enabled + self.forced = forced + + def __str__(self): + s = self.name + if self.enabled: + s = red(s) + else: + s = '-' + s + s = blue(s) + if self.forced: + s = '(%s)' % s + return s + + def _cmp_combined(a, b): + """ + Sort by name, combining enabled and disabled flags. + """ + return (a.name > b.name) - (a.name < b.name) + + sort_combined = cmp_sort_key(_cmp_combined) + del _cmp_combined + + def _cmp_separated(a, b): + """ + Sort by name, separating enabled flags from disabled flags. + """ + enabled_diff = b.enabled - a.enabled + if enabled_diff: + return enabled_diff + return (a.name > b.name) - (a.name < b.name) + + sort_separated = cmp_sort_key(_cmp_separated) + del _cmp_separated + class PollSelectAdapter(PollConstants): """ @@ -13593,6 +13634,12 @@ def action_info(settings, trees, myopts, myfiles): 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: @@ -13601,8 +13648,6 @@ def action_info(settings, trees, myopts, myfiles): print '%s="%s"' % (x, settings[x]) else: use = set(settings["USE"].split()) - use_expand = settings["USE_EXPAND"].split() - use_expand.sort() for varname in use_expand: flag_prefix = varname.lower() + "_" for f in list(use): @@ -13641,7 +13686,8 @@ def action_info(settings, trees, myopts, myfiles): # Get our global settings (we only print stuff if it varies from # the current config) mydesiredvars = [ 'CHOST', 'CFLAGS', 'CXXFLAGS', 'LDFLAGS', 'EPREFIX' ] - auxkeys = mydesiredvars + [ "USE", "IUSE"] + auxkeys = mydesiredvars + list(vardb._aux_cache_keys) + auxkeys.append('DEFINED_PHASES') global_vals = {} pkgsettings = portage.config(clone=settings) @@ -13656,12 +13702,17 @@ def action_info(settings, trees, myopts, myfiles): print header_width * "=" from portage.output import EOutput out = EOutput() - for pkg in mypkgs: + for cpv in mypkgs: # Get all package specific variables - auxvalues = vardb.aux_get(pkg, auxkeys) + 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') valuesmap = {} - for i in xrange(len(auxkeys)): - valuesmap[auxkeys[i]] = set(auxvalues[i].split()) + for k in auxkeys: + valuesmap[k] = set(metadata[k].split()) + diff_values = {} for myvar in mydesiredvars: # If the package variable doesn't match the @@ -13669,34 +13720,80 @@ def action_info(settings, trees, myopts, myfiles): # so set diff_found so we know to print if valuesmap[myvar] != global_vals[myvar]: diff_values[myvar] = valuesmap[myvar] - valuesmap["IUSE"] = set(filter_iuse_defaults(valuesmap["IUSE"])) - valuesmap["USE"] = valuesmap["USE"].intersection(valuesmap["IUSE"]) - pkgsettings.reset() - # If a matching ebuild is no longer available in the tree, maybe it - # would make sense to compare against the flags for the best - # available version with the same slot? - mydb = None - if portdb.cpv_exists(pkg): - mydb = portdb - pkgsettings.setcpv(pkg, mydb=mydb) - if valuesmap["IUSE"].intersection( - pkgsettings["PORTAGE_USE"].split()) != valuesmap["USE"]: - diff_values["USE"] = valuesmap["USE"] + + 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 + # If a difference was found, print the info for # this package. if diff_values: # Print package info - print "%s was built with the following:" % pkg - for myvar in mydesiredvars + ["USE"]: + for myvar in mydesiredvars: if myvar in diff_values: mylist = list(diff_values[myvar]) mylist.sort() print "%s=\"%s\"" % (myvar, " ".join(mylist)) - print - print ">>> Attempting to run pkg_info() for '%s'" % pkg - ebuildpath = vardb.findname(pkg) + 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) + out.ewarn("No ebuild found for '%s'" % pkg.cpv) continue portage.doebuild(ebuildpath, "info", pkgsettings["ROOT"], pkgsettings, debug=(settings.get("PORTAGE_DEBUG", "") == 1), @@ -14470,6 +14567,10 @@ def action_build(settings, trees, mtimedb, 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: diff --git a/pym/portage/env/loaders.py b/pym/portage/env/loaders.py index e031ed60f..400797c0c 100644 --- a/pym/portage/env/loaders.py +++ b/pym/portage/env/loaders.py @@ -4,6 +4,7 @@ # $Id$ import os +import stat class LoaderError(Exception): @@ -36,14 +37,18 @@ def RecursiveFileLoader(filename): @rtype: list @returns: List of files to process """ - if not os.path.exists(filename): + try: + st = os.stat(filename) + except OSError: return - elif os.path.isdir(filename): + if stat.S_ISDIR(st.st_mode): for root, dirs, files in os.walk(filename): - if 'CVS' in dirs: - dirs.remove('CVS') - files = [f for f in files if not f.startswith('.') and not f.endswith('~')] + for d in list(dirs): + if d[:1] == '.' or d == 'CVS': + dirs.remove(d) for f in files: + if f[:1] == '.' or f[-1:] == '~': + continue yield os.path.join(root, f) else: yield filename -- 2.26.2