Exemple #1
0
def includeme(app: App):
    app.include("discovery")

    # TODO: spawn, when using
    # TODO: spawn, when dry_run=False only
    def _register():
        from discovery import get_discovery

        port = None

        if app.registry.dry_run:
            logger.info("dry run, %s skipped", NAME)
            get_discovery().register("gofmtrpc",
                                     url=f"http://127.0.0.1:{port}")
            return

        from egoist.internal.netutil import find_free_port
        from util import spawn_with_connection

        port = find_free_port()
        get_discovery().register("gofmtrpc", url=f"http://127.0.0.1:{port}")

        argv = ["gofmtrpc", "-addr", f":{port}"]
        p, _ = spawn_with_connection(argv, sentinel_option="-sentinel")

        import atexit

        def _shutdown():
            logger.info("terminate gofmtrpc")
            with p:
                p.terminate()

        atexit.register(_shutdown)

    app.action(NAME, _register)
Exemple #2
0
def define_something(app: App) -> None:
    import sys

    name = "define_something"
    seen = False

    print("** on decorator", file=sys.stderr)

    def _register_something(app: App, something: t.Any) -> AnyFunction:
        nonlocal seen
        if not seen:
            seen = True

        def _register() -> AnyFunction:
            name = something.__name__
            print("*** {name}, on register".format(name=name), file=sys.stderr)

        app.action((name, something.__name__), _register)
        return _register

    app.add_directive(name, _register_something)

    def _include() -> None:
        nonlocal seen
        if seen:
            print("** on include", file=sys.stderr)

    # for conflict check
    app.action(name, _include)
Exemple #3
0
def includeme(app: App):
    app.include("discovery")

    # TODO: only spawn, when using
    def _register():
        import shutil
        from egoist.internal.netutil import find_free_port
        from discovery import get_discovery
        import util

        sentinel = util.create_sentinel_file()
        port = find_free_port()

        get_discovery().register("gofmtrpc", url=f"http://127.0.0.1:{port}")

        assert shutil.which("gofmtrpc")
        argv = [
            "gofmtrpc",
            "-addr",
            f":{port}",
            "-sentinel",
            sentinel,
        ]
        p = util.ConnectedProcess().spawn(argv, sentinel=sentinel)
        import atexit

        def _shutdown():
            logger.info("terminate gofmtrpc")
            with p:
                p.terminate()

        atexit.register(_shutdown)

    app.action(NAME, _register)
Exemple #4
0
def makegen(
    app: App,
    *,
    tasks: t.Optional[t.List[str]] = None,
    rootdir: t.Optional[str] = None,
    out: t.Optional[str] = None,
    relative: bool = True,
) -> None:
    import contextlib
    import os
    from egoist.components.tracker import get_tracker
    from egoist.commands.generate import generate

    app.commit(dry_run=True)

    if not bool(os.environ.get("VERBOSE", "")):
        logging.getLogger("prestring.output").setLevel(logging.WARNING)
    generate(app, tasks=tasks, rootdir=rootdir)

    root_path = get_root_path(app.settings, root=rootdir)
    deps = get_tracker().get_dependencies(root=root_path, relative=relative)

    with contextlib.ExitStack() as s:
        out_port: t.Optional[t.IO[str]] = None
        if out is not None:
            out_port = s.enter_context(open(out, "w"))
        print(emit(deps, filename=getattr(out_port, "name", None)),
              file=out_port)
Exemple #5
0
def define_foo(app: App, fn: AnyFunction, name: str) -> AnyFunction:
    """*** define foo ***"""
    print(app, fn, "foo", name)

    def _register():
        print("!")

    app.registry.generators[name].append(fn)
    app.action(fn.__name__, _register)
    return fn
Exemple #6
0
def includeme(app: App) -> None:
    from egoist.experimental.serverprocess.lazyparams import find_free_port, create_sentinel_file

    app.include("egoist.experimental.serverprocess")  # for add_server_process

    app.add_server_process(
        "gofmtrpc -addr :{port} -sentinel {sentinel}",
        params=dict(port=find_free_port, sentinel=create_sentinel_file),
        name=NAME,
    )
Exemple #7
0
def setup_server(app: App) -> None:
    from egoist.ext.serverprocess.lazyparams import find_free_port, create_sentinel_file

    app.include("egoist.ext.serverprocess")  # for add_server_process
    app.add_server_process(
        "uvicorn server:app --port {port}",
        params=dict(port=find_free_port),
        name="api-server",
        env={"SENTINEL": create_sentinel_file},
    )
Exemple #8
0
def includeme(app: App) -> None:
    app.include("directives.define_server_process")

    from rpcutil import find_free_port, create_sentinel_file

    app.define_server_process(
        "gofmtrpc -addr :{port} -sentinel {sentinel}",
        params=dict(port=find_free_port, sentinel=create_sentinel_file),
        name="gofmtrpc",
    )
