Skip to content

Commit dd77fb1

Browse files
committed
libs: Add envoy.docs.abstract
Signed-off-by: Ryan Northey <[email protected]>
1 parent c89b741 commit dd77fb1

File tree

22 files changed

+1586
-3
lines changed

22 files changed

+1586
-3
lines changed

README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ pypi: https://pypi.org/project/envoy.base.runner
109109

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

112-
version: 0.0.9
112+
version: 0.0.10.dev0
113113

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

@@ -236,6 +236,23 @@ pypi: https://pypi.org/project/envoy.docker.utils
236236
---
237237

238238

239+
#### [envoy.docs.abstract](envoy.docs.abstract)
240+
241+
version: 0.0.1
242+
243+
pypi: https://pypi.org/project/envoy.docs.abstract
244+
245+
##### requirements:
246+
247+
- [abstracts](https://pypi.org/project/abstracts)
248+
- [envoy.base.runner](https://pypi.org/project/envoy.base.runner)
249+
- [envoy.base.utils](https://pypi.org/project/envoy.base.utils) >=0.0.9
250+
- [jinja2](https://pypi.org/project/jinja2)
251+
- [protobuf](https://pypi.org/project/protobuf)
252+
253+
---
254+
255+
239256
#### [envoy.docs.sphinx_runner](envoy.docs.sphinx_runner)
240257

241258
version: 0.0.4.dev0

deps/requirements.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ docutils~=0.16.0
1212
envoy.abstract.command>=0.0.3
1313
envoy.base.checker>=0.0.2
1414
envoy.base.runner>=0.0.4
15-
envoy.base.utils>=0.0.8
15+
envoy.base.utils>=0.0.9
1616
envoy.code_format.python_check>=0.0.4
1717
envoy.dependency.pip_check>=0.0.4
1818
envoy.distribution.distrotest>=0.0.3
@@ -27,6 +27,7 @@ envoy.gpg.sign>=0.0.3
2727
flake8
2828
frozendict
2929
gidgethub
30+
protobuf
3031
jinja2
3132
mypy
3233
mypy-abstracts
@@ -44,6 +45,7 @@ sphinxcontrib-httpdomain
4445
sphinxcontrib-serializinghtml
4546
sphinxext-rediraffe
4647
trycast
48+
types-protobuf
4749
types-setuptools
4850
verboselogs
4951
wheel-inspect

envoy.base.utils/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.0.9
1+
0.0.10-dev

envoy.docs.abstract/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
pytooling_package("envoy.docs.abstract")

envoy.docs.abstract/README.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
envoy.docs.abstract
3+
===================
4+
5+
Abstract RST classes and utils used in Envoy proxy's CI

envoy.docs.abstract/VERSION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0.0.1
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
pytooling_library(
3+
"envoy.docs.abstract",
4+
dependencies=[
5+
"//deps:abstracts",
6+
"//deps:envoy.base.utils",
7+
"//deps:envoy.base.runner",
8+
"//deps:protobuf",
9+
"//deps:jinja2",
10+
],
11+
)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
2+
from .api import (
3+
AAPIDocsBuilder,
4+
APIFilesGenerator,
5+
EmptyExtensionsDict,
6+
ExtensionDetailsDict)
7+
from .builder import ADocsBuilder
8+
from .deps import ADependenciesDocsBuilder, RepositoryLocationsDict
9+
from .exceptions import RSTFormatterError
10+
from .extensions import (
11+
AExtensionsDocsBuilder, ExtensionsMetadataDict,
12+
ExtensionSecurityPosturesDict)
13+
from .formatter import ARSTFormatter, AProtobufRSTFormatter
14+
from .runner import ADocsBuildingRunner, BuildersDict
15+
16+
17+
__all__ = (
18+
"AAPIDocsBuilder",
19+
"ADependenciesDocsBuilder",
20+
"AExtensionsDocsBuilder",
21+
"ADocsBuilder",
22+
"ADocsBuildingRunner",
23+
"APIFilesGenerator",
24+
"AProtobufRSTFormatter",
25+
"ARSTFormatter",
26+
"BuildersDict",
27+
"EmptyExtensionsDict",
28+
"ExtensionDetailsDict",
29+
"ExtensionSecurityPosturesDict",
30+
"ExtensionsMetadataDict",
31+
"RepositoryLocationsDict",
32+
"RSTFormatterError")
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
2+
import abc
3+
import pathlib
4+
import string
5+
import tarfile
6+
from functools import cached_property
7+
from typing import Dict, Generator, Optional, Tuple, Union
8+
9+
import abstracts
10+
11+
from .builder import ADocsBuilder
12+
from .formatter import ARSTFormatter
13+
14+
15+
APIFilesGenerator = Generator[Tuple[str, bytes], None, None]
16+
EmptyExtensionsDict = Dict[pathlib.Path, Union[str, bytes]]
17+
ExtensionDetailsDict = Dict[str, str]
18+
19+
EMPTY_EXTENSION_DOCS_TEMPLATE = string.Template(
20+
"""$header
21+
22+
$description
23+
24+
$reflink
25+
26+
This extension does not have a structured configuration, `google.protobuf.Empty
27+
<https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#empty>`_
28+
should be used instead.
29+
30+
$extension
31+
""")
32+
33+
34+
class AAPIDocsBuilder(ADocsBuilder, metaclass=abstracts.Abstraction):
35+
36+
@cached_property
37+
def api_extensions_root(self) -> pathlib.PurePosixPath:
38+
return self.api_root.joinpath("config")
39+
40+
@property
41+
def api_files(self) -> APIFilesGenerator:
42+
with tarfile.open(self._api_files) as tar:
43+
for member in tar.getmembers():
44+
if member.isdir():
45+
continue
46+
path = self.normalize_proto_path(member.path)
47+
if path:
48+
content = tar.extractfile(member)
49+
if content:
50+
yield path, content.read()
51+
52+
@cached_property
53+
def api_root(self) -> pathlib.PurePosixPath:
54+
return pathlib.PurePosixPath("api-v3")
55+
56+
@property
57+
@abc.abstractmethod
58+
def empty_extensions(self) -> EmptyExtensionsDict:
59+
raise NotImplementedError
60+
61+
@property
62+
def empty_extension_template(self) -> string.Template:
63+
return EMPTY_EXTENSION_DOCS_TEMPLATE
64+
65+
@property
66+
@abc.abstractmethod
67+
def rst_formatter(self) -> ARSTFormatter:
68+
raise NotImplementedError
69+
70+
@property
71+
@abc.abstractmethod
72+
def v3_proto_rst(self) -> Tuple[str, ...]:
73+
raise NotImplementedError
74+
75+
async def build(self) -> None:
76+
for path, content in self.api_files:
77+
self.out(
78+
self.api_root.joinpath(path),
79+
content)
80+
for empty_path, empty_content in self.empty_extensions.items():
81+
self.out(
82+
self.api_extensions_root.joinpath(empty_path),
83+
empty_content)
84+
85+
def canonical(self, path: str) -> str:
86+
if path.startswith("contrib/"):
87+
path = path[8:]
88+
if path.startswith("envoy/"):
89+
path = path[6:]
90+
return path
91+
92+
def format_ref(self, ref):
93+
return self.rst_formatter.internal_link(
94+
"configuration overview", ref)
95+
96+
def get_reflink(self, title: str, ref: Optional[str]) -> str:
97+
return (
98+
f"{title} {self.format_ref(ref)} ."
99+
if ref
100+
else "")
101+
102+
def normalize_proto_path(self, path) -> Optional[str]:
103+
if "/pkg/" not in path:
104+
return None
105+
path = path.split('/pkg/')[1]
106+
if path in self.v3_proto_rst:
107+
return self.canonical(path)
108+
109+
def render_empty_extension(
110+
self,
111+
extension: str,
112+
details: ExtensionDetailsDict) -> str:
113+
return self.empty_extension_template.substitute(
114+
header=self.rst_formatter.header(details['title'], "="),
115+
description=details.get('description', ''),
116+
reflink=self.get_reflink(details["title"], details.get("ref")),
117+
extension=self.rst_formatter.extension(extension))
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
import abstracts
3+
4+
5+
class ADocsBuilder(metaclass=abstracts.Abstraction):
6+
7+
def __init__(self, out, api_files) -> None:
8+
self.out = out
9+
self._api_files = api_files

0 commit comments

Comments
 (0)