class Main(object): def __init__( self, clean=False, debug=False, gen=None, include_dir_paths=None, log_filename=None, thrift_file_paths=None ): object.__init__(self) self.__clean = clean self.__debug = debug if gen is None: gen = {} self.__gen = gen if include_dir_paths is None: include_dir_paths = tuple() else: include_dir_paths_dedup = [] for include_dir_path in include_dir_paths: if include_dir_path not in include_dir_paths_dedup: include_dir_paths_dedup.append(include_dir_path) include_dir_paths = tuple(include_dir_paths_dedup) self.__compiler = Compiler(include_dir_paths=include_dir_paths) self.__log_filename = log_filename if thrift_file_paths is None: thrift_file_paths = tuple() self.__thrift_file_paths = thrift_file_paths @classmethod def _add_arguments(cls, argument_parser): argument_parser.add_argument( '-d', '--debug', action='store_true', help='enable debug logging' ) argument_parser.add_argument( '--clean', action='store_true', help="clean out generated code" ) argument_parser.add_argument( '--dry-run', action='store_true', help="compile but don't generate code" ) argument_parser.add_argument( '-l', '--log-filename', help='file name to log messages to' ) argument_parser.add_argument( '--gen', action='append', help='language[:key1=val1[,key2,[key3=val3]]]' ) argument_parser.add_argument( 'thrift_file_paths', nargs='*' ) def _main(self): logging_kwds = { 'format': '%(asctime)s:%(module)s:%(lineno)s:%(name)s:%(levelname)s: %(message)s', 'level': logging.WARN } # @IgnorePep8 if self.__debug: logging_kwds['level'] = logging.DEBUG if self.__log_filename is not None: logging_kwds['filename'] = self.__log_filename logging.basicConfig(**logging_kwds) if self.__clean: self._clean() return self._compile() def _clean(self): raise NotImplementedError(self.__class__.__module__ + '.' + self.__class__.__name__ + '.clean') def _compile(self): raise NotImplementedError(self.__class__.__module__ + '.' + self.__class__.__name__ + '.compile') def _compile_thrift_file(self, thrift_file_path, document_root_dir_path=None, generator=None, out=None): try: for i in xrange(2): if generator is not None: gen = generator.__class__.__name__ gen = gen[:gen.index('Generator')] gen = decamelize(gen) if len(self.__gen) > 0 and gen not in self.__gen: return else: generator = Generator() try: document = \ self.__compiler.compile( document_root_dir_path=document_root_dir_path, generator=generator, thrift_file_path=thrift_file_path, ) except (ScanException, CompileException): if self.__debug: raise if i == 0: logging.basicConfig(level=logging.DEBUG) continue # Try again with debugging on else: raise if out is not None: document.save(out) elif isinstance(generator, LintGenerator): document.lint() return document except: logging.error("exception compiling %s", thrift_file_path) raise def _get_thrift_file_paths(self, thrift_dir_path): thrift_file_paths = self.__thrift_file_paths for dir_path, _, file_names in os.walk(thrift_dir_path): for file_name in file_names: if os.path.splitext(file_name)[1] != '.thrift': continue thrift_file_name = file_name thrift_file_path = os.path.join(dir_path, thrift_file_name) if len(thrift_file_paths) > 0 and not thrift_file_path in thrift_file_paths: continue yield thrift_file_path @classmethod def main(cls, args=None, **kwds): if args is None: argument_parser = argparse.ArgumentParser() cls._add_arguments(argument_parser) args = argument_parser.parse_args() parsed_gen = {} if args.gen is not None: for gen in args.gen: gen = gen.split(':', 1) if len(gen) == 1: parsed_gen[gen[0]] = {} elif len(gen) == 2: gen, gen_kwds_str = gen gen_kwds = {} for gen_kwd in gen_kwds_str.split(','): gen_kwd_split = gen_kwd.split('=', 1) if len(gen_kwd_split) == 1: gen_kwds[gen_kwd_split[0]] = None else: gen_kwds[gen_kwd_split[0]] = gen_kwd_split[1] parsed_gen[gen] = gen_kwds cls( clean=args.clean, debug=args.debug, gen=parsed_gen, log_filename=args.log_filename, thrift_file_paths=args.thrift_file_paths, **kwds )._main()