def _convert(self, src_path):
        """return converted all lines of one source file"""
        results           = []
        line_generator    = LineGenerator(src_path)
        self.next_rules   = []
        self.indent_level = 0

        try:
            while not line_generator.is_end():
                prev_line   = line_generator.get_prev_line()
                line        = line_generator.get_current_line()
                next_line   = line_generator.get_next_line()
                result_line = ''

                if re.search('^\s*\$', line):
                    result_line = self._get_result_by_template(line_generator, src_path)
                else:
                    result_line = self._get_result_by_define(prev_line, line, next_line)

                #print result_line ##### debug
                results.append(result_line + '\n')
                line_generator.proceed()
        except:
            prev_line   = line_generator.get_prev_line()
            line        = line_generator.get_current_line()
            next_line   = line_generator.get_next_line()
            cprint('<red:Convert Error: />line %d' % line_generator.get_line_number())
            cprint('  <lred:%s/>\n> <lred:%s/>\n  <lred:%s/>' % (prev_line, line, next_line))
            raise
        return results
 def go(self):
     """convert all source files according to defines and templates"""
     for i, src_path in enumerate(self.src_files):
         length = len(self.src_files)
         rate   = (i + 1.0) / length * 100
         cprint('%d / %d <yellow:(%5.1f %%)/> ::: %s' % (i+1, length, rate, src_path))
         convert_result = self._convert(src_path)
         self._write_file(convert_result, src_path, self.build_path, self.ext_map)
    def _get_output_path(self, src_path, build_dir, ext_map):
        groups = re.search('^.*?/(.*)(\..+)', src_path).groups()
        src_file_name   = groups[0]
        src_file_ext    = groups[1]
        try:
            build_file_ext  = ext_map[src_file_ext]
        except:
            cprint('<red:key of extension table not found: /><purple:%s/>' % src_file_ext)
            cprint('<lred:    * check your tkgen.cfg file./>\n')
            raise

        build_file_name = build_dir + src_file_name + build_file_ext
        return build_file_name
    def _write_file(self, text_list, src_path, build_dir, ext_map):
        if not re.search('^(.*)/', src_path):
            return

        build_file_name = self._get_output_path(src_path, build_dir, ext_map)
        dir_to_build_file = re.search('^(.*)/', build_file_name).group(1)
        if not os.path.isdir(dir_to_build_file):
            os.makedirs(dir_to_build_file)

        file_obj = codecs.open(build_file_name, 'w', 'utf-8')
        file_obj.writelines(text_list)
        file_obj.close()
        cprint((' ' * 17) + '-> <blue:%s/>' % build_file_name)
Example #5
0
def run_postprocess(module_path, opts, config):
    try:
        module = __import__(
            module_path, globals(), locals(), [''], -1
        )
    except ImportError:
        cprint("<red:Import Error: module file for postprocess not found: %s/>" % (module_path))
        sys.exit()

    entry_func_name = 'postprocess'
    try:
        func = getattr(module, entry_func_name)
        func(opts, config)
    except AttributeError:
        cprint("<red:Attribute Error: postprocess function <%s.%s> not found/>" \
               % (module_path, entry_func_name))
        sys.exit()
 def _import_modules(self, module_files):
     """モジュール名のキーにモジュールオブジェクトを入れた辞書を返す"""
     result = {}
     for file_path in module_files:
         # 'package/module.py' -> 'package.module'
         groups      = re.search('^(.*)/(.*)\.py$', file_path).groups()
         package     = groups[0]
         module_name = groups[1]
         module_path = (package + '.' + module_name)
         try:
             result[module_name] = __import__(
                 module_path, globals(), locals(), [''], -1  # これまだ引数完全に理解してない
             )
         except ImportError:
             cprint("<red:Import Error: module file not found: %s/>" % (module_path))
             sys.exit()
     # print result
     return result
Example #7
0
def get_updated_src_files(src_files, last_update_timestamps, option_all=False):
    updated_src_files = []
    # return copy of all source file paths
    if option_all:
        cprint('<purple:option "all" is True: update all source files./>')
        return [path for path in src_files]

    # return only updated source file paths
    for path in src_files:
        t = tkutil.file.get_timestamp(path)
        color = 'white'
        tag   = ' ' * 10
        if path in last_update_timestamps:
            last_update = last_update_timestamps[path]
            if t > last_update:
                updated_src_files.append(path)
                last_update_timestamps[path] = t
                color = 'yellow'
                tag   = '[ updated]'
        else:
            updated_src_files.append(path)
            last_update_timestamps[path] = t
            color = 'green'
            tag   = '[new file]'

        cprint ('<%s:%s %s %s-%s %s:%s:%s ::: %s/>'
            % (color, tag, t[:4], t[4:6], t[6:8], t[8:10], t[10:12], t[12:], path)
        )
    cprint('<cyan:number of updated files: %d/>' % len(updated_src_files))
    return updated_src_files
