1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
| import sys from pathlib import Path import subprocess import click
class UpgradeDependencies: @classmethod def _build_args(cls, dependencies): packs, specials = [], {} for dep in dependencies: if ":" in dep: k, v = dep.split(":") specials[k.strip()] = v.strip().split() else: packs.append(dep.strip()) return packs, specials
@classmethod def _parse_dependencies(cls, text, title): main, dev = text.split(title) devs = dev.split("[tool.")[0].strip().splitlines() mains = main.strip().splitlines() prod_packs, specials = cls._build_args(mains) dev_packs, specials = cls._build_args(devs) return prod_packs, dev_packs, specials
@classmethod def get_args(cls): dev_title = "[tool.poetry.group.dev.dependencies]" dev_flag = "--group dev" main_args, dev_args, others = [], [], [] if dev_title in text: main_title = "[tool.poetry.dependencies]" else: dev_flag = "--group dev" dev_title = "[tool.poetry.group.dev.dependencies]" main_args, dev_args, others = cls._parse_dependencies(text, main_title, dev_title, dev_flag) return main_args, dev_args, others, dev_flag
@classmethod def gen_cmd(cls): main_args, dev_args, others, dev_flag = cls.get_args() command = f"poetry add {' '.join(main_args)} && poetry add {dev_flag} {' '.join(dev_args)}" for packages in others: command += f" && poetry add {' '.join(packages)}" return command
def exit_if_run_failed(cmd): try: subprocess.run(cmd, check=True, shell=True) except subprocess.CalledProcessError as e: print(f"Error: {e}") sys.exit(1)
@click.command() def update(): """升级所有依赖包到最新版""" exit_if_run_failed(UpgradeDependencies.gen_cmd())
@click.command() def lint(): """格式化加静态检查""" remove_imports = "autoflake --in-place --remove-all-unused-imports" cmd = "" paths = "." if args := sys.argv[1:]: if "-r" in args: args.remove("-r") if all(Path(i).is_file() for i in args): cmd = f"{remove_imports} {paths} && " + cmd paths = " ".join(args) tools = ("isort", "black", "ruff", "mypy") cmd += f"poetry run {tools[0]} {paths} && poetry run {tools[1]} {paths} && poetry run {tools[2]} {paths} && poetry run {tools[3]} {paths}" exit_if_run_failed(cmd)
@click.command() def dev(): """启动服务:相当于django的runserver""" cmd = "poetry run python main.py" if args := sys.argv[1:]: cmd += " " + " ".join(args) exit_if_run_failed(cmd)
@click.command() def makemigrations(): """生成数据库迁移文件,类似Django的./manage.py makemigrations""" exit_if_run_failed("aerich migrate")
@click.command() def migrate(): """更新数据库表结构:相当于django的./manage.py migrate""" exit_if_run_failed("aerich upgrade")
if __name__ == "__main__": cli()
|