예제 #1
0
    def test_pkg_use(self):
        path = pjoin(self.dir, self.profile)
        self.assertEqualChunks(self.klass(path).pkg_use, {})
        self.parsing_checks("package.use", "pkg_use")
        self.write_file("package.use", "dev-util/bar X")
        self.assertEqualChunks(
            self.klass(path).pkg_use, {"dev-util/bar": (chunked_data(atom("dev-util/bar"), (), ("X",)),)}
        )
        self.write_file("package.use", "-dev-util/bar X")
        self.assertRaises(profiles.ProfileError, getattr, self.klass(path), "pkg_use")

        self._check_package_use_files(path, "package.use", "pkg_use")

        self.write_file("package.use", "dev-util/bar -X\ndev-util/foo X")
        self.assertEqualChunks(
            self.klass(path).pkg_use,
            {
                "dev-util/bar": (chunked_data(atom("dev-util/bar"), ("X",), ()),),
                "dev-util/foo": (chunked_data(atom("dev-util/foo"), (), ("X",)),),
            },
        )
        self.simple_eapi_awareness_check(
            "package.use", "pkg_use", bad_data="=de/bs-1:1 x\nda/bs y", good_data="=de/bs-1 x\nda/bs y"
        )

        self.write_file("package.use", "dev-util/diffball")
        self.assertRaises(profiles.ProfileError, getattr, self.klass(path), "pkg_use")
예제 #2
0
    def __init__(self, masked_use={}, stable_masked_use={}, forced_use={},
                 stable_forced_use={}, provides={}, iuse_effective=[],
                 masks=[], unmasks=[], arch='x86', name='none'):
        self.provides_repo = SimpleTree(provides)

        self.masked_use = ChunkedDataDict()
        self.masked_use.update_from_stream(
            chunked_data(atom(k), *split_negations(v))
            for k, v in masked_use.iteritems())
        self.masked_use.freeze()

        self.stable_masked_use = ChunkedDataDict()
        self.stable_masked_use.update_from_stream(
            chunked_data(atom(k), *split_negations(v))
            for k, v in stable_masked_use.iteritems())
        self.stable_masked_use.freeze()

        self.forced_use = ChunkedDataDict()
        self.forced_use.update_from_stream(
            chunked_data(atom(k), *split_negations(v))
            for k, v in forced_use.iteritems())
        self.forced_use.freeze()

        self.stable_forced_use = ChunkedDataDict()
        self.stable_forced_use.update_from_stream(
            chunked_data(atom(k), *split_negations(v))
            for k, v in stable_forced_use.iteritems())
        self.stable_forced_use.freeze()

        self.masks = tuple(map(atom, masks))
        self.unmasks = tuple(map(atom, unmasks))
        self.iuse_effective = tuple(iuse_effective)
        self.arch = arch
        self.name = name
예제 #3
0
    def __init__(self,
                 masked_use={},
                 stable_masked_use={},
                 forced_use={},
                 stable_forced_use={},
                 pkg_use={},
                 provides={},
                 iuse_effective=[],
                 use=[],
                 masks=[],
                 unmasks=[],
                 arch='x86',
                 name='none'):
        self.provides_repo = SimpleTree(provides)

        self.masked_use = ChunkedDataDict()
        self.masked_use.update_from_stream(
            chunked_data(atom(k), *split_negations(v))
            for k, v in masked_use.items())
        self.masked_use.freeze()

        self.stable_masked_use = ChunkedDataDict()
        self.stable_masked_use.update_from_stream(
            chunked_data(atom(k), *split_negations(v))
            for k, v in stable_masked_use.items())
        self.stable_masked_use.freeze()

        self.forced_use = ChunkedDataDict()
        self.forced_use.update_from_stream(
            chunked_data(atom(k), *split_negations(v))
            for k, v in forced_use.items())
        self.forced_use.freeze()

        self.stable_forced_use = ChunkedDataDict()
        self.stable_forced_use.update_from_stream(
            chunked_data(atom(k), *split_negations(v))
            for k, v in stable_forced_use.items())
        self.stable_forced_use.freeze()

        self.pkg_use = ChunkedDataDict()
        self.pkg_use.update_from_stream(
            chunked_data(atom(k), *split_negations(v))
            for k, v in pkg_use.items())
        self.pkg_use.freeze()

        self.masks = tuple(map(atom, masks))
        self.unmasks = tuple(map(atom, unmasks))
        self.iuse_effective = set(iuse_effective)
        self.use = set(use)
        self.key = arch
        self.name = name

        vfilter = domain.generate_filter(self.masks, self.unmasks)
        self.visible = vfilter.match
