Beispiel #1
0
 def test_pretty_docs(self):
     for target in self.currying_targets:
         for func in (passthrough, documented):
             assert currying.pretty_docs(target(func),
                                         'new doc').__doc__ == 'new doc'
             assert currying.pretty_docs(
                 target(func)).__doc__ is func.__doc__
Beispiel #2
0
class uninstall_op(ebd, format.uninstall):
    """phase operations and steps for uninstall execution"""
    def __init__(self, domain, pkg, observer):
        format.uninstall.__init__(self, domain, pkg, observer)
        ebd.__init__(self,
                     pkg,
                     observer=observer,
                     initial_env=domain.settings,
                     env_data_source=pkg.environment,
                     clean=False,
                     tmp_offset="unmerge")

    prerm = pretty_docs(
        observer.decorate_build_method("prerm")(post_curry(
            ebd._generic_phase, "prerm", False, False, False)),
        "run the prerm phase")
    postrm = pretty_docs(
        observer.decorate_build_method("postrm")(post_curry(
            ebd._generic_phase,
            "postrm",
            False,
            False,
            False,
            failure_allowed=True)), "run the postrm phase")

    def add_triggers(self, domain_op, engine):
        self.old_pkg.add_format_triggers(domain_op, self, engine)

    def finish(self):
        self.cleanup()
        return format.uninstall.finish(self)
Beispiel #3
0
def _single_thread_allowed(functor):
    def _inner(*args, **kwds):
        _acquire_global_ebp_lock()
        try:
            return functor(*args, **kwds)
        finally:
            _release_global_ebp_lock()
    _inner.func = functor
    pretty_docs(_inner, name=functor.__name__)
    return _inner
Beispiel #4
0
 def test_pretty_docs(self):
     for target in self.currying_targets:
         for func in (passthrough, documented):
             self.assertEqual(
                 currying.pretty_docs(
                     target(func), 'new doc').__doc__,
                 'new doc')
             self.assertIdentical(
                 currying.pretty_docs(target(func)).__doc__,
                 func.__doc__)
Beispiel #5
0
 def test_pretty_docs(self):
     for target in self.currying_targets:
         for func in (passthrough, documented):
             self.assertEqual(
                 currying.pretty_docs(
                     target(func), 'new doc').__doc__,
                 'new doc')
             self.assertIdentical(
                 currying.pretty_docs(target(func)).__doc__,
                 func.__doc__)
Beispiel #6
0
def _single_thread_allowed(functor):
    def _inner(*args, **kwds):
        _acquire_global_ebp_lock()
        try:
            return functor(*args, **kwds)
        finally:
            _release_global_ebp_lock()
    _inner.func = functor
    pretty_docs(_inner, name=functor.__name__)
    return _inner
Beispiel #7
0
def _single_thread_allowed(functor):
    """Decorator that forces method to run under single thread."""
    def _inner(*args, **kwargs):
        _acquire_global_ebp_lock()
        try:
            return functor(*args, **kwargs)
        finally:
            _release_global_ebp_lock()

    _inner.func = functor
    pretty_docs(_inner, name=functor.__name__)
    return _inner
Beispiel #8
0
 def test_module_magic(self):
     for target in self.currying_targets:
         assert currying.pretty_docs(target(passthrough)).__module__ is \
             passthrough.__module__
         # test is kinda useless if they are identical without pretty_docs
         assert getattr(target(passthrough), '__module__', None) is not \
             passthrough.__module__
Beispiel #9
0
 def test_module_magic(self):
     for target in self.currying_targets:
         assert currying.pretty_docs(target(passthrough)).__module__ is \
             passthrough.__module__
         # test is kinda useless if they are identical without pretty_docs
         assert getattr(target(passthrough), '__module__', None) is not \
             passthrough.__module__
Beispiel #10
0
def mk_check(name):
    return pretty_docs(
        post_curry(getattr, 'is_' + name, False),
        extradocs=(
            "return True if obj is an instance of :obj:`%s`, else False" %
            name),
        name=("is" + name))
