postprocess_go_fbs.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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(
  7. r'''
  8. \bimport
  9. (
  10. \s+((\.|\w+)\s+)?"[^"]+" ( \s+//[^\n]* )?
  11. | \s* \( \s* ( ( \s+ ((\.|\w+)\s+)? "[^"]+" )? ( \s* //[^\n]* )? )* \s* \)
  12. )''',
  13. re.MULTILINE | re.DOTALL | re.VERBOSE,
  14. )
  15. def parse_args():
  16. parser = argparse.ArgumentParser()
  17. parser.add_argument('--arcadia-prefix', required=True)
  18. parser.add_argument('--input-dir', required=True)
  19. parser.add_argument('--map', nargs='*', default=None)
  20. return parser.parse_args()
  21. def process_go_file(file_name, import_map, arcadia_prefix):
  22. content = ''
  23. with open(file_name, 'r') as f:
  24. content = f.read()
  25. start = -1
  26. end = -1
  27. for it in IMPORT_DECL.finditer(content):
  28. if start < 0:
  29. start = it.start()
  30. end = it.end()
  31. if start < 0:
  32. return
  33. imports = content[start:end]
  34. for namespace, path in import_map.items():
  35. ns = namespace.split('.')
  36. name = '__'.join(ns)
  37. import_path = '/'.join(ns)
  38. imports = imports.replace('{} "{}"'.format(name, import_path), '{} "{}{}"'.format(name, arcadia_prefix, path))
  39. if imports != content[start:end]:
  40. with open(file_name, 'w') as f:
  41. f.write(content[:start])
  42. f.write(imports)
  43. f.write(content[end:])
  44. def main():
  45. args = parse_args()
  46. if not args.map:
  47. return
  48. raw_import_map = sorted(set(args.map))
  49. import_map = dict(z.split('=', 1) for z in raw_import_map)
  50. if len(raw_import_map) != len(import_map):
  51. for k, v in (z.split('=', 1) for z in raw_import_map):
  52. if v != import_map[k]:
  53. raise Exception(
  54. 'import map [{}] contains different values for key [{}]: [{}] and [{}].'.format(
  55. args.map, k, v, import_map[k]
  56. )
  57. )
  58. for root, _, files in os.walk(args.input_dir):
  59. for src in (f for f in files if f.endswith('.go')):
  60. process_go_file(os.path.join(root, src), import_map, args.arcadia_prefix)
  61. if __name__ == '__main__':
  62. main()