import os import sys import shutil import argparse # Explicitly enable local imports # Don't forget to add imported scripts to inputs of the calling command! sys.path.append(os.path.dirname(os.path.abspath(__file__))) import process_command_files as pcf import java_pack_to_file as jcov import resolve_java_srcs as resolve from autotar_gendirs import unpack_dir def writelines(f, rng): f.writelines(item + '\n' for item in rng) class SourcesSorter: FILE_ARG = 1 RESOURCES_DIR_ARG = 2 SRCDIR_ARG = 3 JSOURCES_DIR_ARG = 4 def __init__(self, moddir): self.moddir = moddir self.next_arg = SourcesSorter.FILE_ARG self.cur_resources_list_file = None self.cur_jsources_list_file = None self.cur_srcdir = None self.cur_resources = [] self.cur_jsources = [] def sort_args(self, remaining_args): for src in remaining_args: if self.next_arg == SourcesSorter.RESOURCES_DIR_ARG: assert self.cur_resources_list_file is None self.cur_resources_list_file = src self.next_arg = SourcesSorter.FILE_ARG continue elif self.next_arg == SourcesSorter.JSOURCES_DIR_ARG: assert self.cur_jsources_list_file is None self.cur_jsources_list_file = src self.next_arg = SourcesSorter.FILE_ARG continue elif self.next_arg == SourcesSorter.SRCDIR_ARG: assert self.cur_srcdir is None self.cur_srcdir = src if os.path.isabs(src) else os.path.join(self.moddir, src) self.next_arg = SourcesSorter.FILE_ARG continue if src == '--resources': if self.cur_resources_list_file is not None: with open(self.cur_resources_list_file, 'w') as f: writelines(f, self.cur_resources) self.cur_resources_list_file = None self.cur_srcdir = None self.cur_resources = [] self.next_arg = SourcesSorter.RESOURCES_DIR_ARG continue if src == '--jsources': if self.cur_jsources_list_file is not None: with open(self.cur_jsources_list_file, 'w') as f: writelines(f, self.cur_jsources) self.cur_jsources_list_file = None self.cur_jsources = [] self.next_arg = SourcesSorter.JSOURCES_DIR_ARG continue elif src == '--srcdir': self.next_arg = SourcesSorter.SRCDIR_ARG continue yield src if self.cur_resources_list_file is not None: with open(self.cur_resources_list_file, 'w') as f: writelines(f, self.cur_resources) if self.cur_jsources_list_file is not None: with open(self.cur_jsources_list_file, 'w') as f: writelines(f, self.cur_jsources) class SourcesConsumer: def __init__(self, source_root, with_kotlin, with_coverage): self.source_root = source_root self.with_kotlin = with_kotlin self.with_coverage = with_coverage self.java = [] self.kotlin = [] self.coverage = [] def consume(self, src, sorter): if src.endswith(".java"): self.java.append(src) self.kotlin.append(src) self._add_rel_src_to_coverage(src) elif self.with_kotlin and src.endswith(".kt"): self.kotlin.append(src) self._add_rel_src_to_coverage(src) else: assert sorter.cur_srcdir is not None and sorter.cur_resources_list_file is not None sorter.cur_resources.append(os.path.relpath(src, sorter.cur_srcdir)) if sorter.cur_jsources_list_file is not None: assert sorter.cur_srcdir is not None sorter.cur_jsources.append(os.path.relpath(src, sorter.cur_srcdir)) def _add_rel_src_to_coverage(self, src): if not self.with_coverage or not self.source_root: return rel = os.path.relpath(src, self.source_root) if not rel.startswith('..' + os.path.sep): self.coverage.append(rel) def prepare_build_dirs(bindir, with_sources_jar): dirs = ['cls', 'misc'] if with_sources_jar: dirs.append('src') for dir in [os.path.join(bindir, dirname) for dirname in dirs]: if not os.path.exists(dir): os.makedirs(dir) def split_cmd_by_delim(cmd, delim='DELIM'): result = [[]] for arg in cmd: if arg == delim: result.append([]) else: result[-1].append(arg) return result[0], result[1:] def main(): args, resolve_args = split_cmd_by_delim(pcf.get_args(sys.argv[1:])) parser = argparse.ArgumentParser() parser.add_argument('--with-sources-jar', action='store_true') parser.add_argument('--moddir') parser.add_argument('--bindir') parser.add_argument('--java') parser.add_argument('--kotlin') parser.add_argument('--coverage') parser.add_argument('--source-root') args, remaining_args = parser.parse_known_args(args) prepare_build_dirs(args.bindir, args.with_sources_jar) src_sorter = SourcesSorter(args.moddir) src_consumer = SourcesConsumer( source_root=args.source_root, with_kotlin=True if args.kotlin else False, with_coverage=True if args.coverage else False) jsrcs_dir = None for src in src_sorter.sort_args(remaining_args): if src.endswith(".gentar"): unpack_dir(src, os.path.dirname(src)) continue if src.endswith(".jsrc"): jsrcs_dir = os.path.join(args.bindir, 'jsrcs') unpack_dir(src, jsrcs_dir) continue src_consumer.consume(src, src_sorter) if args.java: with open(args.java, 'w') as f: writelines(f, src_consumer.java) if args.kotlin: with open(args.kotlin, 'w') as f: writelines(f, src_consumer.kotlin) if args.coverage: jcov.write_coverage_sources(args.coverage, args.source_root, src_consumer.coverage) for rargs in resolve_args: resolve.cli_main(rargs, force_skip_source_jars=not args.with_sources_jar) if jsrcs_dir is not None: resolve.resolve_sources_and_fill_filelists( directory=jsrcs_dir, sources_file=args.java, resources_file=os.path.join(args.bindir, 'default.res.txt'), kotlin_sources_file=args.kotlin if args.kotlin else None, include_patterns=['**/*'], exclude_patterns=[], resolve_kotlin=True if args.kotlin else False, append=True, all_resources=False, ) if args.with_sources_jar: # TODO ugly hack here. Once jar directory preparation will be handled in a single script # sources copying should use common API here as well. Current "common API" is to populate # file with files to be copied by another script. It can't be uses here since there is no # way to send filelist to that external script from current point in code shutil.copytree(jsrcs_dir, os.path.join(args.bindir, 'src'), dirs_exist_ok=True) return 0 if __name__ == '__main__': sys.exit(main())