Beispiel #11
0
 def test_module_magic(self):
     for target in self.currying_targets:
         self.assertIdentical(
             currying.pretty_docs(target(passthrough)).__module__,
             passthrough.__module__)
         # test is kinda useless if they are identical without pretty_docs
         self.assertNotIdentical(
             getattr(target(passthrough), '__module__', None),
             passthrough.__module__)
Beispiel #12
0
 def test_module_magic(self):
     for target in self.currying_targets:
         self.assertIdentical(
             currying.pretty_docs(target(passthrough)).__module__,
             passthrough.__module__)
         # test is kinda useless if they are identical without pretty_docs
         self.assertNotIdentical(
             getattr(target(passthrough), '__module__', None),
             passthrough.__module__)
Beispiel #13
0
class install_op(ebd, format.install):
    """phase operations and steps for install execution"""

    def __init__(self, domain, pkg, observer):
        format.install.__init__(self, domain, pkg, observer)
        ebd.__init__(
            self, pkg, observer=observer, initial_env=domain.settings,
            env_data_source=pkg.environment, clean=False)

    preinst = pretty_docs(
        observer.decorate_build_method("preinst")(
            post_curry(ebd._generic_phase, "preinst", False, False)),
        "run the postinst phase")
    postinst = pretty_docs(
        observer.decorate_build_method("postinst")(
            post_curry(ebd._generic_phase, "postinst", False, False)),
        "run the postinst phase")

    def add_triggers(self, domain_op, engine):
        self.new_pkg.add_format_triggers(domain_op, self, engine)
Beispiel #14
0
def curry_node_type(klass, node_type, extradoc=None):
    """Helper function for creating restrictions of a certain type.

    This uses :obj:`partial` to pass a node_type to the wrapped class,
    and extends the docstring.

    :param klass: callable (usually a class) that is wrapped.
    :param node_type: value passed as node_type.
    :param extradoc: addition to the docstring. Defaults to
        "Automatically set to %s type." % node_type

    :return: a wrapped callable.
    """
    if extradoc is None:
        extradoc = "Automatically set to %s type." % (node_type,)
    doc = klass.__doc__
    result = partial(klass, node_type=node_type)
    if doc is None:
        doc = ''
    else:
        # do this so indentation on pydoc __doc__ is sane
        doc = "\n".join(line.lstrip() for line in doc.split("\n")) + "\n"
        doc += extradoc
    return pretty_docs(result, doc)
Beispiel #15
0
def curry_node_type(klass, node_type, extradoc=None):
    """Helper function for creating restrictions of a certain type.

    This uses :obj:`partial` to pass a node_type to the wrapped class,
    and extends the docstring.

    :param klass: callable (usually a class) that is wrapped.
    :param node_type: value passed as node_type.
    :param extradoc: addition to the docstring. Defaults to
        "Automatically set to %s type." % node_type

    :return: a wrapped callable.
    """
    if extradoc is None:
        extradoc = "Automatically set to %s type." % (node_type, )
    doc = klass.__doc__
    result = partial(klass, node_type=node_type)
    if doc is None:
        doc = ''
    else:
        # do this so indentation on pydoc __doc__ is sane
        doc = "\n".join(line.lstrip() for line in doc.split("\n")) + "\n"
        doc += extradoc
    return pretty_docs(result, doc)
Beispiel #16
0
def _mk_pretty_derived_func(func, name_base, name, *args, **kwds):
    if name:
        name = '_' + name
    return pretty_docs(partial(func, *args, **kwds),
                       name='%s%s' % (name_base, name))
