* Ebuild output is no longer cut off early when using PORT_LOGDIR.
* Distfiles indirection- $DISTFILES access goes through a tmp dir to fail
access to files not listed in SRC_URI.
+* Emerge now uses --resume to restart itself after portage upgrade.
+* Atomic file updates via the new atomic_ofstream class.
+* Global updates and fixpackages performance optimizations.
+* Tests show that file locking is now more reliable.
+* A bash call stack is printed when an ebuild dies in ebuild.sh.
* USE flag output ordering has changed. The old ordering is now an option
by the name of --alphabetical. Adding the option to EMERGE_DEFAULT_OPTS
in make.conf will restore the old behaviour permanently.
+* The deprecated --inject has been removed, use /etc/portage/profile/package.provided
+* The deprecated --upgradeonly has been removed, use /etc/portage/package.*
+ instead.
+* 'emerge sync' has been deprecated, use 'emerge --sync' instead (same
+ for other actions)
+* Tools that call emerge should override the EMERGE_DEFAULT_OPTS environment
+ variable or use the emerge --ignore-default-opts option.
# Distributed under the terms of the GNU General Public License v2
# $Id: /var/cvsroot/gentoo-src/portage/bin/doman,v 1.13.2.2 2005/07/29 05:55:34 vapier Exp $
-if [ $# -lt 1 ] ; then
+if [[ $# -lt 1 ]] ; then
echo "$0: at least one argument needed" 1>&2
exit 1
fi
-BASE="/usr/share"
i18n=""
+ret=0
+
for x in "$@" ; do
- if [ "${x:0:6}" == "-i18n=" ] ; then
- i18n="${x:6}/"
+ if [[ ${x:0:6} == "-i18n=" ]] ; then
+ i18n=${x:6}/
continue
fi
- if [ "${x}" == ".keep" ] ; then
+ if [[ ${x} == ".keep" ]] ; then
continue
fi
suffix=${x##*.}
- if [ "$suffix" == "gz" ] ; then
- compressed="gz"
- realname="${x%.*}"
- suffix="${realname##*.}"
- else
- realname="$x"
- compressed=""
+ if [[ ${suffix} == "gz" ]] ; then
+ realname=${x%.*}
+ suffix=${realname##*.}
+ echo "QA Notice: you should let portage compress '${realname}' for you" 2>&1
fi
mandir=${i18n}man${suffix:0:1}
if echo ${mandir} | @EGREP@ -q 'man[0-9n](|f|p|pm)$' -; then
- if [ -s "${x}" ] ; then
- if [ ! -d "${D}${BASE}/man/${mandir}" ] ; then
- install -d "${D}${BASE}/man/${mandir}"
+ if [[ -s ${x} ]] ; then
+ if [[ ! -d ${D}/usr/share/man/${mandir} ]] ; then
+ install -d "${D}/usr/share/man/${mandir}"
fi
- install -m0644 "${x}" "${D}${BASE}/man/${mandir}"
-
- if [ -z "${compressed}" ] ; then
- gzip -f -9 "${D}${BASE}/man/${mandir}/${x##*/}"
- fi
- else
+ install -m0644 "${x}" "${D}/usr/share/man/${mandir}"
+ ((ret+=$?))
+ elif [[ ! -e ${x} ]] ; then
echo "doman: ${x} does not exist" 1>&2
+ ((++ret))
fi
else
echo "doman: '${x}' is probably not a man page; skipping" 1>&2
+ ((++ret))
fi
done
+
+exit ${ret}
import portage, portage_util, portage_const
+if portage.settings["NOCOLOR"] in ("yes","true") or not sys.stdout.isatty():
+ import output
+ output.nocolor()
+
ebuild = os.path.realpath(pargs.pop(0))
if not os.path.exists(ebuild):
# are supported at the moment. Keep this list in sync with
# http://hardened.gentoo.org/gnu-stack.xml (Arch Status)
case ${CTARGET:-${CHOST}} in
- i?86*|ia64*|m68k*|s390*|x86_64*)
+ i?86*|ia64*|m68k*|powerpc64*|s390*|x86_64*)
f=$(scanelf -qyRF '%e %p' "${D}") ;;
*)
f="" ;;
params=["selective", "deep", "self", "recurse", "empty"]
actions=[
"clean", "config", "depclean",
-"info", "inject", "metadata",
-"prune", "regen", "rsync", "search",
+"info", "metadata",
+"prune", "regen", "search",
"sync", "system", "unmerge", "world",
]
options=[
"--searchdesc", "--selective",
"--skipfirst", "--skip-first",
"--tree",
-"--update", "--upgradeonly",
+"--update",
"--usepkg", "--usepkgonly",
"--verbose", "--version"
]
"f":"--fetchonly", "F":"--fetch-all-uri",
"g":"--getbinpkg", "G":"--getbinpkgonly",
"h":"--help",
-"i":"--inject",
"k":"--usepkg", "K":"--usepkgonly",
"l":"--changelog",
"n":"--noreplace", "N":"--newuse",
"q":"--quiet",
"s":"--search", "S":"--searchdesc",
't':"--tree",
-"u":"--update", "U":"--upgradeonly",
+"u":"--update",
"v":"--verbose", "V":"--version"
}
elif x == "--skip-first":
x = "--skipfirst"
if x in options:
- myopts.append(x)
+ if x not in myopts:
+ myopts.append(x)
elif x[2:] in actions:
- if x[2:]=="rsync" or x=="rsync":
- # "emerge --rsync"
- print
- print red("*** '--rsync' has been deprecated.")
- print red("*** Please use '--sync' instead.")
- print
- x="--sync"
if myaction:
if myaction not in ["system", "world"]:
myaction="--"+myaction
sys.exit(1)
elif (not myaction) and (x in actions):
if x not in ["system", "world"]:
- #print red("*** Deprecated use of action '"+x+"'")
- if x=="rsync":
- # "emerge rsync"
- print
- print red("*** 'rsync' will now install the package rsync.")
- print red("*** To sync the tree, please use '--sync' instead.")
- print
- myfiles.append(x)
- continue
+ print red("*** Deprecated use of action '%s', use '--%s' instead" % (x,x))
if myaction:
print
print red("!!!")+green(" Multiple actions requested... Please choose one only.")
print ">>> --newuse implies --update... adding --update to options."
myopts.append("--update")
-# Print deprecation warning for -U
-if ("--upgradeonly" in myopts):
- print
- print red("*** Warning: --upgradeonly is a deprecated option in portage-"+portage.VERSION)
- print red("*** and will likely be removed in a future version.")
- print
- # Also allow -U to apply --update/-u
- if not ("--update" in myopts):
- print ">>> --upgradeonly implies --update... adding --update to options."
- myopts.append("--update")
-
# Also allow -l to apply --pretend/-p, but if already in --ask mode
if ("--changelog" in myopts) and not (("--pretend" in myopts) or ("--ask" in myopts)):
print ">>> --changelog implies --pretend... adding --pretend to options."
if portage.settings["EMERGE_WARNING_DELAY"]:
EMERGE_WARNING_DELAY = string.atoi("0"+portage.settings["EMERGE_WARNING_DELAY"])
-if "inject" == myaction:
- print
- print red("*** --inject has been deprecated.")
- print red("*** If you manage a piece of software yourself, add it's name and")
- print red("*** version (eg foo/bar-1.0) to /etc/portage/profile/package.provided.")
- print red("*** If you want to prevent portage from upgrading a package, add it to")
- print red("*** /etc/portage/package.mask prepending it with '>' (eg >foo/bar-1.0)")
- print red("*** For more information on fine-grained portage control, please see")
- print red("*** the portage man page.")
- print
-
def emergelog(mystr,short_msg=None):
if "notitles" not in portage.features:
if short_msg:
else:
myeb_pkg = None
- if "--upgradeonly" in myopts:
- # Check that there isn't a newer version of this package already installed
- cand = None
- try:
- # XXX: This can throw an exception if the ebuild doesn't exist
- if myeb:
- cand=self.is_newer_ver_installed(myroot,x,myeb)
- elif myeb_pkg:
- cand=self.is_newer_ver_installed(myroot,x,myeb_pkg)
- except SystemExit, e:
- raise # Needed else can't exit
- except Exception, e:
- print "Warning: "+str(e)
- if cand:
- # --newuse can't work because the installed version isn't available
- # just pretend like the package doesn't matter
- # XXX: hidden assumption here that the higher versioned package
- # satisfies the atom that was given
- continue
-
if myeb:
myk=["ebuild",myroot,myeb]
elif myeb_pkg:
y=portage.portdb.findname(x[pkgindex])
if not "--pretend" in myopts:
print ">>> Emerging ("+str(mergecount)+" of "+str(len(mymergelist))+")",x[pkgindex],"to",x[1]
- emergelog(" >>> Emerging ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" to "+x[1])
+ emergelog(" >>> emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" to "+x[1])
self.pkgsettings["EMERGE_FROM"] = x[0][:]
self.pkgsettings.backup_changes("EMERGE_FROM")
if "--debug" in myopts:
edebug=1
-if myaction in ["sync","rsync","metadata"] and (not "--help" in myopts):
+if myaction in ["sync","metadata"] and (not "--help" in myopts):
if "--pretend" in myopts:
print "emerge: \"sync\" actions do not support \"--pretend.\""
sys.exit(1)
except:
pass
+ if updatecache_flg and \
+ myaction != "metadata" and \
+ "metadata-transfer" not in portage.settings.features:
+ updatecache_flg = False
+
if os.path.exists(myportdir+"/metadata/cache") and updatecache_flg:
if "--quiet" not in myopts:
print "\n>>> Updating Portage cache: ",
print "\n!!! Regular expression error in \"%s\": %s" % ( mysearch, comment )
sys.exit(1)
searchinstance.output()
-elif "inject"==myaction:
- if not myfiles:
- print "emerge: please specify at least one cat/pkg-ver to inject."
- sys.exit(1)
- if "--pretend" in myopts:
- print "emerge: the \"inject\" action does not support \"--pretend.\""
- sys.exit(1)
- for x in myfiles:
- if x[0] in [">","<","=","!"]:
- print "!!! '"+x+"' is an invalid specification."
- print "!!! Must be 'category/package-version' with no other symbols."
- print
- continue
- mycps=portage.catpkgsplit(x)
- if (not mycps) or (mycps[0]=="null"):
- print "!!!",x,"is not a specific cat/pkg-version, skipping..."
- continue
- if portage.db["/"]["vartree"].exists_specific(x):
- print "!!! Not injecting",x+"; Package already exists."
- else:
- if "--ask" in myopts:
- if userquery("Do you want to inject the package %s?" % x)=="No":
- print
- print "Quitting."
- print
- sys.exit(0)
- portage.db["/"]["vartree"].dbapi.cpv_inject(x)
- print ">>> Injected",x+"."
- emergelog(" === inject: "+x)
elif "unmerge"==myaction or "prune"==myaction or "clean"==myaction:
if 1==unmerge(myaction, myfiles):
post_emerge()
echo "man:"
for x in "${D}"/opt/*/man "${D}"/usr/share/man "${D}"/usr/local/man "${D}"/usr/X11R6/man ; do
if [[ -d ${x} ]] ; then
- prepman "`echo "${x}" | sed -e "s:${D}::" -e "s:/man[/]*$::"`"
+ x=${x#${D}}
+ x=${x%/man}
+ prepman "${x}"
((ret+=$?))
fi
done
# Distributed under the terms of the GNU General Public License v2
# $Id: /var/cvsroot/gentoo-src/portage/bin/prepallstrip,v 1.12 2004/10/04 13:56:50 vapier Exp $
-if [[ " ${FEATURES} " == *" nostrip "* ]] || \
- [[ " ${RESTRICT} " == *" nostrip "* ]] || \
- [[ " ${RESTRICT} " == *" strip "* ]]
-then
- exit 0
-fi
-
-echo "prepallstrip:"
exec prepstrip "${D}"
# Distributed under the terms of the GNU General Public License v2
# $Id: /var/cvsroot/gentoo-src/portage/bin/prepman,v 1.10.2.3 2005/05/29 12:40:08 jstubbs Exp $
-if [ -z "$1" ] ; then
+if [[ -z $1 ]] ; then
z="${D}/usr/share/man"
else
z="${D}$1/man"
fi
-[ ! -d "${z}" ] && exit 0
+if [[ ! -d ${z} ]] ; then
+ echo "QA Notice: prepman called with non-existent dir '${z#${D}}'" 2>&1
+ exit 0
+fi
-for x in `find "${z}"/ -type d 2>/dev/null` ; do
- for y in `find "${x}"/ -mindepth 1 -maxdepth 1 \( -type f -or -type l \) ! -name '.keep' 2>/dev/null` ; do
- if [ -L "${y}" ] ; then
+for x in $(find "${z}"/ -type d 2>/dev/null) ; do
+ for y in $(find "${x}"/ -mindepth 1 -maxdepth 1 \( -type f -or -type l \) ! -name '.keep' 2>/dev/null) ; do
+ if [[ -L ${y} ]] ; then
# Symlink ...
- mylink="${y}"
- linkto="`readlink "${y}"`"
+ mylink=${y}
+ linkto=$(readlink "${y}")
# Do NOT change links to directories
- if [ -d "${z}/${linkto}" ] ; then
+ if [[ -d ${z}/${linkto} ]] ; then
continue
fi
-
- if [ "${linkto##*.}" != "gz" ] && [ "${linkto##*.}" != "bz2" ]; then
+
+ if [[ ${linkto##*.} != "gz" ]] && [[ ${linkto##*.} != "bz2" ]] ; then
linkto="${linkto}.gz"
fi
- if [ "${mylink##*.}" != "gz" ] && [ "${mylink##*.}" != "bz2" ]; then
+ if [[ ${mylink##*.} != "gz" ]] && [[ ${mylink##*.} != "bz2" ]] ; then
mylink="${mylink}.gz"
fi
echo "fixing man page symlink: ${mylink##*/}"
ln -snf "${linkto}" "${mylink}"
- if [ "${y}" != "${mylink}" ] ; then
+ if [[ ${y} != "${mylink}" ]] ; then
echo "removing old symlink: ${y##*/}"
rm -f "${y}"
fi
else
- if [ "${y##*.}" != "gz" ] && [ "${y##*.}" != "bz2" ] && [ ! -d "${y}" ]; then
+ if [[ ${y##*.} != "gz" ]] && [[ ${y##*.} != "bz2" ]] && [[ ! -d ${y} ]] ; then
echo "gzipping man page: ${y##*/}"
gzip -f -9 "${y}"
fi
def err(txt):
warn(txt)
sys.exit(1)
+
def err_help(txt):
help(exitstatus=-1,helpfulness=0)
warn(txt)
qawarnings.append(x)
-def err(txt):
- print exename+": "+txt
- sys.exit(1)
-
ven_cat = r'[\w0-9-]+' # Category
ven_nam = r'([+a-z0-9-]+(?:[+_a-z0-9-]*[+a-z0-9-]+)*)' # Name
ven_ver = r'((?:\d+\.)*\d+[a-z]?)' # Version
def show_version():
print exename+" "+version
sys.exit(0)
+
def help(exitstatus=1,helpfulness=1):
if quiet:
helpfulness=0
fails["ebuild.namenomatch"].append(x+"/"+y+".ebuild")
continue
try:
- myaux=portage.db["/"]["porttree"].dbapi.aux_get(catdir+"/"+y,allvars)
+ myaux = dict( zip(allvars, portage.db["/"]["porttree"].dbapi.aux_get(catdir+"/"+y, allvars ) ) )
except KeyError:
stats["ebuild.syntax"]=stats["ebuild.syntax"]+1
fails["ebuild.syntax"].append(x+"/"+y+".ebuild")
fails["ebuild.output"].append(x+"/"+y+".ebuild")
continue
- mynewaux = {}
- for idx in range(len(allvars)):
- if idx < len(myaux):
- mynewaux[allvars[idx]] = myaux[idx]
- else:
- mynewaux[allvars[idx]] = ""
- myaux = mynewaux
-
# Test for negative logic and bad words in the RESTRICT var.
#for x in myaux[allvars.index("RESTRICT")].split():
# if x.startswith("no"):
# 'keepwork' prevents the clean phase from deleting the WORKDIR.
# 'test' causes ebuilds to perform testing phases if they are capable
# of it. Some packages support this automaticaly via makefiles.
+# 'metadata-transfer'
+# automatically perform a metadata transfer when `emerge --sync`
+# is run.
# 'noauto' causes ebuild to perform only the action requested and
# not any other required actions like clean or unpack -- for
# debugging purposes only.
# 'keepwork' prevents the clean phase from deleting the WORKDIR.
# 'test' causes ebuilds to perform testing phases if they are capable
# of it. Some packages support this automaticaly via makefiles.
+# 'metadata-transfer'
+# automatically perform a metadata transfer when `emerge --sync`
+# is run.
# 'noauto' causes ebuild to perform only the action requested and
# not any other required actions like clean or unpack -- for
# debugging purposes only.
# 'keepwork' prevents the clean phase from deleting the WORKDIR.
# 'test' causes ebuilds to perform testing phases if they are capable
# of it. Some packages support this automaticaly via makefiles.
+# 'metadata-transfer'
+# automatically perform a metadata transfer when `emerge --sync`
+# is run.
# 'noauto' causes ebuild to perform only the action requested and
# not any other required actions like clean or unpack -- for
# debugging purposes only.
# 'keepwork' prevents the clean phase from deleting the WORKDIR.
# 'test' causes ebuilds to perform testing phases if they are capable
# of it. Some packages support this automaticaly via makefiles.
+# 'metadata-transfer'
+# automatically perform a metadata transfer when `emerge --sync`
+# is run.
# 'noauto' causes ebuild to perform only the action requested and
# not any other required actions like clean or unpack -- for
# debugging purposes only.
# 'keepwork' prevents the clean phase from deleting the WORKDIR.
# 'test' causes ebuilds to perform testing phases if they are capable
# of it. Some packages support this automaticaly via makefiles.
+# 'metadata-transfer'
+# automatically perform a metadata transfer when `emerge --sync`
+# is run.
# 'noauto' causes ebuild to perform only the action requested and
# not any other required actions like clean or unpack -- for
# debugging purposes only.
# 'keepwork' prevents the clean phase from deleting the WORKDIR.
# 'test' causes ebuilds to perform testing phases if they are capable
# of it. Some packages support this automaticaly via makefiles.
+# 'metadata-transfer'
+# automatically perform a metadata transfer when `emerge --sync`
+# is run.
# 'noauto' causes ebuild to perform only the action requested and
# not any other required actions like clean or unpack -- for
# debugging purposes only.
# 'keepwork' prevents the clean phase from deleting the WORKDIR.
# 'test' causes ebuilds to perform testing phases if they are capable
# of it. Some packages support this automaticaly via makefiles.
+# 'metadata-transfer'
+# automatically perform a metadata transfer when `emerge --sync`
+# is run.
# 'noauto' causes ebuild to perform only the action requested and
# not any other required actions like clean or unpack -- for
# debugging purposes only.
# 'keepwork' prevents the clean phase from deleting the WORKDIR.
# 'test' causes ebuilds to perform testing phases if they are capable
# of it. Some packages support this automaticaly via makefiles.
+# 'metadata-transfer'
+# automatically perform a metadata transfer when `emerge --sync`
+# is run.
# 'noauto' causes ebuild to perform only the action requested and
# not any other required actions like clean or unpack -- for
# debugging purposes only.
# 'keepwork' prevents the clean phase from deleting the WORKDIR.
# 'test' causes ebuilds to perform testing phases if they are capable
# of it. Some packages support this automaticaly via makefiles.
+# 'metadata-transfer'
+# automatically perform a metadata transfer when `emerge --sync`
+# is run.
# 'noauto' causes ebuild to perform only the action requested and
# not any other required actions like clean or unpack -- for
# debugging purposes only.
# 'keepwork' prevents the clean phase from deleting the WORKDIR.
# 'test' causes ebuilds to perform testing phases if they are capable
# of it. Some packages support this automaticaly via makefiles.
+# 'metadata-transfer'
+# automatically perform a metadata transfer when `emerge --sync`
+# is run.
# 'noauto' causes ebuild to perform only the action requested and
# not any other required actions like clean or unpack -- for
# debugging purposes only.
# 'keepwork' prevents the clean phase from deleting the WORKDIR.
# 'test' causes ebuilds to perform testing phases if they are capable
# of it. Some packages support this automaticaly via makefiles.
+# 'metadata-transfer'
+# automatically perform a metadata transfer when `emerge --sync`
+# is run.
# 'noauto' causes ebuild to perform only the action requested and
# not any other required actions like clean or unpack -- for
# debugging purposes only.
# 'keepwork' prevents the clean phase from deleting the WORKDIR.
# 'test' causes ebuilds to perform testing phases if they are capable
# of it. Some packages support this automaticaly via makefiles.
+# 'metadata-transfer'
+# automatically perform a metadata transfer when `emerge --sync`
+# is run.
# 'noauto' causes ebuild to perform only the action requested and
# not any other required actions like clean or unpack -- for
# debugging purposes only.
# 'keepwork' prevents the clean phase from deleting the WORKDIR.
# 'test' causes ebuilds to perform testing phases if they are capable
# of it. Some packages support this automaticaly via makefiles.
+# 'metadata-transfer'
+# automatically perform a metadata transfer when `emerge --sync`
+# is run.
# 'noauto' causes ebuild to perform only the action requested and
# not any other required actions like clean or unpack -- for
# debugging purposes only.
RESUMECOMMAND="/usr/bin/wget -c -t 5 --passive-ftp -P \${DISTDIR} \${URI}"
# Default user options
-FEATURES="sandbox distlocks"
+FEATURES="sandbox distlocks metadata-transfer"
# Default chunksize for binhost comms
PORTAGE_BINHOST_CHUNKSIZE="3000"
information when submitting a bug report.\fR Expanded output can be obtained
with the \fI\-\-verbose\fR option.
.TP
-.BR "\-\-inject " (\fB\-i\fR)
-Injecting a package inserts a 'stub' for that package so that Portage
-thinks that it is installed. It is handy if you need, say, a binary
-version of XFree86 for esoteric hardware, or you just like to roll
-your own packages. You \fBmust\fR specify a category and particular
-version of a package for injecting. For example,
-\fBemerge \-\-inject sys\-kernel/gentoo\-sources\-2.4.19\fR.
-.TP
.BR \-\-metadata
Causes portage to process all the metacache files as is normally done on the
tail end of an rsync update using \fBemerge \-\-sync\fR. The processing
also update direct dependencies which may not be what you want. In general,
use this option only in combination with the world or system target.
.TP
-.BR "\-\-upgradeonly " (\fB\-U\fR)
-Updates packages, but excludes updates that would result in a lower version of
-the package being installed. \fBSLOT\fRs are considered at a basic level.
-.br
-This option is deprecated and should not be used anymore. Please use the
-/etc/portage/package.* files from now on.
-.TP
.BR "\-\-version " (\fB\-V\fR)
Displays the version number of \fBemerge\fR.
.TP
.B keepwork
Do not delete the ${WORKDIR} directory after the merge process.
.TP
+.B metadata-transfer
+Automatically perform a metadata transfer when `emerge --sync` is run.
+.TP
.B mirror
This will cause \fBFETCHCOMMAND\fR to always be run even if
the file already exists in \fBDISTDIR\fR.
raise cache_errors.CacheCorruption(cpv, e)
for k, v in values.items():
- if k != "_mtime_":
+ if k != "_mtime_" and (k == "_eclasses_" or k in self._known_keys):
myf.writelines("%s=%s\n" % (k, v))
myf.close()
if not c.isalpha():
if c == "=" and idx > 0:
hashed = True
- d[line[:idx]] = line[idx + 1:]
+ d[line[:idx]] = line[idx + 1:].rstrip("\n")
elif c == "_" or c.isdigit():
continue
break
--- /dev/null
+# Copyright 1999-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+import time
+if not hasattr(__builtins__, "set"):
+ from sets import Set as set
+import template
+from flat_hash import database as db_rw
+from metadata import database as db_ro
+
+class database(template.database):
+
+ autocommits = True
+ serialize_eclasses = False
+
+ def __init__(self, location, label, auxdbkeys, **config):
+ super(database, self).__init__(location, label, auxdbkeys)
+ self.db_rw = db_rw(location, label, auxdbkeys, **config)
+ self.db_ro = db_ro(label,"metadata/cache",auxdbkeys)
+
+ def __getitem__(self, cpv):
+ """funnel whiteout validation through here, since value needs to be fetched"""
+ try:
+ value = self.db_rw[cpv]
+ except KeyError:
+ return self.db_ro[cpv] # raises a KeyError when necessary
+ if self._is_whiteout(value):
+ if self._is_whiteout_valid(cpv, value):
+ raise KeyError(cpv)
+ else:
+ del self.db_rw[cpv]
+ return self.db_ro[cpv] # raises a KeyError when necessary
+ else:
+ return value
+
+ def _setitem(self, name, values):
+ try:
+ value_ro = self.db_ro[name]
+ if self._are_values_identical(value_ro,values):
+ # we have matching values in the underlying db_ro
+ # so it is unnecessary to store data in db_rw
+ try:
+ del self.db_rw[name] # delete unwanted whiteout when necessary
+ except KeyError:
+ pass
+ except KeyError:
+ self.db_rw[name] = values
+
+ def _delitem(self, cpv):
+ value = self[cpv] # validates whiteout and/or raises a KeyError when necessary
+ if self.db_ro.has_key(cpv):
+ self.db_rw[cpv] = self._create_whiteout(value)
+ else:
+ del self.db_rw[cpv]
+
+ def has_key(self, cpv):
+ try:
+ self[cpv] # validates whiteout when necessary
+ except KeyError:
+ return False
+ return True
+
+ def iterkeys(self):
+ s = set()
+ for cpv in self.db_rw.iterkeys():
+ if self.has_key(cpv): # validates whiteout when necessary
+ yield cpv
+ # set includes whiteouts so they won't be yielded later
+ s.add(cpv)
+ for cpv in self.db_ro.iterkeys():
+ if cpv not in s:
+ yield cpv
+
+ def _is_whiteout(self, value):
+ return value["EAPI"] == "whiteout"
+
+ def _create_whiteout(self, value):
+ return {"EAPI":"whiteout","_eclasses_":value["_eclasses_"],"_mtime_":value["_mtime_"]}
+
+ def _is_whiteout_valid(self, name, value_rw):
+ try:
+ value_ro = self.db_ro[name]
+ return self._are_values_identical(value_rw,value_ro)
+ except KeyError:
+ return False
+
+ def _are_values_identical(self, value1, value2):
+ if long(value1["_mtime_"]) != long(value2["_mtime_"]):
+ return False
+ return value1["_eclasses_"] == value2["_eclasses_"]
# basically flags the cache needs be updated when transfered cache to cache.
# leave this.
- complete_eclass_entries_ = True
+ complete_eclass_entries = True
autocommits = False
cleanse_keys = False
serialize_eclasses = True
print " "+turquoise("emerge")+" [ "+green("options")+" ] [ "+green("action")+" ] < "+turquoise("system")+" | "+turquoise("world")+" >"
print " "+turquoise("emerge")+" < "+turquoise("--sync")+" | "+turquoise("--metadata")+" | "+turquoise("--info")+" >"
print " "+turquoise("emerge")+" "+turquoise("--resume")+" [ "+green("--pretend")+" | "+green("--ask")+" | "+green("--skipfirst")+" ]"
- print " "+turquoise("emerge")+" "+turquoise("--help")+" [ "+green("system")+" | "+green("config")+" | "+green("sync")+" ] "
- print bold("Options:")+" "+green("-")+"["+green("abcCdDefhikKlnNoOpPsSuUvV")+"] ["+green("--oneshot")+"] ["+green("--newuse")+"] ["+green("--noconfmem")+"]"
+ print " "+turquoise("emerge")+" "+turquoise("--help")+" [ "+green("system")+" | "+green("config")+" | "+green("--sync")+" ] "
+ print bold("Options:")+" "+green("-")+"["+green("abcCdDefhikKlnNoOpPsSuvV")+"] ["+green("--oneshot")+"] ["+green("--newuse")+"] ["+green("--noconfmem")+"]"
print " ["+green("--columns")+"] ["+green("--nospinner")+"]"
print bold("Actions:")+" [ "+green("--clean")+" | "+green("--depclean")+" | "+green("--prune")+" | "+green("--regen")+" | "+green("--search")+" | "+green("--unmerge")+" ]"
print
print " other information useful for quick reference on a system. See"
print " "+bold("emerge info")+" for more advanced information."
print
- elif myaction in ["rsync","sync"]:
+ elif myaction == "sync":
print
print bold("Usage: ")+turquoise("emerge")+" "+turquoise("--sync")
print
def xtermTitle(mystr):
if havecolor and dotitles and os.environ.has_key("TERM") and sys.stderr.isatty():
myt=os.environ["TERM"]
- legal_terms = ["xterm","Eterm","aterm","rxvt","screen","kterm","rxvt-unicode"]
+ legal_terms = ["xterm","Eterm","aterm","rxvt","screen","kterm","rxvt-unicode","gnome"]
for term in legal_terms:
if myt.startswith(term):
sys.stderr.write("\x1b]2;"+str(mystr)+"\x07")
sys.stderr.flush()
break
-prompt_command = os.getenv("PROMPT_COMMAND", 'echo -ne "${USER}@${HOSTNAME%%.*}:${PWD/$HOME/~}"')
-default_xterm_title = commands.getoutput(prompt_command)
-del prompt_command
+default_xterm_title = None
def xtermTitleReset():
+ global default_xterm_title
+ if default_xterm_title is None:
+ prompt_command = os.getenv('PROMPT_COMMAND')
+ if prompt_command is not None:
+ default_xterm_title = commands.getoutput(prompt_command)
+ else:
+ pwd = os.getenv('PWD','')
+ home = os.getenv('HOME', '')
+ if home != '' and pwd.startswith(home):
+ pwd = '~' + pwd[len(home):]
+ default_xterm_title = '%s@%s:%s' % (
+ os.getenv('LOGNAME', ''), os.getenv('HOSTNAME', '').split('.', 1)[0], pwd)
xtermTitle(default_xterm_title)
def notitles():
from portage_checksum import perform_md5,perform_checksum,prelink_capable
import eclass_cache
from portage_localization import _
+ from portage_update import fixdbentries, update_dbentries
# Need these functions directly in portage namespace to not break every external tool in existence
from portage_versions import ververify,vercmp,catsplit,catpkgsplit,pkgsplit,pkgcmp
match = x[mykey]
break
- if 0 and match and mykey in ["PORTAGE_BINHOST"]:
- # These require HTTP Encoding
- try:
- import urllib
- if urllib.unquote(match) != match:
- writemsg("Note: %s already contains escape codes." % (mykey))
- else:
- match = urllib.quote(match)
- except SystemExit, e:
- raise
- except:
- writemsg("Failed to fix %s using urllib, attempting to continue.\n" % (mykey))
- pass
-
- elif mykey == "CONFIG_PROTECT_MASK":
+ if mykey == "CONFIG_PROTECT_MASK":
match += " "+portage_const.PREFIX+"/etc/env.d"
return match
rValue.append(kmask+" keyword")
return rValue
-def fixdbentries(old_value, new_value, dbdir):
- """python replacement for the fixdbentries script, replaces old_value
- with new_value for package names in files in dbdir."""
- for myfile in [f for f in os.listdir(dbdir) if not f == "CONTENTS"]:
- file_path = os.path.join(dbdir, myfile)
- f = open(file_path, "r")
- mycontent = f.read()
- f.close()
- if not mycontent.count(old_value):
- continue
- old_value = re.escape(old_value);
- mycontent = re.sub(old_value+"$", new_value, mycontent)
- mycontent = re.sub(old_value+"(\\s)", new_value+"\\1", mycontent)
- mycontent = re.sub(old_value+"(-[^a-zA-Z])", new_value+"\\1", mycontent)
- mycontent = re.sub(old_value+"([^a-zA-Z0-9-])", new_value+"\\1", mycontent)
- write_atomic(file_path, mycontent)
-
class packagetree:
def __init__(self,virtual,clone=None):
if clone:
os.rename(old_eb_path+".ebuild", new_eb_path+".ebuild")
write_atomic(os.path.join(newpath, "CATEGORY"), mynewcat+"\n")
+ fixdbentries([mylist], newpath)
- dbdir = self.root+VDB_PATH
+ def update_ents(self, update_iter):
+ """Run fixdbentries on all installed packages (time consuming). Like
+ fixpackages, this should be run from a helper script and display
+ a progress indicator."""
+ dbdir = os.path.join(self.root, VDB_PATH)
for catdir in listdir(dbdir):
catdir = dbdir+"/"+catdir
if os.path.isdir(catdir):
for pkgdir in listdir(catdir):
pkgdir = catdir+"/"+pkgdir
if os.path.isdir(pkgdir):
- fixdbentries(origcp, newcp, pkgdir)
+ fixdbentries(update_iter, pkgdir)
def move_slot_ent(self,mylist):
pkg=mylist[1]
#print ">>> Updating data in:",mycpv
sys.stdout.write("%")
sys.stdout.flush()
- mytmpdir=settings["PORTAGE_TMPDIR"]+"/tbz2"
- mytbz2=xpak.tbz2(tbz2path)
- mytbz2.decompose(mytmpdir, cleanup=1)
- fixdbentries(origcp, newcp, mytmpdir)
-
- write_atomic(os.path.join(mytmpdir, "CATEGORY"), mynewcat+"\n")
- try:
- os.rename(mytmpdir+"/"+string.split(mycpv,"/")[1]+".ebuild", mytmpdir+"/"+string.split(mynewcpv, "/")[1]+".ebuild")
- except SystemExit, e:
- raise
- except Exception, e:
- pass
-
- mytbz2.recompose(mytmpdir, cleanup=1)
+ mytbz2 = xpak.tbz2(tbz2path)
+ mydata = mytbz2.get_data()
+ updated_items = update_dbentries([mylist], mydata)
+ mydata.update(updated_items)
+ mydata["CATEGORY"] = mynewcat+"\n"
+ if mynewpkg != myoldpkg:
+ mydata[mynewpkg+".ebuild"] = mydata[myoldpkg+".ebuild"]
+ del mydata[myoldpkg+".ebuild"]
+ mytbz2.recompose_mem(xpak.xpak_mem(mydata))
self.dbapi.cpv_remove(mycpv)
if (mynewpkg != myoldpkg):
self.dbapi.cpv_inject(mynewcpv)
return 1
- def move_slot_ent(self,mylist,mytmpdir):
- #mytmpdir=settings["PORTAGE_TMPDIR"]+"/tbz2"
- mytmpdir=mytmpdir+"/tbz2"
+ def move_slot_ent(self, mylist):
if not self.populated:
self.populate()
pkg=mylist[1]
continue
#print ">>> Updating data in:",mycpv
- mytbz2=xpak.tbz2(tbz2path)
- mytbz2.decompose(mytmpdir, cleanup=1)
+ mytbz2 = xpak.tbz2(tbz2path)
+ mydata = mytbz2.get_data()
- slot=grabfile(mytmpdir+"/SLOT");
+ slot = mydata["SLOT"]
if (not slot):
continue
sys.stdout.write("S")
sys.stdout.flush()
-
- write_atomic(os.path.join(mytmpdir, "SLOT"), newslot+"\n")
- mytbz2.recompose(mytmpdir, cleanup=1)
+ mydata["SLOT"] = newslot+"\n"
+ mytbz2.recompose_mem(xpak.xpak_mem(mydata))
return 1
- def update_ents(self,mybiglist,mytmpdir):
- #XXX mytmpdir=settings["PORTAGE_TMPDIR"]+"/tbz2"
+ def update_ents(self, update_iter):
+ if len(update_iter) == 0:
+ return
if not self.populated:
self.populate()
+
for mycpv in self.dbapi.cp_all():
tbz2path=self.getname(mycpv)
if os.path.exists(tbz2path) and not os.access(tbz2path,os.W_OK):
continue
#print ">>> Updating binary data:",mycpv
writemsg("*")
- mytbz2=xpak.tbz2(tbz2path)
- mytbz2.decompose(mytmpdir,cleanup=1)
- for mylist in mybiglist:
- mylist=string.split(mylist)
- if mylist[0] != "move":
- continue
- fixdbentries(mylist[1], mylist[2], mytmpdir)
- mytbz2.recompose(mytmpdir,cleanup=1)
+ mytbz2 = xpak.tbz2(tbz2path)
+ mydata = mytbz2.get_data()
+ updated_items = update_dbentries(update_iter, mydata)
+ if len(updated_items) > 0:
+ mydata.update(updated_items)
+ mytbz2.recompose_mem(xpak.xpak_mem(mydata))
return 1
def populate(self, getbinpkgs=0,getbinpkgsonly=0):
if not mycat:
#old-style or corrupt package
writemsg("!!! Invalid binary package: "+mypkg+"\n")
+ writemsg("!!! This binary package is not recoverable and should be deleted.\n")
self.invalids.append(mypkg)
continue
mycat=string.strip(mycat)
#,"porttree":portagetree(root,virts),"bintree":binarytree(root,virts)}
features=settings["FEATURES"].split()
-do_upgrade_packagesmessage=0
def do_upgrade(mykey):
- global do_upgrade_packagesmessage
+ """Valid updates are returned as a list of split update commands."""
writemsg("\n\n")
writemsg(green("Performing Global Updates: ")+bold(mykey)+"\n")
writemsg("(Could take a couple of minutes if you have a lot of binary packages.)\n")
writemsg(" "+bold(".")+"='update pass' "+bold("*")+"='binary update' "+bold("@")+"='/var/db move'\n"+" "+bold("s")+"='/var/db SLOT move' "+bold("S")+"='binary SLOT move' "+bold("p")+"='update /etc/portage/package.*'\n")
processed=1
- #remove stale virtual entries (mappings for packages that no longer exist)
+ myupd = []
+ mylines = grabfile(mykey)
+ for myline in mylines:
+ mysplit = myline.split()
+ if len(mysplit) == 0:
+ continue
+ if mysplit[0] not in ("move", "slotmove"):
+ writemsg("portage: Update type \""+mysplit[0]+"\" not recognized.\n")
+ processed=0
+ continue
+ if mysplit[0]=="move":
+ if len(mysplit)!=3:
+ writemsg("portage: Update command \""+myline+"\" invalid; skipping.\n")
+ processed=0
+ continue
+ orig_value, new_value = mysplit[1], mysplit[2]
+ for cp in (orig_value, new_value):
+ if not (isvalidatom(cp) and isjustname(cp)):
+ writemsg("\nERROR: Malformed update entry '%s'\n" % myline)
+ processed=0
+ continue
+ if mysplit[0]=="slotmove":
+ if len(mysplit)!=4:
+ writemsg("portage: Update command \""+myline+"\" invalid; skipping.\n")
+ processed=0
+ continue
+ pkg, origslot, newslot = mysplit[1], mysplit[2], mysplit[3]
+ if not isvalidatom(pkg):
+ writemsg("\nERROR: Malformed update entry '%s'\n" % myline)
+ processed=0
+ continue
+
+ # The list of valid updates is filtered by continue statements above.
+ myupd.append(mysplit)
+ sys.stdout.write(".")
+ sys.stdout.flush()
+ return myupd, processed == 1
+
+def commit_mtimedb():
+ if mtimedb:
+ # Store mtimedb
+ mymfn=mtimedbfile
+ f = None
+ try:
+ mtimedb["version"]=VERSION
+ f = atomic_ofstream(mymfn)
+ cPickle.dump(mtimedb, f, -1)
+ f.close()
+ except SystemExit, e:
+ raise
+ except Exception, e:
+ if f is not None:
+ f.abort()
+
+ try:
+ os.chown(mymfn,uid,portage_gid)
+ os.chmod(mymfn,0664)
+ except SystemExit, e:
+ raise
+ except Exception, e:
+ pass
+def portageexit():
+ global uid,portage_gid,portdb,db
+ if secpass and not os.environ.has_key("SANDBOX_ACTIVE"):
+ close_portdbapi_caches()
+ commit_mtimedb()
+
+atexit_register(portageexit)
+
+def update_config_files(update_iter):
+ """Perform global updates on /etc/portage/package.* and the world file."""
update_files={}
file_contents={}
myxfiles = ["package.mask","package.unmask","package.keywords","package.use"]
if file_contents.has_key(x):
del file_contents[x]
continue
+ worldlist = grabfile(WORLD_FILE)
- worldlist=grabfile("/"+WORLD_FILE)
- myupd=grabfile(mykey)
- db["/"]["bintree"]=binarytree("/",settings["PKGDIR"],virts)
- for myline in myupd:
- mysplit=myline.split()
- if not len(mysplit):
- continue
- if mysplit[0]!="move" and mysplit[0]!="slotmove":
- writemsg("portage: Update type \""+mysplit[0]+"\" not recognized.\n")
- processed=0
- continue
- if mysplit[0]=="move" and len(mysplit)!=3:
- writemsg("portage: Update command \""+myline+"\" invalid; skipping.\n")
- processed=0
- continue
- if mysplit[0]=="slotmove" and len(mysplit)!=4:
- writemsg("portage: Update command \""+myline+"\" invalid; skipping.\n")
- processed=0
- continue
- sys.stdout.write(".")
- sys.stdout.flush()
-
- if mysplit[0]=="move":
- try:
- db["/"]["vartree"].dbapi.move_ent(mysplit)
- db["/"]["bintree"].move_ent(mysplit)
- except portage_exception.InvalidPackageName, e:
- writemsg("\nERROR: Malformed update entry '%s'\n" % myline)
- continue
+ for update_cmd in update_iter:
+ if update_cmd[0] == "move":
+ old_value, new_value = update_cmd[1], update_cmd[2]
#update world entries:
for x in range(0,len(worldlist)):
#update world entries, if any.
- worldlist[x]=dep_transform(worldlist[x],mysplit[1],mysplit[2])
+ worldlist[x] = dep_transform(worldlist[x], old_value, new_value)
#update /etc/portage/packages.*
for x in file_contents:
for mypos in range(0,len(file_contents[x])):
- line=file_contents[x][mypos]
- if line[0]=="#" or string.strip(line)=="":
+ line = file_contents[x][mypos]
+ if line[0] == "#" or string.strip(line) == "":
continue
- key=dep_getkey(line.split()[0])
- if key==mysplit[1]:
- file_contents[x][mypos]=string.replace(line,mysplit[1],mysplit[2])
- update_files[x]=1
+ key = dep_getkey(line.split()[0])
+ if key == old_value:
+ file_contents[x][mypos] = string.replace(line, old_value, new_value)
+ update_files[x] = 1
sys.stdout.write("p")
sys.stdout.flush()
- elif mysplit[0]=="slotmove":
- try:
- db["/"]["vartree"].dbapi.move_slot_ent(mysplit)
- db["/"]["bintree"].move_slot_ent(mysplit,settings["PORTAGE_TMPDIR"]+"/tbz2")
- except portage_exception.InvalidAtom, e:
- writemsg("\nERROR: Malformed update entry '%s'\n" % myline)
+ write_atomic(WORLD_FILE,"\n".join(worldlist))
for x in update_files:
mydblink = dblink('','','/',settings)
- if mydblink.isprotected(USER_CONFIG_PATH+os.path.sep+x):
- updating_file=new_protect_filename(USER_CONFIG_PATH+os.path.sep+x)[0]
- else:
- updating_file=USER_CONFIG_PATH+os.path.sep+x
+ updating_file = os.path.join(USER_CONFIG_PATH, x)
+ if mydblink.isprotected(updating_file):
+ updating_file = new_protect_filename(updating_file)[0]
try:
write_atomic(updating_file, "".join(file_contents[x]))
except IOError:
continue
- # We gotta do the brute force updates for these now.
- if (settings["PORTAGE_CALLER"] in ["fixpackages"]) or \
- ("fixpackages" in features):
- db["/"]["bintree"].update_ents(myupd,settings["PORTAGE_TMPDIR"]+"/tbz2")
- else:
- do_upgrade_packagesmessage = 1
-
- if processed:
- #update our internal mtime since we processed all our directives.
- mtimedb["updates"][mykey]=os.stat(mykey)[stat.ST_MTIME]
- write_atomic(WORLD_FILE,"\n".join(worldlist))
- print ""
+def global_updates():
+ updpath = os.path.join(settings["PORTDIR"], "profiles", "updates")
+ mylist = listdir(updpath, EmptyOnError=1)
+ # validate the file name (filter out CVS directory, etc...)
+ mylist = [myfile for myfile in mylist if len(myfile) == 7 and myfile[1:3] == "Q-"]
+ if len(mylist) > 0:
+ # resort the list
+ mylist = [myfile[3:]+"-"+myfile[:2] for myfile in mylist]
+ mylist.sort()
+ mylist = [myfile[5:]+"-"+myfile[:4] for myfile in mylist]
-def commit_mtimedb():
- if mtimedb:
- # Store mtimedb
- mymfn=mtimedbfile
- f = None
- try:
- mtimedb["version"]=VERSION
- f = atomic_ofstream(mymfn)
- cPickle.dump(mtimedb, f, -1)
- f.close()
- except SystemExit, e:
- raise
- except Exception, e:
- if f is not None:
- f.abort()
-
- try:
- os.chown(mymfn,uid,portage_gid)
- os.chmod(mymfn,0664)
- except SystemExit, e:
- raise
- except Exception, e:
- pass
-
-def portageexit():
- global uid,portage_gid,portdb,db
- if secpass and not os.environ.has_key("SANDBOX_ACTIVE"):
- close_portdbapi_caches()
- commit_mtimedb()
-
-atexit_register(portageexit)
-
-if (secpass==2) and (not os.environ.has_key("SANDBOX_ACTIVE")):
- if settings["PORTAGE_CALLER"] in ["emerge","fixpackages"]:
- #only do this if we're root and not running repoman/ebuild digest
- updpath=os.path.normpath(settings["PORTDIR"]+"///profiles/updates")
- didupdate=0
if not mtimedb.has_key("updates"):
- mtimedb["updates"]={}
- try:
- mylist=listdir(updpath,EmptyOnError=1)
- # resort the list
- mylist=[myfile[3:]+"-"+myfile[:2] for myfile in mylist]
- mylist.sort()
- mylist=[myfile[5:]+"-"+myfile[:4] for myfile in mylist]
- for myfile in mylist:
- mykey=updpath+"/"+myfile
- if not os.path.isfile(mykey):
- continue
- if (not mtimedb["updates"].has_key(mykey)) or \
- (mtimedb["updates"][mykey] != os.stat(mykey)[stat.ST_MTIME]) or \
- (settings["PORTAGE_CALLER"] == "fixpackages"):
- didupdate=1
- do_upgrade(mykey)
- commit_mtimedb() # This lets us save state for C-c.
- except OSError:
- #directory doesn't exist
- pass
+ mtimedb["updates"] = {}
+
+ didupdate = 0
+ do_upgrade_packagesmessage = 0
+ myupd = []
+ timestamps = {}
+ for myfile in mylist:
+ mykey = os.path.join(updpath, myfile)
+ mystat = os.stat(mykey)
+ if not stat.S_ISREG(mystat.st_mode):
+ continue
+ if mykey not in mtimedb["updates"] or \
+ mtimedb["updates"][mykey] != mystat.st_mtime or \
+ settings["PORTAGE_CALLER"] == "fixpackages":
+ didupdate = 1
+ valid_updates, no_errors = do_upgrade(mykey)
+ myupd.extend(valid_updates)
+ if no_errors:
+ # Update our internal mtime since we
+ # processed all of our directives.
+ timestamps[mykey] = mystat.st_mtime
+ update_config_files(myupd)
+
+ db["/"]["bintree"] = binarytree("/", settings["PKGDIR"], virts)
+ for update_cmd in myupd:
+ if update_cmd[0] == "move":
+ db["/"]["vartree"].dbapi.move_ent(update_cmd)
+ db["/"]["bintree"].move_ent(update_cmd)
+ elif update_cmd[0] == "slotmove":
+ db["/"]["vartree"].dbapi.move_slot_ent(update_cmd)
+ db["/"]["bintree"].move_slot_ent(update_cmd)
+
+ print
+
+ # The above global updates proceed quickly, so they
+ # are considered a single mtimedb transaction.
+ if len(timestamps) > 0:
+ # We do not update the mtime in the mtimedb
+ # until after _all_ of the above updates have
+ # been processed because the mtimedb will
+ # automatically commit when killed by ctrl C.
+ for mykey, mtime in timestamps.iteritems():
+ mtimedb["updates"][mykey] = mtime
+ commit_mtimedb()
+
+ # We gotta do the brute force updates for these now.
+ if settings["PORTAGE_CALLER"] == "fixpackages" or \
+ "fixpackages" in features:
+ db["/"]["bintree"].update_ents(myupd)
+ else:
+ do_upgrade_packagesmessage = 1
+
if didupdate:
#make sure our internal databases are consistent; recreate our virts and vartree
do_vartree(settings)
if do_upgrade_packagesmessage and \
- listdir(settings["PKGDIR"]+"/All/",EmptyOnError=1):
+ listdir(os.path.join(settings["PKGDIR"], "All"), EmptyOnError=1):
writemsg("\n\n\n ** Skipping packages. Run 'fixpackages' or set it in FEATURES to fix the")
writemsg("\n tbz2's in the packages directory. "+bold("Note: This can take a very long time."))
writemsg("\n")
-
-
-
+if (secpass==2) and (not os.environ.has_key("SANDBOX_ACTIVE")):
+ if settings["PORTAGE_CALLER"] in ["emerge","fixpackages"]:
+ #only do this if we're root and not running repoman/ebuild digest
+ global_updates()
#continue setting up other trees
db["/"]["porttree"]=portagetree("/",virts)
"""An incorrect formatting was passed instead of the expected one"""
class IncorrectParameter(PortageException):
- """An parameter of the wrong type was passed"""
+ """A parameter of the wrong type was passed"""
class MissingParameter(PortageException):
- """An parameter is required for the action requested but was not passed"""
+ """A parameter is required for the action requested but was not passed"""
+class ParseError(PortageException):
+ """An error was generated while attempting to parse the request"""
class InvalidData(PortageException):
"""An incorrect formatting was passed instead of the expected one"""
raise
- if type(lockfilename) == types.StringType and os.fstat(myfd).st_nlink != 1:
+ if type(lockfilename) == types.StringType and \
+ myfd != HARDLINK_FD and os.fstat(myfd).st_nlink != 1:
# The file was deleted on us... Keep trying to make one...
os.close(myfd)
portage_util.writemsg("lockfile recurse\n",1)
--- /dev/null
+
+import os, re
+
+from portage_util import write_atomic
+
+ignored_dbentries = ("CONTENTS", "environment.bz2")
+
+def update_dbentry(update_cmd, mycontent):
+ if update_cmd[0] == "move":
+ old_value, new_value = update_cmd[1], update_cmd[2]
+ if mycontent.count(old_value):
+ old_value = re.escape(old_value);
+ mycontent = re.sub(old_value+"$", new_value, mycontent)
+ mycontent = re.sub(old_value+"(\\s)", new_value+"\\1", mycontent)
+ mycontent = re.sub(old_value+"(-[^a-zA-Z])", new_value+"\\1", mycontent)
+ mycontent = re.sub(old_value+"([^a-zA-Z0-9-])", new_value+"\\1", mycontent)
+ return mycontent
+
+def update_dbentries(update_iter, mydata):
+ """Performs update commands and returns a
+ dict containing only the updated items."""
+ updated_items = {}
+ for k, mycontent in mydata.iteritems():
+ if k not in ignored_dbentries:
+ orig_content = mycontent
+ for update_cmd in update_iter:
+ mycontent = update_dbentry(update_cmd, mycontent)
+ if mycontent is not orig_content:
+ updated_items[k] = mycontent
+ return updated_items
+
+def fixdbentries(update_iter, dbdir):
+ """Performs update commands which result in search and replace operations
+ for each of the files in dbdir (excluding CONTENTS and environment.bz2).
+ Returns True when actual modifications are necessary and False otherwise."""
+ mydata = {}
+ for myfile in [f for f in os.listdir(dbdir) if f not in ignored_dbentries]:
+ file_path = os.path.join(dbdir, myfile)
+ f = open(file_path, "r")
+ mydata[myfile] = f.read()
+ f.close()
+ updated_items = update_dbentries(update_iter, mydata)
+ for myfile, mycontent in updated_items.iteritems():
+ file_path = os.path.join(dbdir, myfile)
+ write_atomic(file_path, mycontent)
+ return len(updated_items) > 0
# (integer) == encodeint(integer) ===> 4 characters (big-endian copy)
# '+' means concatenate the fields ===> All chunks are strings
-import sys,os,string
+import sys,os,string,shutil,errno
from stat import *
def addtolist(mylist,curdir):
addtolist(mylist,"")
mylist.sort()
+ mydata = {}
+ for x in mylist:
+ a = open(x, "r")
+ mydata[x] = a.read()
+ a.close()
+ os.chdir(origdir)
- #Our list index has been created
-
+ xpak_segment = xpak_mem(mydata)
+ if outfile:
+ outf = open(outfile, "w")
+ outf.write(xpak_segment)
+ outf.close()
+ else:
+ return xpak_segment
+
+def xpak_mem(mydata):
+ """Create an xpack segement from a map object."""
indexglob=""
indexpos=0
dataglob=""
datapos=0
- for x in mylist:
- a=open(x,"r")
- newglob=a.read()
- a.close()
+ for x, newglob in mydata.iteritems():
mydatasize=len(newglob)
indexglob=indexglob+encodeint(len(x))+x+encodeint(datapos)+encodeint(mydatasize)
indexpos=indexpos+4+len(x)+4+4
dataglob=dataglob+newglob
datapos=datapos+mydatasize
- os.chdir(origdir)
- if outfile:
- outf=open(outfile,"w")
- outf.write("XPAKPACK"+encodeint(len(indexglob))+encodeint(len(dataglob)))
- outf.write(indexglob)
- outf.write(dataglob)
- outf.write("XPAKSTOP")
- outf.close()
- else:
- myret="XPAKPACK"+encodeint(len(indexglob))+encodeint(len(dataglob))
- myret=myret+indexglob+dataglob+"XPAKSTOP"
- return myret
+ return "XPAKPACK" \
+ + encodeint(len(indexglob)) \
+ + encodeint(len(dataglob)) \
+ + indexglob \
+ + dataglob \
+ + "XPAKSTOP"
def xsplit(infile):
"""(infile) -- Splits the infile into two files.
Returns result of upackinfo()."""
if not self.scan():
raise IOError
- if cleanup and os.path.exists(datadir):
- # XXX: Potentially bad
- os.system("rm -Rf "+datadir+"/*")
+ if cleanup:
+ self.cleanup(datadir)
if not os.path.exists(datadir):
os.makedirs(datadir)
return self.unpackinfo(datadir)
"""Creates an xpak segment from the datadir provided, truncates the tbz2
to the end of regular data if an xpak segment already exists, and adds
the new segment to the file with terminating info."""
+ xpdata = xpak(datadir)
+ self.recompose_mem(xpdata)
+ if cleanup:
+ self.cleanup(datadir)
+
+ def recompose_mem(self, xpdata):
self.scan() # Don't care about condition... We'll rewrite the data anyway.
myfile=open(self.file,"a+")
if not myfile:
raise IOError
myfile.seek(-self.xpaksize,2) # 0,2 or -0,2 just mean EOF.
myfile.truncate()
- xpdata=xpak(datadir)
myfile.write(xpdata+encodeint(len(xpdata))+"STOP")
myfile.flush()
myfile.close()
- if cleanup:
- # XXX: Potentially bad
- os.system("rm -Rf "+datadir)
return 1
+ def cleanup(self, datadir):
+ datadir_split = os.path.split(datadir)
+ if len(datadir_split) >= 2 and len(datadir_split[1]) > 0:
+ # This is potentially dangerous,
+ # thus the above sanity check.
+ try:
+ shutil.rmtree(datadir)
+ except OSError, oe:
+ if oe.errno == errno.ENOENT:
+ pass
+ else:
+ raise oe
+
def scan(self):
"""Scans the tbz2 to locate the xpak segment and setup internal values.
This function is called by relevant functions already."""
os.chdir(origdir)
return 1
+ def get_data(self):
+ """Returns all the files from the dataSegment as a map object."""
+ if not self.scan():
+ return 0
+ a = open(self.file, "r")
+ mydata = {}
+ startpos=0
+ while ((startpos+8)<self.indexsize):
+ namelen=decodeint(self.index[startpos:startpos+4])
+ datapos=decodeint(self.index[startpos+4+namelen:startpos+8+namelen]);
+ datalen=decodeint(self.index[startpos+8+namelen:startpos+12+namelen]);
+ myname=self.index[startpos+4:startpos+4+namelen]
+ a.seek(self.datapos+datapos)
+ mydata[myname] = a.read(datalen)
+ startpos=startpos+namelen+12
+ a.close()
+ return mydata
+
def getboth(self):
"""Returns an array [indexSegment,dataSegment]"""
if not self.scan():
+++ /dev/null
-#!/bin/bash
-cd /usr/portage/
-for x in `find -name '*.ebuild'`
-do
- echo $x
- bn=${x##*/}
- dn=${x%/*}
- fn=.use-${bn/.ebuild/}
- myout=${dn}/${fn}
-
- #massive pipeline follows
- sed -e 's/^\([^#]*\)#.*$/\1/' -e '/^pkg_/q' $x | \
- grep -e 'use [[:alnum:]]*' | \
- grep -v DESCRIPTION | \
- sed -e 's/^.*use \([[:alnum:]]*\).*$/\1/' | \
- sed -e '/^$/d' | \
- sort | \
- uniq > $myout
-
-done
+++ /dev/null
-#!/usr/bin/python2.2
-import portage,sys
-portdir=portage.settings["PORTDIR"]
-for cp in portage.portdb.cp_all():
- for cpv in portage.portdb.cp_list(cp):
- try:
- myaux=portage.portdb.aux_get(cpv,["DEPEND","RDEPEND","SRC_URI"])
- except KeyError:
- pass
- myuse={}
- for str in myaux:
- mysplit=str.split()
- for part in mysplit:
- if part[-1]=="?":
- if part[0]=="!":
- if not myuse.has_key(part[1:-1]):
- myuse[part[1:-1]]=None
- else:
- if not myuse.has_key(part[:-1]):
- myuse[part[:-1]]=None
- if not myuse:
- continue
- cpsplit=cpv.split("/")
- mypath=portdir+"/"+cp+"/.use-"+cpsplit[1]
- print mypath
- myfile=open(mypath,"r")
- for x in myfile.readlines():
- if x[:-1]:
- if not myuse.has_key(x[:-1]):
- myuse[x[:-1]]=None
- print myuse.keys()
- myfile.close()
- if not myuse.keys():
- #no IUSE to add
- continue
- myepath=portdir+"/"+cp+"/"+cpsplit[1]+".ebuild"
- myefile=open(myepath,"r")
- mylines=myefile.readlines()
- myefile.close()
- mynewlines=[]
- pos=0
- while (pos<len(mylines)) and (mylines[pos][0]=="#"):
- mynewlines.append(mylines[pos])
- pos += 1
- myuses=myuse.keys()
- iuseline="\nIUSE=\""+myuses[0]
- for x in myuses[1:]:
- iuseline=iuseline+" "+x
- iuseline=iuseline+"\"\n"
- mynewlines.append(iuseline)
- while (pos<len(mylines)):
- mynewlines.append(mylines[pos])
- pos += 1
-
- myefile=open(myepath,"w")
- for x in mynewlines:
- myefile.write(x)
- myefile.close()
+++ /dev/null
-#!/usr/bin/env python
-import os
-from os.path import walk, splitext, exists, basename, dirname
-import sys
-
-import output
-from output import *
-import portage
-import xpak
-import string
-from string import strip, find, replace, split
-import commands
-import shutil
-import re
-import time
-
-#number of ebuilds merged
-merged=0
-# there can only be one action specified; the default action is to merge
-# specified packages, not update.
-actions=["help",
- "rebuild",
- "search",
- "update",
- "clean",
- "zap",
- "rsync"]
-# emerge (prints help)
-# emerge help (prints help)
-# emerge help config (prints config file management help)
-
-# emerge rsync
-
-# the default behavior of emerge is to satisfy dependencies specified by merging packages.
-# emerge system (satisfy deps for "system" package class)
-# emerge world (equivalent to emerge system since "world" doesn't offer any new deps)
-# emerge <depstring> (satisfy dep by merging most recent version of app available that satisfies dep)
-# NOTE: this will cause something to be merged again if the dep happens to be already satisfied
-# "unslotted" is invalid for a package class here because it only applies to already-installed ebuilds.
-# pkgclass support: "system", "world", <depstring>, <pkgname>, <ebuild>, <tbz2>
-
-# no changes here except we use "update" rather than "--update"
-# emerge update <pkgclass/depstring/pkgname>
-# emerge update (defaults to "world")
-# "emerge update <ebuild/tbz2> doesn't make too much sense.
-# But it should do the same thing are "emerge <ebuild/tbz2>".
-
-# rebuild is like "update" except that all packages will be rebuilt even if they currently are installed.
-# emerge rebuild (defaults to "world")
-# emerge rebuild <pkgclass/depstring/pkgname/ebuild>
-# "emerge rebuild <ebuild/tbz2> doesn't make too much sense.
-# But it should do the same thing are "emerge <ebuild/tbz2>".
-
-# emerge search (invalid)
-# emerge search <regex>
-
-# clean does "cleaning" only; it does not do anything that would generally be considered dangerous
-# emerge clean (defaults to "world"; apply default AUTOCLEAN behavior defined in make.conf)
-# emerge --rev clean (defaults to "world", cleans out old revisions)
-# emerge --slot clean (defaults to "world", cleans out old stuff from slots)
-# emerge [--rev/--slot] clean <pkgclass>
-# AUTOCLEAN var can be set to "slot", "rev", or "none/off/etc".
-
-# zap flat out removes stuff. No holds barred. Can be dangerous.
-# emerge zap <pkgclass> (only "unslotted" is valid, which is still dangerous. Or a dep "=foo/bar")
-# NOTE: of course, "emerge zap" alone is invalid and will *not* default to a "world" package class
-
-pkgclass=["world","system","unslotted"]
-helpclass=["config"]
-
-# These next options are the only long options for Portage 1.8.9 except for "--help" (equiv. to "help")
-
-options=["--autoclean",
- "--buildpkg",
- "--debug",
- "--fetchonly",
- "--noreplace",
- "--onlydeps",
- "--pretend",
- "--usepkg",
- "--verbose",
- "--emptytree",
- "--rev",
- "--slot",
- "--help"]
-
-# Here are the currently supported short mappings.
-
-shortmapping={"a":"--autoclean",
- "b":"--buildpkg",
- "d":"--debug",
- "f":"--fetchonly",
- "h":"--help",
- "k":"--usepkg",
- "n":"--noreplace",
- "o":"--onlydeps",
- "p":"--pretend",
- "v":"--verbose" }
-
-# end of spec
-
-myaction=None
-myopts=[]
-mymode=[]
-myfiles=[]
-edebug=0
-
-# process short actions and options
-for x in sys.argv[1:]:
- if x[0:1]=="-"and not x[1:2]=="-":
- for y in x[1:]:
- if shortmapping.has_key(y):
- sys.argv.append(shortmapping[y])
- else:
- print y
- print "!!! Error: -"+y+" is an invalid short action or option."
- sys.argv.remove(x)
-
-# process the command arguments
-for x in sys.argv[1:]:
- if x=="update" or x=="--unmerge" or x=="--world":
- print
- if x=="update":
- print " "+red("* WARNING:"),green("emerge update"),"has been deprecated, use",green("emerge --update"),"instead."
- elif x=="--unmerge":
- print " "+red("* WARNING:"),green("emerge --unmerge"),"has been deprecated, use",green("emerge --zap"),"instead."
- elif x=="--world":
- print " "+red("* WARNING:"),green("emerge --world"),"has been deprecated, use",green("emerge world"),"instead."
- print " "+red("*"),"Read",green("emerge --help"),"to get a complete overview of the interface changes."
- print
- sys.exit(1)
-
- if len(x)>=2:
- if x[0:1]=="-":
- if x[1:2]=="-":
- if x in actions:
- if myaction:
- print "!!! Error: more than one action specified on command-line."
- print "!!! Available actions:",actions
- sys.exit(1)
- else:
- myaction=x
- elif x in options:
- myopts.append(x)
- else:
- print "!!! Error:",x,"is an invalid action or option."
- sys.exit(1)
- else:
- for y in x[1:]:
- if shortmapping.has_key(y):
- myopts.append(shortmapping[y])
- else:
- print y
- print "!!! Error: -"+y+" is an invalid short action or option."
- elif x in modes:
- if len(mymode)>=1:
- print "!!! Error: more than one mode specified on command-line."
- print "!!! Available modes:",modes
- sys.exit(1)
- else:
- mymode.append(x)
- else:
- # this little conditional helps tab completion
- if x[-1]=="/":
- myfiles.append(x[:-1])
- else:
- myfiles.append(x)
-
-# check if root user is the current user for the actions where emerge needs this
-if os.getuid()!=0 and "--help"!=myaction and "--search"!=myaction:
- print "!!! to be able to perform the requested action, emerge must be run by root."
- sys.exit(1)
-
-# search functionality
-class search:
-
- #
- # class constants
- #
- VERSION_SHORT=1
- VERSION_RELEASE=2
-
- #
- # public interface
- #
- def __init__(self,searchkey=""):
- """Searches the available and installed packages for the supplied search key.
- The list of available and installed packages is created at object instantiation.
- This makes successive searches faster."""
- self.searchkey = searchkey
- self.treecache = portage.portagetree()
- self.treecache.populate()
- self.installcache = portage.vartree()
- self.installcache.populate()
- self.re_portagedir = re.compile('/usr/portage/')
- self.re_description = re.compile('DESCRIPTION="')
- self.initResults()
-
- def setKey(self,searchkey):
- """changes the search key"""
- self.searchkey = searchkey
- self.initResults()
-
- def execute(self):
- """Performs the saerch for the supplied search key"""
- if self.searchkey:
- self.initResults()
- for package in self.treecache.getallnodes():
- package_parts=package.split("/")
- if package_parts:
- if self.searchkey != "*":
- if re.search(self.searchkey.lower(), package_parts[1].lower()):
- self.packagematches.append(package)
- else:
- self.packagematches.append(package)
-
- def output(self):
- """Outputs the results of the search."""
- print "[ Results for search key : "+white(self.searchkey)+" ]"
- print "[ Applications found : "+white(str(len(self.packagematches)))+" ]"
- print " "
- for match in self.packagematches:
- full_package = strip(self.treecache.dep_bestmatch(match))
- if len(full_package) > 1:
- print green("*")+" "+white(match)
- print " ", "Latest version Available:",self.getVersion(full_package, search.VERSION_RELEASE)
- print " ", self.getInstallationStatus(match)
- print " ", "Description:",self.getDescription(self.getFullPath(match, full_package),self.getVersion(full_package, search.VERSION_SHORT))
- print " "
- else:
- print green("*")+" "+white(match)+" "+red("[ Masked ]")
- print " "
-
- #
- # private interface
- #
- def initResults(self):
- self.packagematches = []
-
- def getInstallationStatus(self,package):
- installed_package = self.installcache.dep_bestmatch(package)
- result = ""
- version = self.getVersion(installed_package,search.VERSION_RELEASE)
- if len(version) > 1:
- result = "Latest version Installed: "+version
- else:
- result = "Latest version Installed: [ Not Installed ]"
- return result
-
- def getDescription(self,ebuildPath,packageVersion): ## Gets description from latest ebuild ##
- file = open(ebuildPath)
- result = "";
- indescription=0
- while 1:
- data = file.readline()
- if data:
- if self.re_description.match(data.upper()):
- indescription=1
- p = self.re_description.split(data)
- p = p[1].split('"')
- result = p[0].strip()
- if len(p)>1:
- break
- elif indescription==1:
- if '"' in data:
- p = data.split('"')
- result = result+" "+p[0].strip()
- indescription = 0
- else:
- result = result+" "+data.strip()
- else:
- break;
- result = replace(result, "${PV}", packageVersion)
- result = replace(result, "${pv}", packageVersion)
- result = replace(result, "${description}", "KDE " + packageVersion + " ")
- result = replace(result, "\n", "")
- file.close()
- # format and wrap the description text nicely
- wraplength=60
- formatted_result=""
- while len(result)>wraplength:
- lineposition=0
- position=wraplength
- while result[lineposition+position]!=' ' and position != 0:
- position = position-1
- if position==0:
- position=wraplength
- if len(formatted_result)==0:
- formatted_result=result[:position]
- else:
- formatted_result=formatted_result+"\n "+result[:position]
- result=result[position+1:]
- if wraplength==60:
- wraplength=73
- formatted_result=formatted_result+"\n "+result
- return formatted_result
-
- def getFullPath(self,packageShortName,packageFullName): ## Returns the full path of the ebuild ##
- absolute_path = '/usr/portage/' + strip(packageShortName)
- package_parts = packageFullName.split("/")
- result = absolute_path + "/" + package_parts[1] + ".ebuild"
- return result
-
- def getVersion(self,full_package,detail):
- if len(full_package) > 1:
- package_parts = portage.catpkgsplit(full_package)
- if detail == search.VERSION_RELEASE and package_parts[3] != 'r0':
- result = package_parts[2]+ "-" + package_parts[3]
- else:
- result = package_parts[2]
- else:
- result = ""
- return result
-
-#build our package digraph
-def getsyslist():
- if os.path.exists(portage.profiledir+"/packages"):
- pfile=portage.profiledir+"/packages"
- else:
- print "!!! Couldn't find",portage.profiledir+"/packages;"
- print "\"system\" mode unavailable."
- sys.exit(1)
- myfile=open(pfile,"r")
- mylines=myfile.readlines()
- myfile.close()
-
- mynewlines=[]
- for x in mylines:
- myline=string.join(string.split(x))
- if not len(myline):
- continue
- elif myline[0]=="#":
- continue
- elif myline[0]!="*":
- continue
- myline=myline[1:]
- mynewlines.append(myline.strip())
-
- return mynewlines
-
-class depgraph:
-
- def __init__(self,mymode,myaction,myopts):
- self.mymode=mymode
- self.myaction=myaction
- self.myopts=myopts
- virts=portage.getvirtuals("/")
- self.db={}
- self.db["/"]={"virtuals":virts,"vartree":portage.vartree("/",virts),"porttree":portage.portagetree("/",virts),"bintree":portage.binarytree("/",virts)}
- if portage.root!="/":
- pr=portage.root
- virts=portage.getvirtuals(pr)
- self.db[pr]={"virtuals":virts,"vartree":portage.vartree(pr,virts),"porttree":portage.portagetree(pr,virts),"bintree":portage.binarytree(pr,virts)}
- self.digraph=portage.digraph()
- self.orderedkeys=[]
- #the following is so we have an empty vartree (used in emerge update calculations)
- self.emptytree=portage.vartree("/",virts,self.db["/"]["vartree"])
- self.emptytree.tree={}
- if "--emptytree" in myopts:
- print "Running in empty tree mode"
- self.db["/"]["vartree"].tree=self.emptytree.tree
- self.db["/"]["vartree"].populated=1
- self.db["/"]["vartree"].inject("virtual/glibc-1.0")
- self.outdatedpackages=[]
- def create(self,mybigkey,myparent=None,addme=1):
- """creates the actual digraph of packages to merge. return 1 on success, 0 on failure
- mybigkey = specification of package to merge; myparent = parent package (one depending on me);
- addme = should I be added to the tree? (for the --onlydeps mode)"""
- if mybigkey==None:
- return
- sys.stdout.write(".")
- sys.stdout.flush()
- if self.digraph.hasnode(mybigkey):
- #if we've already hit this node before, we're already recursing on the dependencies.
- #no need to recurse again.
- if addme:
- if myparent:
- self.digraph.addnode(mybigkey,myparent)
- return 1
- mytype,myroot,mykey=string.split(mybigkey)
- if "--noreplace" in self.myopts:
- if self.db[myroot]["vartree"].exists_specific(mykey):
- print "\n>>>",mykey,"already merged in",myroot+", skipping...\n"
- return 1
- if mytype=="binary":
- if not self.db[portage.root]["bintree"].exists_specific(mykey):
- print "\n\n!!!",mytype,mykey,"not found (possibly blocked by package.mask)\n"
- sys.exit(1)
- mypkgparts=portage.catpkgsplit(mykey)
- mytbz2=xpak.tbz2(self.db[portage.root]["bintree"].getname(mykey))
- edepend=["",string.join(mytbz2.getelements("RDEPEND")," "),mytbz2.getfile("SLOT",mypkgparts[2])]
- elif mytype=="ebuild":
- if not self.db[myroot]["porttree"].exists_specific(mykey):
- print "\n\n!!!",mytype,mykey,"not found (possibly blocked by package.mask)\n"
- sys.exit(1)
- mydep={}
- myebuild=self.db[myroot]["porttree"].getname(mykey)
- edepend=portage.doebuild(myebuild,"depend",myroot,1,edebug)
- if edepend==1:
- print "!!! emerge aborting."
- sys.exit(1)
- elif mytype=="blocks":
- edepend=None
- parenttype,parentroot,parentkey=string.split(myparent)
- mykeyparts=portage.catpkgsplit(mykey)
- parentkeyparts=portage.catpkgsplit(parentkey)
- # only add blocking deps that aren't from the same package that is installing
- if mykeyparts[0]!=parentkeyparts[0] or mykeyparts[1]!=parentkeyparts[1]:
- self.digraph.addnode(mybigkey,myparent)
-
- if edepend:
- mydep={}
- if myroot=="/":
- mydep["/"]=edepend[0]+" "+edepend[1]
- else:
- mydep["/"],mydep[myroot]=edepend
- if addme:
- self.digraph.addnode(mybigkey,myparent)
- for dep in mydep.keys():
- if "--update"==self.myaction:
- mycheck=self.emptytree.depcheck(mydep[dep])
- else:
- mycheck=self.db[dep]["vartree"].depcheck(mydep[dep])
- if mycheck[0]==0:
- print "!!! depgraph.create() error: string format:",mydep
- return 0
- for x in mycheck[1]:
- mynew=self.match(x,dep,mykey)
- if not self.digraph.hasnode(mynew):
- if addme:
- if not self.create(mynew,mybigkey):
- return 0
- else:
- if not self.create(mynew,None):
- return 0
- else:
- self.digraph.addnode(mynew,mybigkey)
-
- return 1
-
- def altlist(self):
- mygraph=self.digraph.copy()
- dolist=["/"]
- retlist=[]
- for x in self.db.keys():
- self.db[x]["merge"]=[]
- if x not in dolist:
- dolist.append(x)
- while (not mygraph.empty()):
- mycurkey=mygraph.firstzero()
- if not mycurkey:
- print "!!! Error: circular dependencies"
- sys.exit(1)
- splitski=string.split(mycurkey)
- if "--update"==self.myaction:
- if not self.db["/"]["vartree"].exists_specific(splitski[2]):
- self.db["/"]["merge"].append(splitski)
- else:
- self.db[splitski[1]]["merge"].append(splitski)
- mygraph.delnode(mycurkey)
- for x in dolist:
- for y in self.db[x]["merge"]:
- retlist.append(y)
- return retlist
-
- def syscreate(self,mylines=[]):
- for myline in mylines:
- if "--update"==self.myaction or "--rebuild"==self.myaction:
- self.create(self.match(myline,mykey="update (likely old /var/db/pkg entry)"))
- else:
- mycheck=self.db[portage.root]["vartree"].depcheck(myline)
- if mycheck[0]==0:
- print "\n!!! Warning:",myline,"has an invalid depstring\n"
- continue
- if mycheck[1]==None:
- continue
- for x in mycheck[1]:
- self.create(self.match(myline,mykey="syscreate1"))
-
- def match(self,mydep,myroot=portage.root,mykey=None):
- # support mutual exclusive deps
- mydep2=mydep
- if mydep2[0]=="!":
- mydep2=mydep[1:]
-
- if self.myaction=="--rebuild":
- myeb=self.db[portage.root]["vartree"].dep_bestmatch(mydep2)
- if not self.db[portage.root]["porttree"].exists_specific(myeb):
- self.outdatedpackages.append(myeb)
- return None
- else:
- myeb=self.db[portage.root]["porttree"].dep_bestmatch(mydep2)
- if not myeb:
- if not mykey:
- print "\n!!! Warning: couldn't find match for",mydep
- else:
- print "\n!!! Warning: couldn't find match for",mydep,"in",mykey
- return None
-
- # handle filtering of virtual deps for the rebuild action
- if self.myaction=="--rebuild" and myeb[0:len("virtual")]=="virtual":
- return None
-
- # handle filtering of non slot packages
- if "noslot" in mymode and self.db[portage.root]["vartree"].slotted(myeb)==1:
- return None
-
- if mydep[0]=="!":
- myk="blocks "+myroot+" "+myeb
- else:
- if "--usepkg" in self.myopts:
- mypk=self.db[portage.root]["bintree"].dep_bestmatch(mydep)
- if myeb==mypk:
- myk="binary "+portage.root+" "+mypk
- else:
- myk="ebuild "+myroot+" "+myeb
- else:
- myk="ebuild "+myroot+" "+myeb
-
- return myk
-
- def display(self,mylist):
- for x in mylist:
- if x[0]=="blocks":
- addl=""+red("B")+" "
- print "["+x[0]+" "+addl+"]",red(x[2])
- else:
- if self.db[x[1]]["vartree"].exists_specific(x[2]):
- addl=" "+yellow("R")+" "
- elif self.db[x[1]]["vartree"].exists_specific_cat(x[2]):
- addl=" "+turquoise("U")+" "
- else:
- addl=" "+green("N")+" "
- print "["+x[0]+" "+addl+"]",x[2],"to",x[1]
-
- def outdated(self):
- return self.outdatedpackages
-
- def merge(self,mylist):
- returnme=0
- #check for blocking dependencies
- for x in mylist:
- if x[0]=="blocks":
- print "\n!!! Error: the "+x[2]+" package conflicts with this package and both can't be installed on the same system together."
- sys.exit(1)
-
- #above line used by --fetchonly
- for x in mylist:
- myroot=x[1]
- print ">>> emerge",x[2],"to",x[1]
- #the last argument in the portage.doebuild() tells doebuild to *not* do dep checking
- #(emerge is already handling that)
- y=self.db[myroot]["porttree"].getname(x[2])
- if x[0]=="ebuild":
- if "--fetchonly" in self.myopts:
- retval=portage.doebuild(y,"fetch",myroot,0,edebug)
- if retval:
- print
- print "!!! Fetch for",y,"failed, continuing..."
- print
- returnme=1
- elif "--buildpkg" in self.myopts:
- #create pkg, then merge pkg
- retval=portage.doebuild(y,"clean",myroot,0,edebug)
- if retval:
- print "!!! emerge aborting on ",y,"."
- sys.exit(1)
- retval=portage.doebuild(y,"package",myroot,0,edebug)
- if retval:
- print "!!! emerge aborting on ",y,"."
- sys.exit(1)
- #dynamically update our database
- self.db[portage.root]["bintree"].inject(x[2])
- mytbz2=self.db[portage.root]["bintree"].getname(x[2])
- retval=portage.pkgmerge(mytbz2,myroot)
- if retval==None:
- print "!!! emerge aborting on ",y,"."
- sys.exit(1)
- else:
- retval=portage.doebuild(y,"clean",myroot,0,edebug)
- if retval:
- print "!!! emerge aborting on ",y,"."
- sys.exit(1)
- retval=portage.doebuild(y,"merge",myroot,0,edebug)
- if retval:
- print "!!! emerge aborting on ",y,"."
- sys.exit(1)
- #dynamically update our database
- elif x[0]=="binary":
- #merge the tbz2
- mytbz2=self.db[portage.root]["bintree"].getname(x[2])
- retval=portage.pkgmerge(mytbz2,x[1])
- if retval==None:
- print "!!! emerge aborting on ",y,"."
- sys.exit(1)
- #need to check for errors
- self.db[x[1]]["vartree"].inject(x[2])
- if "--autoclean" in self.myopts:
- retval=portage.doebuild(y,"clean",myroot,0,edebug)
- if retval:
- print "!!! emerge aborting on ",y,"."
- sys.exit(1)
- #my doing an exit this way, --fetchonly can continue to try to
- #fetch everything even if a particular download fails.
- if "--fetchonly" in self.myopts:
- if returnme:
- print "\n\n!!! Some fetch errors were encountered. Please see above for details.\n\n"
- sys.exit(returnme)
- else:
- sys.exit(0)
-
-def post_emerge(retval=0):
- auxpat=re.compile('^([^-]*)(-\d+)?\.info(-\d+)?(\.gz)?')
- global myopts
- print
- if "--pretend" in myopts:
- sys.exit(retval)
- root=portage.root
- if not os.path.isdir(root+"usr/share/info"):
- print " "+root+"usr/share/info doesn't exist, skipping info regeneration."
- elif not os.path.exists("/usr/bin/install-info"):
- print " /usr/bin/install-info doesn't exist; skipping info regeneration."
- else:
- print " "+green("*")+" Regenerating GNU info directory index..."
- if os.path.exists(root+"usr/share/info/dir"):
- os.rename(root+"usr/share/info/dir",root+"usr/share/info/dir.old")
- icount=0
- badcount=0
- for x in os.listdir(root+"usr/share/info"):
- aux=auxpat.search(x)
- if not aux:
- continue
- auxgroups=aux.groups()
- if not (auxgroups[1] or auxgroups[2]):
- myso=commands.getstatusoutput("/usr/bin/install-info --dir-file="+root+"usr/share/info/dir "+root+"usr/share/info/"+x)[1]
- if myso!="":
- print auxgroups
- badcount=badcount+1
- if "--verbose" in myopts:
- print myso
- icount=icount+1
- if badcount:
- if "--verbose" not in myopts:
- print " "+yellow("*")+" Processed",icount,"info files:",badcount,"errors; type "+green("emerge --verbose")+" to view errors."
- else:
- print " "+yellow("*")+" Processed",icount,"info files;",badcount,"errors."
-
- else:
- print " "+green("*")+" Processed",icount,"info files."
- if portage.settings["CONFIG_PROTECT"]:
- #number of directories with some protect files in them
- procount=0
- for x in string.split(portage.settings["CONFIG_PROTECT"]):
- if os.path.isdir(x):
- a=commands.getstatusoutput("cd "+x+"; find -iname '._cfg????_*'")
- if a[0]!=0:
- print " "+red("*")+" error scanning",x
- else:
- files=string.split(a[1])
- if files:
- procount=procount+1
- print " "+yellow("* IMPORTANT:")+"",len(files),"config files in",x,"need updating."
- if procount:
- print " "+yellow("*")+" Type "+green("emerge --help config")+" to learn how to update config files."
- print
- sys.exit(retval)
-
-# general options that should be taken into account before any action
-if not portage.settings.has_key("MAINTAINER_noclean"):
- if not "--autoclean" in myopts:
- myopts.append("--autoclean")
-if "--debug" in myopts:
- edebug=1
-
-# process modes that aren't in the universal emerge interface format first
-# this format is 'emerge --action --option --option [packageset]'
-if "rsync" in mymode and not myaction:
- if not os.path.exists("/usr/bin/rsync"):
- print "!!! /usr/bin/rsync does not exist, so rsync support is disabled."
- sys.exit(1)
- rclean=0
- myportdir=portage.settings["PORTDIR"]
- if myportdir[-1]=="/":
- myportdir=myportdir[:-1]
- if not os.path.exists(myportdir):
- print ">>>",myportdir,"not found, creating it."
- os.makedirs(myportdir,0755)
- if "--clean" in myopts:
- #we'll --delete files when we rsync
- rclean=1
- mycommand="/usr/bin/rsync -rlptDv --stats --progress "
- if rclean:
- mycommand=mycommand+"--delete --exclude='distfiles/*' --exclude='packages/*' "
- mycommand=mycommand+"rsync://cvs.gentoo.org/gentoo-x86-portage/* "+myportdir
- print ">>> starting rsync with cvs.gentoo.org..."
- #protect users that did not set a default umask
- os.umask(022)
- sys.exit(os.system(mycommand))
-
-# HELP action
-elif "--help"==myaction:
- if len(mymode)==0:
- print
- print bold("Usage: ")+turquoise("emerge")+" [ "+green("action")+" ] [ "+green("options")+" ] [ "+turquoise("ebuildfile")+" | "+turquoise("tbz2file")+" | "+turquoise("dependency")+" ] ..."
- print " "+turquoise("emerge")+" [ "+green("action")+" ] [ "+green("options")+" ] [ "+turquoise("system")+" | "+turquoise("world")+" | "+turquoise("noslot")+" ]"
- print " "+turquoise("emerge")+" [ "+green("--clean")+" "+green("-c")+" ] "+turquoise("rsync")
- print " "+turquoise("emerge")+" "+green("--help")+" "" "+green("-h")+" [ "+turquoise("rsync")+" | "+turquoise("system")+" | "+turquoise("world")+" | "+turquoise("noslot")+" | "+turquoise("config")+" ] "
- print
- print turquoise("Actions:")
- print " "+green("--help")+" "+green("-h")
- print " displays this help, an additional mode specifier provides"
- print " detailed help about that mode instead"
- print
- print " "+green("--update")+" "+green("-u")
- print " updates installed packages, this is typically used with",bold("world")
- print " and",bold("system")
- print
- print " "+green("--zap")+" "+green("-z")
- print " removes an installed package. the arguments can be in two"
- print " different formats : /var/db/pkg/category/package-version"
- print " or category/package."
- print
- print " "+green("--rebuild")+" "+green("-r")
- print " forcably rebuild installed packages, this is typically used with"
- print " "+bold("world"),"and",bold("system")
- print
- print " "+green("--search")+" "+green("-s")
- print " searches for matches of the supplied string in the current local"
- print " portage tree. The search string is a regular expression."
- print " A few examples: "
- print " "+bold("emerge --search \"^kde\"")
- print " list all packages starting with kde"
- print " "+bold("emerge --search \"gcc$\"")
- print " list all packages ending with gcc"
- print " "+bold("emerge --search \"\"")+" or"
- print " "+bold("emerge --search \"*\"")
- print " list all available packages "
- print
- print turquoise("Options:")
- print " "+green("--autoclean")+" "+green("-a")
- print " emerge normally cleans out the package-specific temporary"
- print " build directory before it starts the building a package. With"
- print " --autoclean, it will also clean the directory *after* the"
- print " build completes. This option is automatically enabled for"
- print " normal users, but maintainers can use this option to enable"
- print " autocleaning."
- print
- print " "+green("--buildpkg")+" "+green("-b")
- print " tell emerge to build binary packages for all ebuilds processed"
- print " (in addition to actually merging the packages. Useful for"
- print " maintainers or if you administrate multiple Gentoo Linux"
- print " systems (build once, emerge tbz2s everywhere)."
- print
- print " "+green("--debug")+" "+green("-d")
- print " Tell emerge to run the ebuild command in --debug mode. In this"
- print " mode, the bash build environment will run with the -x option,"
- print " causing it to output verbose debug information print to stdout."
- print " --debug is great for finding bash syntax errors."
- print
- print " "+green("--fetchonly")+" "+green("-f")
- print " Instead of doing any package building, just perform fetches for"
- print " all packages (main package as well as all dependencies.)"
- print
- print " "+green("--onlydeps")+" "+green("-o")
- print " Only merge (or pretend to merge) the dependencies of the"
- print " specified packages, not the packages themselves."
- print
- print " "+green("--pretend")+" "+green("-p")
- print " instead of actually performing the merge, simply display what"
- print " ebuilds and tbz2s *would* have been installed if --pretend"
- print " weren't used. Using --pretend is strongly recommended before"
- print " installing an unfamiliar package. In the printout, N = new,"
- print " U = upgrading, R = replacing"
- print
- print " "+green("--noreplace")+" "+green("-n")
- print " Skip the packages specified on the command-line that have"
- print " already been installed. Without this option, any packages,"
- print " ebuilds, or deps you specify on on the command-line *will* cause"
- print " Portage to remerge the package, even if it is already installed."
- print " Note that Portage will never remerge dependencies automatically."
- print
- print " "+green("--usepkg")+" "+green("-k")
- print " tell emerge to use binary packages (from $PKGDIR) if they are"
- print " available, thus possibly avoiding some time-consuming compiles."
- print " This option is useful for CD installs; you can export"
- print " PKGDIR=/mnt/cdrom/packages and then use this option to have"
- print " emerge \"pull\" binary packages from the CD in order to satisfy"
- print " dependencies."
- print
- print " "+green("--verbose")+" "+green("-v")
- print " Tell emerge to run in verbose mode. Currently, this causes"
- print " emerge to print out GNU info errors, if any."
- print
- elif "rsync" in mymode:
- print
- print bold("Usage: ")+turquoise("emerge")+" [ "+green("--clean")+" "+green("-c")+" ] "+turquoise("rsync")
- print
- print " \"emerge rsync\" initiates an rsync update with cvs.gentoo.org,"
- print " updating your Portage tree (typically in /usr/portage). This option"
- print " will erase any changes that you have made to existing Portage files"
- print " so be careful. \"emerge --clean rsync\" does the same thing as \"emerge"
- print " rsync\", but files that no longer exist on our server are removed."
- print
- elif "system" in mymode:
- print
- print bold("Usage: ")+turquoise("emerge")+" [ "+green("action")+" ] "+" [ "+green("options")+" ] "+turquoise("system")
- print
- print " \"emerge system\" is the Portage system update command. When run, it"
- print " will scan the etc/make.profile/packages file and determine what"
- print " packages need to be installed so that your system meets the minimum"
- print " requirements of your current system profile. Note that this doesn't"
- print " necessarily bring your system up-to-date at all; instead, it just"
- print " ensures that you have no missing parts. For example, if your system"
- print " profile specifies that you should have sys-apps/iptables installed"
- print " and you don't, then \"emerge system\" will install it (the most"
- print " recent version that matches the profile spec) for you. It's always a"
- print " good idea to do an \"emerge --pretend system\" before an \"emerge"
- print " system\", just so you know what emerge is planning to do."
- print
- elif "world" in mymode:
- print
- print bold("Usage: ")+turquoise("emerge")+" [ "+green("action")+" ] "+" [ "+green("options")+" ] "+turquoise("world")
- print
- elif "noslot" in mymode:
- print
- print bold("Usage: ")+turquoise("emerge")+" [ "+green("action")+" ] "+" [ "+green("options")+" ] "+turquoise("noslot")
- print
- elif "config" in mymode:
- outstuff=green("Config file management support (preliminary)")+"""
-
-Portage has a special feature called "config file protection". The purpose of
-this feature is to prevent new package installs from clobbering existig
-configuration files. By default, config file protection is turned on for /etc
-and the KDE configuration dirs; more may be added in the future.
-
-When Portage installs a file into a protected directory tree like /etc, any
-existing files will not be overwritten. If a file of the same name already
-exists, Portage will change the name of the to-be- installed file from 'foo' to
-'._cfg0000_foo'. If '._cfg0000_foo' already exists, this name becomes
-'._cfg0001_foo', etc. In this way, existing files are not overwritten,
-allowing the administrator to manually merge the new config files and avoid any
-unexpected changes.
-
-In addition to protecting overwritten files, Portage will not delete any files
-from a protected directory when a package is unmerged. While this may be a
-little bit untidy, it does prevent potentially valuable config files from being
-deleted, which is of paramount importance.
-
-Protected directories are set using the CONFIG_PROTECT variable, normally
-defined in /etc/make.globals. Directory exceptions to the CONFIG_PROTECTed
-directories can be specified using the CONFIG_PROTECT_MASK variable. To find
-files that need to be updated in /etc, type:
-
-# find /etc -iname '._cfg????_*'
-
-You can disable this feature by setting CONFIG_PROTECT="" in /etc/make.conf.
-Then, Portage will mercilessly auto-update your config files. Alternatively,
-you can leave Config File Protection on but tell Portage that it can overwrite
-files in certain specific /etc subdirectories. For example, if you wanted
-Portage to automatically update your rc scripts and your wget configuration,
-but didn't want any other changes made without your explicit approval, you'd
-add this to /etc/make.conf:
-
-CONFIG_PROTECT_MASK="/etc/wget /etc/rc.d"
-
-"""
- print outstuff
-
-# SEARCH action
-elif "--search"==myaction:
- if not myfiles:
- print
- print "No search terms provided."
- print
- else:
- searchinstance = search()
- for mysearch in myfiles:
- searchinstance.setKey(mysearch)
- searchinstance.execute()
- searchinstance.output()
-
-# ZAP action
-elif "--zap"==myaction:
- if not myfiles and not "noslot" in mymode:
- print
- print "No packages to unmerge have been provided."
- print
- else:
- full_paths={}
- full_ebuild_paths={}
- full_package_paths={}
- non_slot_packages=[]
-
- var_path=portage.root+"var/db/pkg"
- if "noslot" in mymode:
- localtree=portage.vartree(portage.root)
- for x in localtree.getallnodes():
- if localtree.slotted(x)==0:
- mymatches=localtree.dep_match(x)
- for package in mymatches:
- myfullpaths=localtree.getebuildpaths(package)
- for full_path in myfullpaths :
- if not os.path.exists(full_path):
- print "The ebuild '"+full_path+"' couldn't be found."
- print "Your portage installation tree seems to be corrupted."
- else:
- full_package_paths[full_path]=package
- else:
- # process all arguments, verify if they can be resolved to an installed
- # ebuild file and add the absolute paths of these ebuild to a list
- for x in myfiles:
-
- # an absolute path has been given
- if (x[0]=='/'):
- path_parts=split(x, '/')
- if len(path_parts) != 6:
- print "When providing an absolute path it should be"
- print "in the following format : "+var_path+"/category/package"
- print "The path '"+x+"' doesn't respect this."
- sys.exit(1)
- elif not os.path.exists(x):
- print "The path '"+x+"' doesn't exist."
- sys.exit(1)
- elif -1 == find(x, var_path):
- print "The path '"+x+"' didn't commence with '"+var_path+"'."
- sys.exit(1)
- else:
- # check if the SLOT file is present, and get the package version
- # from the PF file in that case
- package_slot_path=strip(x)+"/SLOT"
- package_pf_path=strip(x)+"/PF"
- if os.path.exists(package_pf_path):
- package_pf_file=open(package_pf_path)
- package_pf=package_pf_file.readline().strip()
- package_pf_file.close()
- else:
- package_pf=path_parts[5]
- full_path=strip(x)+"/"+package_pf+".ebuild"
- if not os.path.exists(full_path):
- print "The ebuild '"+full_path+"' couldn't be found."
- print "Your portage installation tree seems to be corrupted."
- else:
- path_parts=split(full_path, "/")
- full_ebuild_paths[full_path]=path_parts[4]+"/"+package_pf
-
- # a category and package name have been given
- else:
- localtree=portage.vartree(portage.root)
- mymatches=localtree.dep_match(x)
- # if no matches were found, try again by adding a '=' dep symbol if no
- # dep symbols are already present
- if not mymatches and x[0] not in ('<','>','=','~'):
- mymatches=localtree.dep_match("="+x)
-
- # only loops over the matches if they were found
- if mymatches:
- for package in mymatches:
- myfullpaths=localtree.getebuildpaths(package)
- for full_path in myfullpaths :
- if not os.path.exists(full_path):
- print "The ebuild '"+full_path+"' couldn't be found."
- print "Your portage installation tree seems to be corrupted."
- else:
- full_package_paths[full_path]=package
-
- # determine what the non slot packages are
- if len(full_package_paths) > 0:
- # determine the latest installed packages of each cat/pkg key
- full_paths_keys=full_package_paths.keys()
- # sort the ebuild paths
- full_paths_keys.sort()
- previous_package_set=None
- for full_path in full_paths_keys:
- # construct the key that will be used to determine when a new package set
- # is being processed, the package slot is taken into account for this
- package_parts=portage.pkgsplit(full_package_paths[full_path])
- slot_path=dirname(full_path)+"/SLOT"
- if not os.path.exists(slot_path):
- package_slot=package_parts[1]
- non_slot_packages.append(package_parts[0]+"-"+package_parts[1])
-
- full_paths=full_ebuild_paths.keys()
- full_paths.extend(full_package_paths.keys())
-
- if len(full_paths)==0:
- print "Couldn't find any matching installed packages."
- sys.exit(1)
- else:
- if "--pretend" in myopts:
- print
- print "The are the packages that I would unmerge :"
- print
- else:
- print
- print "The following packages are going to be unmerged :"
- print
- # this makes revisions come before slot versions
- # and therefor unmerges the older packages first
- full_paths.sort()
- for full_path in full_paths:
- path_parts=split(full_path, "/")
- print " "+path_parts[4]+"/"+path_parts[5]
-
- if len(non_slot_packages)>0:
- print
- if "--verbose" not in myopts:
- print " "+yellow("* IMPORTANT:"),len(non_slot_packages),"non slot packages; use "+green("--verbose")+" to view details."
- else:
- print " "+yellow("* IMPORTANT:"),len(non_slot_packages),"non slot packages"
- print " "+yellow("*")+" These packages have been merged with an old version of portage that didn't"
- print " "+yellow("*")+" support binary compatibility slots. This means that each package with a"
- print " "+yellow("*")+" different version number will be considered different and only older versions"
- print " "+yellow("*")+" of different releases will be unmerged automatically."
- print " "+yellow("*")+" To get rid of all non slot packages, you can rebuild your system with"
- print " "+yellow("*")+" "+green("emerge --noslot rebuild")+"."
- print
- for non_slot_package in non_slot_packages:
- print " "+non_slot_package
-
- if "--pretend" in myopts:
- print
- else:
- secs=string.atoi(portage.settings["UNMERGE_DELAY"])
- if secs > 0:
- print
- print "Waiting",secs,"seconds to make sure that you want these"
- print "packages to be removed ..."
- while secs > 0:
- sys.stdout.write(str(secs)+" ")
- sys.stdout.flush()
- time.sleep(1)
- secs = secs-1
- print secs
- for full_path in full_paths:
- print "Unmerging "+os.path.basename(full_path)+" ..."
- retval=portage.doebuild(full_path,"unmerge",portage.root,0,edebug)
- post_emerge()
-
-# REBUILD action
-elif "--rebuild"==myaction:
- if not "system" in mymode and not "world" in mymode and not "noslot" in mymode:
- print
- print " "+red("* WARNING:"),green("emerge --rebuild"),"shouldn't be used for regular packages"
- print " "+red("*"),"it's only intended to be used with",green("system")+", "+green("world")+", and",green("noroot")
- print
- else:
- if "--pretend" in myopts:
- print
- print "These are the packages that I would rebuild, in order."
- print
-
- if "system" in mymode:
- mydepgraph=depgraph(mymode,myaction,myopts)
- print "Calculating system dependencies",
- mydepgraph.syscreate(getsyslist())
- print " done!"
- elif "world" in mymode or "noslot" in mymode:
- mydepgraph=depgraph(mymode,myaction,myopts)
- print "Calculating world dependencies",
- mydepgraph.syscreate(mydepgraph.db["/"]["vartree"].getallnodes())
- print " done!"
-
- if "--pretend" in myopts:
- mydepgraph.display(mydepgraph.altlist())
-
- myoutdated=mydepgraph.outdated()
- if len(myoutdated):
- if "--verbose" not in myopts:
- print
- print " "+yellow("* IMPORTANT:"),len(myoutdated),"packages aren't available anymore; use "+green("--verbose")+" for details."
- else:
- print
- print " "+yellow("* IMPORTANT:"),len(myoutdated),"packages aren't available anymore"
- print " "+yellow("*")+" Your portage tree doesn't contain the ebuilds anymore that correspond to the"
- print " "+yellow("*")+" following packages. This means that portage is unable to rebuild them."
- print " "+yellow("*")+" Instead you should upgrade to the latest versions or install possible"
- print " "+yellow("*")+" alternative packages that provide the same functionalities."
- myoutdated.sort()
- for mypackage in myoutdated:
- print " "+mypackage
- else:
- mydepgraph.merge(mydepgraph.altlist())
- post_emerge()
-
-# INSTALL and UPDATE action
-elif "--update"==myaction or not myaction:
- if not myaction and "world" in mymode:
- print
- print " "+red("* WARNING:"),green("emerge world"),"can't be used without an action"
- print " "+red("*"),green("world"),"is only intended to be used with",green("emerge --update")
- print
- else:
- if "--pretend" in myopts:
- print
- print "These are the packages that I would merge, in order."
- print
-
- if "system" in mymode:
- mydepgraph=depgraph(mymode,myaction,myopts)
- print "Calculating system dependencies",
- mydepgraph.syscreate(getsyslist())
- print " done!"
- elif "world" in mymode:
- mydepgraph=depgraph(mymode,myaction,myopts)
- print "Calculating world dependencies",
- mydepgraph.syscreate(mydepgraph.db["/"]["vartree"].getallnodes())
- print " done!"
- elif "noslot" in mymode:
- mydepgraph=depgraph(mymode,myaction,myopts)
- print "Calculating noslot dependencies",
- mydepgraph.syscreate(mydepgraph.db["/"]["vartree"].getallnodes())
- print " done!"
- else:
- mydepgraph=depgraph(mymode,myaction,myopts)
- if not myfiles:
- post_emerge()
- #we don't have any files to process; skip this step and exit
- print "Calculating dependencies",
- for mypkg in myfiles:
- if mypkg[-5:]==".tbz2":
- mytype="binary"
- mytbz2=xpak.tbz2(mypkg)
- mykey=mytbz2.getelements("CATEGORY")[0]+"/"+os.path.basename(mypkg)[:-5]
- elif mypkg[-7:]==".ebuild":
- mytype="ebuild"
- mykey=os.path.basename(os.path.abspath(mypkg+"/../.."))+"/"+os.path.basename(mypkg)[:-7]
- else:
- mykey=""
- if "--usepkg" in myopts:
- mykey=mydepgraph.db[portage.root]["bintree"].dep_bestmatch(mypkg)
- mytype="binary"
- if not mykey:
- mykey=mydepgraph.db[portage.root]["porttree"].dep_bestmatch(mypkg)
- mytype="ebuild"
- if not mykey:
- print "!!! Couldn't find match for",mypkg+"; aborting."
- sys.exit(1)
- # else:
- # print "!!! Error:",x,"is neither an ebuild nor a .tbz2 package."
- # sys.exit(1)
- mydepgraph.create(mytype+" "+portage.root+" "+mykey,None,"--onlydeps" not in myopts)
- print " done!"
-
- if "--pretend" in myopts:
- mydepgraph.display(mydepgraph.altlist())
- else:
- mydepgraph.merge(mydepgraph.altlist())
- post_emerge()
-