From ebf81e7a0540a01079ac03661426cd3771664de7 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Wed, 1 Jun 2016 15:57:20 -0700 Subject: [PATCH] Add programmatic access to protoc in grpcio-tools --- ...otoc_compiler.pyx => _protoc_compiler.pyx} | 0 .../python/grpcio_tools/grpc/tools/command.py | 70 +++++++++++++++++++ .../python/grpcio_tools/grpc/tools/protoc.py | 13 +++- tools/distrib/python/grpcio_tools/setup.py | 4 +- 4 files changed, 82 insertions(+), 5 deletions(-) rename tools/distrib/python/grpcio_tools/grpc/tools/{protoc_compiler.pyx => _protoc_compiler.pyx} (100%) create mode 100644 tools/distrib/python/grpcio_tools/grpc/tools/command.py diff --git a/tools/distrib/python/grpcio_tools/grpc/tools/protoc_compiler.pyx b/tools/distrib/python/grpcio_tools/grpc/tools/_protoc_compiler.pyx similarity index 100% rename from tools/distrib/python/grpcio_tools/grpc/tools/protoc_compiler.pyx rename to tools/distrib/python/grpcio_tools/grpc/tools/_protoc_compiler.pyx diff --git a/tools/distrib/python/grpcio_tools/grpc/tools/command.py b/tools/distrib/python/grpcio_tools/grpc/tools/command.py new file mode 100644 index 00000000000..ccf38b7d569 --- /dev/null +++ b/tools/distrib/python/grpcio_tools/grpc/tools/command.py @@ -0,0 +1,70 @@ +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os +import sys + +import setuptools + +from grpc.tools import protoc + + +class BuildProtoModules(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). + proto_files = [] + inclusion_root = os.path.abspath(self.distribution.package_dir['']) + 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: + command = [ + 'grpc.tools.protoc', + '--proto_path={}'.format(inclusion_root), + '--python_out={}'.format(inclusion_root), + '--grpc_python_out={}'.format(inclusion_root), + ] + [proto_file] + if protoc.main(command) != 0: + sys.stderr.write('warning: {} failed'.format(command)) diff --git a/tools/distrib/python/grpcio_tools/grpc/tools/protoc.py b/tools/distrib/python/grpcio_tools/grpc/tools/protoc.py index 1c69e78920c..931fda27d26 100644 --- a/tools/distrib/python/grpcio_tools/grpc/tools/protoc.py +++ b/tools/distrib/python/grpcio_tools/grpc/tools/protoc.py @@ -32,10 +32,17 @@ import pkg_resources import sys -from grpc.tools import protoc_compiler +from grpc.tools import _protoc_compiler +def main(command_arguments): + """Run the protocol buffer compiler with the given command-line arguments. + + Args: + command_arguments: a list of strings representing command line arguments to + `protoc`. + """ + return _protoc_compiler.run_main(command_arguments) if __name__ == '__main__': proto_include = pkg_resources.resource_filename('grpc.tools', '_proto') - protoc_compiler.run_main( - sys.argv + ['-I{}'.format(proto_include)]) + sys.exit(main(sys.argv + ['-I{}'.format(proto_include)])) diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py index f9cb0534d54..afb6063906e 100644 --- a/tools/distrib/python/grpcio_tools/setup.py +++ b/tools/distrib/python/grpcio_tools/setup.py @@ -99,8 +99,8 @@ def protoc_ext_module(): os.path.join(protoc_lib_deps.CC_INCLUDE, cc_file) for cc_file in protoc_lib_deps.CC_FILES] plugin_ext = extension.Extension( - name='grpc.tools.protoc_compiler', - sources=['grpc/tools/protoc_compiler.pyx'] + plugin_sources, + name='grpc.tools._protoc_compiler', + sources=['grpc/tools/_protoc_compiler.pyx'] + plugin_sources, include_dirs=[ '.', 'grpc_root',