Exemple #9
0
    def _register_something(app: App, something: t.Any) -> AnyFunction:
        nonlocal seen
        if not seen:
            seen = True

        def _register() -> AnyFunction:
            name = something.__name__
            print("*** {name}, on register".format(name=name), file=sys.stderr)

        app.action((name, something.__name__), _register)
        return _register
Exemple #10
0
def define_server_process(app: App):
    def _define(
        app: App,
        fmt: str,
        *,
        name: str,
        urlfmt: str = "http://{host}:{port}",
        host: str = "127.0.0.1",
        port: t.Optional[int] = None,
        params: t.Optional[t.Dict[str, t.Callable[[], object]]] = None,
    ):
        def _register():
            nonlocal host
            nonlocal port

            import shlex
            import atexit
            from discovery import get_discovery
            from rpcutil import find_free_port

            kwargs = {k: fn(app) for k, fn in (params or {}).items()}
            if port is None:
                port = kwargs.get("port") or find_free_port()
            if "host" in kwargs:
                host = kwargs.get["host"]

            argv = shlex.split(fmt.format(**kwargs))
            url = urlfmt.format(host=host, port=port)

            get_discovery().register(name, url=url)
            if app.registry.dry_run:
                logger.info("dry run, %s skipped", name)
                return

            from spawn import spawn_with_connection

            p, _ = spawn_with_connection(argv)

            def _shutdown():  # xxx:
                logger.info("terminate %s", name)
                with p:
                    p.terminate()

            atexit.register(_shutdown)

        app.action(("define_server_process", name), _register)

    app.include("discovery")
    app.add_directive("define_server_process", _define)
Exemple #11
0
def describe(app: App) -> None:
    import json
    import inspect
    from egoist.langhelpers import get_fullname_of_type, get_fullname_of_callable

    app.commit(dry_run=False)

    definitions: t.Dict[str, t.Dict[str, t.Union[str, t.List[str]]]] = {}
    delayed_include_mapping = app.delayed_include_mapping
    for kit, fns in app.registry.generators.items():
        for fn in fns:
            name = get_fullname_of_callable(fn)
            summary = (inspect.getdoc(fn) or "").strip().split("\n", 1)[0]

            definitions[name] = {"doc": summary, "generator": kit}

            if fn in delayed_include_mapping:
                definitions[name]["include_when"] = [
                    get_fullname_of_callable(dep) if callable(dep) else
                    (_app.module.__name__ +
                     dep if dep.startswith(".") else dep)
                    for _app, dep in delayed_include_mapping[fn]
                ]

    factories = {
        name: [get_fullname_of_type(x) for x in xs]  # type: ignore
        for name, xs in app.registry.factories.items()
    }

    empty_context = app.context_factory()
    current_directives = set(name
                             for name, attr in app.context.__dict__.items()
                             if callable(attr))
    append_directives = current_directives.difference(
        empty_context.__dict__.keys())
    append_directives = append_directives.difference(["run"])

    d = {
        "definitions": definitions,
        "components": factories,
        "directives": {
            name: get_fullname_of_type(getattr(app.context, name))
            for name in append_directives
        },
    }
    print(json.dumps(d, indent=2, ensure_ascii=False))
Exemple #12
0
def generate(app: App,
             *,
             tasks: t.Optional[t.List[str]] = None,
             rootdir: t.Optional[str] = None,
             dry_run: bool = False) -> None:
    root_path = get_root_path(app.settings, root=rootdir)
    app.commit(dry_run=dry_run)
    app.context.queue.clear()  # xxx: clear

    action_list: t.List[t.Callable[..., t.Any]] = []
    included_after_commit_list: t.List[t.Union[str, t.Callable[...,
                                                               t.Any]]] = []

    for kit, fns in app.registry.generators.items():
        walk_or_module = app.maybe_dotted(kit)
        if callable(walk_or_module):
            walk = walk_or_module
        elif hasattr(walk_or_module, "walk"):
            walk = walk_or_module.walk  # type: ignore
        else:
            # TODO: genetle error message
            raise ConfigurationError("{kit!r} is not callable")

        if not tasks:
            sources = {fn.__name__: fn for fn in fns}
        else:
            sources = {fn.__name__: fn for fn in fns if fn.__name__ in tasks}
        action_list.append(partial(walk, sources, root=root_path))

        # for app.include_when()
        delayed_include_mapping = app.delayed_include_mapping
        for fn in sources.values():
            if fn in delayed_include_mapping:
                for _app, path in delayed_include_mapping[fn]:
                    _app.include(path)
                    included_after_commit_list.append(path)
        app.delayed_include_mapping.clear()  # xxx: clear

    if len(included_after_commit_list) > 0:
        app.shallow_commit()

    for action in action_list:
        action()
