示例#1
0
    def test_force(self):
        # TODO we could do with both more tests and a more powerful
        # force_* implementation. This just tests if the function
        # takes the right number of arguments.

        # TODO test negate handling
        succeeds = values.GetAttrRestriction('test', values.AlwaysTrue)
        fails = values.GetAttrRestriction('test', values.AlwaysFalse)

        class Dummy:
            test = True

        dummy = Dummy()

        class FakePackage:
            """XXX this is vastly too minimal."""
            value = dummy

        pkg = FakePackage()

        args = [pkg, 'value', dummy]
        self.assertForceTrue(succeeds, args)
        self.assertNotForceFalse(succeeds, args)
        self.assertNotForceTrue(fails, args)
        self.assertForceFalse(fails, args)
示例#2
0
def parse_maintainer_name(value):
    """
    Case insensitive Regex match on the name bit of metadata.xml's
    maintainer data.
    """
    return packages.PackageRestriction(
        'maintainers',
        values.AnyMatch(
            values.GetAttrRestriction(
                'name', values.StrRegex(value.lower(), case_sensitive=False))))
示例#3
0
def parse_ownsre(value):
    """Value is a regexp matched against the string form of an fs object.

    This means the object kind is prepended to the path the regexp has
    to match.
    """
    return packages.PackageRestriction(
        'contents',
        values.AnyMatch(
            values.GetAttrRestriction('location', values.StrRegex(value))))
示例#4
0
class RequiredUseCheck(Check):
    """REQUIRED_USE validity checks."""

    # only run the check for EAPI 4 and above
    _source = (sources.RestrictionRepoSource, (
        packages.PackageRestriction('eapi', values.GetAttrRestriction(
            'options.has_required_use', values.FunctionRestriction(bool))),))
    required_addons = (addons.UseAddon, addons.ProfileAddon)
    known_results = frozenset([InvalidRequiredUse, RequiredUseDefaults, UnstatedIuse])

    def __init__(self, *args, use_addon, profile_addon):
        super().__init__(*args)
        self.iuse_filter = use_addon.get_filter('required_use')
        self.profiles = profile_addon

    def feed(self, pkg):
        # check REQUIRED_USE for invalid nodes
        _nodes, unstated = self.iuse_filter((str,), pkg, pkg.required_use)
        yield from unstated

        # check both stable/unstable profiles for stable KEYWORDS and only
        # unstable profiles for unstable KEYWORDS
        keywords = []
        for keyword in pkg.sorted_keywords:
            if keyword[0] != '~':
                keywords.append(keyword)
            keywords.append('~' + keyword.lstrip('~'))

        # check USE defaults (pkg IUSE defaults + profile USE) against
        # REQUIRED_USE for all profiles matching a pkg's KEYWORDS
        failures = defaultdict(list)
        for keyword in keywords:
            for profile in sorted(self.profiles.get(keyword, ()), key=attrgetter('name')):
                # skip packages masked by the profile
                if profile.visible(pkg):
                    src = FakeConfigurable(pkg, profile)
                    for node in pkg.required_use.evaluate_depset(src.use):
                        if not node.match(src.use):
                            failures[node].append((src.use, profile.key, profile.name))

        if self.options.verbosity > 0:
            # report all failures with profile info in verbose mode
            for node, profile_info in failures.items():
                for use, keyword, profile in profile_info:
                    yield RequiredUseDefaults(
                        str(node), sorted(use), keyword, profile, pkg=pkg)
        else:
            # only report one failure per REQUIRED_USE node in regular mode
            for node, profile_info in failures.items():
                num_profiles = len(profile_info)
                _use, _keyword, profile = profile_info[0]
                yield RequiredUseDefaults(
                    str(node), profile=profile, num_profiles=num_profiles, pkg=pkg)
示例#5
0
class MissingSlotDepCheck(Check):
    """Check for missing slot dependencies."""

    # only run the check for EAPI 5 and above
    _source = (sources.RestrictionRepoSource, (
        packages.PackageRestriction('eapi', values.GetAttrRestriction(
            'options.sub_slotting', values.FunctionRestriction(bool))),))
    required_addons = (addons.UseAddon,)
    known_results = frozenset([MissingSlotDep])

    def __init__(self, *args, use_addon):
        super().__init__(*args)
        self.iuse_filter = use_addon.get_filter()

    def feed(self, pkg):
        rdepend, _ = self.iuse_filter((atom_cls,), pkg, pkg.rdepend)
        depend, _ = self.iuse_filter((atom_cls,), pkg, pkg.depend)

        # skip deps that are blockers or have explicit slots/slot operators
        for dep in (x for x in set(rdepend).intersection(depend) if not
                    (x.blocks or x.slot is not None or x.slot_operator is not None)):
            dep_slots = {x.slot for x in pkg.repo.itermatch(dep.no_usedeps)}
            if len(dep_slots) > 1:
                yield MissingSlotDep(str(dep), sorted(dep_slots), pkg=pkg)
示例#6
0
def parse_owns(value):
    return packages.PackageRestriction(
        'contents',
        values.AnyMatch(
            values.GetAttrRestriction('location',
                                      values.StrExactMatch(value))))