diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2020-02-18 18:44:43 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-18 18:44:43 +0100 |
commit | 5e47e0bcba7585909a11e9c7424e864fc26a7fd2 (patch) | |
tree | fd808e05f549866b81fbaed527c0226355c02af3 /scripts | |
parent | 41fcba5dd7ecbbc788814c722f31e630422ba28e (diff) | |
download | psutil-5e47e0bcba7585909a11e9c7424e864fc26a7fd2.tar.gz |
Add C linter script (#1698)
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/internal/.git-pre-commit | 16 | ||||
-rwxr-xr-x | scripts/internal/clinter.py | 76 | ||||
-rwxr-xr-x | scripts/internal/winmake.py | 4 |
3 files changed, 92 insertions, 4 deletions
diff --git a/scripts/internal/.git-pre-commit b/scripts/internal/.git-pre-commit index 621879df..e6009253 100755 --- a/scripts/internal/.git-pre-commit +++ b/scripts/internal/.git-pre-commit @@ -77,6 +77,8 @@ def main(): out = sh("git diff --cached --name-only") py_files = [x for x in out.split('\n') if x.endswith('.py') and os.path.exists(x)] + c_files = [x for x in out.split('\n') if x.endswith(('.c', '.h')) and + os.path.exists(x)] lineno = 0 kw = {'encoding': 'utf8'} if sys.version_info[0] == 3 else {} @@ -100,7 +102,7 @@ def main(): print("%s:%s %s" % (path, lineno, line)) return exit("commit aborted: bare except clause") - # flake8 + # Python linter if py_files: try: import flake8 # NOQA @@ -108,12 +110,22 @@ def main(): return exit("commit aborted: flake8 is not installed; " "run 'make setup-dev-env'") - # XXX: we should scape spaces and possibly other amenities here + # XXX: we should escape spaces and possibly other amenities here ret = subprocess.call( "%s -m flake8 %s" % (sys.executable, " ".join(py_files)), shell=True) if ret != 0: return exit("commit aborted: python code is not flake8 compliant") + # C linter + if c_files: + # XXX: we should escape spaces and possibly other amenities here + cmd = "%s scripts/internal/clinter.py %s" % ( + sys.executable, " ".join(c_files)) + print(cmd) + ret = subprocess.call(cmd, shell=True) + if ret != 0: + return exit("commit aborted: C code didn't pass style check") + main() diff --git a/scripts/internal/clinter.py b/scripts/internal/clinter.py new file mode 100755 index 00000000..1d4ba9b1 --- /dev/null +++ b/scripts/internal/clinter.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2009 Giampaolo Rodola'. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""A super simple linter to check C syntax.""" + +from __future__ import print_function +import argparse +import sys + + +warned = False + + +def warn(path, line, lineno, msg): + global warned + warned = True + print("%s:%s: %s" % (path, lineno, msg), file=sys.stderr) + + +def check_line(path, line, idx, lines): + s = line + lineno = idx + 1 + eof = lineno == len(lines) + if s.endswith(' \n'): + warn(path, line, lineno, "extra space at EOL") + elif '\t' in line: + warn(path, line, lineno, "line has a tab") + elif s.endswith('\r\n'): + warn(path, line, lineno, "Windows line ending") + # end of global block, e.g. "}newfunction...": + elif s == "}\n": + if not eof: + nextline = lines[idx + 1] + # "#" is a pre-processor line + if nextline != '\n' and \ + nextline.strip()[0] != '#' and \ + nextline.strip()[:2] != '*/': + warn(path, line, lineno, "expected 1 blank line") + + sls = s.lstrip() + if sls.startswith('//') and sls[2] != ' ' and line.strip() != '//': + warn(path, line, lineno, "no space after // comment") + + # e.g. "if(..." after keywords + keywords = ("if", "else", "while", "do", "enum", "for") + for kw in keywords: + if sls.startswith(kw + '('): + warn(path, line, lineno, "missing space between %r and '('" % kw) + # eof + if eof: + if not line.endswith('\n'): + warn(path, line, lineno, "no blank line at EOF") + + +def process(path): + with open(path, 'rt') as f: + lines = f.readlines() + for idx, line in enumerate(lines): + check_line(path, line, idx, lines) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('paths', nargs='+', help='path(s) to a file(s)') + args = parser.parse_args() + for path in args.paths: + process(path) + if warned: + sys.exit(1) + + +if __name__ == '__main__': + main() diff --git a/scripts/internal/winmake.py b/scripts/internal/winmake.py index f54211d9..4d3fa318 100755 --- a/scripts/internal/winmake.py +++ b/scripts/internal/winmake.py @@ -386,7 +386,7 @@ def setup_dev_env(): sh("%s -m pip install -U %s" % (PYTHON, " ".join(DEPS))) -def flake8(): +def lint(): """Run flake8 against all py files""" py_files = subprocess.check_output("git ls-files") if PY3: @@ -551,11 +551,11 @@ def main(): sp.add_parser('build', help="build") sp.add_parser('clean', help="deletes dev files") sp.add_parser('coverage', help="run coverage tests.") - sp.add_parser('flake8', help="run flake8 against all py files") sp.add_parser('help', help="print this help") sp.add_parser('install', help="build + install in develop/edit mode") sp.add_parser('install-git-hooks', help="install GIT pre-commit hook") sp.add_parser('install-pip', help="install pip") + sp.add_parser('lint', help="run flake8 against all py files") sp.add_parser('print-access-denied', help="print AD exceptions") sp.add_parser('print-api-speed', help="benchmark all API calls") sp.add_parser('setup-dev-env', help="install deps") |