import sys import shutil import glob import io import copy import subprocess import pathlib import logging import enum import argparse import dataclasses from typing import ( Optional, override, ) from online.fxreader.pr34.commands_typed.logging import setup as logging_setup from online.fxreader.pr34.commands_typed import cli as _cli from online.fxreader.pr34.commands_typed import cli_bootstrap logging_setup() logger = logging.getLogger(__name__) class Command(enum.StrEnum): mypy = 'mypy' pyright = 'pyright' ruff = 'ruff' deploy_wheel = 'deploy:wheel' tests = 'tests' meson_setup = 'meson:setup' @dataclasses.dataclass class Settings( _cli.DistSettings, ): base_dir: pathlib.Path = pathlib.Path(__file__).parent.parent build_dir: pathlib.Path = base_dir / 'tmp' / 'build' wheel_dir: pathlib.Path = base_dir / 'deps' / 'dist' env_path: pathlib.Path = cli_bootstrap.BootstrapSettings.get().env_path python_path: pathlib.Path = pathlib.Path(sys.executable) class CLI(_cli.CLI): def __init__(self) -> None: self.settings = Settings() self._projects: dict[str, _cli.Project] = { 'online.fxreader.pr34': _cli.Project( source_dir=self.settings.base_dir / 'python', build_dir=self.settings.base_dir / 'tmp' / 'online' / 'fxreader' / 'pr34' / 'build', dest_dir=self.settings.base_dir / 'tmp' / 'online' / 'fxreader' / 'pr34' / 'install', meson_path=self.settings.base_dir / 'python' / 'meson.build', ) } self._dependencies: dict[str, _cli.Dependency] = dict() @override @property def dist_settings(self) -> _cli.DistSettings: return self.settings @override @property def projects(self) -> dict[str, _cli.Project]: return self._projects def mypy( self, argv: list[str], ) -> None: import online.fxreader.pr34.commands_typed.mypy as _mypy project = self._projects['online.fxreader.pr34'] _mypy.run( argv, settings=_mypy.MypySettings( paths=[ # Settings.settings().project_root / 'dotfiles/.local/bin/commands', # project.source_dir / 'm.py', project.source_dir / '_m.py', project.source_dir / 'online', project.source_dir / 'cli.py', project.source_dir / 'm.py', # Settings.settings().project_root / 'deps/com.github.aiortc.aiortc/src', # Settings.settings().project_root / 'm.py', ], max_errors={ 'online/fxreader/pr34/commands_typed': 0, # 'online/fxreader/pr34/commands': 0, 'cli.py': 0, 'm.py': 0, '../deps/com.github.aiortc.aiortc/src/online_fxreader': 0, '../deps/com.github.aiortc.aiortc/src/aiortc/contrib/signaling': 0, }, ), ) @override @property def dependencies(self) -> dict[str, _cli.Dependency]: return self._dependencies def run(self, argv: Optional[list[str]] = None) -> None: if argv is None: argv = copy.deepcopy(sys.argv) parser = argparse.ArgumentParser() parser.add_argument('command', choices=[o.value for o in Command]) parser.add_argument('-p', '--project', choices=[o for o in self.projects]) parser.add_argument( '-o', '--output_dir', default=None, help='wheel output dir for deploy:wheel', ) parser.add_argument( '-f', '--force', default=False, action='store_true', help='remove install dir, before installing, default = false', ) options, args = parser.parse_known_args(argv[1:]) default_project: Optional[str] = None for k, v in self.projects.items(): if cli_bootstrap.paths_equal( v.source_dir.resolve(), # pathlib.Path(__file__).parent.resolve(), pathlib.Path.cwd(), ): default_project = k if options.project is None: if not default_project is None: options.project = default_project else: logger.error(dict(msg='not provided project name')) raise NotImplementedError options.command = Command(options.command) if options.command is Command.deploy_wheel: assert not options.project is None self.deploy_wheel( project_name=options.project, argv=args, output_dir=options.output_dir, # mypy=True, ruff=True, pyright=True, ) elif options.command is Command.pyright: self.pyright( project_name=options.project, argv=args, ) elif options.command is Command.ruff: self.ruff( project_name=options.project, argv=args, ) elif options.command is Command.meson_setup: assert not options.project is None self.meson_setup( project_name=options.project, argv=args, force=options.force, ) elif options.command is Command.mypy: self.mypy( argv=args, ) elif options.command is Command.tests: for k, v in self.projects.items(): subprocess.check_call( [ sys.executable, '-m', 'unittest', 'online.fxreader.pr34.tests.test_crypto', *args, ], cwd=str(v.source_dir), ) else: raise NotImplementedError if __name__ == '__main__': CLI().run()