| import os |
| import sys |
| import subprocess |
| from argparse import ArgumentParser |
| from git import Repo, exc |
| |
| CONFIG = os.path.join( |
| os.path.abspath(os.path.dirname(__file__)), |
| 'lint_diff.ini', |
| ) |
| |
| # NOTE: The `diff` and `exclude` options of pycodestyle seem to be |
| # incompatible, so instead just exclude the necessary files when |
| # computing the diff itself. |
| EXCLUDE = ( |
| "numpy/typing/tests/data/", |
| "numpy/typing/_char_codes.py", |
| "numpy/__config__.py", |
| "numpy/f2py", |
| ) |
| |
| |
| class DiffLinter: |
| def __init__(self, branch): |
| self.branch = branch |
| self.repo = Repo('.') |
| self.head = self.repo.head.commit |
| |
| def get_branch_diff(self, uncommitted = False): |
| """ |
| Determine the first common ancestor commit. |
| Find diff between branch and FCA commit. |
| Note: if `uncommitted` is set, check only |
| uncommitted changes |
| """ |
| try: |
| commit = self.repo.merge_base(self.branch, self.head)[0] |
| except exc.GitCommandError: |
| print(f"Branch with name `{self.branch}` does not exist") |
| sys.exit(1) |
| |
| exclude = [f':(exclude){i}' for i in EXCLUDE] |
| if uncommitted: |
| diff = self.repo.git.diff( |
| self.head, '--unified=0', '***.py', *exclude |
| ) |
| else: |
| diff = self.repo.git.diff( |
| commit, self.head, '--unified=0', '***.py', *exclude |
| ) |
| return diff |
| |
| def run_pycodestyle(self, diff): |
| """ |
| Original Author: Josh Wilson (@person142) |
| Source: |
| https://github.com/scipy/scipy/blob/main/tools/lint_diff.py |
| Run pycodestyle on the given diff. |
| """ |
| res = subprocess.run( |
| ['pycodestyle', '--diff', '--config', CONFIG], |
| input=diff, |
| stdout=subprocess.PIPE, |
| encoding='utf-8', |
| ) |
| return res.returncode, res.stdout |
| |
| def run_lint(self, uncommitted): |
| diff = self.get_branch_diff(uncommitted) |
| retcode, errors = self.run_pycodestyle(diff) |
| |
| errors and print(errors) |
| |
| sys.exit(retcode) |
| |
| |
| if __name__ == '__main__': |
| parser = ArgumentParser() |
| parser.add_argument("--branch", type=str, default='main', |
| help="The branch to diff against") |
| parser.add_argument("--uncommitted", action='store_true', |
| help="Check only uncommitted changes") |
| args = parser.parse_args() |
| |
| DiffLinter(args.branch).run_lint(args.uncommitted) |