1#!/usr/bin/env python3
2# Copyright 2015 gRPC authors.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16from __future__ import print_function
17
18import argparse
19import os
20import os.path
21import shutil
22import subprocess
23import sys
24import tempfile
25
26import grpc_version
27
28parser = argparse.ArgumentParser()
29parser.add_argument('--repo-owner',
30                    type=str,
31                    help=('Owner of the GitHub repository to be pushed'))
32parser.add_argument('--doc-branch',
33                    type=str,
34                    default='python-doc-%s' % grpc_version.VERSION)
35args = parser.parse_args()
36
37SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
38PROJECT_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, '..', '..', '..'))
39
40SETUP_PATH = os.path.join(PROJECT_ROOT, 'setup.py')
41REQUIREMENTS_PATH = os.path.join(PROJECT_ROOT, 'requirements.bazel.txt')
42DOC_PATH = os.path.join(PROJECT_ROOT, 'doc/build')
43
44if "VIRTUAL_ENV" in os.environ:
45    VIRTUALENV_DIR = os.environ['VIRTUAL_ENV']
46    PYTHON_PATH = os.path.join(VIRTUALENV_DIR, 'bin', 'python')
47    subprocess_arguments_list = []
48else:
49    VIRTUALENV_DIR = os.path.join(SCRIPT_DIR, 'distrib_virtualenv')
50    PYTHON_PATH = os.path.join(VIRTUALENV_DIR, 'bin', 'python')
51    subprocess_arguments_list = [
52        ['python3', '-m', 'virtualenv', VIRTUALENV_DIR],
53    ]
54
55subprocess_arguments_list += [
56    [PYTHON_PATH, '-m', 'pip', 'install', '--upgrade', 'pip==19.3.1'],
57    [PYTHON_PATH, '-m', 'pip', 'install', '-r', REQUIREMENTS_PATH],
58    [PYTHON_PATH, '-m', 'pip', 'install', '--upgrade', 'Sphinx'],
59    [PYTHON_PATH, SETUP_PATH, 'doc'],
60]
61
62for subprocess_arguments in subprocess_arguments_list:
63    print('Running command: {}'.format(subprocess_arguments))
64    subprocess.check_call(args=subprocess_arguments)
65
66if not args.repo_owner or not args.doc_branch:
67    tty_width = int(os.popen('stty size', 'r').read().split()[1])
68    print('-' * tty_width)
69    print('Please check generated Python doc inside doc/build')
70    print(
71        'To push to a GitHub repo, please provide repo owner and doc branch name'
72    )
73else:
74    # Create a temporary directory out of tree, checkout gh-pages from the
75    # specified repository, edit it, and push it. It's up to the user to then go
76    # onto GitHub and make a PR against grpc/grpc:gh-pages.
77    repo_parent_dir = tempfile.mkdtemp()
78    print('Documentation parent directory: {}'.format(repo_parent_dir))
79    repo_dir = os.path.join(repo_parent_dir, 'grpc')
80    python_doc_dir = os.path.join(repo_dir, 'python')
81    doc_branch = args.doc_branch
82
83    print('Cloning your repository...')
84    subprocess.check_call([
85        'git',
86        'clone',
87        '--branch',
88        'gh-pages',
89        'https://github.com/grpc/grpc',
90    ],
91                          cwd=repo_parent_dir)
92    subprocess.check_call(['git', 'checkout', '-b', doc_branch], cwd=repo_dir)
93    subprocess.check_call([
94        'git', 'remote', 'add', 'ssh-origin',
95        '[email protected]:%s/grpc.git' % args.repo_owner
96    ],
97                          cwd=repo_dir)
98    print('Updating documentation...')
99    shutil.rmtree(python_doc_dir, ignore_errors=True)
100    shutil.copytree(DOC_PATH, python_doc_dir)
101    print('Attempting to push documentation to %s/%s...' %
102          (args.repo_owner, doc_branch))
103    try:
104        subprocess.check_call(['git', 'add', '--all'], cwd=repo_dir)
105        subprocess.check_call(
106            ['git', 'commit', '-m', 'Auto-update Python documentation'],
107            cwd=repo_dir)
108        subprocess.check_call(
109            ['git', 'push', '--set-upstream', 'ssh-origin', doc_branch],
110            cwd=repo_dir)
111    except subprocess.CalledProcessError:
112        print('Failed to push documentation. Examine this directory and push '
113              'manually: {}'.format(repo_parent_dir))
114        sys.exit(1)
115    shutil.rmtree(repo_parent_dir)
116