Skip to content

Commit

Permalink
envoy.base.utils: Add protoc worker protocol
Browse files Browse the repository at this point in the history
Signed-off-by: Ryan Northey <[email protected]>
  • Loading branch information
phlax committed Jun 15, 2022
1 parent 19ef9fb commit 5d9601e
Show file tree
Hide file tree
Showing 11 changed files with 408 additions and 43 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,15 +124,16 @@ pypi: https://pypi.org/project/aio.run.runner

#### [envoy.base.utils](envoy.base.utils)

version: 0.3.7.dev0
version: 0.3.7

pypi: https://pypi.org/project/envoy.base.utils

##### requirements:

- [abstracts](https://pypi.org/project/abstracts) >=0.0.12
- [aio.api.bazel](https://pypi.org/project/aio.api.bazel) >=0.0.2
- [aio.api.github](https://pypi.org/project/aio.api.github) >=0.1.2
- [aio.core](https://pypi.org/project/aio.core) >=0.8.6
- [aio.core](https://pypi.org/project/aio.core) >=0.8.9
- [aio.run.runner](https://pypi.org/project/aio.run.runner) >=0.3.3
- [aiohttp](https://pypi.org/project/aiohttp) >=3.8.1
- [frozendict](https://pypi.org/project/frozendict)
Expand Down
2 changes: 1 addition & 1 deletion envoy.base.utils/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.3.7-dev
0.3.7
3 changes: 2 additions & 1 deletion envoy.base.utils/envoy/base/utils/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ pytooling_library(
"envoy.base.utils",
dependencies=[
"//deps:abstracts",
"//deps:aio.core",
"//deps:aio.api.bazel",
"//deps:aio.api.github",
"//deps:aio.core",
"//deps:aio.run.runner",
"//deps:aiohttp",
"//deps:frozendict",
Expand Down
25 changes: 23 additions & 2 deletions envoy.base.utils/envoy/base/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,23 @@
is_sha,
tar_mode,
last_n_bytes_of)
from . import interface, typing
from . import abstract, interface, typing
from .abstract import (
AChangelog,
AChangelogEntry,
AChangelogs,
AInventories,
AProject,
AProtobufSet,
AProtobufValidator,
AProtocProtocol)

from .parallel_cmd import parallel_cmd
from .parallel_runner import ParallelRunner
from .project import Changelog, ChangelogEntry, Changelogs, Project
from .project_cmd import project_cmd
from .project_runner import ProjectRunner
from .protobuf import ProtobufSet, ProtobufValidator
from .protobuf import ProtobufSet, ProtobufValidator, ProtocProtocol
from .interface import IProject
from .data_env import DataEnvironment
from .data_env_cmd import data_env_cmd
Expand All @@ -36,7 +46,17 @@


__all__ = (
"abstract",
"AChangelog",
"AChangelogEntry",
"AChangelogs",
"AInventories",
"AProject",
"AProtobufSet",
"AProtobufValidator",
"AProtocProtocol",
"async_list",
"bazel_worker_cmd",
"cd_and_return",
"Changelog",
"ChangelogEntry",
Expand Down Expand Up @@ -67,6 +87,7 @@
"project_cmd",
"ProtobufSet",
"ProtobufValidator",
"ProtocProtocol",
"typed",
"untar",
"TAR_EXTS",
Expand Down
8 changes: 6 additions & 2 deletions envoy.base.utils/envoy/base/utils/abstract/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
AChangelogs,
AInventories,
AProject)
from .protobuf import AProtobufSet, AProtobufValidator
from .protobuf import (
AProtobufSet,
AProtobufValidator,
AProtocProtocol)

__all__ = (
"AChangelog",
Expand All @@ -14,4 +17,5 @@
"AInventories",
"AProject",
"AProtobufSet",
"AProtobufValidator")
"AProtobufValidator",
"AProtocProtocol")
88 changes: 82 additions & 6 deletions envoy.base.utils/envoy/base/utils/abstract/protobuf.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@

import argparse
import importlib
import json
import pathlib
from functools import cached_property, lru_cache
from typing import Callable, Type
from typing import Callable, Dict, Type

from google.protobuf import descriptor, descriptor_pb2
from google.protobuf import descriptor_pool as _descriptor_pool
Expand All @@ -14,6 +15,9 @@

import abstracts

from aio.api import bazel
from aio.core.utils import dottedname_resolve

from envoy.base.utils import interface


Expand All @@ -32,19 +36,23 @@ def _yaml():
return _envoy_yaml


@abstracts.implementer(interface.IProtobufSet)
class AProtobufSet(metaclass=abstracts.Abstraction):

def __init__(self, descriptor_path: str | pathlib.Path) -> None:
self._descriptor_path = descriptor_path

def __getitem__(self, name: str) -> descriptor_pb2.FileDescriptorProto:
return self.source_files[name]

@cached_property
def descriptor_path(self) -> pathlib.Path:
return pathlib.Path(self._descriptor_path)

@cached_property
def descriptor_pool(self) -> _descriptor_pool.DescriptorPool:
pool = _descriptor_pool.DescriptorPool()
for f in self.descriptor_set.file:
for f in self.source_files.values():
pool.Add(f)
return pool

Expand All @@ -54,7 +62,21 @@ def descriptor_set(self) -> descriptor_pb2.FileDescriptorSet:
descriptor.ParseFromString(self.descriptor_path.read_bytes())
return descriptor

@cached_property
def source_files(self) -> Dict[str, descriptor_pb2.FileDescriptorProto]:
return {
f.name: f
for f
in self.descriptor_set.file}

def find_file(self, type_name: str) -> descriptor.Descriptor:
return self.descriptor_pool.FindFileByName(type_name)

def find_message(self, type_name: str) -> descriptor.Descriptor:
return self.descriptor_pool.FindMessageTypeByName(type_name)


@abstracts.implementer(interface.IProtobufValidator)
class AProtobufValidator(metaclass=abstracts.Abstraction):

def __init__(self, descriptor_path: str | pathlib.Path) -> None:
Expand All @@ -81,17 +103,15 @@ def protobuf_set_class(self) -> Type[interface.IProtobufSet]:
def yaml(self):
return _yaml()

def find_message(self, type_name: str) -> descriptor.Descriptor:
return self.descriptor_pool.FindMessageTypeByName(type_name)

@lru_cache
def message(self, type_name: str) -> _message.Message:
return self.message_prototype(type_name)()

def message_prototype(
self,
type_name: str) -> Callable[[], _message.Message]:
return self.message_factory.GetPrototype(self.find_message(type_name))
return self.message_factory.GetPrototype(
self.protobuf_set.find_message(type_name))

def validate_fragment(
self,
Expand All @@ -113,3 +133,59 @@ def validate_yaml(
fragment: str,
type_name: str = BOOTSTRAP_PROTO) -> None:
self.validate_fragment(self.yaml.safe_load(fragment), type_name)


@abstracts.implementer(bazel.IBazelProcessProtocol)
class AProtocProtocol(
bazel.ABazelProcessProtocol,
metaclass=abstracts.Abstraction):

@classmethod
def add_protocol_arguments(cls, parser: argparse.ArgumentParser) -> None:
parser.add_argument("descriptor_set")
parser.add_argument("traverser")
parser.add_argument("plugin")

@property
def descriptor_set(self) -> str:
return self.args.descriptor_set

@cached_property
def plugin(self) -> Callable:
return dottedname_resolve(f"{self.args.plugin}.main")()

@cached_property
def proto_set(self) -> interface.IProtobufSet:
return self.proto_set_class(
pathlib.Path(self.descriptor_set).absolute())

@property # type:ignore
@abstracts.interfacemethod
def proto_set_class(self) -> Type[interface.IProtobufSet]:
raise NotImplementedError

@cached_property
def traverser(self) -> Callable:
return dottedname_resolve(self.args.traverser)

def parse_request(
self,
request: argparse.Namespace) -> Dict[str, pathlib.Path]:
return dict(
zip(vars(request)["in"].split(","),
(pathlib.Path(p)
for p
in request.out.split(","))))

async def process(self, request: argparse.Namespace) -> None:
for infile, outfile in self.parse_request(request).items():
self._process_item(infile, outfile)

def _output(self, infile: str) -> str:
return self.traverser(
self.proto_set[infile],
self.plugin())

def _process_item(self, infile: str, outfile: pathlib.Path) -> None:
outfile.parent.mkdir(exist_ok=True, parents=True)
outfile.write_text(self._output(infile))
32 changes: 29 additions & 3 deletions envoy.base.utils/envoy/base/utils/interface.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,58 @@

import pathlib
from typing import (
AsyncGenerator, ItemsView, Iterator, KeysView, List,
AsyncGenerator, Dict, ItemsView, Iterator, KeysView, List,
Optional, Set, Tuple, Type, Union, ValuesView)

import aiohttp
from google.protobuf import descriptor_pool
from google.protobuf import (
descriptor,
descriptor_pool,
descriptor_pb2)
from packaging import version as _version

import abstracts

from aio.api import github as _github
from aio.api import bazel, github as _github
from aio.core import directory as _directory, event

from envoy.base.utils import typing


class IProtocProtocol(
bazel.IBazelProcessProtocol,
metaclass=abstracts.Interface):
pass


class IProtobufSet(metaclass=abstracts.Interface):

@abstracts.interfacemethod
def __init__(self, descriptor_path: str | pathlib.Path) -> None:
raise NotImplementedError

@abstracts.interfacemethod
def __getitem__(self, name: str) -> descriptor_pb2.FileDescriptorProto:
raise NotImplementedError

@property # type:ignore
@abstracts.interfacemethod
def descriptor_pool(self) -> descriptor_pool.DescriptorPool:
raise NotImplementedError

@property # type:ignore
@abstracts.interfacemethod
def source_files(self) -> Dict[str, descriptor_pb2.FileDescriptorProto]:
raise NotImplementedError

@abstracts.interfacemethod
def find_file(self, type_name: str) -> descriptor.Descriptor:
raise NotImplementedError

@abstracts.interfacemethod
def find_message(self, type_name: str) -> descriptor.Descriptor:
raise NotImplementedError


class IProtobufValidator(metaclass=abstracts.Interface):

Expand Down
12 changes: 12 additions & 0 deletions envoy.base.utils/envoy/base/utils/protobuf.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@

import sys
from typing import Type

import abstracts

from envoy.base.utils import abstract, interface


sys.path = [p for p in sys.path if not p.endswith('bazel_tools')]


@abstracts.implementer(interface.IProtobufSet)
class ProtobufSet(abstract.AProtobufSet):
pass
Expand All @@ -17,3 +21,11 @@ class ProtobufValidator(abstract.AProtobufValidator):
@property
def protobuf_set_class(self) -> Type[interface.IProtobufSet]:
return ProtobufSet


@abstracts.implementer(interface.IProtocProtocol)
class ProtocProtocol(abstract.AProtocProtocol):

@property
def proto_set_class(self):
return ProtobufSet
3 changes: 2 additions & 1 deletion envoy.base.utils/setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ py_modules = envoy.base.utils
packages = find_namespace:
install_requires =
abstracts>=0.0.12
aio.core>=0.8.6
aio.core>=0.8.9
aio.api.bazel>=0.0.2
aio.api.github>=0.1.2
aio.run.runner>=0.3.3
aiohttp>=3.8.1
Expand Down
1 change: 1 addition & 0 deletions envoy.base.utils/tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pytooling_tests(
dependencies=[
":data",
"//deps:abstracts",
"//deps:aio.api.bazel",
"//deps:aio.core",
"//deps:aio.run.runner",
"//deps:pyyaml",
Expand Down
Loading

0 comments on commit 5d9601e

Please sign in to comment.