1# -*- coding: utf-8 -*-
2# Copyright 2010-2018, Google Inc.
3# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions are
7# met:
8#
9#     * Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11#     * Redistributions in binary form must reproduce the above
12# copyright notice, this list of conditions and the following disclaimer
13# in the documentation and/or other materials provided with the
14# distribution.
15#     * Neither the name of Google Inc. nor the names of its
16# contributors may be used to endorse or promote products derived from
17# this software without specific prior written permission.
18#
19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31"""Script to invoke protoc with considering project root directory.
32
33  % python protoc_wrapper.py               \
34      --protoc_command=protoc              \
35      --protoc_dir=/usr/bin    (optional)  \
36      --proto=../protos/my_data.proto      \
37      --proto_path=../protos   (optional)  \
38      --cpp_out=../out/debug/gen           \
39      --project_root=../
40"""
41
42__author__ = "yukawa"
43
44import optparse
45import os
46import subprocess
47import sys
48
49def ParseOption():
50  """Parse command line options."""
51  parser = optparse.OptionParser()
52  parser.add_option('--protoc_command', dest='protoc_command',
53                    help='executable name of protoc')
54  parser.add_option('--protoc_dir', dest='protoc_dir',
55                    help='directory where protoc is located')
56  parser.add_option('--proto', dest='proto', help='path of the *.proto file')
57  parser.add_option('--cpp_out', dest='cpp_out', default='',
58                    help='path where cpp files should be generated')
59  parser.add_option('--java_out', dest='java_out', default='',
60                    help='path where java files should be generated')
61  parser.add_option('--project_root', dest='project_root', default='.',
62                    help='run protoc after moving this directory')
63  parser.add_option('--proto_path', dest='proto_path', default='',
64                    help='directory to be passed to --proto_path option')
65
66  (opts, _) = parser.parse_args()
67
68  return opts
69
70
71def main():
72  """The main function."""
73  opts = ParseOption()
74
75  # Convert to absolute paths before changing the current directory.
76  project_root = os.path.abspath(opts.project_root)
77  proto_path = os.path.abspath(opts.proto_path) if opts.proto_path else ''
78  cpp_out = os.path.abspath(opts.cpp_out) if opts.cpp_out else ''
79  java_out = os.path.abspath(opts.java_out) if opts.java_out else ''
80
81  protoc_path = opts.protoc_command
82  if opts.protoc_dir:
83    protoc_path = os.path.join(os.path.abspath(opts.protoc_dir), protoc_path)
84
85  # The path of proto file should be transformed as a relative path from
86  # the project root so that correct relative paths should be embedded into
87  # generated files.
88  proto_files = [os.path.relpath(os.path.abspath(p), project_root)
89                 for p in opts.proto.split(' ')]
90
91  # Move to the project root.
92  os.chdir(project_root)
93
94  commands = [protoc_path] + proto_files
95  if cpp_out:
96    commands += ['--cpp_out=' + cpp_out]
97  if java_out:
98    commands += ['--java_out=' + java_out]
99  if proto_path:
100    rel_proto_path = os.path.relpath(proto_path, project_root)
101    commands += ['--proto_path=' + rel_proto_path]
102  sys.exit(subprocess.call(commands))
103
104
105if __name__ == '__main__':
106  main()
107