Beispiel #17
0
    def unpack(self):
        """execute the unpack phase"""
        if self.setup_is_for_src:
            self.setup_distfiles()
        if self.userpriv:
            try:
                os.chown(self.env["WORKDIR"], portage_uid, -1)
            except OSError as oe:
                raise_from(
                    format.GenericBuildError(
                        "failed forcing %i uid for WORKDIR: %s" %
                        (portage_uid, str(oe))))
        return self._generic_phase("unpack", True, True, False)

    compile = pretty_docs(
        observer.decorate_build_method("compile")(post_curry(
            ebd._generic_phase, "compile", True, True, False)),
        "run the compile phase (maps to src_compile)")

    @observer.decorate_build_method("install")
    def install(self):
        """run the install phase (maps to src_install)"""
        if self.fakeroot:
            return self._generic_phase("install", True, False, True)
        else:
            return self._generic_phase("install", False, True, False)

    @observer.decorate_build_method("test")
    def test(self):
        """run the test phase (if enabled), maps to src_test"""
        if not self.run_test:
            return True
Beispiel #18
0
def mk_check(name):
    return pretty_docs(post_curry(getattr, 'is_' + name, False),
        extradocs=("return True if obj is an instance of :obj:`%s`, else False" % name),
        name=("is" +name)
        )
Beispiel #19
0
 def _wrap_exception(self, functor, name):
     f = currying.partial(
         self._recast_exception_decorator, self.__casting_exception__, name, functor)
     return currying.pretty_docs(f)
Beispiel #20
0
    def unpack(self):
        """execute the unpack phase"""
        if self.setup_is_for_src:
            self.setup_distfiles()
        if self.userpriv:
            try:
                os.chown(self.env["WORKDIR"], portage_uid, -1)
            except OSError as oe:
                raise_from(format.GenericBuildError(
                    "failed forcing %i uid for WORKDIR: %s" %
                        (portage_uid, str(oe))))
        return self._generic_phase("unpack", True, True, False)

    compile = pretty_docs(
        observer.decorate_build_method("compile")(
            post_curry(
            ebd._generic_phase, "compile", True, True, False)),
            "run the compile phase (maps to src_compile)")

    @observer.decorate_build_method("install")
    def install(self):
        """run the install phase (maps to src_install)"""
        if self.fakeroot:
            return self._generic_phase("install", True, False, True)
        else:
            return self._generic_phase("install", False, True, False)

    @observer.decorate_build_method("test")
    def test(self):
        """run the test phase (if enabled), maps to src_test"""
        if not self.run_test:
Beispiel #21
0
 def test_pretty_docs(self):
     for target in self.currying_targets:
         for func in (passthrough, documented):
             assert currying.pretty_docs(target(func), 'new doc').__doc__ == 'new doc'
             assert currying.pretty_docs(target(func)).__doc__ is func.__doc__
