From 98d2d81045c1687caf0687502b98b21dd3eea255 Mon Sep 17 00:00:00 2001 From: Dennis Fink Date: Mon, 18 Nov 2019 10:01:50 +0100 Subject: Bumped version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setup.py') diff --git a/setup.py b/setup.py index 80aca3e..f1e4de2 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ URL = 'https://projects.metalgamer.eu/patternutils' EMAIL = 'dennis.fink@c3l.lu' AUTHOR = 'Dennis Fink' -VERSION = '0.0.5' +VERSION = '0.0.6' ENTRY_POINTS = { 'console_scripts': [ 'pmatch=patternutils.commands.pmatch:pmatch', -- cgit v1.3.1 From 64295b80512a7a448d5a42803fa3fbac22d7bd25 Mon Sep 17 00:00:00 2001 From: Dennis Fink Date: Mon, 18 Nov 2019 16:48:14 +0100 Subject: Bumped version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setup.py') diff --git a/setup.py b/setup.py index f1e4de2..922e7e5 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ URL = 'https://projects.metalgamer.eu/patternutils' EMAIL = 'dennis.fink@c3l.lu' AUTHOR = 'Dennis Fink' -VERSION = '0.0.6' +VERSION = '0.0.7' ENTRY_POINTS = { 'console_scripts': [ 'pmatch=patternutils.commands.pmatch:pmatch', -- cgit v1.3.1 From 9c096d663b113e40e9df30f47dd5133e69f6d03d Mon Sep 17 00:00:00 2001 From: Dennis Fink Date: Fri, 29 Nov 2019 15:16:28 +0100 Subject: Run black autoformatter on files --- patternutils/commands/patterncfg.py | 126 ++++++++++++++++++++++++------------ patternutils/commands/pmatch.py | 110 ++++++++++++++++++++----------- patternutils/commands/targs.py | 79 +++++++++++++--------- patternutils/commands/tln.py | 117 ++++++++++++++++++++++----------- patternutils/commands/tmv.py | 101 ++++++++++++++++++++--------- patternutils/config.py | 12 ++-- patternutils/match.py | 4 +- patternutils/template.py | 20 +++--- patternutils/utils.py | 12 ++-- setup.py | 40 ++++++------ 10 files changed, 398 insertions(+), 223 deletions(-) (limited to 'setup.py') diff --git a/patternutils/commands/patterncfg.py b/patternutils/commands/patterncfg.py index 5215d56..b75fbdf 100644 --- a/patternutils/commands/patterncfg.py +++ b/patternutils/commands/patterncfg.py @@ -18,100 +18,131 @@ else: from .. import config -CURRENT_SUPPORTED_PROGRAMS = ('pmatch', 'tmv', 'targs', 'tln') +CURRENT_SUPPORTED_PROGRAMS = ("pmatch", "tmv", "targs", "tln") -@click.group(context_settings={'help_option_names': ('-h', '--help', '-?')}) +@click.group(context_settings={"help_option_names": ("-h", "--help", "-?")}) def patterncfg() -> None: pass -@patterncfg.command(name='init', help='initialize config folders') +@patterncfg.command(name="init", help="initialize config folders") def init() -> None: for dir in CURRENT_SUPPORTED_PROGRAMS: os.makedirs(os.path.join(config.CONFIG_PATH, dir), exist_ok=True) -@patterncfg.command(name='list', help='list all patternutils template files') +@patterncfg.command(name="list", help="list all patternutils template files") def list() -> None: try: for d in os.listdir(config.CONFIG_PATH): - click.secho(d, fg='blue') + click.secho(d, fg="blue") for f in os.listdir(os.path.join(config.CONFIG_PATH, d)): - click.echo('└── {}'.format(f)) + click.echo("└── {}".format(f)) except FileNotFoundError as e: - click.secho('{} not found! Please run patterncfg init first.'.format(e.filename), fg='red', err=True) + click.secho( + "{} not found! Please run patterncfg init first.".format(e.filename), + fg="red", + err=True, + ) raise SystemExit -@patterncfg.command(name='add', help='add new template file') -@click.option('-t', '--template-engine', default=None, type=click.Choice(('python', 'jinja2')), - help='select the template engine to use. Only applicable for tmv, targs and tln') -@click.argument('command', required=True, type=click.Choice(CURRENT_SUPPORTED_PROGRAMS)) -@click.argument('name') +@patterncfg.command(name="add", help="add new template file") +@click.option( + "-t", + "--template-engine", + default=None, + type=click.Choice(("python", "jinja2")), + help="select the template engine to use. Only applicable for tmv, targs and tln", +) +@click.argument("command", required=True, type=click.Choice(CURRENT_SUPPORTED_PROGRAMS)) +@click.argument("name") def add(template_engine: Optional[str], command: str, name: str) -> None: - if command == 'pmatch': - fileext = 'regex' + if command == "pmatch": + fileext = "regex" else: - if template_engine not in ('python', 'jinja2'): - fileext = 'python' + if template_engine not in ("python", "jinja2"): + fileext = "python" else: fileext = template_engine - filename = os.path.join(config.CONFIG_PATH, command, '{}.{}'.format(name, fileext)) + filename = os.path.join(config.CONFIG_PATH, command, "{}.{}".format(name, fileext)) click.edit(filename=filename) -@patterncfg.command(name='remove', help='remove template file') -@click.option('-c', '--command', default=None, type=click.Choice(CURRENT_SUPPORTED_PROGRAMS), - help='select the command from which to remove the file') -@click.argument('name') +@patterncfg.command(name="remove", help="remove template file") +@click.option( + "-c", + "--command", + default=None, + type=click.Choice(CURRENT_SUPPORTED_PROGRAMS), + help="select the command from which to remove the file", +) +@click.argument("name") def remove(command: Optional[str], name: str) -> None: files = config.find_templates(name, command) if not files: - click.secho('No files found!', fg='red', err=True) + click.secho("No files found!", fg="red", err=True) raise SystemExit elif len(files) != 1: - click.secho('Multiple files found! Please specify the command from which to remove the file.', fg='red', err=True) + click.secho( + "Multiple files found! Please specify the command from which to remove the file.", + fg="red", + err=True, + ) for f in files: - click.secho(f, fg='red', err=True) + click.secho(f, fg="red", err=True) raise SystemExit else: os.remove(files[0]) -@patterncfg.command(name='view', help='view template file') -@click.option('-c', '--command', default=None, type=click.Choice(CURRENT_SUPPORTED_PROGRAMS), - help='select the command from which to view the file') -@click.option('--color/--no-color', is_flag=True, default=has_pygments, - help='Colorize output using pygments') -@click.argument('name') +@patterncfg.command(name="view", help="view template file") +@click.option( + "-c", + "--command", + default=None, + type=click.Choice(CURRENT_SUPPORTED_PROGRAMS), + help="select the command from which to view the file", +) +@click.option( + "--color/--no-color", + is_flag=True, + default=has_pygments, + help="Colorize output using pygments", +) +@click.argument("name") def view(name: str, command: str, color: bool) -> None: files = config.find_templates(name, command) if not files: - click.secho('No files found!', fg='red', err=True) + click.secho("No files found!", fg="red", err=True) raise SystemExit elif len(files) != 1: - click.secho('Multiple files found! Please specify the command from which to view the file.', fg='red', err=True) + click.secho( + "Multiple files found! Please specify the command from which to view the file.", + fg="red", + err=True, + ) for f in files: - click.secho(f, fg='red', err=True) + click.secho(f, fg="red", err=True) raise SystemExit else: filename = files[0] try: - with open(filename, encoding='utf-8') as fd: + with open(filename, encoding="utf-8") as fd: text = fd.read() except FileNotFoundError: - click.secho('File not found!', fg='red', err=True) + click.secho("File not found!", fg="red", err=True) raise SystemExit else: if color: - if filename.endswith('jinja2'): + if filename.endswith("jinja2"): lexer = DjangoLexer else: lexer = Python3Lexer @@ -119,20 +150,29 @@ def view(name: str, command: str, color: bool) -> None: click.echo(text[:-1]) -@patterncfg.command(name='edit', help='edit a template file') -@click.option('-c', '--command', default=None, type=click.Choice(CURRENT_SUPPORTED_PROGRAMS), - help='select the command from which to edit the file') -@click.argument('name') +@patterncfg.command(name="edit", help="edit a template file") +@click.option( + "-c", + "--command", + default=None, + type=click.Choice(CURRENT_SUPPORTED_PROGRAMS), + help="select the command from which to edit the file", +) +@click.argument("name") def edit(name: str, command: str) -> None: files = config.find_templates(name, command) if not files: - click.secho('No files found!', fg='red', err=True) + click.secho("No files found!", fg="red", err=True) raise SystemExit elif len(files) != 1: - click.secho('Multiple files found! Please specify the command from which to edit the file.', fg='red', err=True) + click.secho( + "Multiple files found! Please specify the command from which to edit the file.", + fg="red", + err=True, + ) for f in files: - click.secho(f, fg='red', err=True) + click.secho(f, fg="red", err=True) raise SystemExit else: filename = files[0] diff --git a/patternutils/commands/pmatch.py b/patternutils/commands/pmatch.py index 383ef8b..bd88a03 100644 --- a/patternutils/commands/pmatch.py +++ b/patternutils/commands/pmatch.py @@ -13,7 +13,9 @@ from .. import match as mat from .. import config -def walk(dir: str, recursive: bool = False, match_directories: bool = False) -> Generator[os.DirEntry, None, None]: +def walk( + dir: str, recursive: bool = False, match_directories: bool = False +) -> Generator[os.DirEntry, None, None]: for entry in os.scandir(dir): is_dir = entry.is_dir() if recursive and is_dir: @@ -25,9 +27,7 @@ def walk(dir: str, recursive: bool = False, match_directories: bool = False) -> def apply_regex( - walk_function: Iterator[Any], - regex_pattern: Pattern[str], - match_full_path: bool, + walk_function: Iterator[Any], regex_pattern: Pattern[str], match_full_path: bool, ) -> Tuple[List[Dict[str, str]], bool]: matches = [] @@ -37,14 +37,14 @@ def apply_regex( try: match = mat.apply(subject, regex_pattern) except ValueError: - click.secho('{} did not match'.format(subject), fg='red', err=True) + click.secho("{} did not match".format(subject), fg="red", err=True) has_invalid_matches = True else: - match['_path'] = f.path - match['_name'] = f.name - match['_abspath'] = os.path.abspath(f.path) - match['_realpath'] = os.path.realpath(f.path) - match['_relpath'] = os.path.relpath(f.path) + match["_path"] = f.path + match["_name"] = f.name + match["_abspath"] = os.path.abspath(f.path) + match["_realpath"] = os.path.realpath(f.path) + match["_relpath"] = os.path.relpath(f.path) matches.append(match) return matches, has_invalid_matches @@ -57,26 +57,58 @@ def json_dumps(data: Any, human_readable: bool = False) -> str: return json.dumps(data) -@click.command(context_settings={'help_option_names': ('-h', '--help', '-?')}) -@click.option('-d', '--directory', multiple=True, default=['./']) -@click.option('-m', '--match-directories', is_flag=True, default=False, - help='search directory name also for matches') -@click.option('-r', '--recursive', is_flag=True, default=False, - help='search directories recursively') -@click.option('--abort-on-no-match', is_flag=True, default=False, - help='exit if a name does not match the INPUT_PATTERN') -@click.option('--match-full-path', is_flag=True, default=False, - help='match on full path instead of only filename') -@click.option('-p', '--use-predefined-pattern', is_flag=True, default=False, - help='use predefined regex pattern') -@click.option('--stream', is_flag=True, default=False, - help='Output a stream of objects instead a list of objects') -@click.option('--human-readable', is_flag=True, default=False, - help='output the JSON in a human readable format') -@click.option('-v', '--verbose', is_flag=True, default=False, - help='explain what is being done') +@click.command(context_settings={"help_option_names": ("-h", "--help", "-?")}) +@click.option("-d", "--directory", multiple=True, default=["./"]) +@click.option( + "-m", + "--match-directories", + is_flag=True, + default=False, + help="search directory name also for matches", +) +@click.option( + "-r", + "--recursive", + is_flag=True, + default=False, + help="search directories recursively", +) +@click.option( + "--abort-on-no-match", + is_flag=True, + default=False, + help="exit if a name does not match the INPUT_PATTERN", +) +@click.option( + "--match-full-path", + is_flag=True, + default=False, + help="match on full path instead of only filename", +) +@click.option( + "-p", + "--use-predefined-pattern", + is_flag=True, + default=False, + help="use predefined regex pattern", +) +@click.option( + "--stream", + is_flag=True, + default=False, + help="Output a stream of objects instead a list of objects", +) +@click.option( + "--human-readable", + is_flag=True, + default=False, + help="output the JSON in a human readable format", +) +@click.option( + "-v", "--verbose", is_flag=True, default=False, help="explain what is being done" +) @click.version_option() -@click.argument('regex-pattern') +@click.argument("regex-pattern") def pmatch( regex_pattern: str, directory: List[str], @@ -92,27 +124,31 @@ def pmatch( if use_predefined_pattern: try: - regex_pattern, _ = config.load_template(regex_pattern, 'pmatch') + regex_pattern, _ = config.load_template(regex_pattern, "pmatch") except FileNotFoundError: - click.secho('File not found!', fg='red', err=True) + click.secho("File not found!", fg="red", err=True) raise SystemExit except RuntimeError: - click.secho('Multiple files found!', fg='red', err=True) + click.secho("Multiple files found!", fg="red", err=True) raise SystemExit try: regex_pattern_c = re.compile(regex_pattern) except re.error as e: if verbose: - click.secho('Regular expression could not be compiled!', fg='red', err=True) - click.secho(e.msg, fg='red', err=True) # type: ignore + click.secho("Regular expression could not be compiled!", fg="red", err=True) + click.secho(e.msg, fg="red", err=True) # type: ignore raise SystemExit # Monkey patch walk function to include commandline options - walk_function = functools.partial(walk, recursive=recursive, match_directories=match_directories) + walk_function = functools.partial( + walk, recursive=recursive, match_directories=match_directories + ) new_walk = itertools.chain.from_iterable(map(walk_function, directory)) - matches, has_invalid_matches = apply_regex(new_walk, regex_pattern_c, match_full_path) + matches, has_invalid_matches = apply_regex( + new_walk, regex_pattern_c, match_full_path + ) if has_invalid_matches and abort_on_no_match: raise SystemExit @@ -124,5 +160,5 @@ def pmatch( click.echo(json_dumps(matches, human_readable)) -if __name__ == '__main__': +if __name__ == "__main__": pmatch() diff --git a/patternutils/commands/targs.py b/patternutils/commands/targs.py index 5971ea2..e25679f 100644 --- a/patternutils/commands/targs.py +++ b/patternutils/commands/targs.py @@ -34,25 +34,46 @@ def run_command( run(prepared_command) -@click.command(context_settings={'help_option_names': ('-h', '--help', '-?')}) -@click.option('--read-from', default='-', type=click.File('r')) -@click.option('-s', '--shell', is_flag=True, default=False, - help='run command in a shell') -@click.option('-t', '--template-engine', default='python', type=click.Choice(['python', 'jinja2']), - help='select the template engine to use') -@click.option('-v', '--verbose', is_flag=True, default=False, - help='explain what is being done') -@click.option('-P', '--max-procs', default=1, type=click.IntRange(min=0, clamp=True)) -@click.option('-p', '--use-predefined-template', is_flag=True, default=False, - help='use predefined template') -@click.option('--redirect-stdout', is_flag=True, default=False, - help='Redirect stdout to /dev/null') -@click.option('--redirect-stderr', is_flag=True, default=False, - help='Redirect stderr to /dev/null') -@click.option('--stream', is_flag=True, defaults=False, - help='Input is a stream of JSON objects') +@click.command(context_settings={"help_option_names": ("-h", "--help", "-?")}) +@click.option("--read-from", default="-", type=click.File("r")) +@click.option( + "-s", "--shell", is_flag=True, default=False, help="run command in a shell" +) +@click.option( + "-t", + "--template-engine", + default="python", + type=click.Choice(["python", "jinja2"]), + help="select the template engine to use", +) +@click.option( + "-v", "--verbose", is_flag=True, default=False, help="explain what is being done" +) +@click.option("-P", "--max-procs", default=1, type=click.IntRange(min=0, clamp=True)) +@click.option( + "-p", + "--use-predefined-template", + is_flag=True, + default=False, + help="use predefined template", +) +@click.option( + "--redirect-stdout", + is_flag=True, + default=False, + help="Redirect stdout to /dev/null", +) +@click.option( + "--redirect-stderr", + is_flag=True, + default=False, + help="Redirect stderr to /dev/null", +) +@click.option( + "--stream", is_flag=True, defaults=False, help="Input is a stream of JSON objects" +) @click.version_option() -@click.argument('command') +@click.argument("command") def targs( command: str, read_from: click.File, @@ -72,23 +93,23 @@ def targs( else: data = [json.loads(line) for line in read_from] except json.JSONDecodeError: - click.secho('JSON not valid!', fg='red', err=True) + click.secho("JSON not valid!", fg="red", err=True) raise SystemExit if use_predefined_template: try: - command, template_engine = config.load_template(command, 'targs') + command, template_engine = config.load_template(command, "targs") except FileNotFoundError: - click.secho('File not found!', fg='red', err=True) + click.secho("File not found!", fg="red", err=True) raise SystemExit except RuntimeError: - click.secho('Multiple files found!', fg='red', err=True) + click.secho("Multiple files found!", fg="red", err=True) raise SystemExit try: render = template.get_render_function(command, engine=template_engine) except RuntimeError: - click.secho('jinja2 not installed!', fg='red', err=True) + click.secho("jinja2 not installed!", fg="red", err=True) raise SystemExit max_procs = utils.max_procs() if max_procs == 0 else max_procs @@ -96,16 +117,10 @@ def targs( stdout = subprocess.DEVNULL if redirect_stdout else None stderr = subprocess.DEVNULL if redirect_stderr else None patched_subprocess = functools.partial( - subprocess.run, - shell=shell, - stdout=stdout, - stderr=stderr, + subprocess.run, shell=shell, stdout=stdout, stderr=stderr, ) patched_run_command = functools.partial( - run_command, - render=render, - run=patched_subprocess, - shell=shell, + run_command, render=render, run=patched_subprocess, shell=shell, ) if max_procs == 1: for r in data: @@ -115,5 +130,5 @@ def targs( p.map(patched_run_command, data) -if __name__ == '__main__': +if __name__ == "__main__": targs() diff --git a/patternutils/commands/tln.py b/patternutils/commands/tln.py index 27112ec..4e21f1f 100644 --- a/patternutils/commands/tln.py +++ b/patternutils/commands/tln.py @@ -20,32 +20,74 @@ def link_file(old_filename: str, new_filename: str, symbolic: bool) -> None: os.link(old_filename, new_filename) -@click.command(context_settings={'help_option_names': ('-h', '--help', '-?')}) -@click.option('-i', '--interactive', is_flag=True, default=False, - help='prompt wether to remove destinations') -@click.option('-e', '--editor', is_flag=True, default=False, - help='Open an editor before renaming files to allow manual changes') -@click.option('-f', '--force', is_flag=True, default=False, - help='remove existing destination files') -@click.option('-s', '--symbolic', is_flag=True, default=False, - help='make symbolic links instead of hard links') -@click.option('-t', '--template-engine', default='python', type=click.Choice(['python', 'jinja2']), - help='select the template engine to use') -@click.option('-k', '--key', default='_abspath', - help='select the key to use as the source file') -@click.option('--stream', is_flag=True, default=False, - help='Input is a stream of JSON objects') -@click.option('-p', '--use-predefined-template', is_flag=True, default=False, - help='use predefined template') -@click.option('--read-from', default='-', type=click.File('r')) -@click.option('--abort-on-path-exist', is_flag=True, default=False, - help='exit if a renamed path already exists') -@click.option('-n', '--dry-run', is_flag=True, default=False, - help='perform a trial run with no changes made') -@click.option('-v', '--verbose', is_flag=True, default=False, - help='explain what is being done') +@click.command(context_settings={"help_option_names": ("-h", "--help", "-?")}) +@click.option( + "-i", + "--interactive", + is_flag=True, + default=False, + help="prompt wether to remove destinations", +) +@click.option( + "-e", + "--editor", + is_flag=True, + default=False, + help="Open an editor before renaming files to allow manual changes", +) +@click.option( + "-f", + "--force", + is_flag=True, + default=False, + help="remove existing destination files", +) +@click.option( + "-s", + "--symbolic", + is_flag=True, + default=False, + help="make symbolic links instead of hard links", +) +@click.option( + "-t", + "--template-engine", + default="python", + type=click.Choice(["python", "jinja2"]), + help="select the template engine to use", +) +@click.option( + "-k", "--key", default="_abspath", help="select the key to use as the source file" +) +@click.option( + "--stream", is_flag=True, default=False, help="Input is a stream of JSON objects" +) +@click.option( + "-p", + "--use-predefined-template", + is_flag=True, + default=False, + help="use predefined template", +) +@click.option("--read-from", default="-", type=click.File("r")) +@click.option( + "--abort-on-path-exist", + is_flag=True, + default=False, + help="exit if a renamed path already exists", +) +@click.option( + "-n", + "--dry-run", + is_flag=True, + default=False, + help="perform a trial run with no changes made", +) +@click.option( + "-v", "--verbose", is_flag=True, default=False, help="explain what is being done" +) @click.version_option() -@click.argument('output-pattern') +@click.argument("output-pattern") def tln( output_pattern: str, interactive: bool, @@ -58,7 +100,8 @@ def tln( key: str, stream: bool, abort_on_path_exist: bool, - dry_run, bool, + dry_run, + bool, verbose: bool, ) -> None: @@ -68,39 +111,41 @@ def tln( else: data = [json.loads(line) for line in read_from] except json.JSONDecodeError: - click.secho('JSON not valid!', fg='red', err=True) + click.secho("JSON not valid!", fg="red", err=True) raise SystemExit if use_predefined_template: try: - output_pattern, template_engine = config.load_template(output_pattern, 'tln') + output_pattern, template_engine = config.load_template( + output_pattern, "tln" + ) except FileNotFoundError: - click.secho('File not found!', fg='red', err=True) + click.secho("File not found!", fg="red", err=True) raise SystemExit except RuntimeError: - click.secho('Multiple files found!', fg='red', err=True) + click.secho("Multiple files found!", fg="red", err=True) raise SystemExit try: render = template.get_render_function(output_pattern, engine=template_engine) except RuntimeError: - click.secho('jinja2 not installed!', fg='red', err=True) + click.secho("jinja2 not installed!", fg="red", err=True) raise SystemExit - new_filenames = dict((entry['_abspath'], render(**entry)) for entry in data) + new_filenames = dict((entry["_abspath"], render(**entry)) for entry in data) if editor: try: new_filenames = utils.edit(new_filenames) except RuntimeError: - click.secho('You edit is not parseable!', fg='red', err=True) + click.secho("You edit is not parseable!", fg="red", err=True) raise SystemExit has_existing = False non_existing = {} for old, new in new_filenames.items(): if os.path.exists(new): - click.secho('{} does exist!'.format(new), fg='red', err=True) + click.secho("{} does exist!".format(new), fg="red", err=True) has_existing = True else: non_existing[old] = new @@ -115,8 +160,8 @@ def tln( for old, new in files_to_move: if verbose or interactive: - click.echo('{} -> {}'.format(old, new)) + click.echo("{} -> {}".format(old, new)) - if not (interactive and not click.confirm('Is the match correct?')): + if not (interactive and not click.confirm("Is the match correct?")): if not dry_run: link_file(old, new, symbolic) diff --git a/patternutils/commands/tmv.py b/patternutils/commands/tmv.py index 25932bc..eb6dc99 100644 --- a/patternutils/commands/tmv.py +++ b/patternutils/commands/tmv.py @@ -18,30 +18,65 @@ def move_file(old_filename: str, new_filename: str) -> None: shutil.move(old_filename, new_filename) -@click.command(context_settings={'help_option_names': ('-h', '--help', '-?')}) -@click.option('-i', '--interactive', is_flag=True, default=False, - help='prompt before renaming files') -@click.option('-e', '--editor', is_flag=True, default=False, - help='Open an editor before renaming files to allow manual changes') -@click.option('-f', '--force', is_flag=True, default=False, - help='force rename') -@click.option('-t', '--template-engine', default='python', type=click.Choice(['python', 'jinja2']), - help='select the template engine to use') -@click.option('-k', '--key', default='_abspath', - help='select the key to use as the source file') -@click.option('-s', '--stream', is_flag=True, default=False, - help='Input is a stream of JSON objects') -@click.option('-p', '--use-predefined-template', is_flag=True, default=False, - help='use predefined template') -@click.option('--read-from', default='-', type=click.File('r')) -@click.option('--abort-on-path-exist', is_flag=True, default=False, - help='exit if a renamed path already exists') -@click.option('-n', '--dry-run', is_flag=True, default=False, - help='perform a trial run with no changes made') -@click.option('-v', '--verbose', is_flag=True, default=False, - help='explain what is being done') +@click.command(context_settings={"help_option_names": ("-h", "--help", "-?")}) +@click.option( + "-i", + "--interactive", + is_flag=True, + default=False, + help="prompt before renaming files", +) +@click.option( + "-e", + "--editor", + is_flag=True, + default=False, + help="Open an editor before renaming files to allow manual changes", +) +@click.option("-f", "--force", is_flag=True, default=False, help="force rename") +@click.option( + "-t", + "--template-engine", + default="python", + type=click.Choice(["python", "jinja2"]), + help="select the template engine to use", +) +@click.option( + "-k", "--key", default="_abspath", help="select the key to use as the source file" +) +@click.option( + "-s", + "--stream", + is_flag=True, + default=False, + help="Input is a stream of JSON objects", +) +@click.option( + "-p", + "--use-predefined-template", + is_flag=True, + default=False, + help="use predefined template", +) +@click.option("--read-from", default="-", type=click.File("r")) +@click.option( + "--abort-on-path-exist", + is_flag=True, + default=False, + help="exit if a renamed path already exists", +) +@click.option( + "-n", + "--dry-run", + is_flag=True, + default=False, + help="perform a trial run with no changes made", +) +@click.option( + "-v", "--verbose", is_flag=True, default=False, help="explain what is being done" +) @click.version_option() -@click.argument('output-pattern') +@click.argument("output-pattern") def tmv( output_pattern: str, interactive: bool, @@ -72,23 +107,25 @@ def tmv( else: data = [json.loads(line) for line in read_from] except json.JSONDecodeError: - click.secho('JSON not valid!', fg='red', err=True) + click.secho("JSON not valid!", fg="red", err=True) raise SystemExit if use_predefined_template: try: - output_pattern, template_engine = config.load_template(output_pattern, 'tmv') + output_pattern, template_engine = config.load_template( + output_pattern, "tmv" + ) except FileNotFoundError: - click.secho('File not found!', fg='red', err=True) + click.secho("File not found!", fg="red", err=True) raise SystemExit except RuntimeError: - click.secho('Multiple files found!', fg='red', err=True) + click.secho("Multiple files found!", fg="red", err=True) raise SystemExit try: render = template.get_render_function(output_pattern, engine=template_engine) except RuntimeError: - click.secho('jinja2 not installed!', fg='red', err=True) + click.secho("jinja2 not installed!", fg="red", err=True) raise SystemExit new_filenames = dict((entry[key], render(**entry)) for entry in data) @@ -97,14 +134,14 @@ def tmv( try: new_filenames = utils.edit(new_filenames) except RuntimeError: - click.secho('You edit is not parseable!', fg='red', err=True) + click.secho("You edit is not parseable!", fg="red", err=True) raise SystemExit has_existing = False non_existing = {} for old, new in new_filenames.items(): if os.path.exists(new): - click.secho('{} does exist!'.format(new), fg='red', err=True) + click.secho("{} does exist!".format(new), fg="red", err=True) has_existing = True else: non_existing[old] = new @@ -119,8 +156,8 @@ def tmv( for old, new in files_to_move: if verbose or interactive: - click.echo('{} -> {}'.format(old, new)) + click.echo("{} -> {}".format(old, new)) - if not (interactive and not click.confirm('Is the match correct?')): + if not (interactive and not click.confirm("Is the match correct?")): if not dry_run: move_file(old, new) diff --git a/patternutils/config.py b/patternutils/config.py index 155789b..59b6c89 100644 --- a/patternutils/config.py +++ b/patternutils/config.py @@ -5,7 +5,7 @@ import click from typing import Tuple, List, Optional -CONFIG_PATH = click.get_app_dir('patternutils') +CONFIG_PATH = click.get_app_dir("patternutils") def load_template(template_name: str, command_name: Optional[str]) -> Tuple[str, str]: @@ -14,21 +14,21 @@ def load_template(template_name: str, command_name: Optional[str]) -> Tuple[str, files = find_templates(template_name, command_name) if len(files) == 1: template_file = files[0] - with open(template_file, encoding='utf-8') as f: + with open(template_file, encoding="utf-8") as f: template_lines = f.read() elif not files: raise FileNotFoundError elif len(files) > 1: - raise RuntimeError('Multiple files found!') + raise RuntimeError("Multiple files found!") - output_pattern = template_lines.replace('\n', '') + output_pattern = template_lines.replace("\n", "") template_engine = os.path.splitext(template_file)[1][1:] return output_pattern, template_engine def find_templates(template_name: str, command_name: Optional[str] = None) -> List[str]: - template_glob = '{}.*'.format(template_name) - command_glob = '*' if command_name is None else command_name + template_glob = "{}.*".format(template_name) + command_glob = "*" if command_name is None else command_name command_glob = os.path.join(CONFIG_PATH, command_glob) return glob.glob(os.path.join(command_glob, template_glob)) diff --git a/patternutils/match.py b/patternutils/match.py index 01411c2..8f65802 100644 --- a/patternutils/match.py +++ b/patternutils/match.py @@ -5,7 +5,7 @@ def apply(subject: str, regex_pattern: Pattern[str]) -> Dict[str, str]: match = regex_pattern.search(subject) if match is not None: groupdict = match.groupdict() - groupdict['_subject'] = subject + groupdict["_subject"] = subject return groupdict else: - raise ValueError('subject doesn\'t match regex pattern') + raise ValueError("subject doesn't match regex pattern") diff --git a/patternutils/template.py b/patternutils/template.py index a4cf794..53746a2 100644 --- a/patternutils/template.py +++ b/patternutils/template.py @@ -12,10 +12,10 @@ else: jinja_feature = True jinja_env = jinja2.Environment() - def to_datetime(value: str, format: str = '%Y-%m-%d') -> datetime: + def to_datetime(value: str, format: str = "%Y-%m-%d") -> datetime: return datetime.strptime(value, format) - def format_datetime(value: datetime, format: str = '%Y-%m-%d') -> str: + def format_datetime(value: datetime, format: str = "%Y-%m-%d") -> str: return value.strftime(format) def to_int(value: str, base: int = 10) -> int: @@ -27,20 +27,20 @@ else: def quote(value: str) -> str: return shlex.quote(value) - jinja_env.filters['datetime'] = to_datetime - jinja_env.filters['datetimeformat'] = format_datetime - jinja_env.filters['int'] = to_int - jinja_env.filters['float'] = to_float - jinja_env.filters['quote'] = quote + jinja_env.filters["datetime"] = to_datetime + jinja_env.filters["datetimeformat"] = format_datetime + jinja_env.filters["int"] = to_int + jinja_env.filters["float"] = to_float + jinja_env.filters["quote"] = quote -def get_render_function(template: str, *, engine: str = 'python') -> Callable[..., str]: - if engine == 'jinja2': +def get_render_function(template: str, *, engine: str = "python") -> Callable[..., str]: + if engine == "jinja2": if jinja_feature: env_template = jinja_env.from_string(template) render_function = env_template.render else: - raise RuntimeError('jinja2 not installed!') + raise RuntimeError("jinja2 not installed!") else: render_function = template.format return render_function diff --git a/patternutils/utils.py b/patternutils/utils.py index e78a86b..6f8132d 100644 --- a/patternutils/utils.py +++ b/patternutils/utils.py @@ -13,14 +13,16 @@ def max_procs() -> int: def edit(data: Dict[str, str]) -> Dict[str, str]: longest = len(max(data, key=len)) - temporary = ['{}\t{}\n'.format(key.ljust(longest), value) for key, value in data.items()] - edited = click.edit(''.join(temporary)) + temporary = [ + "{}\t{}\n".format(key.ljust(longest), value) for key, value in data.items() + ] + edited = click.edit("".join(temporary)) if edited is not None: new_data = dict() - for line in edited.split('\n'): - if line and '\t' in line: - old, new = line.split('\t') + for line in edited.split("\n"): + if line and "\t" in line: + old, new = line.split("\t") new_data[old.strip()] = new if new_data: return new_data diff --git a/setup.py b/setup.py index 922e7e5..f21c8bb 100644 --- a/setup.py +++ b/setup.py @@ -3,31 +3,31 @@ from setuptools import find_packages, setup -NAME = 'patternutils' -DESCRIPTION = 'Combine regular expressions with template engines in a powerful matter.' -URL = 'https://projects.metalgamer.eu/patternutils' -EMAIL = 'dennis.fink@c3l.lu' -AUTHOR = 'Dennis Fink' +NAME = "patternutils" +DESCRIPTION = "Combine regular expressions with template engines in a powerful matter." +URL = "https://projects.metalgamer.eu/patternutils" +EMAIL = "dennis.fink@c3l.lu" +AUTHOR = "Dennis Fink" -VERSION = '0.0.7' +VERSION = "0.0.7" ENTRY_POINTS = { - 'console_scripts': [ - 'pmatch=patternutils.commands.pmatch:pmatch', - 'targs=patternutils.commands.targs:targs', - 'tmv=patternutils.commands.tmv:tmv', - 'tln=patternutils.commands.tln:tln', - 'patterncfg=patternutils.commands.patterncfg:patterncfg', + "console_scripts": [ + "pmatch=patternutils.commands.pmatch:pmatch", + "targs=patternutils.commands.targs:targs", + "tmv=patternutils.commands.tmv:tmv", + "tln=patternutils.commands.tln:tln", + "patterncfg=patternutils.commands.patterncfg:patterncfg", ], } REQUIRED = [ - 'click==7.0', + "click==7.0", ] OPTIONAL = { - 'jinja2': ['Jinja2==2.10.1'], - 'pygments': ['Pygments==2.4.2'], + "jinja2": ["Jinja2==2.10.1"], + "pygments": ["Pygments==2.4.2"], } setup( @@ -37,17 +37,17 @@ setup( author=AUTHOR, author_email=EMAIL, url=URL, - packages=find_packages(exclude=('tests',)), + packages=find_packages(exclude=("tests",)), entry_points=ENTRY_POINTS, install_requires=REQUIRED, extras_requires=OPTIONAL, include_package_data=True, - license='GPLv3+', + license="GPLv3+", classifiers=[ # Trove classifiers # Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers - 'Programming Language :: Python', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: Implementation :: CPython', + "Programming Language :: Python", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: Implementation :: CPython", ], ) -- cgit v1.3.1 From 954ff69b17b5b7c81780dbd6aa03847dd26a1edf Mon Sep 17 00:00:00 2001 From: Dennis Fink Date: Fri, 25 Sep 2020 21:26:55 +0200 Subject: Bumped version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setup.py') diff --git a/setup.py b/setup.py index f21c8bb..95a892f 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ URL = "https://projects.metalgamer.eu/patternutils" EMAIL = "dennis.fink@c3l.lu" AUTHOR = "Dennis Fink" -VERSION = "0.0.7" +VERSION = "0.0.8" ENTRY_POINTS = { "console_scripts": [ "pmatch=patternutils.commands.pmatch:pmatch", -- cgit v1.3.1