export DIROPTIONS="-m0755"
export MOPREFIX=${PN}
-# When compiler flags are unset, many packages will substitute their own
-# implicit flags. For uniformity, use an empty string as the default.
-[ "${CFLAGS-unset}" == "unset" ] && export CFLAGS=""
-[ "${CXXFLAGS-unset}" == "unset" ] && export CXXFLAGS=""
-[ "${LDFLAGS-unset}" == "unset" ] && export LDFLAGS=""
-
check_KV() {
if [ -z "${KV}" ]; then
eerror ""
if [ "${newstuff}" == "yes" ]; then
# We don't necessarily have privileges to do a full dyn_clean here.
rm -rf "${WORKDIR}"
- if [ -d "${T}" ] && ! hasq keeptemp ${FEATURES} ; then
+ if [ -d "${T}" ] && \
+ ! hasq keeptemp $FEATURES && ! hasq keepwork $FEATURES ; then
rm -rf "${T}" && mkdir "${T}"
- else
- [ -e "${T}/environment" ] && \
- mv "${T}/environment" "${T}/environment.keeptemp"
fi
fi
if [ -e "${WORKDIR}" ]; then
fi
rm -rf "${PORTAGE_BUILDDIR}/image" "${PORTAGE_BUILDDIR}/homedir"
+ rm -f "${PORTAGE_BUILDDIR}/.installed"
- if ! hasq keeptemp $FEATURES; then
+ if ! hasq keeptemp $FEATURES && ! hasq keepwork $FEATURES ; then
rm -rf "${T}"
- else
- [ -e "${T}/environment" ] && mv "${T}/environment" "${T}/environment.keeptemp"
fi
if ! hasq keepwork $FEATURES; then
rm -rf "${PORTAGE_BUILDDIR}/.unpacked"
rm -rf "${PORTAGE_BUILDDIR}/.compiled"
rm -rf "${PORTAGE_BUILDDIR}/.tested"
- rm -rf "${PORTAGE_BUILDDIR}/.installed"
rm -rf "${PORTAGE_BUILDDIR}/.packaged"
rm -rf "${PORTAGE_BUILDDIR}/build-info"
rm -rf "${WORKDIR}"
exit 1
fi
eval $(portageq envvar -v FEATURES FETCHCOMMAND GENTOO_MIRRORS \
- PORTAGE_BIN_PATH PORTAGE_GPG_DIR PORTAGE_INST_UID PORTAGE_INST_GID \
+ PORTAGE_BIN_PATH PORTAGE_GPG_DIR \
PORTAGE_NICENESS PORTAGE_RSYNC_EXTRA_OPTS PORTAGE_TMPDIR PORTDIR \
http_proxy ftp_proxy EPREFIX)
DISTDIR="${PORTAGE_TMPDIR}/emerge-webrsync"
vecho "Syncing local tree ..."
- if type -P tarsync &> /dev/null; then
+ # tarsync-0.2.1 doesn't seem to support lzma compression.
+ if [ "${file##*.}" != "lzma" ] && type -P tarsync &> /dev/null; then
if ! tarsync $(vvecho -v) -s 1 -o portage -g portage -e /distfiles -e /packages -e /local "${file}" "${PORTDIR}"; then
eecho "tarsync failed; tarball is corrupt? (${file})"
return 1
# Free disk space
rm -f "${file}"
- # Make sure user and group file ownership is ${PORTAGE_INST_UID}:${PORTAGE_INST_GID}
- chown -R ${PORTAGE_INST_UID:-0}:${PORTAGE_INST_GID:-0} portage
+ chown ${PORTAGE_USER:-portage}:${PORTAGE_GROUP:-portage} portage &> /dev/null && \
+ chown -R ${PORTAGE_USER:-portage}:${PORTAGE_GROUP:-portage} portage
+
cd portage
rsync -av --progress --stats --delete --delete-after \
--exclude='/distfiles' --exclude='/packages' \
LAST_E_CMD LAST_E_LEN LD_PRELOAD MISC_FUNCTIONS_ARGS MOPREFIX \
NORMAL PKGDIR PKGUSE PKG_LOGDIR PKG_TMPDIR \
PORTAGE_ACTUAL_DISTDIR PORTAGE_ARCHLIST PORTAGE_BASHRC \
- PORTAGE_BINPKG_TMPFILE PORTAGE_BUILDDIR \
+ PORTAGE_BINPKG_TAR_OPTS PORTAGE_BINPKG_TMPFILE PORTAGE_BUILDDIR \
PORTAGE_COLORMAP PORTAGE_CONFIGROOT PORTAGE_DEBUG \
PORTAGE_DEPCACHEDIR PORTAGE_GID PORTAGE_INST_GID \
PORTAGE_INST_UID PORTAGE_LOG_FILE PORTAGE_MASTER_PID \
[ -z "${PORTAGE_BINPKG_TMPFILE}" ] && \
PORTAGE_BINPKG_TMPFILE="${PKGDIR}/${CATEGORY}/${PF}.tbz2"
mkdir -p "${PORTAGE_BINPKG_TMPFILE%/*}" || die "mkdir failed"
- tar ${tar_options} -cf - . | bzip2 -f > "${PORTAGE_BINPKG_TMPFILE}" || \
+ tar $tar_options -cf - $PORTAGE_BINPKG_TAR_OPTS . | \
+ bzip2 -f > "$PORTAGE_BINPKG_TMPFILE" || \
die "Failed to create tarball"
cd ..
export PYTHONPATH=${PORTAGE_PYM_PATH:-${EPREFIX}/usr/lib/portage/pym}
parser.add_option('-i', '--ignore-arches', dest='ignore_arches', action='store_true',
default=False, help='ignore arch-specific failures (where arch != host)')
- parser.add_option('-I', '--ignored-masked', dest='ignore_masked', action='store_true',
- default=False, help='ignore masked packages (not allowed with commit mode')
+ parser.add_option('-I', '--ignore-masked', dest='ignore_masked', action='store_true',
+ default=False, help='ignore masked packages (not allowed with commit mode)')
+
+ parser.add_option('--without-mask', dest='without_mask', action='store_true',
+ default=False, help='behave as if no package.mask entries exist')
parser.add_option('--mode', type='choice', dest='mode', choices=modes.keys(),
help='specify which mode repoman will run in (default=full)')
"file.size":"Files in the files directory must be under 20k",
"file.name":"File/dir name must be composed of only the following chars: %s " % allowed_filename_chars,
"file.UTF8":"File is not UTF8 compliant",
+ "KEYWORDS.dropped":"Ebuilds that appear to have dropped KEYWORDS for some arch",
"KEYWORDS.missing":"Ebuilds that have a missing or empty KEYWORDS variable",
"KEYWORDS.stable":"Ebuilds that have been added directly with stable KEYWORDS",
"KEYWORDS.stupid":"Ebuilds that use KEYWORDS=-* instead of package.mask",
"LICENSE.missing":"Ebuilds that have a missing or empty LICENSE variable",
"DESCRIPTION.missing":"Ebuilds that have a missing or empty DESCRIPTION variable",
"DESCRIPTION.toolong":"DESCRIPTION is over %d characters" % max_desc_len,
+ "EAPI.incompatible":"Ebuilds that use features that are only available with a different EAPI",
"EAPI.unsupported":"Ebuilds that have an unsupported EAPI version (you must upgrade portage)",
"SLOT.missing":"Ebuilds that have a missing or empty SLOT variable",
"HOMEPAGE.missing":"Ebuilds that have a missing or empty HOMEPAGE variable",
"DEPEND.badindev","RDEPEND.badindev","PDEPEND.badindev",
"DEPEND.badmaskedindev","RDEPEND.badmaskedindev","PDEPEND.badmaskedindev",
"DESCRIPTION.toolong",
+"KEYWORDS.dropped",
"KEYWORDS.stupid",
"KEYWORDS.missing",
"RESTRICT.invalid",
new_ebuilds.update(x for x in mynew if x.endswith(".ebuild"))
del mycvstree, mynew
+have_masked = False
dofail = 0
arch_caches={}
arch_xmatch_caches = {}
fails["EAPI.unsupported"].append(os.path.join(x, y))
continue
ebuild_metadata[pf] = myaux
- ebuildlist.sort()
+
+ # Sort ebuilds in ascending order for the KEYWORDS.dropped check.
+ pkgsplits = {}
+ for i in xrange(len(ebuildlist)):
+ ebuild_split = portage.pkgsplit(ebuildlist[i])
+ pkgsplits[ebuild_split] = ebuildlist[i]
+ ebuildlist[i] = ebuild_split
+ ebuildlist.sort(portage.pkgcmp)
+ for i in xrange(len(ebuildlist)):
+ ebuildlist[i] = pkgsplits[ebuildlist[i]]
+ del pkgsplits
+
+ slot_keywords = {}
if len(ebuild_metadata) != len(ebuildlist):
# If we can't access all the metadata then it's totally unsafe to
continue
myaux = ebuild_metadata[y]
+ eapi = myaux["EAPI"]
# Test for negative logic and bad words in the RESTRICT var.
#for x in myaux[allvars.index("RESTRICT")].split():
x + "/" + y + ".ebuild added with stable keywords: %s" % \
" ".join(stable_keywords))
+ ebuild_archs = set(kw.lstrip("~") for kw in keywords \
+ if not kw.startswith("-"))
+
+ previous_keywords = slot_keywords.get(myaux["SLOT"])
+ if previous_keywords is None:
+ slot_keywords[myaux["SLOT"]] = set()
+ else:
+ dropped_keywords = previous_keywords.difference(ebuild_archs)
+ if dropped_keywords:
+ stats["KEYWORDS.dropped"] += 1
+ fails["KEYWORDS.dropped"].append(
+ relative_path + ": %s" % \
+ " ".join(sorted(dropped_keywords)))
+
+ slot_keywords[myaux["SLOT"]].update(ebuild_archs)
+
# KEYWORDS="-*" is a stupid replacement for package.mask and screws general KEYWORDS semantics
if "-*" in keywords:
haskeyword = False
if myteststr.find(token) != -1:
badsyntax.append("'%s' not separated by space" % (token))
-
if mytype in ("DEPEND", "RDEPEND", "PDEPEND"):
for token in mydepstr.split():
if token in operator_tokens or \
token.endswith("?"):
continue
- if not portage.isvalidatom(token, allow_blockers=True) or \
- ":" in token and myaux["EAPI"] == "0":
+ if not portage.isvalidatom(token, allow_blockers=True):
badsyntax.append("'%s' not a valid atom" % token)
+ else:
+ atom = token.lstrip("!")
+ if eapi == "0":
+ if portage.dep.dep_getslot(atom):
+ stats['EAPI.incompatible'] += 1
+ fails['EAPI.incompatible'].append(
+ (relative_path + ": %s slot dependency" + \
+ " not supported with EAPI='%s':" + \
+ " '%s'") % (mytype, eapi, atom))
type_list.extend([mytype] * (len(badsyntax) - len(type_list)))
for mypos in range(len(myuse)-1,-1,-1):
if myuse[mypos] and (myuse[mypos] in luselist[mykey]):
del myuse[mypos]
- if default_use and myaux["EAPI"] == "0":
- myuse += default_use
+
+ if default_use and eapi == "0":
+ for myflag in default_use:
+ stats['EAPI.incompatible'] += 1
+ fails['EAPI.incompatible'].append(
+ (relative_path + ": IUSE defaults" + \
+ " not supported with EAPI='%s':" + \
+ " '%s'") % (eapi, myflag))
+
for mypos in range(len(myuse)):
stats["IUSE.invalid"]=stats["IUSE.invalid"]+1
fails["IUSE.invalid"].append(x+"/"+y+".ebuild: %s" % myuse[mypos])
config_profile_path=profdir,
config_incrementals=portage.const.INCREMENTALS,
local_config=False)
+ if options.without_mask:
+ dep_settings.pmaskdict.clear()
arch_caches[prof[0]] = dep_settings
while True:
try:
ismasked = os.path.join(catdir, y) not in \
portdb.xmatch("list-visible", x)
if ismasked:
+ have_masked = True
if options.ignore_masked:
continue
#we are testing deps for a masked package; give it some lee-way
mygroups[xs[0]]+=[seperator.join(xs[1:])]
return mygroups
+if have_masked and not (options.without_mask or options.ignore_masked):
+ print bold("Note: use --without-mask to check " + \
+ "KEYWORDS on dependencies of masked packages")
+
if options.mode != 'commit':
if dofull:
print bold("Note: type \"repoman full\" for a complete listing.")
# ** USE, CONFIG_*, and FEATURES are incremental **
# ***************************************************
+# When compiler flags are unset, many packages will substitute their own
+# implicit flags. For uniformity, use an empty string as the default.
+CFLAGS=""
+CXXFLAGS=""
+LDFLAGS=""
# Default rsync mirror
SYNC="rsync://rsync.gentoo.org/gentoo-portage"
.TP
.B strict
Have portage react strongly to conditions that have the potential to be
-dangerous (like missing or incorrect digests for ebuilds or distfiles).
+dangerous (like missing or incorrect digests for ebuilds).
.TP
.B stricter
Have portage react strongly to conditions that may conflict with system
header field is not defined then the client will use it's ${PORTAGE_BINHOST}
setting as the base URI.
.TP
+.B PORTAGE_BINPKG_TAR_OPTS
+This variable contains options to be passed to the tar command for creation
+of binary packages.
+.TP
\fBPORTAGE_COMPRESS\fR = \fI"bzip2"\fR
This variable contains the command used to compress documentation during the
install phase.
\fB-v\fR, \fB--verbose\fR
Displays every package name while checking
.TP
-\fB-I\fR, \fB--ignore-arches\fR
+\fB\-i\fR, \fB\-\-ignore\-arches\fR
Ignore arch-specific failures (where arch != host)
.TP
+\fB\-I\fR, \fB\-\-ignore\-masked\fR
+Ignore masked packages (not allowed with commit mode)
+.TP
+\fB\-\-without\-mask\fR
+Behave as if no package.mask entries exist
+.TP
\fB-m\fR, \fB--commitmsg\fR
Adds a commit message via the command line
.TP
.B DESCRIPTION.missing
Ebuilds that have a missing or empty DESCRIPTION variable
.TP
+.B EAPI.incompatible
+Ebuilds that use features that are only available with a different EAPI
+.TP
.B EAPI.unsupported
Ebuilds that have an unsupported EAPI version (you must upgrade portage)
.TP
.B IUSE.invalid
This build has a variable in IUSE that is not in the use.desc or use.local.desc file
.TP
+.B KEYWORDS.dropped
+Ebuilds that appear to have dropped KEYWORDS for some arch
+.TP
.B KEYWORDS.invalid
This ebuild contains KEYWORDS that are not listed in profiles/arch.list or for which no valid profile was found
.TP
usepkgonly = "--usepkgonly" in self.myopts
empty = "empty" in self.myparams
selective = "selective" in self.myparams
+ noreplace = "--noreplace" in self.myopts
reinstall = False
# Behavior of the "selective" parameter depends on
# whether or not a package matches an argument atom.
# descending order
cpv_list.reverse()
for cpv in cpv_list:
+ # Make --noreplace take precedence over --newuse.
+ if not installed and noreplace and \
+ cpv in vardb.match(atom):
+ break
reinstall_for_flags = None
try:
metadata = dict(izip(db_keys,
"PKGUSE", "PKG_LOGDIR", "PKG_TMPDIR",
"PORTAGE_ACTUAL_DISTDIR", "PORTAGE_ARCHLIST",
"PORTAGE_BASHRC",
- "PORTAGE_BINPKG_FILE", "PORTAGE_BINPKG_TMPFILE",
+ "PORTAGE_BINPKG_FILE", "PORTAGE_BINPKG_TAR_OPTS",
+ "PORTAGE_BINPKG_TMPFILE",
"PORTAGE_BIN_PATH",
"PORTAGE_BUILDDIR", "PORTAGE_COLORMAP",
"PORTAGE_CONFIGROOT", "PORTAGE_DEBUG", "PORTAGE_DEPCACHEDIR",
mymirrors += [x.rstrip("/") for x in mysettings["GENTOO_MIRRORS"].split() if x]
pkgdir = mysettings.get("O")
- if pkgdir:
+ if pkgdir is not None:
mydigests = Manifest(
pkgdir, mysettings["DISTDIR"]).getTypeDigests("DIST")
else:
"""Verifies checksums. Assumes all files have been downloaded.
DEPRECATED: this is now only a compability wrapper for
portage.manifest.Manifest()."""
- if not strict:
- return 1
pkgdir = mysettings["O"]
manifest_path = os.path.join(pkgdir, "Manifest")
if not os.path.exists(manifest_path):
eout = portage.output.EOutput()
eout.quiet = mysettings.get("PORTAGE_QUIET", None) == "1"
try:
- eout.ebegin("checking ebuild checksums ;-)")
- mf.checkTypeHashes("EBUILD")
- eout.eend(0)
- eout.ebegin("checking auxfile checksums ;-)")
- mf.checkTypeHashes("AUX")
- eout.eend(0)
- eout.ebegin("checking miscfile checksums ;-)")
- mf.checkTypeHashes("MISC", ignoreMissingFiles=True)
- eout.eend(0)
+ if strict:
+ eout.ebegin("checking ebuild checksums ;-)")
+ mf.checkTypeHashes("EBUILD")
+ eout.eend(0)
+ eout.ebegin("checking auxfile checksums ;-)")
+ mf.checkTypeHashes("AUX")
+ eout.eend(0)
+ eout.ebegin("checking miscfile checksums ;-)")
+ mf.checkTypeHashes("MISC", ignoreMissingFiles=True)
+ eout.eend(0)
for f in myfiles:
eout.ebegin("checking %s ;-)" % f)
mf.checkFileHashes(mf.findFile(f), f)
if f.endswith(".ebuild") and not mf.hasFile("EBUILD", f):
writemsg("!!! A file is not listed in the Manifest: '%s'\n" % \
os.path.join(pkgdir, f), noiselevel=-1)
- return 0
+ if strict:
+ return 0
""" epatch will just grab all the patches out of a directory, so we have to
make sure there aren't any foreign files that it might grab."""
filesdir = os.path.join(pkgdir, "files")
if file_type != "AUX" and not f.startswith("digest-"):
writemsg("!!! A file is not listed in the Manifest: '%s'\n" % \
os.path.join(filesdir, f), noiselevel=-1)
- return 0
+ if strict:
+ return 0
return 1
# parse actionmap to spawn ebuild with the appropriate args
myrecipient = "root@localhost"
myfrom = mysettings["PORTAGE_ELOG_MAILFROM"]
+ myfrom = myfrom.replace("${HOST}", socket.getfqdn())
mysubject = mysettings["PORTAGE_ELOG_MAILSUBJECT"]
mysubject = mysubject.replace("${PACKAGE}", key)
mysubject = mysubject.replace("${HOST}", socket.getfqdn())
myrecipient = "root@localhost"
myfrom = mysettings["PORTAGE_ELOG_MAILFROM"]
+ myfrom = myfrom.replace("${HOST}", socket.getfqdn())
mysubject = mysettings["PORTAGE_ELOG_MAILSUBJECT"]
mysubject = mysubject.replace("${PACKAGE}", count)
mysubject = mysubject.replace("${HOST}", socket.getfqdn())