예제 #4
0
    def _check_package_use_files(self, path, filename, attr):
        self.write_file(filename, "dev-util/bar X")
        self.assertEqualChunks(
            getattr(self.klass(path), attr), {"dev-util/bar": (chunked_data(atom("dev-util/bar"), (), ("X",)),)}
        )
        self.write_file(filename, "-dev-util/bar X")
        self.assertRaises(profiles.ProfileError, getattr, self.klass(path), attr)

        # verify collapsing optimizations
        self.write_file(filename, "dev-util/foo X\ndev-util/foo X")
        self.assertEqualChunks(
            getattr(self.klass(path), attr), {"dev-util/foo": (chunked_data(atom("dev-util/foo"), (), ("X",)),)}
        )

        self.write_file(filename, "d-u/a X\n=d-u/a-1 X")
        self.assertEqualChunks(getattr(self.klass(path), attr), {"d-u/a": (chunked_data(atom("d-u/a"), (), ("X",)),)})

        self.write_file(filename, "d-u/a X\n=d-u/a-1 -X")
        self.assertEqualChunks(
            getattr(self.klass(path), attr),
            {"d-u/a": (chunked_data(atom("d-u/a"), (), ("X",)), chunked_data(atom("=d-u/a-1"), ("X",), ()))},
        )

        self.write_file(filename, "=d-u/a-1 X\nd-u/a X")
        self.assertEqualChunks(getattr(self.klass(path), attr), {"d-u/a": (chunked_data(atom("d-u/a"), (), ("X",)),)})

        self.write_file(filename, "dev-util/bar -X\ndev-util/foo X")
        self.assertEqualChunks(
            getattr(self.klass(path), attr),
            {
                "dev-util/bar": (chunked_data(atom("dev-util/bar"), ("X",), ()),),
                "dev-util/foo": (chunked_data(atom("dev-util/foo"), (), ("X",)),),
            },
        )
예제 #5
0
파일: domain.py 프로젝트: ulm/pkgcore
 def enabled_use(self):
     use = ChunkedDataDict()
     use.add_bare_global(*split_negations(self.use))
     use.merge(self.profile.pkg_use)
     use.update_from_stream(chunked_data(k, *v) for k, v in self.pkg_use)
     use.freeze()
     return use
예제 #6
0
    def test_forced_use(self):
        path = pjoin(self.dir, self.profile)
        self.assertEqualChunks(self.klass(path).forced_use, {})
        self.parsing_checks("package.use.force", "forced_use")
        self.wipe_path(pjoin(path, "package.use.force"))
        self.parsing_checks("use.force", "forced_use")
        self.write_file("use.force", "")

        self._check_package_use_files(path, "package.use.force", "forced_use")

        self.write_file("use.force", "mmx")

        self.assertEqualChunks(
            self.klass(path).forced_use,
            {
                "dev-util/bar": (chunked_data(atom("dev-util/bar"), ("X",), ("mmx",)),),
                "dev-util/foo": (chunked_data(atom("dev-util/foo"), (), ("X", "mmx")),),
                atrue: (chunked_data(atrue, (), ("mmx",)),),
            },
        )

        self.write_file("use.force", "mmx\n-foon")
        self.assertEqualChunks(
            self.klass(path).forced_use,
            {
                "dev-util/bar": (chunked_data(atom("dev-util/bar"), ("X", "foon"), ("mmx",)),),
                "dev-util/foo": (chunked_data(atom("dev-util/foo"), ("foon",), ("X", "mmx")),),
                atrue: (chunked_data(atrue, ("foon",), ("mmx",)),),
            },
        )

        # verify that use.force is layered first, then package.use.force
        self.write_file("package.use.force", "dev-util/bar -mmx foon")
        p = self.klass(path)
        self.assertEqualChunks(
            self.klass(path).forced_use,
            {
                atrue: (chunked_data(atrue, ("foon",), ("mmx",)),),
                "dev-util/bar": (chunked_data(atom("dev-util/bar"), ("mmx",), ("foon",)),),
            },
        )

        self.write_file("package.use.force", "")
        self.assertEqualChunks(self.klass(path).forced_use, {atrue: (chunked_data(atrue, ("foon",), ("mmx",)),)})
        self.simple_eapi_awareness_check(
            "package.use.force", "forced_use", bad_data="=de/bs-1:1 x\nda/bs y", good_data="=de/bs-1 x\nda/bs y"
        )

        self.write_file("package.use.force", "dev-util/diffball")
        self.assertRaises(profiles.ProfileError, getattr, self.klass(path), "forced_use")
예제 #7
0
    def __init__(self, masked_use={}, forced_use={},
        provides={}, masks=[], virtuals={}, arch='x86', name='none'):
        self.provides_repo = SimpleTree(provides)
        self.masked_use = ChunkedDataDict()
        self.masked_use.update_from_stream(
            chunked_data(atom(k), *split_negations(v))
            for k,v in masked_use.iteritems())
        self.masked_use.freeze()

        self.forced_use = ChunkedDataDict()
        self.forced_use.update_from_stream(
            chunked_data(atom(k), *split_negations(v))
            for k,v in forced_use.iteritems())
        self.forced_use.freeze()

        self.masks = tuple(map(atom, masks))
        self.virtuals = SimpleTree(virtuals)
        self.arch = arch
        self.name = name
예제 #8
0
    def __init__(self,
                 masked_use={},
                 stable_masked_use={},
                 forced_use={},
                 stable_forced_use={},
                 provides={},
                 iuse_effective=[],
                 masks=[],
                 unmasks=[],
                 arch='x86',
                 name='none'):
        self.provides_repo = SimpleTree(provides)

        self.masked_use = ChunkedDataDict()
        self.masked_use.update_from_stream(
            chunked_data(atom(k), *split_negations(v))
            for k, v in masked_use.iteritems())
        self.masked_use.freeze()

        self.stable_masked_use = ChunkedDataDict()
        self.stable_masked_use.update_from_stream(
            chunked_data(atom(k), *split_negations(v))
            for k, v in stable_masked_use.iteritems())
        self.stable_masked_use.freeze()

        self.forced_use = ChunkedDataDict()
        self.forced_use.update_from_stream(
            chunked_data(atom(k), *split_negations(v))
            for k, v in forced_use.iteritems())
        self.forced_use.freeze()

        self.stable_forced_use = ChunkedDataDict()
        self.stable_forced_use.update_from_stream(
            chunked_data(atom(k), *split_negations(v))
            for k, v in stable_forced_use.iteritems())
        self.stable_forced_use.freeze()

        self.masks = tuple(map(atom, masks))
        self.unmasks = tuple(map(atom, unmasks))
        self.iuse_effective = tuple(iuse_effective)
        self.arch = arch
        self.name = name
