| # Copyright 2016 gRPC authors. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| import os |
| import pkg_resources |
| import sys |
| import tempfile |
| |
| import setuptools |
| |
| from grpc_tools import protoc |
| |
| _WELL_KNOWN_PROTOS_INCLUDE = pkg_resources.resource_filename( |
| 'grpc_tools', '_proto') |
| |
| |
| def _compile_proto(proto_file, |
| include='', |
| python_out='', |
| grpc_python_out='', |
| strict=False): |
| command = [ |
| 'grpc_tools.protoc', |
| '--proto_path={}'.format(include), |
| '--proto_path={}'.format(_WELL_KNOWN_PROTOS_INCLUDE), |
| '--python_out={}'.format(python_out), |
| '--grpc_python_out={}'.format(grpc_python_out), |
| ] + [proto_file] |
| if protoc.main(command) != 0: |
| if strict: |
| sys.stderr.write('error: {} failed'.format(command)) |
| else: |
| sys.stderr.write('warning: {} failed'.format(command)) |
| return False |
| return True |
| |
| |
| def build_package_protos(package_root): |
| proto_files = [] |
| inclusion_root = os.path.abspath(package_root) |
| for root, _, files in os.walk(inclusion_root): |
| for filename in files: |
| if filename.endswith('.proto'): |
| proto_files.append( |
| os.path.abspath(os.path.join(root, filename))) |
| |
| for proto_file in proto_files: |
| _compile_proto( |
| proto_file, |
| include=inclusion_root, |
| python_out=inclusion_root, |
| grpc_python_out=inclusion_root, |
| strict=False, |
| ) |
| |
| |
| def build_package_protos_strict(package_root): |
| proto_files = [] |
| inclusion_root = os.path.abspath(package_root) |
| for root, _, files in os.walk(inclusion_root): |
| for filename in files: |
| if filename.endswith('.proto'): |
| proto_files.append( |
| os.path.abspath(os.path.join(root, filename))) |
| |
| tmp_out_directory = tempfile.mkdtemp() |
| compile_failed = False |
| for proto_file in proto_files: |
| # Output all the errors across all the files instead of exiting on the |
| # first error proto file. |
| compile_failed |= not _compile_proto( |
| proto_file, |
| include=inclusion_root, |
| python_out=tmp_out_directory, |
| grpc_python_out=tmp_out_directory, |
| strict=True, |
| ) |
| |
| if compile_failed: |
| sys.exit(1) |
| |
| for proto_file in proto_files: |
| _compile_proto( |
| proto_file, |
| include=inclusion_root, |
| python_out=inclusion_root, |
| grpc_python_out=inclusion_root, |
| strict=False, |
| ) |
| |
| |
| class BuildPackageProtos(setuptools.Command): |
| """Command to generate project *_pb2.py modules from proto files.""" |
| |
| description = 'build grpc protobuf modules' |
| user_options = [] |
| |
| def initialize_options(self): |
| pass |
| |
| def finalize_options(self): |
| pass |
| |
| def run(self): |
| # due to limitations of the proto generator, we require that only *one* |
| # directory is provided as an 'include' directory. We assume it's the '' key |
| # to `self.distribution.package_dir` (and get a key error if it's not |
| # there). |
| build_package_protos(self.distribution.package_dir['']) |
| |
| |
| class BuildPackageProtosStrict(setuptools.Command): |
| """Command to strictly generate project *_pb2.py modules from proto files. |
| |
| The generation will abort if any of the proto files contains error. |
| """ |
| |
| description = 'strictly build grpc protobuf modules' |
| user_options = [] |
| |
| def initialize_options(self): |
| pass |
| |
| def finalize_options(self): |
| pass |
| |
| def run(self): |
| # due to limitations of the proto generator, we require that only *one* |
| # directory is provided as an 'include' directory. We assume it's the '' key |
| # to `self.distribution.package_dir` (and get a key error if it's not |
| # there). |
| build_package_protos_strict(self.distribution.package_dir['']) |