• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2020 The gRPC Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14"""Generates grpc-prefixed packages using template renderer.
15
16To use this script, please use 3.7+ interpreter. This script is work-directory
17agnostic. A quick executable command:
18
19    python3 tools/distrib/python/grpc_prefixed/generate.py
20"""
21
22import dataclasses
23import datetime
24import logging
25import os
26import shutil
27import subprocess
28import sys
29
30import jinja2
31
32WORK_PATH = os.path.realpath(os.path.dirname(__file__))
33LICENSE = os.path.join(WORK_PATH, '../../../../LICENSE')
34BUILD_PATH = os.path.join(WORK_PATH, 'build')
35DIST_PATH = os.path.join(WORK_PATH, 'dist')
36
37env = jinja2.Environment(
38    loader=jinja2.FileSystemLoader(os.path.join(WORK_PATH, 'templates')))
39
40LOGGER = logging.getLogger(__name__)
41POPEN_TIMEOUT_S = datetime.timedelta(minutes=1).total_seconds()
42
43
44@dataclasses.dataclass
45class PackageMeta:
46    """Meta-info of a PyPI package."""
47    name: str
48    name_long: str
49    destination_package: str
50    version: str = '1.0.0'
51
52
53def clean() -> None:
54    try:
55        shutil.rmtree(BUILD_PATH)
56    except FileNotFoundError:
57        pass
58
59    try:
60        shutil.rmtree(DIST_PATH)
61    except FileNotFoundError:
62        pass
63
64
65def generate_package(meta: PackageMeta) -> None:
66    # Makes package directory
67    package_path = os.path.join(BUILD_PATH, meta.name)
68    os.makedirs(package_path, exist_ok=True)
69
70    # Copy license
71    shutil.copyfile(LICENSE, os.path.join(package_path, 'LICENSE'))
72
73    # Generates source code
74    for template_name in env.list_templates():
75        template = env.get_template(template_name)
76        with open(
77                os.path.join(package_path,
78                             template_name.replace('.template', '')), 'w') as f:
79            f.write(template.render(dataclasses.asdict(meta)))
80
81    # Creates wheel
82    job = subprocess.Popen([
83        sys.executable,
84        os.path.join(package_path, 'setup.py'), 'sdist', '--dist-dir', DIST_PATH
85    ],
86                           cwd=package_path,
87                           stdout=subprocess.PIPE,
88                           stderr=subprocess.STDOUT)
89    outs, _ = job.communicate(timeout=POPEN_TIMEOUT_S)
90
91    # Logs result
92    if job.returncode != 0:
93        LOGGER.error('Wheel creation failed with %d', job.returncode)
94        LOGGER.error(outs)
95    else:
96        LOGGER.info('Package <%s> generated', meta.name)
97
98
99def main():
100    clean()
101
102    generate_package(
103        PackageMeta(name='grpc',
104                    name_long='gRPC Python',
105                    destination_package='grpcio'))
106
107    generate_package(
108        PackageMeta(name='grpc-status',
109                    name_long='gRPC Rich Error Status',
110                    destination_package='grpcio-status'))
111
112    generate_package(
113        PackageMeta(name='grpc-channelz',
114                    name_long='gRPC Channel Tracing',
115                    destination_package='grpcio-channelz'))
116
117    generate_package(
118        PackageMeta(name='grpc-tools',
119                    name_long='ProtoBuf Code Generator',
120                    destination_package='grpcio-tools'))
121
122    generate_package(
123        PackageMeta(name='grpc-reflection',
124                    name_long='gRPC Reflection',
125                    destination_package='grpcio-reflection'))
126
127    generate_package(
128        PackageMeta(name='grpc-testing',
129                    name_long='gRPC Testing Utility',
130                    destination_package='grpcio-testing'))
131
132    generate_package(
133        PackageMeta(name='grpc-health-checking',
134                    name_long='gRPC Health Checking',
135                    destination_package='grpcio-health-checking'))
136
137
138if __name__ == "__main__":
139    logging.basicConfig(level=logging.INFO)
140    main()
141