예제 #9
0
    def _parse_package_use(self, data):
        d = defaultdict(list)
        # split the data down ordered cat/pkg lines
        for line in data:
            l = line.split()
            a = self.eapi_atom(l[0])
            if len(l) == 1:
                raise Exception("malformed line- %r" % (line, ))
            d[a.key].append(chunked_data(a, *split_negations(l[1:])))

        return ImmutableDict(
            (k, _build_cp_atom_payload(v, atom(k))) for k, v in d.iteritems())
예제 #10
0
파일: profiles.py 프로젝트: den4ix/pkgcore
    def _parse_package_use(self, data):
        d = defaultdict(list)
        # split the data down ordered cat/pkg lines
        for line in data:
            l = line.split()
            a = self.eapi_atom(l[0])
            if len(l) == 1:
                raise Exception("malformed line, missing USE flag(s): %r" % (line,))
            d[a.key].append(chunked_data(a, *split_negations(l[1:])))

        return ImmutableDict((k, _build_cp_atom_payload(v, atom(k)))
                             for k, v in d.iteritems())
예제 #11
0
    def _parse_package_use(self, data):
        d = defaultdict(list)
        # split the data down ordered cat/pkg lines
        for line, lineno, path in data:
            l = line.split()
            try:
                a = self.eapi_atom(l[0])
            except ebuild_errors.MalformedAtom as e:
                logger.error(e)
                continue
            if len(l) == 1:
                logger.error(f'{path!r}, line {lineno}: missing USE flag(s): {line!r}')
                continue
            d[a.key].append(misc.chunked_data(a, *split_negations(l[1:])))

        return ImmutableDict((k, misc._build_cp_atom_payload(v, atom(k)))
                             for k, v in d.items())
예제 #12
0
    def _parse_package_use(self, data):
        d = defaultdict(list)
        # split the data down ordered cat/pkg lines
        for line in data:
            l = line.split()
            try:
                a = self.eapi_atom(l[0])
            except ebuild_errors.MalformedAtom as e:
                logger.warning(e)
                continue
            if len(l) == 1:
                logger.warning(f"malformed line, missing USE flag(s): {line!r}")
                continue
            d[a.key].append(misc.chunked_data(a, *split_negations(l[1:])))

        return ImmutableDict((k, misc._build_cp_atom_payload(v, atom(k)))
                             for k, v in d.items())
예제 #13
0
    def test_pkg_use(self):
        self.mk_profiles({})
        self.assertEqualPayload(self.get_profile("0").pkg_use, {})
        self.mk_profiles(
            {"package.use": "dev-util/bsdiff X mmx\n"},
            {},
            {"package.use": "dev-util/bsdiff -X\n"},
            {"package.use": "dev-util/bsdiff -mmx\ndev-util/diffball X"},
            {"package.use": "dev-util/bsdiff X\ndev-util/diffball -X\n"},
        )

        self.assertEqualPayload(
            self.get_profile("0").pkg_use,
            {"dev-util/bsdiff": (chunked_data(atom("dev-util/bsdiff"), (), ("X", "mmx")),)},
        )
        self.assertEqualPayload(
            self.get_profile("1").pkg_use,
            {"dev-util/bsdiff": (chunked_data(atom("dev-util/bsdiff"), (), ("X", "mmx")),)},
        )
        self.assertEqualPayload(
            self.get_profile("2").pkg_use,
            {"dev-util/bsdiff": (chunked_data(atom("dev-util/bsdiff"), ("X",), ("mmx",)),)},
        )
        self.assertEqualPayload(
            self.get_profile("3").pkg_use,
            {
                "dev-util/diffball": (chunked_data(atom("dev-util/diffball"), (), ("X",)),),
                "dev-util/bsdiff": (chunked_data(atom("dev-util/bsdiff"), ("X", "mmx"), ()),),
            },
        )
        self.assertEqualPayload(
            self.get_profile("4").pkg_use,
            {
                "dev-util/diffball": (chunked_data(atom("dev-util/diffball"), ("X",), ()),),
                "dev-util/bsdiff": (chunked_data(atom("dev-util/bsdiff"), ("mmx",), ("X",)),),
            },
        )
