portage-2.2
-------------
+* Add support for a new EAPI="2_pre0" value that can be used in ebuilds when
+ testing new features such as USE dependencies. This is an experimental EAPI
+ that will not be supported after the final EAPI 2 is defined. For more
+ information about experimental EAPI features, refer to the "Ebuild" chapter
+ of the html documentation that is installed with portage.
* Add PORTAGE_IONICE_COMMAND setting for make.conf which is called to adjust
IO priority on portage and it's subprocesses.
* Add link level dependency awareness to emerge --depclean and --prune actions
utilities.parse_use_local_desc(f, luselist)
f.close()
except (IOError, OSError, ParseError), e:
- logging.exception("Couldn't read from use.local.desc", e)
+ logging.exception("Couldn't read from use.local.desc")
sys.exit(1)
if portdir_overlay != portdir:
utilities.parse_use_local_desc(f, luselist)
f.close()
except (IOError, OSError, ParseError), e:
- logging.exception("Couldn't read from '%s'" % filename, e)
+ logging.exception("Couldn't read from '%s'" % (filename,))
sys.exit(1)
del filename
for l in range(0, len(vardescs)):
uselist.append(var.lower() + "_" + vardescs[l].split()[0])
except (IOError, OSError, ParseError), e:
- logging.exception("Couldn't read USE flags from use.desc", e)
+ logging.exception("Couldn't read USE flags from use.desc")
sys.exit(1)
# retrieve a list of current licenses in portage
fails["changelog.missing"].append(x+"/ChangeLog")
#metadata.xml file check
+ muselist = []
+
if "metadata.xml" not in checkdirlist:
stats["metadata.missing"]+=1
fails["metadata.missing"].append(x+"/metadata.xml")
stats["metadata.bad"]+=1
fails["metadata.bad"].append(x+"/metadata.xml")
- #load USE flags from metadata.xml
- muselist=[]
- try:
- f = open(os.path.join(checkdir, "metadata.xml"))
- utilities.parse_metadata_use(f, muselist)
- f.close()
- except (IOError, OSError, ParseError), e:
- logging.exception("Couldn't read from metadata.xml", e)
- sys.exit(1)
+ #load USE flags from metadata.xml
+ try:
+ f = open(os.path.join(checkdir, "metadata.xml"))
+ utilities.parse_metadata_use(f, muselist)
+ f.close()
+ except (EnvironmentError, ParseError), e:
+ logging.exception("Couldn't read from metadata.xml")
+ sys.exit(1)
allmasked = True
<title>Ebuild</title>
&package_ebuild_phases;
&package_ebuild_helper_functions;
+&package_ebuild_eapi_2;
</chapter>
--- /dev/null
+<sect1 id='package-ebuild-eapi-2'>
+ <title>EAPI 2_pre0</title>
+ <sect2 id='package-ebuild-eapi-2-use-deps'>
+ <title>USE Dependencies</title>
+ <sect3 id='package-ebuild-eapi-2-use-deps-conditional'>
+ <title>Conditional USE Dependencies</title>
+ <table><title>Syntax Examples</title>
+ <tgroup cols='2' align='left' >
+ <colspec colname='compact'/>
+ <colspec colname='expanded'/>
+ <thead>
+ <row>
+ <entry>Compact Form</entry>
+ <entry>Equivalent Expanded Form</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>foo[bar?]</entry>
+ <entry>foo bar? ( foo[bar] )</entry>
+ </row>
+ <row>
+ <entry>foo[-bar?]</entry>
+ <entry>foo !bar? ( foo[-bar] )</entry>
+ </row>
+ <row>
+ <entry>foo[bar=]</entry>
+ <entry>foo bar? ( foo[bar] ) !bar? ( foo[-bar] )</entry>
+ </row>
+ <row>
+ <entry>foo[bar!=]</entry>
+ <entry>foo bar? ( foo[-bar] ) !bar? ( foo[bar] )</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect3>
+ </sect2>
+</sect1>
<!ENTITY package_ebuild SYSTEM "package/ebuild.docbook">
<!ENTITY package_ebuild_phases SYSTEM "package/ebuild/phases.docbook">
<!ENTITY package_ebuild_helper_functions SYSTEM "package/ebuild/helper_functions.docbook">
+ <!ENTITY package_ebuild_eapi_2 SYSTEM "package/ebuild/eapi/2.docbook">
<!ENTITY qa SYSTEM "qa.docbook">
<!ENTITY config SYSTEM "config.docbook">
<!ENTITY config_bashrc SYSTEM "config/bashrc.docbook">
__slots__ = ("__weakref__",) + \
tuple(prefix + k for k in allowed_keys)
+ def __init__(self, *args, **kwargs):
+
+ if len(args) > 1:
+ raise TypeError(
+ "expected at most 1 positional argument, got " + \
+ repr(len(args)))
+
+ if args:
+ self.update(args[0])
+
+ if kwargs:
+ self.update(kwargs)
+
def __iter__(self):
for k, v in self.iteritems():
yield k
import portage.exception
from portage.exception import InvalidData, InvalidAtom
from portage.versions import catpkgsplit, catsplit, pkgcmp, pkgsplit, ververify
+import portage.cache.mappings
def cpvequal(cpv1, cpv2):
"""
__slots__ = ("__weakref__", "conditional", "conditional_disabled",
"conditional_enabled", "disabled", "enabled", "tokens", "required")
+ _conditionals_class = portage.cache.mappings.slot_dict_class(
+ ("disabled", "enabled", "equal", "not_equal"), prefix="")
+
def __init__(self, use):
enabled_flags = []
disabled_flags = []
- conditional_enabled = []
- conditional_disabled = []
+ conditional = self._conditionals_class()
+ for k in conditional.allowed_keys:
+ conditional[k] = []
+
for x in use:
- if "-" == x[:1]:
- if "?" == x[-1:]:
- conditional_disabled.append(x[1:-1])
+ last_char = x[-1:]
+ if "?" == last_char:
+ if "-" == x[:1]:
+ conditional.disabled.append(x[1:-1])
else:
- disabled_flags.append(x[1:])
+ conditional.enabled.append(x[:-1])
+ elif "=" == last_char:
+ if "-" == x[:1]:
+ raise InvalidAtom("Invalid use dep: '%s'" % (x,))
+ if "!" == x[-2:-1]:
+ conditional.not_equal.append(x[:-2])
+ else:
+ conditional.equal.append(x[:-1])
else:
- if "?" == x[-1:]:
- conditional_enabled.append(x[:-1])
+ if "-" == x[:1]:
+ disabled_flags.append(x[1:])
else:
enabled_flags.append(x)
+
self.tokens = use
if not isinstance(self.tokens, tuple):
self.tokens = tuple(self.tokens)
+
+ self.required = frozenset(chain(
+ enabled_flags,
+ disabled_flags,
+ *conditional.values()
+ ))
+
self.enabled = frozenset(enabled_flags)
self.disabled = frozenset(disabled_flags)
- self.conditional_enabled = frozenset(conditional_enabled)
- self.conditional_disabled = frozenset(conditional_disabled)
- self.conditional = self.conditional_enabled.union(
- self.conditional_disabled)
- self.required = frozenset(chain(self.enabled, self.disabled,
- self.conditional_enabled, self.conditional_disabled))
+ self.conditional = None
+
+ for v in conditional.itervalues():
+ if v:
+ for k, v in conditional.iteritems():
+ conditional[k] = frozenset(v)
+ self.conditional = conditional
+ break
def __str__(self):
- return "".join("[%s]" % x for x in self.tokens)
+ return "[%s]" % (",".join(self.tokens),)
def evaluate_conditionals(self, use):
"""
- Create a new instance with conditionals evaluated as follows:
+ Create a new instance with conditionals evaluated.
+
+ Conditional evaluation behavior:
+
+ parent state conditional result
+
+ x x? x
+ -x x?
+ x -x?
+ -x -x? -x
+
+ x x= x
+ -x x= -x
+ x x!= -x
+ -x x!= x
+
+ Conditional syntax examples:
+
+ compact form equivalent expanded form
+
+ foo[bar?] foo bar? ( foo[bar] )
+ foo[-bar?] foo !bar? ( foo[-bar] )
+ foo[bar=] foo bar? ( foo[bar] ) !bar? ( foo[-bar] )
+ foo[bar!=] foo bar? ( foo[-bar] ) !bar? ( foo[bar] )
- parent state conditional result
- x x? x
- -x x? -x
- x -x? -x
- -x -x? x
"""
tokens = []
+
+ conditional = self.conditional
tokens.extend(self.enabled)
tokens.extend("-" + x for x in self.disabled)
- tokens.extend(self.conditional_enabled.intersection(use))
- tokens.extend("-" + x for x in self.conditional_enabled.difference(use))
- tokens.extend("-" + x for x in self.conditional_disabled.intersection(use))
- tokens.extend(self.conditional_disabled.difference(use))
+ tokens.extend(x for x in conditional.enabled if x in use)
+ tokens.extend("-" + x for x in conditional.disabled if x not in use)
+
+ tokens.extend(x for x in conditional.equal if x in use)
+ tokens.extend("-" + x for x in conditional.equal if x not in use)
+ tokens.extend("-" + x for x in conditional.not_equal if x in use)
+ tokens.extend(x for x in conditional.not_equal if x not in use)
+
return _use_dep(tokens)
class _AtomCache(type):
_atoms = weakref.WeakValueDictionary()
_str_methods = ("endswith", "find", "index", "lstrip", "replace",
- "startswith", "strip", "rindex", "rfind", "rstrip", "__getitem__",
+ "startswith", "split", "strip",
+ "rindex", "rfind", "rstrip", "__getitem__",
"__eq__", "__hash__", "__len__", "__ne__", "__repr__", "__str__")
__slots__ = ("__weakref__", "blocker", "cp", "cpv", "operator",
use_list = []
open_bracket = depend.find('[')
# -1 = failure (think c++ string::npos)
+ comma_separated = False
+ bracket_count = 0
while( open_bracket != -1 ):
+ bracket_count += 1
+ if bracket_count > 1:
+ raise InvalidAtom("USE Dependency with more " + \
+ "than one set of brackets: %s" % (depend,))
close_bracket = depend.find(']', open_bracket )
if close_bracket == -1:
raise InvalidAtom("USE Dependency with no closing bracket: %s" % depend )
use = depend[open_bracket + 1: close_bracket]
# foo[1:1] may return '' instead of None, we don't want '' in the result
- if len(use):
- use_list.append(use)
+ if not use:
+ raise InvalidAtom("USE Dependency with " + \
+ "no use flag ([]): %s" % depend )
+ if not comma_separated:
+ comma_separated = "," in use
+
+ if comma_separated and bracket_count > 1:
+ raise InvalidAtom("USE Dependency contains a mixture of " + \
+ "comma and bracket separators: %s" % depend )
+
+ if comma_separated:
+ for x in use.split(","):
+ if x:
+ use_list.append(x)
+ else:
+ raise InvalidAtom("USE Dependency with no use " + \
+ "flag next to comma: %s" % depend )
else:
- raise InvalidAtom("USE Dependency with no use flag ([]): %s" % depend )
+ use_list.append(use)
+
# Find next use flag
open_bracket = depend.find( '[', open_bracket+1 )
return tuple(use_list)
return 0
if allow_blockers and atom.startswith("!"):
atom = atom[1:]
+
+ try:
+ use = dep_getusedeps(atom)
+ if use:
+ use = _use_dep(use)
+ except InvalidAtom:
+ return 0
+
cpv = dep_getcpv(atom)
cpv_catsplit = catsplit(cpv)
mycpv_cps = None
if slot:
cpv += ":" + slot
if isinstance(use, tuple):
- for u in use:
- cpv = cpv + "[" + u + "]"
+ cpv += "[%s]" % (",".join(use),)
self.assertEqual( dep_getusedeps(
cpv ), use )
else:
( "sys-apps/portage:foo", True ),
( "sys-apps/portage-2.1:foo", False ),
( "sys-apps/portage-2.1:", False ),
- ( "=sys-apps/portage-2.2*:foo[bar][-baz][doc?][-build?]", True ),
+ ( "=sys-apps/portage-2.2*:foo[bar?,-baz?,doc!=,build=]", True ),
+ ( "=sys-apps/portage-2.2*:foo[build=]", True ),
+ ( "=sys-apps/portage-2.2*:foo[doc!=]", True ),
+ ( "=sys-apps/portage-2.2*:foo[-doc!=]", False ),
+ ( "=sys-apps/portage-2.2*:foo[-doc=]", False ),
+ ( "=sys-apps/portage-2.2*:foo[bar][-baz][doc?][-build?]", False ),
+ ( "=sys-apps/portage-2.2*:foo[bar,-baz,doc?,-build?]", True ),
+ ( "=sys-apps/portage-2.2*:foo[bar,-baz,doc?,-build?,]", False ),
+ ( "=sys-apps/portage-2.2*:foo[,bar,-baz,doc?,-build?]", False ),
+ ( "=sys-apps/portage-2.2*:foo[bar,-baz][doc?,-build?]", False ),
+ ( "=sys-apps/portage-2.2*:foo[bar][doc,build]", False ),
( ">~cate-gory/foo-1.0", False ),
( ">~category/foo-1.0", False ),
( "<~category/foo-1.0", False ),