prepare_jar_build.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. import os
  2. import sys
  3. import shutil
  4. import argparse
  5. # Explicitly enable local imports
  6. # Don't forget to add imported scripts to inputs of the calling command!
  7. sys.path.append(os.path.dirname(os.path.abspath(__file__)))
  8. import process_command_files as pcf
  9. import java_pack_to_file as jcov
  10. import resolve_java_srcs as resolve
  11. from autotar_gendirs import unpack_dir
  12. def writelines(f, rng):
  13. f.writelines(item + '\n' for item in rng)
  14. class SourcesSorter:
  15. FILE_ARG = 1
  16. RESOURCES_DIR_ARG = 2
  17. SRCDIR_ARG = 3
  18. JSOURCES_DIR_ARG = 4
  19. def __init__(self, moddir):
  20. self.moddir = moddir
  21. self.next_arg = SourcesSorter.FILE_ARG
  22. self.cur_resources_list_file = None
  23. self.cur_jsources_list_file = None
  24. self.cur_srcdir = None
  25. self.cur_resources = []
  26. self.cur_jsources = []
  27. def sort_args(self, remaining_args):
  28. for src in remaining_args:
  29. if self.next_arg == SourcesSorter.RESOURCES_DIR_ARG:
  30. assert self.cur_resources_list_file is None
  31. self.cur_resources_list_file = src
  32. self.next_arg = SourcesSorter.FILE_ARG
  33. continue
  34. elif self.next_arg == SourcesSorter.JSOURCES_DIR_ARG:
  35. assert self.cur_jsources_list_file is None
  36. self.cur_jsources_list_file = src
  37. self.next_arg = SourcesSorter.FILE_ARG
  38. continue
  39. elif self.next_arg == SourcesSorter.SRCDIR_ARG:
  40. assert self.cur_srcdir is None
  41. self.cur_srcdir = src if os.path.isabs(src) else os.path.join(self.moddir, src)
  42. self.next_arg = SourcesSorter.FILE_ARG
  43. continue
  44. if src == '--resources':
  45. if self.cur_resources_list_file is not None:
  46. with open(self.cur_resources_list_file, 'w') as f:
  47. writelines(f, self.cur_resources)
  48. self.cur_resources_list_file = None
  49. self.cur_srcdir = None
  50. self.cur_resources = []
  51. self.next_arg = SourcesSorter.RESOURCES_DIR_ARG
  52. continue
  53. if src == '--jsources':
  54. if self.cur_jsources_list_file is not None:
  55. with open(self.cur_jsources_list_file, 'w') as f:
  56. writelines(f, self.cur_jsources)
  57. self.cur_jsources_list_file = None
  58. self.cur_jsources = []
  59. self.next_arg = SourcesSorter.JSOURCES_DIR_ARG
  60. continue
  61. elif src == '--srcdir':
  62. self.next_arg = SourcesSorter.SRCDIR_ARG
  63. continue
  64. yield src
  65. if self.cur_resources_list_file is not None:
  66. with open(self.cur_resources_list_file, 'w') as f:
  67. writelines(f, self.cur_resources)
  68. if self.cur_jsources_list_file is not None:
  69. with open(self.cur_jsources_list_file, 'w') as f:
  70. writelines(f, self.cur_jsources)
  71. class SourcesConsumer:
  72. def __init__(self, source_root, with_kotlin, with_coverage):
  73. self.source_root = source_root
  74. self.with_kotlin = with_kotlin
  75. self.with_coverage = with_coverage
  76. self.java = []
  77. self.kotlin = []
  78. self.coverage = []
  79. def consume(self, src, sorter):
  80. if src.endswith(".java"):
  81. self.java.append(src)
  82. self.kotlin.append(src)
  83. self._add_rel_src_to_coverage(src)
  84. elif self.with_kotlin and src.endswith(".kt"):
  85. self.kotlin.append(src)
  86. self._add_rel_src_to_coverage(src)
  87. else:
  88. assert sorter.cur_srcdir is not None and sorter.cur_resources_list_file is not None
  89. sorter.cur_resources.append(os.path.relpath(src, sorter.cur_srcdir))
  90. if sorter.cur_jsources_list_file is not None:
  91. assert sorter.cur_srcdir is not None
  92. sorter.cur_jsources.append(os.path.relpath(src, sorter.cur_srcdir))
  93. def _add_rel_src_to_coverage(self, src):
  94. if not self.with_coverage or not self.source_root:
  95. return
  96. rel = os.path.relpath(src, self.source_root)
  97. if not rel.startswith('..' + os.path.sep):
  98. self.coverage.append(rel)
  99. def prepare_build_dirs(bindir, with_sources_jar):
  100. dirs = ['cls', 'misc']
  101. if with_sources_jar:
  102. dirs.append('src')
  103. for dir in [os.path.join(bindir, dirname) for dirname in dirs]:
  104. if not os.path.exists(dir):
  105. os.makedirs(dir)
  106. def split_cmd_by_delim(cmd, delim='DELIM'):
  107. result = [[]]
  108. for arg in cmd:
  109. if arg == delim:
  110. result.append([])
  111. else:
  112. result[-1].append(arg)
  113. return result[0], result[1:]
  114. def main():
  115. args, resolve_args = split_cmd_by_delim(pcf.get_args(sys.argv[1:]))
  116. parser = argparse.ArgumentParser()
  117. parser.add_argument('--with-sources-jar', action='store_true')
  118. parser.add_argument('--moddir')
  119. parser.add_argument('--bindir')
  120. parser.add_argument('--java')
  121. parser.add_argument('--kotlin')
  122. parser.add_argument('--coverage')
  123. parser.add_argument('--source-root')
  124. args, remaining_args = parser.parse_known_args(args)
  125. prepare_build_dirs(args.bindir, args.with_sources_jar)
  126. src_sorter = SourcesSorter(args.moddir)
  127. src_consumer = SourcesConsumer(
  128. source_root=args.source_root,
  129. with_kotlin=True if args.kotlin else False,
  130. with_coverage=True if args.coverage else False)
  131. jsrcs_dir = None
  132. for src in src_sorter.sort_args(remaining_args):
  133. if src.endswith(".gentar"):
  134. unpack_dir(src, os.path.dirname(src))
  135. continue
  136. if src.endswith(".jsrc"):
  137. jsrcs_dir = os.path.join(args.bindir, 'jsrcs')
  138. unpack_dir(src, jsrcs_dir)
  139. continue
  140. src_consumer.consume(src, src_sorter)
  141. if args.java:
  142. with open(args.java, 'w') as f:
  143. writelines(f, src_consumer.java)
  144. if args.kotlin:
  145. with open(args.kotlin, 'w') as f:
  146. writelines(f, src_consumer.kotlin)
  147. if args.coverage:
  148. jcov.write_coverage_sources(args.coverage, args.source_root, src_consumer.coverage)
  149. for rargs in resolve_args:
  150. resolve.cli_main(rargs, force_skip_source_jars=not args.with_sources_jar)
  151. if jsrcs_dir is not None:
  152. resolve.resolve_sources_and_fill_filelists(
  153. directory=jsrcs_dir,
  154. sources_file=args.java,
  155. resources_file=os.path.join(args.bindir, 'default.res.txt'),
  156. kotlin_sources_file=args.kotlin if args.kotlin else None,
  157. include_patterns=['**/*'],
  158. exclude_patterns=[],
  159. resolve_kotlin=True if args.kotlin else False,
  160. append=True,
  161. all_resources=False,
  162. )
  163. if args.with_sources_jar:
  164. # TODO ugly hack here. Once jar directory preparation will be handled in a single script
  165. # sources copying should use common API here as well. Current "common API" is to populate
  166. # file with files to be copied by another script. It can't be uses here since there is no
  167. # way to send filelist to that external script from current point in code
  168. shutil.copytree(jsrcs_dir, os.path.join(args.bindir, 'src'), dirs_exist_ok=True)
  169. return 0
  170. if __name__ == '__main__':
  171. sys.exit(main())