From 99eefe48b27492d40deb45a67c921e71bd211d8b Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Fri, 29 May 2020 14:06:26 -0700 Subject: [PATCH] Add grpc-prefixed package generation script --- .gitignore | 1 + tools/distrib/python/grpc_prefixed/.gitignore | 2 + .../distrib/python/grpc_prefixed/generate.py | 138 ++++++++++++++++++ .../templates/MANIFEST.in.template | 4 + .../templates/README.rst.template | 1 + .../grpc_prefixed/templates/setup.py.template | 45 ++++++ 6 files changed, 191 insertions(+) create mode 100644 tools/distrib/python/grpc_prefixed/.gitignore create mode 100644 tools/distrib/python/grpc_prefixed/generate.py create mode 100644 tools/distrib/python/grpc_prefixed/templates/MANIFEST.in.template create mode 100644 tools/distrib/python/grpc_prefixed/templates/README.rst.template create mode 100644 tools/distrib/python/grpc_prefixed/templates/setup.py.template diff --git a/.gitignore b/.gitignore index 32d26a4bf2b..c0ec88139f2 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ a.out src/python/grpcio_*/LICENSE src/python/grpcio_status/grpc_status/google/rpc/status.proto .pytype +*.egg-info # Node installation output node_modules diff --git a/tools/distrib/python/grpc_prefixed/.gitignore b/tools/distrib/python/grpc_prefixed/.gitignore new file mode 100644 index 00000000000..9d0b71a3c79 --- /dev/null +++ b/tools/distrib/python/grpc_prefixed/.gitignore @@ -0,0 +1,2 @@ +build +dist diff --git a/tools/distrib/python/grpc_prefixed/generate.py b/tools/distrib/python/grpc_prefixed/generate.py new file mode 100644 index 00000000000..eeef0d96845 --- /dev/null +++ b/tools/distrib/python/grpc_prefixed/generate.py @@ -0,0 +1,138 @@ +# Copyright 2020 The 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. +"""Generates grpc-prefixed packages using template renderer. + +To use this script, please use 3.7+ interpreter. This script is work-directory +agnostic. A quick executable command: + + python3 tools/distrib/python/grpc_prefixed/generate.py +""" + +import dataclasses +import logging +import os +import shutil +import subprocess +import sys + +import jinja2 + +WORK_PATH = os.path.realpath(os.path.dirname(__file__)) +LICENSE = os.path.join(WORK_PATH, '../../../../LICENSE') +BUILD_PATH = os.path.join(WORK_PATH, 'build') +DIST_PATH = os.path.join(WORK_PATH, 'dist') + +env = jinja2.Environment( + loader=jinja2.FileSystemLoader(os.path.join(WORK_PATH, 'templates'))) + +LOGGER = logging.getLogger(__name__) + + +@dataclasses.dataclass +class PackageMeta: + """Meta-info of a PyPI package.""" + name: str + name_long: str + destination_package: str + version: str = '1.0.0' + + +def clean() -> None: + try: + shutil.rmtree(BUILD_PATH) + except FileNotFoundError: + pass + + try: + shutil.rmtree(DIST_PATH) + except FileNotFoundError: + pass + + +def generate_package(meta: PackageMeta) -> None: + # Makes package directory + package_path = os.path.join(BUILD_PATH, meta.name) + os.makedirs(package_path, exist_ok=True) + + # Copy license + shutil.copyfile(LICENSE, os.path.join(package_path, 'LICENSE')) + + # Generates source code + for template_name in env.list_templates(): + template = env.get_template(template_name) + with open( + os.path.join(package_path, + template_name.replace('.template', '')), 'w') as f: + f.write(template.render(dataclasses.asdict(meta))) + + # Creates wheel + job = subprocess.Popen([ + sys.executable, + os.path.join(package_path, 'setup.py'), 'sdist', '--dist-dir', DIST_PATH + ], + cwd=package_path, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + returncode = job.wait() + + # Logs result + if returncode != 0: + LOGGER.error('Wheel creation failed with %d', returncode) + LOGGER.error(job.stdout) + else: + LOGGER.info('Package <%s> generated', meta.name) + + +def main(): + clean() + + generate_package( + PackageMeta(name='grpc', + name_long='gRPC Python', + destination_package='grpcio')) + + generate_package( + PackageMeta(name='grpc-status', + name_long='gRPC Rich Error Status', + destination_package='grpcio-status')) + + generate_package( + PackageMeta(name='grpc-channelz', + name_long='gRPC Channel Tracing', + destination_package='grpcio-channelz')) + + generate_package( + PackageMeta(name='grpc-tools', + name_long='ProtoBuf Code Generator', + destination_package='grpcio-tools')) + + generate_package( + PackageMeta(name='grpc-reflection', + name_long='gRPC Reflection', + destination_package='grpcio-reflection')) + + generate_package( + PackageMeta(name='grpc-testing', + name_long='gRPC Testing Utility', + destination_package='grpcio-testing')) + + generate_package( + PackageMeta(name='grpc-health-checking', + name_long='gRPC Health Checking', + destination_package='grpcio-health-checking')) + + +if __name__ == "__main__": + logging.basicConfig(level=logging.INFO) + main() diff --git a/tools/distrib/python/grpc_prefixed/templates/MANIFEST.in.template b/tools/distrib/python/grpc_prefixed/templates/MANIFEST.in.template new file mode 100644 index 00000000000..5840309d09c --- /dev/null +++ b/tools/distrib/python/grpc_prefixed/templates/MANIFEST.in.template @@ -0,0 +1,4 @@ +include setup.py +include README.rst +include LICENSE +global-exclude *.pyc diff --git a/tools/distrib/python/grpc_prefixed/templates/README.rst.template b/tools/distrib/python/grpc_prefixed/templates/README.rst.template new file mode 100644 index 00000000000..7ad32651d18 --- /dev/null +++ b/tools/distrib/python/grpc_prefixed/templates/README.rst.template @@ -0,0 +1 @@ +The official package of {{ name_long }} is `{{ destination_package }} `_. diff --git a/tools/distrib/python/grpc_prefixed/templates/setup.py.template b/tools/distrib/python/grpc_prefixed/templates/setup.py.template new file mode 100644 index 00000000000..2d62270d04d --- /dev/null +++ b/tools/distrib/python/grpc_prefixed/templates/setup.py.template @@ -0,0 +1,45 @@ +# Copyright 2020 The 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. +"""Setup module for the {{ name_long }} package.""" + +import sys + +import setuptools + +CLASSIFIERS = [ + 'Development Status :: 7 - Inactive', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 3', + 'License :: OSI Approved :: Apache Software License', +] + + +HINT = 'Please install the official package with: pip install {{ destination_package }}' + + +if 'sdist' not in sys.argv: + raise RuntimeError(HINT) + + +setuptools.setup( + name='{{ name }}', + version='{{ version }}', + description=HINT, + author='The gRPC Authors', + author_email='grpc-io@googlegroups.com', + url='https://grpc.io', + license='Apache License 2.0', + classifiers=CLASSIFIERS +)