* Namespace sanitizing: move all portage related code into portage.* namespace,
rename portage_foo modules to portage.foo (but keep symlinks for compability)
* Add license visibility filtering (GLEP 23)
+* Add new elog module "echo" to simply display messages when emerge exits
+* Enable "echo" and "save_summary" elog modules by default
+* Fix -* handling in package.keywords to work as intended (reset the accepted
+ keywords list), also see RELEASE-NOTES.
portage-2.1.2
-------------
* The python namespace for portage has been sanitized, all portage related code
is now contained within the portage namespace. External script should be updated
accordingly, though links exist for backward compability.
+* The "save_summary" and "echo" elog modules are now enabled by default. Setting
+ PORTAGE_ELOG_SYSTEM in make.conf will override this, so if you don't want elog
+ set PORTAGE_ELOG_SYSTEM="" in make.conf
+* -* support in package.keywords was changed as it was inconsistent with
+ ACCEPT_KEYWORDS behavior (also see http://dev.gentoo.org/~genone/docs/KEYWORDS.stupid).
+ Previously having -* in package.keywords matched packages with KEYWORDS="-*",
+ now it resets the ACCEPT_KEYWORDS list for the given atom like it does when
+ used in ACCEPT_KEYWORDS.
+ For packages that don't specify any other KEYWORDS you can use the new ** token
+ as documented in portage(5) to disable KEYWORDS filtering completely.
portage-2.1.2
==================================
# PORTAGE_ELOG_SYSTEM: selects the module(s) to process the log messages. Modules
# included in portage are (empty means logging is disabled):
+# echo (display messages again when emerge exits)
# save (saves one log per package in $PORT_LOGDIR/elog,
# /var/log/portage/elog if $PORT_LOGDIR is unset)
# custom (passes all messages to $PORTAGE_ELOG_COMMAND)
# Some defaults for elog
PORTAGE_ELOG_CLASSES="log warn error"
+PORTAGE_ELOG_SYSTEM="save_summary echo"
PORTAGE_ELOG_MAILURI="@rootuser@"
PORTAGE_ELOG_MAILSUBJECT="[portage] ebuild log for \${PACKAGE} on \${HOST}"
if myopt not in myresumeopts:
myresumeopts[myopt] = myarg
myopts=myresumeopts
+
+ # Adjust config according to options of the command being resumed.
+ for myroot in trees:
+ mysettings = trees[myroot]["vartree"].settings
+ mysettings.unlock()
+ adjust_config(myopts, mysettings)
+ mysettings.lock()
+ del myroot, mysettings
+
myparams = create_depgraph_params(myopts, myaction)
if "--quiet" not in myopts and "--nodeps" not in myopts:
print "Calculating dependencies ",
else:
resumecommand=mysettings["RESUMECOMMAND"]
- fetchcommand=fetchcommand.replace("${DISTDIR}",mysettings["DISTDIR"])
- resumecommand=resumecommand.replace("${DISTDIR}",mysettings["DISTDIR"])
-
if not can_fetch:
if fetched != 2:
if fetched == 0:
locfetch=fetchcommand
writemsg_stdout(">>> Downloading '%s'\n" % \
re.sub(r'//(.+):.+@(.+)/',r'//\1:*password*@\2/', loc))
- myfetch=locfetch.replace("${URI}",loc)
- myfetch=myfetch.replace("${FILE}",myfile)
+ myfetch = locfetch.split()
+ variables = {"${DISTDIR}":mysettings["DISTDIR"],
+ "${URI}":loc, "${FILE}":myfile}
+ for i in xrange(len(myfetch)):
+ token = myfetch[i].strip("\"'")
+ value = variables.get(token)
+ if value is not None:
+ myfetch[i] = value
spawn_keywords = {}
if "userfetch" in mysettings.features and \
con = con.replace(mysettings["PORTAGE_T"], mysettings["PORTAGE_FETCH_T"])
selinux.setexec(con)
- myret = portage.process.spawn_bash(myfetch,
+ myret = portage.process.spawn(myfetch,
env=mysettings.environ(), **spawn_keywords)
if mysettings.selinux_enabled():
if matches:
inc_pgroups = []
for x in pgroups:
- if x != "-*" and x.startswith("-"):
+ if x == "-*":
+ inc_pgroups = []
+ elif x[0] == "-":
try:
inc_pgroups.remove(x[1:])
except ValueError:
pass
- if x not in inc_pgroups:
+ elif x not in inc_pgroups:
inc_pgroups.append(x)
pgroups = inc_pgroups
del inc_pgroups
if gp=="*":
kmask=None
break
- elif gp=="-"+myarch:
+ elif gp=="-"+myarch and myarch in pgroups:
kmask="-"+myarch
break
- elif gp=="~"+myarch:
+ elif gp=="~"+myarch and myarch in pgroups:
kmask="~"+myarch
break
for atom in matches:
pgroups.extend(pkgdict[cp][atom])
if matches:
+ # normalize pgroups with incrementals logic so it
+ # matches ACCEPT_KEYWORDS behavior
inc_pgroups = []
for x in pgroups:
- # The -* special case should be removed once the tree
- # is clean of KEYWORDS=-* crap
- if x != "-*" and x.startswith("-"):
+ if x == "-*":
+ inc_pgroups = []
+ elif x[0] == "-":
try:
inc_pgroups.remove(x[1:])
except ValueError:
pass
- if x not in inc_pgroups:
+ elif x not in inc_pgroups:
inc_pgroups.append(x)
pgroups = inc_pgroups
del inc_pgroups
hasstable = False
hastesting = False
for gp in mygroups:
- if gp=="*":
- writemsg("--- WARNING: Package '%s' uses '*' keyword.\n" % mycpv,
+ if gp == "*" or (gp == "-*" and len(mygroups) == 1):
+ writemsg("--- WARNING: Package '%s' uses '%s' keyword.\n" % (mycpv, gp),
noiselevel=-1)
match=1
break
+# elog/__init__.py - elog core functions
+# Copyright 2006-2007 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
from portage.const import EBUILD_PHASES
from portage.exception import PortageException
from portage.process import atexit_register
+# elog/mod_custom.py - elog dispatch module
+# Copyright 2006-2007 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
import portage.elog_modules.mod_save, portage.process, portage.exception
def process(mysettings, cpv, logentries, fulltext):
--- /dev/null
+# elog/mod_echo.py - elog dispatch module
+# Copyright 2007 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+from portage.output import EOutput
+from portage.const import EBUILD_PHASES
+
+_items = {}
+def process(mysettings, cpv, logentries, fulltext):
+ _items[cpv] = logentries
+
+def finalize(mysettings):
+ printer = EOutput()
+ for cpv in _items.keys():
+ print
+ printer.einfo("Messages for package %s:" % cpv)
+ print
+ for phase in EBUILD_PHASES:
+ if not phase in _items[cpv]:
+ continue
+ for msgtype, msgcontent in _items[cpv][phase]:
+ fmap = {"INFO": printer.einfo,
+ "WARN": printer.ewarn,
+ "ERROR": printer.eerror,
+ "LOG": printer.einfo,
+ "QA": printer.ewarn}
+ for line in msgcontent:
+ fmap[msgtype](line.strip("\n"))
+ return
-# portage.py -- core Portage functionality
-# Copyright 1998-2004 Gentoo Foundation
+# elog/mod_mail.py - elog dispatch module
+# Copyright 2006-2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id$
-# portage.py -- core Portage functionality
-# Copyright 1998-2004 Gentoo Foundation
+# elog/mod_mail_summary.py - elog dispatch module
+# Copyright 2006-2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Id: mod_mail.py 3484 2006-06-10 22:38:44Z genone $
+# $Id$
import portage.mail, socket, os, time
from email.MIMEText import MIMEText as TextMessage
+# elog/mod_save.py - elog dispatch module
+# Copyright 2006-2007 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
import os, time
from portage.data import portage_uid, portage_gid
+# elog/mod_save_summary.py - elog dispatch module
+# Copyright 2006-2007 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
import os, time
from portage.data import portage_uid, portage_gid
+# elog/mod_syslog.py - elog dispatch module
+# Copyright 2006-2007 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
import syslog
from portage.const import EBUILD_PHASES