Files
neon/pre-commit.py
Dmitry Rodionov 5f5a11525c Switch our python package management solution to poetry.
Mainly because it has better support for installing the packages from
different python versions.

It also has better dependency resolver than Pipenv. And supports modern
standard for python dependency management. This includes usage of
pyproject.toml for project specific configuration instead of per
tool conf files. See following links for details:
 https://pip.pypa.io/en/stable/reference/build-system/pyproject-toml/
 https://www.python.org/dev/peps/pep-0518/
2022-01-24 11:33:47 +03:00

117 lines
3.2 KiB
Python
Executable File

#!/usr/bin/env python3
from typing import List
import subprocess
import sys
import enum
import argparse
import os
@enum.unique
class Color(enum.Enum):
RED = "\033[0;31m"
GREEN = "\033[0;33m"
CYAN = "\033[0;36m"
NC = "\033[0m" # No Color
def colorify(
s: str,
color: Color,
no_color: bool = False,
):
if no_color:
return s
return f"{color.value}{s}{NC}"
def rustfmt(fix_inplace: bool = False, no_color: bool = False) -> str:
cmd = "rustfmt --edition=2018"
if not fix_inplace:
cmd += " --check"
if no_color:
cmd += " --color=never"
return cmd
def yapf(fix_inplace: bool) -> str:
cmd = "poetry run yapf --recursive"
if fix_inplace:
cmd += " --in-place"
else:
cmd += " --diff"
return cmd
def mypy() -> str:
return "poetry run mypy"
def get_commit_files() -> List[str]:
files = subprocess.check_output("git diff --cached --name-only --diff-filter=ACM".split())
return files.decode().splitlines()
def check(name: str, suffix: str, cmd: str, changed_files: List[str], no_color: bool = False):
print(f"Checking: {name} ", end="")
applicable_files = list(filter(lambda fname: fname.strip().endswith(suffix), changed_files))
if not applicable_files:
print(colorify("[NOT APPLICABLE]", Color.CYAN, no_color))
return
cmd = f'{cmd} {" ".join(applicable_files)}'
res = subprocess.run(cmd.split(), capture_output=True)
if res.returncode != 0:
print(colorify("[FAILED]", Color.RED, no_color))
if name == "mypy":
print("Please inspect the output below and fix type mismatches.")
else:
print("Please inspect the output below and run make fmt to fix automatically.")
if suffix == ".py":
print("If the output is empty, ensure that you've installed Python tooling by\n"
"running './scripts/pysync' in the current directory (no root needed)")
print()
print(res.stdout.decode())
exit(1)
print(colorify("[OK]", Color.GREEN, no_color))
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--fix-inplace", action="store_true", help="apply fixes inplace")
parser.add_argument("--no-color",
action="store_true",
help="disable colored output",
default=not sys.stdout.isatty())
args = parser.parse_args()
files = get_commit_files()
# we use rustfmt here because cargo fmt does not accept list of files
# it internally gathers project files and feeds them to rustfmt
# so because we want to check only files included in the commit we use rustfmt directly
check(
name="rustfmt",
suffix=".rs",
cmd=rustfmt(fix_inplace=args.fix_inplace, no_color=args.no_color),
changed_files=files,
no_color=args.no_color,
)
check(
name="yapf",
suffix=".py",
cmd=yapf(fix_inplace=args.fix_inplace),
changed_files=files,
no_color=args.no_color,
)
check(
name="mypy",
suffix=".py",
cmd=mypy(),
changed_files=files,
no_color=args.no_color,
)