134 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
| #!/usr/bin/env python3
 | |
| # Copyright (C) 2018 The Android Open Source Project
 | |
| #
 | |
| # 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.
 | |
| 
 | |
| from __future__ import absolute_import
 | |
| from __future__ import division
 | |
| from __future__ import print_function
 | |
| import os
 | |
| import re
 | |
| import argparse
 | |
| import tempfile
 | |
| import subprocess
 | |
| import hashlib
 | |
| from compat import iteritems
 | |
| 
 | |
| SOURCE_TARGET = [
 | |
|     ('protos/perfetto/trace_processor/trace_processor.proto',
 | |
|      'python/perfetto/trace_processor/trace_processor.descriptor'
 | |
|     ),
 | |
|     ('protos/perfetto/metrics/metrics.proto',
 | |
|      'python/perfetto/trace_processor/metrics.descriptor'),
 | |
| ]
 | |
| 
 | |
| ROOT_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
 | |
| 
 | |
| SCRIPT_PATH = 'tools/gen_binary_descriptors'
 | |
| 
 | |
| 
 | |
| def hash_path(path):
 | |
|   hash = hashlib.sha1()
 | |
|   with open(os.path.join(ROOT_DIR, path), 'rb') as f:
 | |
|     hash.update(f.read())
 | |
|   return hash.hexdigest()
 | |
| 
 | |
| 
 | |
| def find_protoc():
 | |
|   for root, _, files in os.walk(os.path.join(ROOT_DIR, 'out')):
 | |
|     if 'protoc' in files:
 | |
|       return os.path.join(root, 'protoc')
 | |
|   return None
 | |
| 
 | |
| 
 | |
| def check(source, target):
 | |
|   assert os.path.exists(os.path.join(ROOT_DIR, target)), \
 | |
|       'Output file {} does not exist and so cannot be checked'.format(target)
 | |
| 
 | |
|   sha1_file = target + '.sha1'
 | |
|   assert os.path.exists(sha1_file), \
 | |
|       'SHA1 file {} does not exist and so cannot be checked'.format(sha1_file)
 | |
| 
 | |
|   with open(sha1_file, 'rb') as f:
 | |
|     s = f.read()
 | |
| 
 | |
|   hashes = re.findall(r'// SHA1\((.*)\)\n// (.*)\n', s.decode())
 | |
|   assert sorted([SCRIPT_PATH, source]) == sorted([key for key, _ in hashes])
 | |
|   for path, expected_sha1 in hashes:
 | |
|     actual_sha1 = hash_path(os.path.join(ROOT_DIR, path))
 | |
|     assert actual_sha1 == expected_sha1, \
 | |
|         'In {} hash given for {} did not match'.format(target, path)
 | |
| 
 | |
| 
 | |
| def generate(source, target, protoc_path):
 | |
|   # delete=False + manual unlink is required for Windows. Otherwise the temp
 | |
|   # file is kept locked exclusively and unaccassible until it's destroyed.
 | |
|   with tempfile.NamedTemporaryFile(delete=False) as fdescriptor:
 | |
|     subprocess.check_call([
 | |
|         protoc_path,
 | |
|         '--include_imports',
 | |
|         '--proto_path=.',
 | |
|         '--proto_path=' + \
 | |
|             os.path.join(ROOT_DIR, "buildtools", "protobuf", "src"),
 | |
|         '--descriptor_set_out={}'.format(fdescriptor.name),
 | |
|         source,
 | |
|     ], cwd=ROOT_DIR)
 | |
| 
 | |
|     s = fdescriptor.read()
 | |
|     fdescriptor.close()
 | |
|     os.remove(fdescriptor.name)
 | |
|     with open(target, 'wb') as out:
 | |
|       out.write(s)
 | |
| 
 | |
|     sha1_path = target + '.sha1'
 | |
|     with open(sha1_path, 'wb') as c:
 | |
|       c.write("""
 | |
| // SHA1({script_path})
 | |
| // {script_hash}
 | |
| // SHA1({source_path})
 | |
| // {source_hash}
 | |
|   """.format(
 | |
|           script_path=SCRIPT_PATH,
 | |
|           script_hash=hash_path(__file__),
 | |
|           source_path=source,
 | |
|           source_hash=hash_path(os.path.join(source)),
 | |
|       ).encode())
 | |
| 
 | |
| 
 | |
| def main():
 | |
|   parser = argparse.ArgumentParser()
 | |
|   parser.add_argument('--check-only', action='store_true')
 | |
|   parser.add_argument('--protoc')
 | |
|   args = parser.parse_args()
 | |
| 
 | |
|   try:
 | |
|     for source, target in SOURCE_TARGET:
 | |
|       if args.check_only:
 | |
|         check(source, target)
 | |
|       else:
 | |
|         protoc = args.protoc or find_protoc()
 | |
|         assert protoc, 'protoc not found specific (--protoc PROTOC_PATH)'
 | |
|         assert os.path.exists(protoc), '{} does not exist'.format(protoc)
 | |
|         if protoc is not args.protoc:
 | |
|           print('Using protoc: {}'.format(protoc))
 | |
|         generate(source, target, protoc)
 | |
|   except AssertionError as e:
 | |
|     if not str(e):
 | |
|       raise
 | |
|     print('Error: {}'.format(e))
 | |
|     return 1
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|   exit(main())
 |