Exemple #13
0
    def includeme(self, app: App) -> None:
        """callback for app.include()"""

        # for information used by describe()
        directive = partial(self.register)
        update_wrapper(directive, self.define_fn)
        app.add_directive(self.name, directive)

        def _include() -> None:
            if self.seen or not self.requires:
                return

            seen = app._aggressive_import_cache
            for path in self.requires:
                if path in seen:
                    continue
                app.include(path)

        app.action(self.name, _include)
Exemple #14
0
def includeme(app: App):
    app.include("discovery")

    # TODO: only spawn, when using
    def _register():
        import sys
        import pathlib
        from egoist.internal.netutil import find_free_port
        from discovery import get_discovery
        import util

        sentinel = util.create_sentinel_file()
        server_py = pathlib.Path(__file__).absolute().with_name("server.py")
        port = find_free_port()

        get_discovery().register("HELLO", url=f"http://127.0.0.1:{port}")

        argv = [
            sys.executable,
            server_py,
            "--port",
            str(port),
            "--host",
            "127.0.0.1",
            "--sentinel",
            sentinel,
        ]

        p = util.ConnectedProcess().spawn(argv, sentinel=sentinel)
        import atexit

        def _shutdown():
            logger.info("terminate HELLO")
            with p:
                p.terminate()

        atexit.register(_shutdown)

    app.action(NAME, _register)
Exemple #15
0
def includeme(app: App) -> None:
    app.include(".tracker")

    actual: FSFactory = create_fs
    app.register_factory(NAME, actual)

    for_dry_run: FSFactory = create_dummy_fs
    app.register_dryurn_factory(NAME, for_dry_run)
Exemple #16
0
from egoist.app import App, SettingsDict, parse_args

settings: SettingsDict = {"rootdir": "cmd/", "here": __file__}
app = App(settings)

app.include("egoist.commands.generate")
app.include("egoist.directives.define_cli")


@app.define_cli("egoist.generators.clikit:walk")
def hello(*, name: str) -> None:
    """hello message"""
    from egoist.generators.clikit import runtime, clikit

    with runtime.generate(clikit):
        runtime.printf("hello %s\n", name)


if __name__ == "__main__":
    for argv in parse_args(sep="-"):
        app.run(argv)
Exemple #17
0
from egoist.app import App, SettingsDict

settings: SettingsDict = {"root": "cmd/", "here": __file__}
app = App(settings)

app.include("egoist.directives.define_cli")


@app.define_cli("egoist.generate.clikit:walk")
def hello(*, name: str) -> None:
    """hello message"""
    from egoist.generate.clikit import runtime, clikit

    with runtime.generate(clikit):
        runtime.printf("hello %s\n", name)


if __name__ == "__main__":
    app.run()
Exemple #18
0
def includeme(app: App) -> None:
    app.include("egoist.components.fs")
Exemple #19
0
from egoist.app import App, SettingsDict, parse_args

settings: SettingsDict = {"rootdir": "output", "here": __file__}
app = App(settings)

app.include("egoist.directives.define_file")


@app.define_file("egoist.generators.filekit:walk", suffix=".txt")
def hello() -> None:
    from egoist.generators.filekit import runtime

    with runtime.create_file() as wf:
        print("hello world", file=wf)


if __name__ == "__main__":
    for argv in parse_args(sep="-"):
        app.run(argv)
Exemple #20
0
from __future__ import annotations
import typing as t
from egoist.app import App

app = App(settings={"here": __file__, "rootdir": ""})
app.include("egoist.directives.define_struct_set")


@app.define_struct_set("egoist.generators.structkit:walk")  # type: ignore
def models__models() -> None:
    from egoist.generators.structkit import runtime, structkit
    import objects

    @runtime.set_metadata_handler
    def metadata_handler(cls: t.Type[t.Any], *, name: str, info: t.Any,
                         metadata: runtime.Metadata) -> None:
        """with form"""
        metadata["tags"] = {
            "json": [name.rstrip("_")],
            "form": [name.rstrip("_")]
        }

    with runtime.generate(structkit, classes=[objects.Person]) as m:
        m.package("models")


if __name__ == "__main__":
    app.run()
Exemple #21
0
def setup_server(app: App) -> None:
    from egoist.ext.serverprocess.lazyparams import find_free_port, create_sentinel_file

    app.include("egoist.ext.serverprocess")  # for add_server_process
Exemple #22
0
def includeme(app: App) -> None:
    app.register_factory(NAME, Tracker)
    app.register_dryurn_factory(NAME, Tracker)
