github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/bin/protogen (about)

     1  #!/usr/bin/env python3
     2  #
     3  # Copyright 2017 Intel Corporation
     4  #
     5  # Licensed under the Apache License, Version 2.0 (the "License");
     6  # you may not use this file except in compliance with the License.
     7  # You may obtain a copy of the License at
     8  #
     9  #     http://www.apache.org/licenses/LICENSE-2.0
    10  #
    11  # Unless required by applicable law or agreed to in writing, software
    12  # distributed under the License is distributed on an "AS IS" BASIS,
    13  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  # See the License for the specific language governing permissions and
    15  # limitations under the License.
    16  # ------------------------------------------------------------------------------
    17  
    18  import os
    19  import tempfile
    20  from glob import glob
    21  import re
    22  import subprocess
    23  import sys
    24  
    25  
    26  try:
    27      from grpc.tools.protoc import main as _protoc
    28  except ImportError:
    29      print("Error: grpc.tools.protoc not found")
    30      exit(1)
    31  
    32  
    33  JOIN = os.path.join
    34  TOP_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
    35  
    36  
    37  def main(args=None):
    38      if args is None:
    39          args = sys.argv[1:]
    40      # 1. Generate and distribute top-level protos
    41      proto_dir = JOIN(TOP_DIR, "protos")
    42  
    43      protoc(proto_dir, "sdk/python", "sawtooth_sdk/protobuf")
    44      protoc(proto_dir, "cli", "sawtooth_cli/protobuf")
    45      protoc(proto_dir, "validator", "sawtooth_validator/protobuf")
    46      protoc(proto_dir, "rest_api", "sawtooth_rest_api/protobuf")
    47      protoc(proto_dir, "families/settings", "sawtooth_settings/protobuf")
    48      protoc(proto_dir, "families/identity", "sawtooth_identity/protobuf")
    49      protoc(proto_dir, "families/block_info", "sawtooth_block_info/protobuf")
    50  
    51      if "javascript" in args:
    52          protoc(proto_dir, "sdk/javascript", "protobuf", "javascript")
    53  
    54      if "go" in args:
    55          protoc(proto_dir, "sdk/go/src", "sawtooth_sdk/protobuf", "go")
    56  
    57      # 2. Generate config protos
    58      proto_dir = JOIN(TOP_DIR, "families/settings/protos")
    59      protoc(proto_dir, "families/settings", "sawtooth_settings/protobuf")
    60      protoc(proto_dir, "cli", "sawtooth_cli/protobuf")
    61  
    62      # 3. Generate PoET protos
    63      proto_dir = \
    64          JOIN(
    65              TOP_DIR,
    66              "consensus/poet/families/sawtooth_validator_registry/protos")
    67      protoc(proto_dir, "consensus/poet/common", "sawtooth_poet_common/protobuf")
    68  
    69      # 5. Generate identity protos
    70      proto_dir = JOIN(TOP_DIR, "families/identity/protos")
    71      protoc(proto_dir, "families/identity", "sawtooth_identity/protobuf")
    72      protoc(proto_dir, "cli", "sawtooth_cli/protobuf")
    73  
    74      # 6. Generate block info protos
    75      proto_dir = JOIN(TOP_DIR, "families/block_info/protos")
    76      protoc(proto_dir, "families/block_info", "sawtooth_block_info/protobuf")
    77  
    78      # 7. Generate smallbank protos
    79      if "go" in args:
    80          proto_dir = JOIN(TOP_DIR, "families/smallbank/protos")
    81          protoc(proto_dir, "families/smallbank",
    82                 "smallbank_go/src/protobuf", "go")
    83  
    84  
    85  def protoc(src_dir, base_dir, pkg, language="python"):
    86      if language == "python":
    87          protoc_python(src_dir, base_dir, pkg)
    88      elif language == "go":
    89          protoc_go(src_dir, base_dir, pkg)
    90      elif language == "javascript":
    91          protoc_javascript(src_dir, base_dir, pkg)
    92  
    93  
    94  def protoc_python(src_dir, base_dir, pkg):
    95      # 1. Create output package directory
    96      pkg_dir = JOIN(TOP_DIR, base_dir, pkg)
    97      os.makedirs(pkg_dir, exist_ok=True)
    98  
    99      # 2. 'touch' the __init__.py file if the output directory exists
   100      init_py = JOIN(pkg_dir, "__init__.py")
   101      if not os.path.exists(init_py):
   102          with open(init_py, "w") as fd:
   103              pass  # Just need it to exist
   104  
   105      # 3. Create a temp directory for building
   106      with tempfile.TemporaryDirectory() as tmp_dir:
   107          tmp_pkg_dir = JOIN(tmp_dir, pkg)
   108          os.makedirs(tmp_pkg_dir)
   109  
   110          # 4. Get a list of all .proto files to build
   111          cwd = os.getcwd()
   112          os.chdir(src_dir)
   113          proto_files = glob("*.proto")
   114          os.chdir(cwd)
   115  
   116          # 5. Copy protos to temp dir and fix imports
   117          for proto in proto_files:
   118              src = JOIN(src_dir, proto)
   119              dst = JOIN(tmp_pkg_dir, proto)
   120              with open(src, encoding='utf-8') as fin:
   121                  with open(dst, "w", encoding='utf-8') as fout:
   122                      src_contents = fin.read()
   123                      fixed_contents = fix_import(src_contents, pkg)
   124                      fout.write(fixed_contents)
   125  
   126          # 6. Compile protobuf files
   127          _protoc([
   128              __file__,
   129              "-I=%s" % tmp_dir,
   130              "--python_out=%s" % JOIN(TOP_DIR, base_dir),
   131          ] + glob("%s/*.proto" % tmp_pkg_dir))
   132  
   133  
   134  def protoc_javascript(src_dir, base_dir, pkg):
   135      pkg_dir = JOIN(TOP_DIR, base_dir, pkg)
   136      os.makedirs(pkg_dir, exist_ok=True)
   137  
   138      with open(JOIN(pkg_dir, 'protobuf_bundle.json'), 'w') as out:
   139          p = subprocess.Popen(
   140              ['node', 'compile_protobuf.js'],
   141              cwd=JOIN(TOP_DIR, base_dir),
   142              stdout=out)
   143          ret_code = p.wait()
   144          out.flush()
   145  
   146      if ret_code != 0:
   147          raise AssertionError('Unable to compile protobuf messages for JS!')
   148  
   149  
   150  def protoc_go(src_dir, base_dir, pkg):
   151      # 1. Get a list of all .proto files to build
   152      cwd = os.getcwd()
   153      os.chdir(src_dir)
   154      proto_files = glob("*.proto")
   155      os.chdir(cwd)
   156  
   157      # 2. Create a temp directory for building
   158      with tempfile.TemporaryDirectory() as tmp_dir:
   159          defer = []
   160  
   161          # 3. In order to have each protobuf file in its own namespace,
   162          # directories need to be created for all of them and the .proto file
   163          # copied in
   164          for proto_file in proto_files:
   165              proto = proto_file[:-6]
   166  
   167              sub_pkg = JOIN(pkg, proto)
   168              tmp_pkg_dir = JOIN(tmp_dir, sub_pkg + "_pb2")
   169              os.makedirs(tmp_pkg_dir)
   170  
   171              src = JOIN(src_dir, proto_file)
   172              dst = JOIN(tmp_pkg_dir, proto_file)
   173              with open(src, encoding='utf-8') as fin:
   174                  with open(dst, "w", encoding='utf-8') as fout:
   175                      src_contents = fin.read()
   176                      fixed_contents = fix_import(
   177                          src_contents, pkg, sub_dir=True)
   178                      fout.write(fixed_contents)
   179  
   180              # Need to defer until the whole directory is setup
   181              defer.append([
   182                  __file__,
   183                  "-I=%s" % tmp_dir,
   184                  "--go_out=%s" % JOIN(TOP_DIR, base_dir),
   185                  "%s" % dst
   186              ])
   187  
   188          for args in defer:
   189              _protoc(args)
   190  
   191  
   192  def fix_import(contents, pkg, sub_dir=False):
   193      pattern = r'^import "(.*)\.proto\"'
   194      if sub_dir:
   195          template = r'import "%s/\1_pb2/\1.proto"'
   196      else:
   197          template = r'import "%s/\1.proto"'
   198  
   199      return re.sub(
   200          pattern,
   201          lambda match: match.expand(template) % pkg,
   202          contents,
   203          flags=re.MULTILINE)
   204  
   205  
   206  if __name__ == "__main__":
   207      try:
   208          main()
   209      except KeyboardInterrupt:
   210          exit(1)