Beispiel #22
0
class buildable(ebd, setup_mixin, format.build):
    """Generic build operation."""

    # XXX this is unclean- should be handing in strictly what is build
    # env, rather then dumping domain settings as env.
    def __init__(self, domain, pkg, verified_files, eclass_cache,
                 observer=None, force_test=False, **kwargs):
        """
        :param pkg: :obj:`pkgcore.ebuild.ebuild_src.package` instance we'll be
            building
        :param eclass_cache: the :class:`pkgcore.ebuild.eclass_cache`
            we'll be using
        :param verified_files: mapping of fetchables mapped to their disk location
        """
        self._built_class = ebuild_built.fresh_built_package
        format.build.__init__(self, domain, pkg, verified_files, observer)
        domain_settings = self.domain.settings
        ebd.__init__(self, pkg, initial_env=domain_settings, **kwargs)

        self.env["FILESDIR"] = pjoin(os.path.dirname(pkg.ebuild.path), "files")
        self.eclass_cache = eclass_cache

        self.run_test = force_test or self.feat_or_bool("test", domain_settings)
        self.allow_failed_test = self.feat_or_bool("test-fail-continue", domain_settings)
        if "test" in self.restrict:
            self.run_test = False
        elif not force_test and "test" not in pkg.use:
            if self.run_test:
                logger.warning(f"disabling test for {pkg} due to test use flag being disabled")
            self.run_test = False

        # XXX minor hack
        path = self.env["PATH"].split(os.pathsep)

        for s, default in (("DISTCC", ".distcc"), ("CCACHE", "ccache")):
            b = (self.feat_or_bool(s, domain_settings) and
                 s not in self.restrict)
            setattr(self, s.lower(), b)
            if b:
                # looks weird I realize, but
                # pjoin("/foor/bar", "/barr/foo") == "/barr/foo"
                # and pjoin("/foo/bar", ".asdf") == "/foo/bar/.asdf"
                self.env.setdefault(s + "_DIR", pjoin(self.domain.tmpdir, default))
                # gentoo bug 355283
                libdir = self.env.get("ABI")
                if libdir is not None:
                    libdir = self.env.get(f"LIBDIR_{libdir}")
                    if libdir is not None:
                        libdir = self.env.get(libdir)
                if libdir is None:
                    libdir = "lib"
                path.insert(0, f"/usr/{libdir}/{s.lower()}/bin")
            else:
                for y in ("_PATH", "_DIR"):
                    if s + y in self.env:
                        del self.env[s+y]
        self.env["PATH"] = os.pathsep.join(path)

        # ordering must match appearance order in SRC_URI per PMS
        self.env["A"] = ' '.join(iter_stable_unique(pkg.distfiles))

        if self.eapi.options.has_AA:
            pkg = self.pkg
            while hasattr(pkg, '_raw_pkg'):
                pkg = getattr(pkg, '_raw_pkg')
            self.env["AA"] = ' '.join(set(iflatten_instance(pkg.distfiles)))

        if self.eapi.options.has_KV:
            self.env["KV"] = domain.KV

        if self.eapi.options.has_merge_type:
            self.env["MERGE_TYPE"] = "source"

        if self.eapi.options.has_portdir:
            self.env["PORTDIR"] = pkg.repo.location
            self.env["ECLASSDIR"] = eclass_cache.eclassdir

        if self.setup_is_for_src:
            self._init_distfiles_env()

    def _init_distfiles_env(self):
        # TODO: PORTAGE_ACTUAL_DISTDIR usage by vcs eclasses needs to be killed off
        distdir_write = self.domain.fetcher.get_storage_path()
        if distdir_write is None:
            raise format.GenericBuildError(
                "no usable distdir was found "
                f"for PORTAGE_ACTUAL_DISTDIR from fetcher {self.domain.fetcher}")
        self.env["PORTAGE_ACTUAL_DISTDIR"] = distdir_write
        self.env["DISTDIR"] = normpath(
            pjoin(self.builddir, "distdir"))
        for x in ("PORTAGE_ACTUAL_DISTDIR", "DISTDIR"):
            self.env[x] = os.path.realpath(self.env[x]).rstrip(os.sep) + os.sep

    def _setup_distfiles(self):
        if not self.verified_files and self.allow_fetching:
            ops = self.domain.pkg_operations(self.pkg, observer=self.observer)
            if not ops.fetch():
                raise format.GenericBuildError("failed fetching required distfiles")
            self.verified_files = ops._fetch_op.verified_files

        if self.verified_files:
            try:
                if os.path.exists(self.env["DISTDIR"]):
                    if (os.path.isdir(self.env["DISTDIR"]) and
                            not os.path.islink(self.env["DISTDIR"])):
                        shutil.rmtree(self.env["DISTDIR"])
                    else:
                        os.unlink(self.env["DISTDIR"])

            except EnvironmentError as e:
                raise format.FailedDirectory(
                    self.env["DISTDIR"],
                    f"failed removing existing file/dir/link: {e}") from e

            if not ensure_dirs(self.env["DISTDIR"], mode=0o770, gid=portage_gid):
                raise format.FailedDirectory(
                    self.env["DISTDIR"],
                    "failed creating distdir symlink directory")

            try:
                for src, dest in [
                        (k, pjoin(self.env["DISTDIR"], v.filename))
                        for (k, v) in self.verified_files.items()]:
                    os.symlink(src, dest)

            except EnvironmentError as e:
                raise format.GenericBuildError(
                    f"Failed symlinking in distfiles for src {src} -> {dest}: {e}") from e

    @observer.decorate_build_method("setup")
    def setup(self):
        """Execute the setup phase, mapping out to pkg_setup in the ebuild.

        Necessarily dirs are created as required, and build env is
        initialized at this point.
        """
        if self.distcc:
            for p in ("", "/lock", "/state"):
                if not ensure_dirs(pjoin(self.env["DISTCC_DIR"], p),
                                   mode=0o2775, gid=portage_gid):
                    raise format.FailedDirectory(
                        pjoin(self.env["DISTCC_DIR"], p),
                        "failed creating needed distcc directory")
        if self.ccache:
            # yuck.
            st = None
            try:
                st = os.stat(self.env["CCACHE_DIR"])
            except OSError as e:
                st = None
                if not ensure_dirs(self.env["CCACHE_DIR"], mode=0o2775,
                                   gid=portage_gid):
                    raise format.FailedDirectory(
                        self.env["CCACHE_DIR"],
                        "failed creation of ccache dir") from e

                # XXX this is more then mildly stupid.
                st = os.stat(self.env["CCACHE_DIR"])
            try:
                if st.st_gid != portage_gid or (st.st_mode & 0o2775) != 0o2775:
                    try:
                        cwd = os.getcwd()
                    except OSError:
                        cwd = "/"
                    with chdir(cwd):
                        # crap.
                        os.chmod(self.env["CCACHE_DIR"], 0o2775)
                        os.chown(self.env["CCACHE_DIR"], -1, portage_gid)
                        if 0 != spawn(
                                ["chgrp", "-R", str(portage_gid), self.env["CCACHE_DIR"]]):
                            raise format.FailedDirectory(
                                self.env["CCACHE_DIR"],
                                "failed changing ownership for CCACHE_DIR")
                        if 0 != spawn_bash(
                                "find '%s' -type d -print0 | %s --null chmod 02775"
                                % (self.env["CCACHE_DIR"], xargs)):
                            raise format.FailedDirectory(
                                self.env["CCACHE_DIR"],
                                "failed correcting perms for CCACHE_DIR")

                        if 0 != spawn_bash(
                                "find '%s' -type f -print0 | %s --null chmod 0775"
                                % (self.env["CCACHE_DIR"], xargs)):
                            raise format.FailedDirectory(
                                self.env["CCACHE_DIR"],
                                "failed correcting perms for CCACHE_DIR")
            except OSError as e:
                raise format.FailedDirectory(
                    self.env["CCACHE_DIR"],
                    "failed ensuring perms/group owner for CCACHE_DIR") from e

        return setup_mixin.setup(self)

    def configure(self):
        """Execute the configure phase.

        Does nothing if the pkg's EAPI is less than 2 (that spec lacks a
        separated configure phase).
        """
        if "configure" in self.eapi.phases:
            return self._generic_phase("configure", True, True)
        return True

    def prepare(self):
        """Execute a source preparation phase.

        does nothing if the pkg's EAPI is less than 2
        """
        ret = True
        if "prepare" in self.eapi.phases:
            ret = self._generic_phase("prepare", True, True)
            if (self.eapi.options.user_patches and
                    not os.path.exists(pjoin(self.env['T'], '.user_patches_applied'))):
                self.observer.error(
                    'eapply_user (or default) must be called in src_prepare()')
                raise format.GenericBuildError('missing eapply_user call')
        return ret

    def nofetch(self):
        """Execute the nofetch phase.

        We need the same prerequisites as setup, so reuse that.
        """
        ensure_dirs(self.env["T"], mode=0o770, gid=portage_gid, minimal=True)
        return setup_mixin.setup(self, "nofetch")

    def unpack(self):
        """Execute the unpack phase."""
        if self.setup_is_for_src:
            self._setup_distfiles()
        if self.userpriv:
            try:
                os.chown(self.env["WORKDIR"], portage_uid, -1)
            except OSError as e:
                raise format.GenericBuildError(
                    "failed forcing %i uid for WORKDIR: %s" %
                    (portage_uid, e)) from e
        return self._generic_phase("unpack", True, True)

    compile = pretty_docs(
        observer.decorate_build_method("compile")(
            post_curry(ebd._generic_phase, "compile", True, True)),
        "Run the compile phase (maps to src_compile).")

    @observer.decorate_build_method("install")
    def install(self):
        """Run the install phase (maps to src_install)."""
        # TODO: replace print() usage with observer
        print(f">>> Install {self.env['PF']} into {self.ED!r} category {self.env['CATEGORY']}")
        ret = self._generic_phase("install", False, True)
        print(f">>> Completed installing {self.env['PF']} into {self.ED!r}")
        return ret

    @observer.decorate_build_method("test")
    def test(self):
        """Run the test phase (if enabled), maps to src_test."""
        if not self.run_test:
            return True
        return self._generic_phase(
            "test", True, True, failure_allowed=self.allow_failed_test)

    def finalize(self):
        """Finalize the operation.

        This yields a built package, but the packages metadata/contents are
        bound to the workdir. In other words, install the package somewhere
        prior to executing clean if you intend on installing it.

        :return: :obj:`pkgcore.ebuild.ebuild_built.package` instance
        """
        factory = ebuild_built.fake_package_factory(self._built_class)
        return factory.new_package(
            self.pkg, self.env["D"], pjoin(self.env["T"], "environment"))