Exemple #23
0
def includeme(app: App) -> None:
    app.include("egoist.components.tracker")
    app.include("egoist.directives.add_subcommand")
    app.include("egoist.commands.generate")
    app.add_subcommand(setup, fn=makegen)
Exemple #24
0
    def _define(
        app: App,
        fmt: str,
        *,
        name: str,
        urlfmt: str = "http://{host}:{port}",
        host: str = "127.0.0.1",
        port: t.Optional[t.Union[int, str]] = None,
        params: t.Optional[t.Dict[str, LazyParam]] = None,
        env: t.Optional[t.Dict[str, LazyParam]] = None,
        cwd: t.Union[str, pathlib.Path, None] = None,
        nowait: bool = False,
    ) -> None:
        app.include("egoist.experimental.serverprocess.components.discovery")
        app.include("egoist.experimental.serverprocess.components.httpclient")

        def _register() -> None:
            nonlocal host
            nonlocal port

            import shlex
            import atexit
            from .components.discovery import get_discovery
            from .lazyparams import find_free_port, create_sentinel_file

            if app.registry.dry_run:
                kwargs: t.Dict[str, t.Any] = {
                    k: "xxx"
                    for k in (params or {}).keys()
                }
                environ = {k: "xxx" for k in (env or {}).keys()}
                port = "xxx"
                sentinel = "xxx"
            else:
                kwargs = {k: fn(app) for k, fn in (params or {}).items()}
                environ = {k: fn(app) for k, fn in (env or {}).items()}

                if port is None:
                    port = (kwargs.get("port") or environ.get("port")
                            or environ.get("PORT") or find_free_port(app))
                elif "port" not in kwargs:
                    kwargs["port"] = port

                if "host" in kwargs:
                    host = kwargs["host"]
                elif "host" not in kwargs:
                    kwargs["host"] = host

                sentinel = (
                    # xxx
                    kwargs.get("sentinel") or environ.get("SENTINEL")
                    or ("" if nowait else create_sentinel_file(app)))

            argv = shlex.split(fmt.format(**kwargs))
            url = urlfmt.format(host=host, port=port)
            get_discovery().register(name, url=url)

            if app.registry.dry_run:
                logger.info("dry run, skip starting server process, %s", name)
                return

            from .spawn import spawn_with_connection

            p, _ = spawn_with_connection(argv,
                                         sentinel=sentinel,
                                         environ=environ,
                                         cwd=cwd,
                                         check=not nowait)

            def _shutdown() -> None:  # xxx:
                logger.info("terminate %s", name)
                with p:
                    p.terminate()

            atexit.register(_shutdown)

        app.action(("add_server_process", name), _register)
Exemple #25
0
def includeme(app: App) -> None:
    app.register_factory(NAME, Discovery)
    app.register_dryurn_factory(NAME, Discovery)
Exemple #26
0
from __future__ import annotations
import typing as t
from egoist.app import App, SettingsDict, parse_args
from egoist.generators.structkit.runtime import metadata, field
from egoist.generators.structkit.runtime import set_metadata_handler, Metadata

settings: SettingsDict = {"rootdir": "", "here": __file__}
app = App(settings)

app.include("egoist.directives.define_struct_set")
app.include("egoist.directives.define_cli")


class Author:
    name: str
    # createdAt: datetime.date


class Article:
    title: str
    author: t.Optional[Author]
    content: str
    comments: t.List[Comment] = field(metadata=metadata(required=False))


class Comment:
    author: Author
    content: str


@app.define_struct_set("egoist.generators.structkit:walk")
Exemple #27
0
def includeme(app: App) -> None:
    app.include("egoist.directives.add_subcommand")
    app.add_subcommand(setup, fn=hello)
Exemple #28
0
def hello(app: App) -> None:
    app.commit(dry_run=False)
    print("do something")
Exemple #29
0
@directive(name="define_foo", requires=["egoist.commands.describe"])
def define_foo(app: App, fn: AnyFunction, name: str) -> AnyFunction:
    """*** define foo ***"""
    print(app, fn, "foo", name)

    def _register():
        print("!")

    app.registry.generators[name].append(fn)
    app.action(fn.__name__, _register)
    return fn


if __name__ == "__main__":
    app = App()
    app.include("__main__.define_foo")

    @app.define_foo("xxx")
    def yyy():
        print("yyy")

    @app.define_foo("xxx")
    def zzz():
        print("zzz")

    print("s")
    app.commit()
    yyy()
    zzz()
    print("e")
Exemple #30
0
def includeme(app: App) -> None:
    app.register_factory(NAME, _create_http_client)
    app.register_dryurn_factory(NAME, _create_fake_http_client)