Skip to content

Commit 81e1a58

Browse files
Pluggable templates (#20)
1 parent e097230 commit 81e1a58

File tree

3 files changed

+34
-19
lines changed

3 files changed

+34
-19
lines changed

packages/gapic-generator/gapic/cli/generate.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,14 @@
3232
@click.option('--output', type=click.File('wb'), default=sys.stdout.buffer,
3333
help='Where to output the `CodeGeneratorResponse`. '
3434
'Defaults to stdout.')
35+
@click.option('--templates', type=click.Path(exists=True), default=None,
36+
help='Which templates to use to generate a library. '
37+
'Defaults to the templates included in gapic-generator, '
38+
'which generate client libraries for Python 3.4 and up.')
3539
def generate(
3640
request: typing.BinaryIO,
37-
output: typing.BinaryIO) -> None:
41+
output: typing.BinaryIO,
42+
templates: str = None) -> None:
3843
"""Generate a full API client description."""
3944

4045
# Load the protobuf CodeGeneratorRequest.
@@ -57,7 +62,7 @@ def generate(
5762
# Translate into a protobuf CodeGeneratorResponse; this reads the
5863
# individual templates and renders them.
5964
# If there are issues, error out appropriately.
60-
res = generator.Generator(api_schema=api_schema).get_response()
65+
res = generator.Generator(api_schema, templates=templates).get_response()
6166

6267
# Output the serialized response.
6368
output.write(res.SerializeToString())

packages/gapic-generator/gapic/generator/generator.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,11 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
import io
1615
import os
1716
from typing import Any, Iterable, Mapping, Sequence
1817

1918
import jinja2
2019

21-
from google.protobuf.compiler.plugin_pb2 import CodeGeneratorRequest
2220
from google.protobuf.compiler.plugin_pb2 import CodeGeneratorResponse
2321

2422
from gapic import utils
@@ -30,25 +28,32 @@
3028
class Generator:
3129
"""A protoc code generator for client libraries.
3230
33-
This class receives a :class:`~.plugin_pb2.CodeGeneratorRequest` (as per
34-
the protoc plugin contract), and provides an interface for getting
35-
a :class:`~.plugin_pb2.CodeGeneratorResponse`.
36-
37-
That request with one or more protocol buffers which collectively
38-
describe an API.
31+
This class receives a :class:`~.api.API`, a representation of the API
32+
schema, and provides an interface for getting a
33+
:class:`~.plugin_pb2.CodeGeneratorResponse` (which it does through
34+
rendering templates).
3935
4036
Args:
41-
request (CodeGeneratorRequest): A request protocol buffer as provided
42-
by protoc. See ``plugin.proto``.
37+
api_schema (~.API): An API schema object, which is sent to every
38+
template as the ``api`` variable.
39+
templates (str): Optional. Path to the templates to be
40+
rendered. If this is not provided, the templates included with
41+
this application are used.
4342
"""
44-
def __init__(self, api_schema: api.API) -> None:
43+
def __init__(self, api_schema: api.API, *,
44+
templates: str = None) -> None:
4545
self._api = api_schema
4646

47+
# If explicit templates were not provided, use our default.
48+
if not templates:
49+
templates = os.path.join(
50+
os.path.realpath(os.path.dirname(__file__)),
51+
'..', 'templates',
52+
)
53+
4754
# Create the jinja environment with which to render templates.
4855
self._env = jinja2.Environment(
49-
loader=loader.TemplateLoader(
50-
searchpath=os.path.join(_dirname, '..', 'templates'),
51-
),
56+
loader=loader.TemplateLoader(searchpath=templates),
5257
undefined=jinja2.StrictUndefined,
5358
)
5459

@@ -173,9 +178,6 @@ def _get_output_filename(
173178
return filename
174179

175180

176-
_dirname = os.path.realpath(os.path.dirname(__file__))
177-
178-
179181
__all__ = (
180182
'Generator',
181183
)

packages/gapic-generator/tests/unit/generator/test_generator.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ def test_constructor():
4141
assert 'wrap' in g._env.filters
4242

4343

44+
def test_custom_template_directory():
45+
# Create a generator.
46+
g = generator.Generator(api_schema=make_api(), templates='/templates/')
47+
48+
# Assert that the Jinja loader will pull from the correct location.
49+
assert g._env.loader.searchpath == ['/templates/']
50+
51+
4452
def test_get_response():
4553
# Create a generator with mock data.
4654
#

0 commit comments

Comments
 (0)