diff --git a/_m.py b/_m.py new file mode 100644 index 0000000..c489448 --- /dev/null +++ b/_m.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python3 +#vim: set filetype=python + +import logging +import json +import enum +import pathlib +import sys +import argparse +#import optparse +import subprocess +import os + + +from typing import (Optional, Any, TypeAlias, Literal, cast,) + +logger = logging.getLogger() + +def js(argv): + return subprocess.check_call([ + 'sudo', + 'docker-compose', + '--project-directory', + os.path.abspath( + os.path.dirname(__file__), + ), + '-f', + os.path.abspath( + os.path.join( + os.path.dirname(__file__), + 'docker', 'js', + 'docker-compose.yml', + ) + ), + *argv, + ]) + +def env( + argv: Optional[list[str]] = None, + **kwargs: Any, +) -> Optional[subprocess.CompletedProcess]: + env_path = pathlib.Path(__file__).parent / 'tmp' / 'env3' + + if not env_path.exists(): + subprocess.check_call([ + sys.executable, '-m', 'venv', + '--system-site-packages', + str(env_path) + ]) + + subprocess.check_call([ + env_path / 'bin' / 'python3', + '-m', 'pip', + 'install', '-r', 'requirements.txt', + ]) + + if not argv is None: + return subprocess.run([ + str(env_path / 'bin' / 'python3'), + *argv, + ], **kwargs) + + return None + +def ruff(args: list[str]) -> None: + res = env([ + '-m', + 'ruff', + 'check', + *args, + '--output-format', 'json', + '--ignore', ','.join([ + 'E731', + 'E713', + 'E714', + 'E703', + ]), + '.', + 'dotfiles/.local/bin/commands', + ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + assert not res is None + + errors = json.loads(res.stdout.decode('utf-8')) + + g: dict[str, Any] = dict() + for o in errors: + if not o['filename'] in g: + g[o['filename']] = [] + g[o['filename']].append(o) + + h = { + k : len(v) + for k, v in g.items() + } + + logger.info(json.dumps(errors, indent=4)) + logger.info(json.dumps(h, indent=4)) + +def mypy(args: list[str]) -> None: + res = env([ + '-m', + 'mypy', + '--strict', + '-O', + 'json', + *args, + 'dotfiles/.local/bin/commands', + 'python', + 'm.py', + ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + assert not res is None + + errors = [ + json.loads(o) + for o in res.stdout.decode('utf-8').splitlines() + ] + + g : dict[str, Any] = dict() + for o in errors: + if not o['file'] in g: + g[o['file']] = [] + g[o['file']].append(o) + + h = { + k : len(v) + for k, v in g.items() + } + + logger.info(json.dumps(errors, indent=4)) + logger.info(json.dumps(h, indent=4)) + +def inside_env() -> bool: + try: + import numpy + return True + except Exception: + return False + +#class Commands(enum.StrEnum): +# js = 'js' +# mypy = 'mypy' +# env = 'env' +# ruff = 'ruff' +# m2 = 'm2' + +Command_args = ['js', 'mypy', 'env', 'ruff', 'm2'] + +Command : TypeAlias = Literal['js', 'mypy', 'env', 'ruff', 'm2'] + +def run(argv: Optional[list[str]] = None) -> None: + logging.basicConfig( + level=logging.INFO, + format=( + '%(levelname)s:%(name)s:%(message)s' + ':%(process)d' + ':%(asctime)s' + ':%(pathname)s:%(funcName)s:%(lineno)s' + ), + ) + + if argv is None: + argv = sys.argv[1:] + + + parser = argparse.ArgumentParser() + parser.add_argument( + 'command', + #'_command', + choices=[ + o + for o in Command_args + ], + #required=True, + ) + + options, args = parser.parse_known_args(argv) + + assert options.command in cast(list[str], Command_args) + + #options.command = Commands(options._command) + + if options.command == 'js': + js(args) + elif options.command == 'env': + env(args) + elif options.command == 'mypy': + mypy(args) + elif options.command == 'ruff': + ruff(args) + elif options.command == 'm2': + if not inside_env(): + env(['--', '_m.py', 'm2', *args]) + return + + import python.tasks.cython + python.tasks.cython.mypyc_build( + pathlib.Path('_m.py') + ) + else: + raise NotImplementedError + +if __name__ == '__main__': + run(sys.argv[1:]) diff --git a/m.py b/m.py index 319dae3..dc74180 100755 --- a/m.py +++ b/m.py @@ -1,205 +1,3 @@ #!/usr/bin/env python3 -#vim: set filetype=python - -import logging -import json -import enum -import pathlib -import sys -import argparse -#import optparse -import subprocess -import os - - -from typing import (Optional, Any, TypeAlias, Literal, cast,) - -logger = logging.getLogger() - -def js(argv): - return subprocess.check_call([ - 'sudo', - 'docker-compose', - '--project-directory', - os.path.abspath( - os.path.dirname(__file__), - ), - '-f', - os.path.abspath( - os.path.join( - os.path.dirname(__file__), - 'docker', 'js', - 'docker-compose.yml', - ) - ), - *argv, - ]) - -def env( - argv: Optional[list[str]] = None, - **kwargs: Any, -) -> Optional[subprocess.CompletedProcess]: - env_path = pathlib.Path(__file__).parent / 'tmp' / 'env3' - - if not env_path.exists(): - subprocess.check_call([ - sys.executable, '-m', 'venv', - '--system-site-packages', - str(env_path) - ]) - - subprocess.check_call([ - env_path / 'bin' / 'python3', - '-m', 'pip', - 'install', '-r', 'requirements.txt', - ]) - - if not argv is None: - return subprocess.run([ - str(env_path / 'bin' / 'python3'), - *argv, - ], **kwargs) - - return None - -def ruff(args: list[str]) -> None: - res = env([ - '-m', - 'ruff', - 'check', - *args, - '--output-format', 'json', - '--ignore', ','.join([ - 'E731', - 'E713', - 'E714', - 'E703', - ]), - '.', - 'dotfiles/.local/bin/commands', - ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - - assert not res is None - - errors = json.loads(res.stdout.decode('utf-8')) - - g: dict[str, Any] = dict() - for o in errors: - if not o['filename'] in g: - g[o['filename']] = [] - g[o['filename']].append(o) - - h = { - k : len(v) - for k, v in g.items() - } - - logger.info(json.dumps(errors, indent=4)) - logger.info(json.dumps(h, indent=4)) - -def mypy(args: list[str]) -> None: - res = env([ - '-m', - 'mypy', - '--strict', - '-O', - 'json', - *args, - 'dotfiles/.local/bin/commands', - 'python', - 'm.py', - ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - - assert not res is None - - errors = [ - json.loads(o) - for o in res.stdout.decode('utf-8').splitlines() - ] - - g : dict[str, Any] = dict() - for o in errors: - if not o['file'] in g: - g[o['file']] = [] - g[o['file']].append(o) - - h = { - k : len(v) - for k, v in g.items() - } - - logger.info(json.dumps(errors, indent=4)) - logger.info(json.dumps(h, indent=4)) - -def inside_env() -> bool: - try: - import numpy - return True - except Exception: - return False - -#class Commands(enum.StrEnum): -# js = 'js' -# mypy = 'mypy' -# env = 'env' -# ruff = 'ruff' -# m2 = 'm2' - -Command_args = ['js', 'mypy', 'env', 'ruff', 'm2'] - -Command : TypeAlias = Literal['js', 'mypy', 'env', 'ruff', 'm2'] - -def run(argv: Optional[list[str]] = None) -> None: - logging.basicConfig( - level=logging.INFO, - format=( - '%(levelname)s:%(name)s:%(message)s' - ':%(process)d' - ':%(asctime)s' - ':%(pathname)s:%(funcName)s:%(lineno)s' - ), - ) - - if argv is None: - argv = sys.argv[1:] - - - parser = argparse.ArgumentParser() - parser.add_argument( - 'command', - #'_command', - choices=[ - o - for o in Command_args - ], - #required=True, - ) - - options, args = parser.parse_known_args(argv) - - assert options.command in cast(list[str], Command_args) - - #options.command = Commands(options._command) - - if options.command == 'js': - js(args) - elif options.command == 'env': - env(args) - elif options.command == 'mypy': - mypy(args) - elif options.command == 'ruff': - ruff(args) - elif options.command == 'm2': - if not inside_env(): - env(['--', 'm.py', 'm2', *args]) - return - - import python.tasks.cython - python.tasks.cython.mypyc_build( - pathlib.Path('m.py') - ) - else: - raise NotImplementedError - -if __name__ == '__main__': - run(sys.argv[1:]) +import _m +_m.run()