postprocess_go_fbs.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import argparse
  2. import re
  3. import os
  4. # very simple regexp to find go import statement in the source code
  5. # NOTE! only one-line comments are somehow considered
  6. IMPORT_DECL=re.compile(r'''
  7. \bimport
  8. (
  9. \s+((\.|\w+)\s+)?"[^"]+" ( \s+//[^\n]* )?
  10. | \s* \( \s* ( ( \s+ ((\.|\w+)\s+)? "[^"]+" )? ( \s* //[^\n]* )? )* \s* \)
  11. )''', re.MULTILINE | re.DOTALL | re.VERBOSE)
  12. def parse_args():
  13. parser = argparse.ArgumentParser()
  14. parser.add_argument('--input-dir', required=True)
  15. parser.add_argument('--map', nargs='*', default=None)
  16. return parser.parse_args()
  17. def process_go_file(file_name, import_map):
  18. content = ''
  19. with open(file_name, 'r') as f:
  20. content = f.read()
  21. start = -1
  22. end = -1
  23. for it in IMPORT_DECL.finditer(content):
  24. if start < 0:
  25. start = it.start()
  26. end = it.end()
  27. if start < 0:
  28. return
  29. imports = content[start:end]
  30. for namespace, path in import_map.items():
  31. ns = namespace.split('.')
  32. name = '__'.join(ns)
  33. import_path = '/'.join(ns)
  34. imports = imports.replace('{} "{}"'.format(name, import_path), '{} "a.yandex-team.ru/{}"'.format(name, path))
  35. if imports != content[start:end]:
  36. with open(file_name, 'w') as f:
  37. f.write(content[:start])
  38. f.write(imports)
  39. f.write(content[end:])
  40. def main():
  41. args = parse_args()
  42. if not args.map:
  43. return
  44. raw_import_map = sorted(set(args.map))
  45. import_map = dict(z.split('=', 1) for z in raw_import_map)
  46. if len(raw_import_map) != len(import_map):
  47. for k, v in (z.split('=', 1) for z in raw_import_map):
  48. if v != import_map[k]:
  49. raise Exception('import map [{}] contains different values for key [{}]: [{}] and [{}].'.format(args.map, k, v, import_map[k]))
  50. for root, _, files in os.walk(args.input_dir):
  51. for src in (f for f in files if f.endswith('.go')):
  52. process_go_file(os.path.join(root, src), import_map)
  53. if __name__ == '__main__':
  54. main()