commit 4457a42e01c9cc40a05b0e810e9083af0176d487 Author: Nikita Orlov Date: Wed Jan 15 15:56:53 2020 +0300 initial commit diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..5c98b42 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,2 @@ +# Default ignored files +/workspace.xml \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..15a15b2 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..65531ca --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..b26b723 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/sources.combiner.iml b/.idea/sources.combiner.iml new file mode 100644 index 0000000..6711606 --- /dev/null +++ b/.idea/sources.combiner.iml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..bef95a6 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +# Source Combiner + +Скрипт для сбора исходных кодов проги в один текстовый файл. +Помощь по параметрам: ```source-combiner -h``` \ No newline at end of file diff --git a/source-combiner b/source-combiner new file mode 100755 index 0000000..b44ad5d --- /dev/null +++ b/source-combiner @@ -0,0 +1,159 @@ +#!/usr/bin/env python3 + +import os +import glob +import logging + + +class UncommentProcess: + + comment_state = False + code = 'uncomment' + + def start(self): + self.comment_state = False + + def exec(self, line) -> str: + """ + + :param str line: + :return str: + """ + stripped = line.strip() + if self.comment_state is True: + if stripped.endswith('*/'): + self.comment_state = False + return '' + else: + if stripped.startswith('/*'): + self.comment_state = True + return '' + + if stripped.startswith('//'): + return '' + + return line + + +class Combine: + + params = { + 'files_mask': "*.php", + 'input_dir': "./", + 'processes': ['uncomment'], + 'format': 'docx' + } + files = 0 + lines = 0 + processes = [] + + def __init__(self, output_file, params): + """ + + :param str output_file: + :param dict params: + """ + for key, val in params.items(): + if key in self.params.keys(): + self.params[key] = val + self.output_file_path = os.path.abspath(output_file) + logging.debug(self.params) + + for code in self.params['processes']: + if code == UncommentProcess.code: + self.processes.append(UncommentProcess()) + + + + def combine(self): + """ + + :return: + """ + self.files = 0 + + with open(self.output_file_path, 'w+') as f: + for file_path in self._find_files_in(self.params.get('input_dir'), self.params.get('files_mask')): + self.lines = 0 + logging.debug(file_path) + self._output_text_to_file(f, title=file_path) + + for line in self._collect_text_from_file(file_path, self.processes): + self._output_text_to_file(f, line=line) + self.lines += 1 + + self.files += 1 + logging.debug('combined {} lines'.format(self.lines)) + + logging.info('combined {} files'.format(self.files)) + + def _find_files_in(self, folder, mask): + folder = os.path.abspath(folder) + files_paths = glob.glob(os.path.join(folder, '**', mask), recursive=True) + logging.info('found {} files with [{}] mask'.format(len(files_paths), mask)) + for file_path in files_paths: + yield file_path + + def _collect_text_from_file(self, file_path, processes): + """ + + :param str file_path: + :param list processes: + :return: + """ + with open(file_path, 'r') as f: + for line in f.readlines(): + yield self._processor(line, processes) + + + def _processor(self, line, processes): + """ + + :param str line: + :param list processes: + :return: + """ + for process in processes: + line = process.exec(line) + + return line + + def _output_text_to_file(self, file, line=None, title=None): + """ + + :param file: + :param str line: + :param str title: + :return: + """ + if title is not None: + seps = '-'.rjust(128, '-') + file.write("\n{}\n{}\n{}\n".format(seps, title, seps)) + elif line is not None: + file.write(line) + + +if __name__ == '__main__': + + import argparse + + parser = argparse.ArgumentParser() + parser.add_argument('output_file', help="файл, в который запишется исходный код", type=str) + parser.add_argument('-m', '--files_mask', help="маска для выбора файлов", default=Combine.params['files_mask'], type=str) + parser.add_argument('-i', '--input_dir', + help="директория, в которой будут взяты все файлы подходящие под маску", + default=Combine.params['input_dir']) + parser.add_argument('-p', '--processes', help="действия, выполняемые при обработке", type=list, + default=Combine.params['processes']) + parser.add_argument('-f', '--format', help="формат output_file", default=Combine.params['format']) + parser.add_argument('-l', '--log', default='debug') + parser.description = """ + Взять все файлы в указанной директории, подходящие по маске, и объединить их в один текстовый файл + """ + args = parser.parse_args() + + loglevel = getattr(logging, args.log.upper()) + logging.basicConfig(format='%(levelname)s:%(message)s', level=loglevel) + + combiner = Combine(args.output_file, vars(args)) + combiner.combine()