예제 #14
0
파일: domain.py 프로젝트: den4ix/pkgcore
    def __init__(self, profile, repositories, vdb, name=None,
                 root='/', prefix='/', incrementals=const.incrementals,
                 triggers=(), **settings):
        # voodoo, unfortunately (so it goes)
        # break this up into chunks once it's stabilized (most of code
        # here has already, but still more to add)
        self._triggers = triggers
        self.name = name

        # prevent critical variables from being changed in make.conf
        for k in profile.profile_only_variables.intersection(settings.keys()):
            del settings[k]

        if 'CHOST' in settings and 'CBUILD' not in settings:
            settings['CBUILD'] = settings['CHOST']

        # if unset, MAKEOPTS defaults to CPU thread count
        if 'MAKEOPTS' not in settings:
            settings['MAKEOPTS'] = '-j%i' % cpu_count()

        # map out sectionname -> config manager immediately.
        repositories_collapsed = [r.collapse() for r in repositories]
        repositories = [r.instantiate() for r in repositories_collapsed]

        self.fetcher = settings.pop("fetcher")

        self.default_licenses_manager = OverlayedLicenses(*repositories)
        vdb_collapsed = [r.collapse() for r in vdb]
        vdb = [r.instantiate() for r in vdb_collapsed]
        self.repos_raw = {
            collapsed.name: repo for (collapsed, repo) in izip(
                repositories_collapsed, repositories)}
        self.repos_raw.update(
            (collapsed.name, repo) for (collapsed, repo) in izip(
                vdb_collapsed, vdb))
        self.repos_raw.pop(None, None)
        if profile.provides_repo is not None:
            self.repos_raw['package.provided'] = profile.provides_repo
            vdb.append(profile.provides_repo)

        self.profile = profile
        pkg_masks, pkg_unmasks, pkg_keywords, pkg_licenses = [], [], [], []
        pkg_use, self.bashrcs = [], []

        self.ebuild_hook_dir = settings.pop("ebuild_hook_dir", None)

        for key, val, action in (
            ("package.mask", pkg_masks, parse_match),
            ("package.unmask", pkg_unmasks, parse_match),
            ("package.keywords", pkg_keywords, package_keywords_splitter),
            ("package.accept_keywords", pkg_keywords, package_keywords_splitter),
            ("package.license", pkg_licenses, package_keywords_splitter),
            ("package.use", pkg_use, package_keywords_splitter),
            ("package.env", self.bashrcs, package_env_splitter),
            ):

            for fp in settings.pop(key, ()):
                try:
                    if key == "package.env":
                        base = self.ebuild_hook_dir
                        if base is None:
                            base = os.path.dirname(fp)
                        action = partial(action, base)
                    for fs_obj in iter_scan(fp, follow_symlinks=True):
                        if not fs_obj.is_reg or '/.' in fs_obj.location:
                            continue
                        val.extend(
                            action(x) for x in
                            iter_read_bash(fs_obj.location, allow_line_cont=True))
                except EnvironmentError as e:
                    if e.errno == errno.ENOENT:
                        raise MissingFile(fp, key)
                    raise_from(Failure("failed reading '%s': %s" % (fp, e)))
                except ValueError as e:
                    raise_from(Failure("failed reading '%s': %s" % (fp, e)))

        for x in incrementals:
            if isinstance(settings.get(x), basestring):
                settings[x] = tuple(settings[x].split())

        # roughly... all incremental stacks should be interpreted left -> right
        # as such we start with the profile settings, and append ours onto it.
        for k, v in profile.default_env.iteritems():
            if k not in settings:
                settings[k] = v
                continue
            if k in incrementals:
                settings[k] = v + tuple(settings[k])

        # next we finalize incrementals.
        for incremental in incrementals:
            # Skip USE/ACCEPT_LICENSE for the time being; hack; we need the
            # negations currently so that pkg iuse induced enablings can be
            # disabled by negations. For example, think of the profile doing
            # USE=-cdr for brasero w/ IUSE=+cdr. Similarly, ACCEPT_LICENSE is
            # skipped because negations are required for license filtering.
            if incremental not in settings or incremental in ("USE", "ACCEPT_LICENSE"):
                continue
            s = set()
            incremental_expansion(
                s, settings[incremental],
                'While expanding %s ' % (incremental,))
            settings[incremental] = tuple(s)

        # use is collapsed; now stack use_expand.
        use = settings['USE'] = set(optimize_incrementals(
            list(settings.get('USE', ())) + os.environ.get('USE', '').split()))

        self._extend_use_for_features(use, settings.get("FEATURES", ()))

        for u in profile.use_expand:
            v = settings.get(u)
            if v is None:
                continue
            u2 = u.lower()+"_"
            use.update(u2 + x for x in v.split())

        if 'ACCEPT_KEYWORDS' not in settings:
            raise Failure("No ACCEPT_KEYWORDS setting detected from profile, "
                          "or user config")
        s = set()
        default_keywords = []
        incremental_expansion(
            s, settings['ACCEPT_KEYWORDS'],
            'while expanding ACCEPT_KEYWORDS')
        default_keywords.extend(s)
        settings['ACCEPT_KEYWORDS'] = set(default_keywords)

        self.use = use

        if "ARCH" not in settings:
            raise Failure(
                "No ARCH setting detected from profile, or user config")

        self.arch = self.stable_arch = settings["ARCH"]
        self.unstable_arch = "~%s" % self.arch

        # ~amd64 -> [amd64, ~amd64]
        for x in default_keywords[:]:
            if x.startswith("~"):
                default_keywords.append(x.lstrip("~"))
        default_keywords = unstable_unique(default_keywords + [self.arch])

        accept_keywords = pkg_keywords + list(profile.accept_keywords)
        vfilters = [self.make_keywords_filter(
            self.arch, default_keywords, accept_keywords, profile.keywords,
            incremental="package.keywords" in incrementals)]

        del default_keywords, accept_keywords

        # we can finally close that fricking
        # "DISALLOW NON FOSS LICENSES" bug via this >:)
        master_license = []
        master_license.extend(settings.get('ACCEPT_LICENSE', ()))
        if master_license or pkg_licenses:
            vfilters.append(self.make_license_filter(master_license, pkg_licenses))

        del master_license

        # if it's made it this far...

        self.root = settings["ROOT"] = root
        self.prefix = prefix
        self.settings = ProtectedDict(settings)

        for data in self.settings.get('bashrc', ()):
            source = local_source(data)
            # this is currently local-only so a path check is ok
            # TODO make this more general
            if not os.path.exists(source.path):
                raise Failure(
                    'user-specified bashrc %r does not exist' % (data,))
            self.bashrcs.append((packages.AlwaysTrue, source))

        # stack use stuff first, then profile.
        self.enabled_use = ChunkedDataDict()
        self.enabled_use.add_bare_global(*split_negations(self.use))
        self.enabled_use.merge(profile.pkg_use)
        self.enabled_use.update_from_stream(
            chunked_data(k, *split_negations(v)) for k, v in pkg_use)

        for attr in ('', 'stable_'):
             c = ChunkedDataDict()
             c.merge(getattr(profile, attr + 'forced_use'))
             c.add_bare_global((), (self.arch,))
             setattr(self, attr + 'forced_use', c)

             c = ChunkedDataDict()
             c.merge(getattr(profile, attr + 'masked_use'))
             setattr(self, attr + 'disabled_use', c)

        self.repos = []
        self.vdb = []
        self.repos_configured = {}
        self.repos_configured_filtered = {}

        rev_names = {repo: name for name, repo in self.repos_raw.iteritems()}

        profile_masks = profile._incremental_masks()
        profile_unmasks = profile._incremental_unmasks()
        repo_masks = {r.repo_id: r._visibility_limiters() for r in repositories}

        for l, repos, filtered in ((self.repos, repositories, True),
                                   (self.vdb, vdb, False)):
            for repo in repos:
                if not repo.configured:
                    pargs = [repo]
                    try:
                        for x in repo.configurables:
                            if x == "domain":
                                pargs.append(self)
                            elif x == "settings":
                                pargs.append(settings)
                            elif x == "profile":
                                pargs.append(profile)
                            else:
                                pargs.append(getattr(self, x))
                    except AttributeError as ae:
                        raise_from(Failure("failed configuring repo '%s': "
                                           "configurable missing: %s" % (repo, ae)))
                    wrapped_repo = repo.configure(*pargs)
                else:
                    wrapped_repo = repo
                key = rev_names.get(repo)
                self.repos_configured[key] = wrapped_repo
                if filtered:
                    config = getattr(repo, 'config', None)
                    masters = getattr(config, 'masters', ())
                    if masters is None:
                        # tough cookies.  If a user has an overlay, no masters
                        # defined, we're not applying the portdir masks.
                        # we do this both since that's annoying, and since
                        # frankly there isn't any good course of action.
                        masters = ()
                    global_masks = [repo_masks.get(master, [(), ()]) for master in masters]
                    global_masks.append(repo_masks[repo.repo_id])
                    global_masks.extend(profile_masks)
                    masks = set()
                    for neg, pos in global_masks:
                        masks.difference_update(neg)
                        masks.update(pos)
                    masks.update(pkg_masks)
                    unmasks = set(chain(pkg_unmasks, *profile_unmasks))
                    filtered = generate_filter(masks, unmasks, *vfilters)
                if filtered:
                    wrapped_repo = visibility.filterTree(wrapped_repo, filtered, True)
                self.repos_configured_filtered[key] = wrapped_repo
                l.append(wrapped_repo)

        self.use_expand_re = re.compile(
            "^(?:[+-])?(%s)_(.*)$" %
            "|".join(x.lower() for x in sorted(profile.use_expand, reverse=True)))
