Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor to support the finalized-ish input format. #6

Merged
merged 22 commits into from
Jul 13, 2018
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ workflows:
version: 2
tests:
jobs:
- unit
- unit-3.6
- unit-3.7
- docs
jobs:
unit:
unit-3.6:
docker:
- image: 'python:3.6'
steps:
Expand All @@ -17,7 +18,22 @@ jobs:
command: pip install nox-automation codecov
- run:
name: Run unit tests.
command: nox -s unit
command: nox -s "unit(python_version='3.6')"
- run:
name: Submit coverage data to codecov.
command: codecov
when: always
unit-3.7:
docker:
- image: 'python:3.7'
steps:
- checkout
- run:
name: Install nox and codecov.
command: pip install nox-automation codecov
- run:
name: Run unit tests.
command: nox -s "unit(python_version='3.7')"
- run:
name: Submit coverage data to codecov.
command: codecov
Expand Down
8 changes: 8 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[flake8]
ignore =
# Closing bracket mismatches opening bracket's line.
# This works poorly with type annotations in method declarations.
E123, E124
# Line over-indented for visual indent.
# This works poorly with type annotations in method declarations.
E128
24 changes: 0 additions & 24 deletions Pipfile

This file was deleted.

115 changes: 0 additions & 115 deletions Pipfile.lock

This file was deleted.

23 changes: 20 additions & 3 deletions api_factory/cli/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import sys
import typing

Expand All @@ -20,6 +21,7 @@
from google.protobuf.compiler import plugin_pb2

from api_factory import generator
from api_factory.schema import api


@click.command()
Expand All @@ -38,9 +40,24 @@ def generate(
# Load the protobuf CodeGeneratorRequest.
req = plugin_pb2.CodeGeneratorRequest.FromString(request.read())

# Translate into a protobuf CodeGeneratorResponse;
# if there are issues, error out appropriately.
res = generator.Generator(req).get_response()
# Determine the appropriate package.
# This generator uses a slightly different mechanism for determining
# which files to generate; it tracks at package level rather than file
# level.
package = os.path.commonprefix([i.package for i in filter(
lambda p: p.name in req.file_to_generate,
req.proto_file,
)]).rstrip('.')

# Build the API model object.
# This object is a frozen representation of the whole API, and is sent
# to each template in the rendering step.
api_schema = api.API.build(req.proto_file, package=package)

# Translate into a protobuf CodeGeneratorResponse; this reads the
# individual templates and renders them.
# If there are issues, error out appropriately.
res = generator.Generator(api_schema=api_schema).get_response()

# Output the serialized response.
output.write(res.SerializeToString())
6 changes: 0 additions & 6 deletions api_factory/generator/files/.flake8

This file was deleted.

4 changes: 0 additions & 4 deletions api_factory/generator/files/MANIFEST.in

This file was deleted.

2 changes: 0 additions & 2 deletions api_factory/generator/files/setup.cfg

This file was deleted.

52 changes: 8 additions & 44 deletions api_factory/generator/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
from google.protobuf.compiler.plugin_pb2 import CodeGeneratorRequest
from google.protobuf.compiler.plugin_pb2 import CodeGeneratorResponse

from api_factory.schema.api import API
from api_factory.generator.loader import TemplateLoader
from api_factory import utils
from api_factory.generator.loader import TemplateLoader
from api_factory.schema import api


class Generator:
Expand All @@ -40,15 +40,12 @@ class Generator:
request (CodeGeneratorRequest): A request protocol buffer as provided
by protoc. See ``plugin.proto``.
"""
def __init__(self, request: CodeGeneratorRequest) -> None:
# Parse the CodeGeneratorRequest into this plugin's internal schema.
self._api = API()
for fdp in request.proto_file:
self._api.load(fdp)
def __init__(self, api_schema: api.API) -> None:
self._api = api_schema

# Create the jinja environment with which to render templates.
self._env = jinja2.Environment(loader=TemplateLoader(
searchpath=os.path.join(_dirname, 'templates'),
searchpath=os.path.join(_dirname, '..', 'templates'),
))

# Add filters which templates require.
Expand Down Expand Up @@ -80,13 +77,6 @@ def get_response(self) -> CodeGeneratorResponse:
additional_context={'service': service},
)

# Some files are direct files and not templates; simply read them
# into output files directly.
#
# Rather than expect an enumeration of these, we simply grab everything
# in the `files/` directory automatically.
output_files += self._read_flat_files(os.path.join(_dirname, 'files'))

# Return the CodeGeneratorResponse output.
return CodeGeneratorResponse(file=output_files)

Expand Down Expand Up @@ -132,32 +122,6 @@ def _render_templates(
# Done; return the File objects based on these templates.
return answer

def _read_flat_files(
self,
target_dir: str,
) -> Sequence[CodeGeneratorResponse.File]:
answer = []

# Iterate over all files in the directory.
for path, _, filenames in os.walk(target_dir):
relative_path = path[len(target_dir):]
for filename in filenames:
# Determine the "relative filename" (the filename against the
# files/ subdirectory and repository root).
relative_filename = filename
if relative_path:
relative_filename = os.path.join(relative_path, filename)

# Read the file from disk and create an appropriate OutputFile.
with io.open(os.path.join(path, filename), 'r') as f:
answer.append(CodeGeneratorResponse.File(
content=f.read(),
name=relative_filename,
))

# Done; return the File objects.
return answer

def _get_output_filename(
self,
template_name: str, *,
Expand Down Expand Up @@ -187,13 +151,13 @@ def _get_output_filename(
# Replace the $namespace variable.
filename = filename.replace(
'$namespace',
'/'.join([i.lower() for i in self._api.client.namespace]),
'/'.join([i.lower() for i in self._api.naming.namespace]),
).lstrip('/')

# Replace the $name and $version variables.
filename = filename.replace('$name_$version',
self._api.versioned_module_name)
filename = filename.replace('$name', self._api.module_name)
self._api.naming.versioned_module_name)
filename = filename.replace('$name', self._api.naming.module_name)

# Replace the $service variable if applicable.
if context and 'service' in context:
Expand Down
29 changes: 0 additions & 29 deletions api_factory/generator/templates/README.rst.j2

This file was deleted.

Loading