Example #8
0
def main(args, opts):
    print('arguments: %s' % args)
    print('options  : %s' % opts)
    print ''

    #--- check output path
    if not opts.output_path:
        cprint('<red:[USAGE] ./setup.py -o path/to/skeleton />\n')
        return 1

    outpath = opts.output_path
    if not (outpath.endswith('/')):
        outpath += '/'

    (status, stdout) = commands.getstatusoutput('cd ' + outpath)
    if (status != 0):
        cprint('<red:[Error] output_path not found: /><yellow:%s/>\n' % outpath)
        return 1


    #--- load config file
    config_path = DEFAULT_CONFIG_PATH
    if (opts.config_path):
        config_path = opts.config_path

    cprint('<yellow:load config file:/> %s' % config_path)
    config = Config(config_path)
    config.describe()


    #--- dryrun?
    if opts.dryrun:
        cprint('<red:DRY RUN MODE./>')
        return 1


    #--- execute shell commands
    print ''
    shell_cmds = get_shell_commands(outpath, config)
    for cmd in shell_cmds:
        cprint('<cyan:$ %s/>' % cmd)
        cprint('<blue:' + '-' * len(cmd) + '/>')
        (status, stdout) = commands.getstatusoutput(cmd)
        print stdout
        if (status != 0):
            cprint('<red:[Error]/>')
            return 1

    print 'completed.'
    return 0
    def _get_result_by_template(self, line_generator, src_path):
        result_lines = ''

        #----- テンプレート呼び出し全体を1つの文字列に
        # 閉じ括弧が現れるまでをまとめる
        template_unit = line_generator.get_current_line()
        while not re.search('\)', template_unit):
            template_unit += ('\n' + line_generator.proceed_and_get_line())

        # <<< があれば >>> があるまでもまとめる
        if re.search('<<', template_unit) or re.search('<<', line_generator.get_next_line()):
            while not re.search('\n>>', template_unit):
                template_unit += ('\n' + line_generator.proceed_and_get_line())
                if line_generator.is_end():
                    cprint("<red:Error: >> is not found/>")
                    print "processing data:\n" + template_unit
                    sys.exit()

        module_name    = ''
        func_name      = ''
        arguments_yaml = ''
        source_strings = ''
        p1 = re.compile('\$(.*?)\.(.*?)\((.*?)\)', re.DOTALL)  # ドットを改行文字にもマッチさせる
        if re.search(p1, template_unit):
            groups = re.search(p1, template_unit).groups()
            module_name    = groups[0]
            func_name      = groups[1]
            arguments_yaml = groups[2]

        p2 = re.compile('<<(.*)>>', re.DOTALL)
        if re.search(p2, template_unit):
            source_strings = re.search(p2, template_unit).group(1)

        # 関数に渡す引数を YAML で解釈して辞書オブジェクトに
        args = yaml.load(arguments_yaml)

        # define での変換用
        def convert(src):
            converter = RegConverter(src, self.defines)
            converter.convert()
            return converter.get_result()

        # 安全なアクセス用 getter
        def data_getter(key):
            try:
                return args[key]
            except:
                return ''
            return None

        # 指定されたモジュール内の関数を呼んでテンプレート処理の結果を得る
        module = self.template_modules[module_name]
        func   = getattr(module, func_name)
        arg_dict = MyDict({
            'CONVERTER': convert,
            'DATA'     : args,
            'data'     : SafetyGetter(args),
            'SOURCE'   : source_strings,
            'SRC_PATH' : src_path,
            'OUT_PATH' : self._get_output_path(src_path, self.build_path, self.ext_map)
        })
        result_lines = func(arg_dict)
        return result_lines
Example #10
0
def main(opts={}, config_path='tkgen.cfg'):
    # initial time
    start_time = time.time()

    # load config file
    cprint('<lred:load config file:/> %s' % config_path)
    config = Config(config_path)
    config.describe()

    # list rule file paths
    rule_file_pattern = config.file_pattern.rule
    cprint('\n\n<lred:target rule files:/> %s%s' % (config.path.rule, rule_file_pattern))
    put_line()
    rule_files = []
    for path in tkutil.file.get_all_files(config.path.rule, rule_file_pattern):
        print path
        rule_files.append(path)

    # list source file paths
    src_file_pattern = config.file_pattern.src
    cprint('\n\n<lred:target source files:/> %s%s' % (config.path.src, src_file_pattern))
    put_line()
    src_files = []
    for path in tkutil.file.get_all_files(config.path.src, src_file_pattern):
        print path
        src_files.append(path)

    # compare timestamp of files and erase not-updated file path
    cprint('\n\n<lred:compare timestamp of files with last update time/>')
    put_line()
    last_update_timestamps = tkutil.file.load_obj_from_file(config.path.last_update) or {}
    updated_src_files = get_updated_src_files(
        src_files, last_update_timestamps, opts.all
    )

    # list python module file path for template processing
    cprint('\n\n<lred:target template module files:/> %s*.py' % config.path.module)
    put_line()
    module_files = []
    for path in tkutil.file.get_all_files(config.path.module, '*.py'):
        if not path == (config.path.module + '__init__.py'):
            print path
            module_files.append(path)

    # load rules, sources, and modules
    template_engine = TemplateEngine(
        rule_files, updated_src_files, module_files, config.path.build, config.extension_map
    )

    # convert sources
    cprint('\n\n<lred:start converting.../>')
    put_line()
    template_engine.go()

    # save timestamps
    tkutil.file.save_obj_to_file(last_update_timestamps, config.path.last_update)

    # post process
    cprint('\n\n<lred:start post process:/> %s' % config.module.postprocess)
    put_line()
    run_postprocess(config.module.postprocess, opts, config)

    # print processing time
    end_time = time.time()
    print '\n\nprocessing time: %.3f [sec]' % (end_time - start_time)

    cprint('<lred:tkgen completed./>')
    return 0