예제 #15
0
파일: domain.py 프로젝트: chutz/pkgcore
    def __init__(self,
                 profile,
                 repositories,
                 vdb,
                 name=None,
                 root='/',
                 prefix='/',
                 incrementals=const.incrementals,
                 triggers=(),
                 **settings):
        # voodoo, unfortunately (so it goes)
        # break this up into chunks once it's stabilized (most of code
        # here has already, but still more to add)
        self._triggers = triggers

        # prevent critical variables from being changed by the user in make.conf
        for k in set(profile.profile_only_variables).intersection(
                settings.keys()):
            del settings[k]

        if 'CHOST' in settings and 'CBUILD' not in settings:
            settings['CBUILD'] = settings['CHOST']

        # map out sectionname -> config manager immediately.
        repositories_collapsed = [r.collapse() for r in repositories]
        repositories = [r.instantiate() for r in repositories_collapsed]

        self.fetcher = settings.pop("fetcher")

        self.default_licenses_manager = OverlayedLicenses(*repositories)
        vdb_collapsed = [r.collapse() for r in vdb]
        vdb = [r.instantiate() for r in vdb_collapsed]
        self.repos_raw = {
            collapsed.name: repo
            for (collapsed, repo) in izip(repositories_collapsed, repositories)
        }
        self.repos_raw.update(
            (collapsed.name, repo)
            for (collapsed, repo) in izip(vdb_collapsed, vdb))
        self.repos_raw.pop(None, None)
        if profile.provides_repo is not None:
            self.repos_raw['package.provided'] = profile.provides_repo
            vdb.append(profile.provides_repo)

        self.profile = profile
        pkg_maskers, pkg_unmaskers, pkg_keywords, pkg_licenses = [], [], [], []
        pkg_use, self.bashrcs = [], []

        self.ebuild_hook_dir = settings.pop("ebuild_hook_dir", None)

        for key, val, action in (
            ("package.mask", pkg_maskers, parse_match),
            ("package.unmask", pkg_unmaskers, parse_match),
            ("package.keywords", pkg_keywords, package_keywords_splitter),
            ("package.accept_keywords", pkg_keywords,
             package_keywords_splitter),
            ("package.license", pkg_licenses, package_keywords_splitter),
            ("package.use", pkg_use, package_keywords_splitter),
            ("package.env", self.bashrcs, package_env_splitter),
        ):

            for fp in settings.pop(key, ()):
                try:
                    if key == "package.env":
                        base = self.ebuild_hook_dir
                        if base is None:
                            base = os.path.dirname(fp)
                        action = partial(action, base)
                    for fs_obj in iter_scan(fp, follow_symlinks=True):
                        if not fs_obj.is_reg or '/.' in fs_obj.location:
                            continue
                        val.extend(
                            action(x) for x in iter_read_bash(fs_obj.location))
                except EnvironmentError as e:
                    if e.errno == errno.ENOENT:
                        raise MissingFile(fp, key)
                    raise_from(Failure("failed reading '%s': %s" % (fp, e)))
                except ValueError as e:
                    raise_from(Failure("failed reading '%s': %s" % (fp, e)))

        self.name = name
        settings.setdefault("PKGCORE_DOMAIN", name)
        for x in incrementals:
            if isinstance(settings.get(x), basestring):
                settings[x] = tuple(settings[x].split())

        # roughly... all incremental stacks should be interpreted left -> right
        # as such we start with the profile settings, and append ours onto it.
        for k, v in profile.default_env.iteritems():
            if k not in settings:
                settings[k] = v
                continue
            if k in incrementals:
                settings[k] = v + tuple(settings[k])

        # next we finalize incrementals.
        for incremental in incrementals:
            # Skip USE/ACCEPT_LICENSE for the time being; hack; we need the
            # negations currently so that pkg iuse induced enablings can be
            # disabled by negations. For example, think of the profile doing
            # USE=-cdr for brasero w/ IUSE=+cdr. Similarly, ACCEPT_LICENSE is
            # skipped because negations are required for license filtering.
            if incremental not in settings or incremental in (
                    "USE", "ACCEPT_LICENSE"):
                continue
            s = set()
            incremental_expansion(s, settings[incremental],
                                  'While expanding %s ' % (incremental, ))
            settings[incremental] = tuple(s)

        # use is collapsed; now stack use_expand.
        use = settings['USE'] = set(
            optimize_incrementals(settings.get("USE", ())))

        self._extend_use_for_features(use, settings.get("FEATURES", ()))

        self.use_expand = frozenset(profile.use_expand)
        self.use_expand_hidden = frozenset(profile.use_expand_hidden)
        for u in profile.use_expand:
            v = settings.get(u)
            if v is None:
                continue
            u2 = u.lower() + "_"
            use.update(u2 + x for x in v.split())

        if not 'ACCEPT_KEYWORDS' in settings:
            raise Failure("No ACCEPT_KEYWORDS setting detected from profile, "
                          "or user config")
        s = set()
        default_keywords = []
        incremental_expansion(s, settings['ACCEPT_KEYWORDS'],
                              'while expanding ACCEPT_KEYWORDS')
        default_keywords.extend(s)
        settings['ACCEPT_KEYWORDS'] = set(default_keywords)

        self.use = use

        if "ARCH" not in settings:
            raise Failure(
                "No ARCH setting detected from profile, or user config")

        self.arch = self.stable_arch = settings["ARCH"]
        self.unstable_arch = "~%s" % self.arch

        # ~amd64 -> [amd64, ~amd64]
        for x in default_keywords[:]:
            if x.startswith("~"):
                default_keywords.append(x.lstrip("~"))
        default_keywords = unstable_unique(default_keywords + [self.arch])

        accept_keywords = pkg_keywords + list(profile.accept_keywords)
        vfilters = [
            self.make_keywords_filter(self.arch,
                                      default_keywords,
                                      accept_keywords,
                                      profile.keywords,
                                      incremental="package.keywords"
                                      in incrementals)
        ]

        del default_keywords, accept_keywords

        # we can finally close that fricking
        # "DISALLOW NON FOSS LICENSES" bug via this >:)
        master_license = []
        master_license.extend(settings.get('ACCEPT_LICENSE', ()))
        if master_license or pkg_licenses:
            vfilters.append(
                self.make_license_filter(master_license, pkg_licenses))

        del master_license

        # if it's made it this far...

        self.root = settings["ROOT"] = root
        self.prefix = prefix
        self.settings = ProtectedDict(settings)

        for data in self.settings.get('bashrc', ()):
            source = local_source(data)
            # this is currently local-only so a path check is ok
            # TODO make this more general
            if not os.path.exists(source.path):
                raise Failure('user-specified bashrc %r does not exist' %
                              (data, ))
            self.bashrcs.append((packages.AlwaysTrue, source))

        # stack use stuff first, then profile.
        self.enabled_use = ChunkedDataDict()
        self.enabled_use.add_bare_global(*split_negations(self.use))
        self.enabled_use.merge(profile.pkg_use)
        self.enabled_use.update_from_stream(
            chunked_data(k, *split_negations(v)) for k, v in pkg_use)

        for attr in ('', 'stable_'):
            c = ChunkedDataDict()
            c.merge(getattr(profile, attr + 'forced_use'))
            c.add_bare_global((), (self.arch, ))
            setattr(self, attr + 'forced_use', c)

            c = ChunkedDataDict()
            c.merge(getattr(profile, attr + 'masked_use'))
            setattr(self, attr + 'disabled_use', c)

        self.repos = []
        self.vdb = []
        self.repos_configured = {}
        self.repos_configured_filtered = {}

        rev_names = {repo: name for name, repo in self.repos_raw.iteritems()}

        profile_masks = profile._incremental_masks()
        profile_unmasks = profile._incremental_unmasks()
        repo_masks = {
            r.repo_id: r._visibility_limiters()
            for r in repositories
        }

        for l, repos, filtered in ((self.repos, repositories, True),
                                   (self.vdb, vdb, False)):
            for repo in repos:
                if not repo.configured:
                    pargs = [repo]
                    try:
                        for x in repo.configurables:
                            if x == "domain":
                                pargs.append(self)
                            elif x == "settings":
                                pargs.append(settings)
                            elif x == "profile":
                                pargs.append(profile)
                            else:
                                pargs.append(getattr(self, x))
                    except AttributeError as ae:
                        raise_from(
                            Failure("failed configuring repo '%s': "
                                    "configurable missing: %s" % (repo, ae)))
                    wrapped_repo = repo.configure(*pargs)
                else:
                    wrapped_repo = repo
                key = rev_names.get(repo)
                self.repos_configured[key] = wrapped_repo
                if filtered:
                    config = getattr(repo, 'config', None)
                    masters = getattr(config, 'masters', ())
                    if masters is None:
                        # tough cookies.  If a user has an overlay, no masters
                        # defined, we're not applying the portdir masks.
                        # we do this both since that's annoying, and since
                        # frankly there isn't any good course of action.
                        masters = ()
                    masks = [
                        repo_masks.get(master, [(), ()]) for master in masters
                    ]
                    masks.append(repo_masks[repo.repo_id])
                    masks.extend(profile_masks)
                    mask_atoms = set()
                    for neg, pos in masks:
                        mask_atoms.difference_update(neg)
                        mask_atoms.update(pos)
                    mask_atoms.update(pkg_maskers)
                    unmask_atoms = set(chain(pkg_unmaskers, *profile_unmasks))
                    filtered = self.generate_filter(
                        generate_masking_restrict(mask_atoms),
                        generate_unmasking_restrict(unmask_atoms), *vfilters)
                if filtered:
                    wrapped_repo = visibility.filterTree(
                        wrapped_repo, filtered, True)
                self.repos_configured_filtered[key] = wrapped_repo
                l.append(wrapped_repo)

        if profile.virtuals:
            l = [
                x for x in (getattr(v, 'old_style_virtuals', None)
                            for v in self.vdb) if x is not None
            ]
            profile_repo = profile.make_virtuals_repo(
                multiplex.tree(*repositories), *l)
            self.repos_raw["profile virtuals"] = profile_repo
            self.repos_configured_filtered["profile virtuals"] = profile_repo
            self.repos_configured["profile virtuals"] = profile_repo
            self.repos = [profile_repo] + self.repos

        self.use_expand_re = re.compile(
            "^(?:[+-])?(%s)_(.*)$" %
            "|".join(x.lower() for x in sorted(self.use_expand, reverse=True)))