Beispiel #23
0
    :return: major,minor tuple of ints
    """
    return ( stat_inst.st_rdev >> 8 ) & 0xff, stat_inst.st_rdev & 0xff


class fsFifo(fsBase):

    """fifo class (socket objects)"""

    __slots__ = ()
    is_fifo = True

    def __repr__(self):
        return "fifo:%s" % self.location

def mk_check(name):
    return pretty_docs(post_curry(getattr, 'is_' + name, False),
        extradocs=("return True if obj is an instance of :obj:`%s`, else False" % name),
        name=("is" +name)
        )

isdir    = mk_check('dir')
isreg    = mk_check('reg')
issym    = mk_check('sym')
isfifo   = mk_check('fifo')
isdev    = mk_check('dev')
isfs_obj = pretty_docs(post_curry(isinstance, fsBase), name='isfs_obj',
    extradocs='return True if obj is an fsBase derived object')

del gen_doc_additions, mk_check
Beispiel #24
0
class fsFifo(fsBase):
    """fifo class (socket objects)"""

    __slots__ = ()
    is_fifo = True

    def __repr__(self):
        return f"fifo:{self.location}"


def mk_check(name):
    return pretty_docs(
        post_curry(getattr, 'is_' + name, False),
        extradocs=(
            "return True if obj is an instance of :obj:`%s`, else False" %
            name),
        name=("is" + name))


isdir = mk_check('dir')
isreg = mk_check('reg')
issym = mk_check('sym')
isfifo = mk_check('fifo')
isdev = mk_check('dev')
isfs_obj = pretty_docs(
    post_curry(isinstance, fsBase),
    name='isfs_obj',
    extradocs='return True if obj is an fsBase derived object')

del gen_doc_additions, mk_check
Beispiel #25
0
def _mk_pretty_derived_func(func, name_base, name, *args, **kwds):
    if name:
        name = '_' + name
    return pretty_docs(partial(func, *args, **kwds),
                       name='%s%s' % (name_base, name))
Beispiel #26
0
 def _wrap_exception(self, functor, name):
     f = partial(
         self._recast_exception_decorator, self.__casting_exception__, name, functor)
     return pretty_docs(f)