예제 #16
0
 def f(chunk):
     return chunked_data(chunk.key, tuple(set(chunk.neg)), tuple(set(chunk.pos)))
예제 #17
0
    def test_masked_use(self):
        self.mk_profiles({})
        self.assertEqualPayload(self.get_profile("0").masked_use, {})

        self.mk_profiles({"use.mask": "X\nmmx\n"}, {}, {"use.mask": "-X"})

        self.assertEqualPayload(self.get_profile("0").masked_use, {atrue: (chunked_data(atrue, (), ("X", "mmx")),)})

        self.assertEqualPayload(self.get_profile("1").masked_use, {atrue: (chunked_data(atrue, (), ("X", "mmx")),)})

        self.assertEqualPayload(self.get_profile("2").masked_use, {atrue: (chunked_data(atrue, ("X",), ("mmx",)),)})

        self.mk_profiles(
            {"use.mask": "X\nmmx\n", "package.use.mask": "dev-util/foo cups"},
            {"package.use.mask": "dev-util/foo -cups"},
            {"use.mask": "-X", "package.use.mask": "dev-util/blah X"},
        )

        self.assertEqualPayload(
            self.get_profile("0").masked_use,
            {
                atrue: (chunked_data(atrue, (), ("X", "mmx")),),
                "dev-util/foo": (chunked_data(atom("dev-util/foo"), (), ("X", "cups", "mmx")),),
            },
        )

        self.assertEqualPayload(
            self.get_profile("1").masked_use,
            {
                atrue: (chunked_data(atrue, (), ("X", "mmx")),),
                "dev-util/foo": (chunked_data(atom("dev-util/foo"), ("cups",), ("X", "mmx")),),
            },
        )

        self.assertEqualPayload(
            self.get_profile("2").masked_use,
            {
                atrue: (chunked_data(atrue, ("X",), ("mmx",)),),
                "dev-util/foo": (chunked_data(atom("dev-util/foo"), ("X", "cups"), ("mmx",)),),
                "dev-util/blah": (chunked_data(atom("dev-util/blah"), (), ("X", "mmx")),),
            },
        )

        self.mk_profiles(
            {"use.mask": "X", "package.use.mask": "dev-util/foo -X"},
            {"use.mask": "X"},
            {"package.use.mask": "dev-util/foo -X"},
        )

        self.assertEqualPayload(
            self.get_profile("0").masked_use,
            {
                atrue: (chunked_data(atrue, (), ("X",)),),
                "dev-util/foo": (chunked_data(atom("dev-util/foo"), ("X",), ()),),
            },
        )
        self.assertEqualPayload(
            self.get_profile("1").masked_use,
            {
                atrue: (chunked_data(atrue, (), ("X",)),),
                "dev-util/foo": (chunked_data(atom("dev-util/foo"), (), ("X",)),),
            },
        )
        self.assertEqualPayload(
            self.get_profile("2").masked_use,
            {
                atrue: (chunked_data(atrue, (), ("X")),),
                "dev-util/foo": (chunked_data(atom("dev-util/foo"), ("X",), ()),),
            },
        )

        # pkgcore bug 237; per PMS, later profiles can punch wholes in the
        # ranges applicable.
        self.mk_profiles(
            {"package.use.mask": "dev-util/foo X"},
            {"package.use.mask": ">=dev-util/foo-1 -X"},
            {"package.use.mask": ">=dev-util/foo-2 X"},
            {"package.use.mask": "dev-util/foo X", "name": "collapse_p"},
            {"package.use.mask": "dev-util/foo -X", "parent": "2", "name": "collapse_n"},
        )

        self.assertEqualPayload(
            self.get_profile("collapse_p").masked_use,
            {"dev-util/foo": (chunked_data(atom("dev-util/foo"), (), ("X",)),)},
        )

        self.assertEqualPayload(
            self.get_profile("collapse_n").masked_use,
            {"dev-util/foo": (chunked_data(atom("dev-util/foo"), ("X",), ()),)},
        )
예제 #18
0
 def f(chunk):
     return chunked_data(chunk.restrict, tuple(sorted(chunk.data)))
예제 #19
0
    def test_forced_use(self):
        self.mk_profiles({})
        self.assertEqualPayload(self.get_profile("0").forced_use, {})
        self.mk_profiles({"use.force": "X\nmmx\n"}, {}, {"use.force": "-X"})

        self.assertEqualPayload(self.get_profile("0").forced_use, {atrue: (chunked_data(atrue, (), ("X", "mmx")),)})
        self.assertEqualPayload(self.get_profile("1").forced_use, {atrue: (chunked_data(atrue, (), ("X", "mmx")),)})
        self.assertEqualPayload(self.get_profile("2").forced_use, {atrue: (chunked_data(atrue, ("X",), ("mmx",)),)})

        self.mk_profiles(
            {"use.force": "X\nmmx\n", "package.use.force": "dev-util/foo cups"},
            {"package.use.force": "dev-util/foo -cups"},
            {"use.force": "-X", "package.use.force": "dev-util/blah X"},
        )

        self.assertEqualPayload(
            self.get_profile("0").forced_use,
            {
                atrue: (chunked_data(atrue, (), ("X", "mmx")),),
                "dev-util/foo": (chunked_data(atom("dev-util/foo"), (), ("X", "mmx", "cups")),),
            },
        )
        self.assertEqualPayload(
            self.get_profile("1").forced_use,
            {
                atrue: (chunked_data(atrue, (), ("X", "mmx")),),
                "dev-util/foo": (chunked_data(atom("dev-util/foo"), ("cups",), ("X", "mmx")),),
            },
        )
        self.assertEqualPayload(
            self.get_profile("2").forced_use,
            {
                atrue: (chunked_data(atrue, ("X",), ("mmx",)),),
                "dev-util/foo": (chunked_data(atom("dev-util/foo"), ("cups", "X"), ("mmx",)),),
                "dev-util/blah": (chunked_data(atom("dev-util/blah"), (), ("X", "mmx")),),
            },
        )

        self.mk_profiles(
            {"use.force": "X", "package.use.force": "dev-util/foo -X"},
            {"use.force": "X"},
            {"package.use.force": "dev-util/foo -X"},
        )

        self.assertEqualPayload(
            self.get_profile("0").forced_use,
            {
                atrue: (chunked_data(atrue, (), ("X",)),),
                "dev-util/foo": (chunked_data(atom("dev-util/foo"), ("X",), ()),),
            },
        )
        self.assertEqualPayload(
            self.get_profile("1").forced_use,
            {
                atrue: (chunked_data(atrue, (), ("X",)),),
                "dev-util/foo": (chunked_data(atom("dev-util/foo"), (), ("X",)),),
            },
        )
        self.assertEqualPayload(
            self.get_profile("2").forced_use,
            {
                atrue: (chunked_data(atrue, (), ("X",)),),
                "dev-util/foo": (chunked_data(atom("dev-util/foo"), ("X",), ()),),
            },
        )