diff options
Diffstat (limited to 'pygitchecker.py')
| -rwxr-xr-x | pygitchecker.py | 79 |
1 files changed, 37 insertions, 42 deletions
diff --git a/pygitchecker.py b/pygitchecker.py index 4f4a872..469dcdf 100755 --- a/pygitchecker.py +++ b/pygitchecker.py | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | # -*- coding: utf-8 -*- | 2 | # -*- coding: utf-8 -*- |
| 3 | """Simple, on demand git checker""" | 3 | """Simple, on demand git checker""" |
| 4 | import argparse | 4 | import argparse |
| 5 | import errno | ||
| 6 | import json | ||
| 5 | import os | 7 | import os |
| 6 | import subprocess | 8 | import subprocess |
| 7 | import sys | 9 | import sys |
| @@ -91,54 +93,33 @@ def fetch_all_files(abspath): | |||
| 91 | return all_files_list | 93 | return all_files_list |
| 92 | 94 | ||
| 93 | 95 | ||
| 94 | def validate_flake8(pfile): | 96 | def validate_python_file(pfile, tests, args): |
| 95 | """Validate using: flake8""" | 97 | """ |
| 96 | try: | 98 | Validates a single .py file against tests |
| 97 | subprocess.run(['/usr/bin/flake8', pfile], check=True) | ||
| 98 | return True | ||
| 99 | except subprocess.CalledProcessError: | ||
| 100 | return False | ||
| 101 | 99 | ||
| 100 | :param tests: A sequence of test dicts | ||
| 101 | :type tests: collections.Sequence | ||
| 102 | 102 | ||
| 103 | def validate_isort(pfile): | 103 | :param pfile: Python file (abs. path) |
| 104 | """Validate using: isort --check --diff""" | 104 | :type pfile: str |
| 105 | try: | ||
| 106 | subprocess.run(['/usr/bin/isort', '--check', '--diff', pfile], | ||
| 107 | check=True) | ||
| 108 | return True | ||
| 109 | except subprocess.CalledProcessError: | ||
| 110 | return False | ||
| 111 | |||
| 112 | 105 | ||
| 113 | def validate_pylint(pfile): | 106 | :param args: Argparse Namespace-object |
| 114 | """Validate using: pylint -r no --exit-zero""" | 107 | :type args: argparse.Namespace |
| 115 | try: | ||
| 116 | subprocess.run(['/usr/bin/pylint', '-r', 'no', '--exit-zero', pfile], | ||
| 117 | check=True) | ||
| 118 | return True | ||
| 119 | except subprocess.CalledProcessError: | ||
| 120 | return False | ||
| 121 | |||
| 122 | |||
| 123 | def validate_python_file(pfile, args): | ||
| 124 | """ | ||
| 125 | Validates a single .py file | ||
| 126 | 108 | ||
| 127 | :return: False if validation fails, False otherwise | 109 | :return: False if validation fails, False otherwise |
| 128 | :rtype: bool | 110 | :rtype: bool |
| 129 | """ | 111 | """ |
| 130 | if not validate_flake8(pfile) and not args.continue_checks: | 112 | for test in tests: |
| 131 | if args.verbose: | ||
| 132 | eprint(f'{pfile}: flake8 validation failed') | ||
| 133 | sys.exit(0) | ||
| 134 | if not validate_isort(pfile) and not args.continue_checks: | ||
| 135 | if args.verbose: | 113 | if args.verbose: |
| 136 | eprint(f'{pfile}: isort validation failed') | 114 | print(f'{pfile} <- {test["name"]}') |
| 137 | sys.exit(0) | 115 | try: |
| 138 | if not validate_pylint(pfile) and not args.continue_checks: | 116 | params = [param.replace('%p', pfile) for param in test['params']] |
| 139 | if args.verbose: | 117 | subprocess.run(params, check=test['check']) |
| 140 | eprint(f'{pfile}: pylint validation failed') | 118 | except subprocess.CalledProcessError: |
| 141 | sys.exit(0) | 119 | if not args.continue_checks: |
| 120 | if args.verbose: | ||
| 121 | eprint(f'{pfile}: {test["name"]} validation failed') | ||
| 122 | sys.exit(0) | ||
| 142 | 123 | ||
| 143 | 124 | ||
| 144 | def main(inargs=None): | 125 | def main(inargs=None): |
| @@ -157,11 +138,18 @@ def main(inargs=None): | |||
| 157 | dest='all_files', | 138 | dest='all_files', |
| 158 | help='Check all files, not only the modified ones') | 139 | help='Check all files, not only the modified ones') |
| 159 | parser.add_argument( | 140 | parser.add_argument( |
| 160 | '-c', '--continue-checks', | 141 | '-C', '--continue-checks', |
| 161 | action='store_true', | 142 | action='store_true', |
| 162 | dest='continue_checks', | 143 | dest='continue_checks', |
| 163 | help='Continue with the checks if validation fails') | 144 | help='Continue with the checks if validation fails') |
| 164 | parser.add_argument( | 145 | parser.add_argument( |
| 146 | '-c', '--config', | ||
| 147 | metavar='FILE', | ||
| 148 | type=str, | ||
| 149 | default=os.path.expanduser('~/.pygitchecker.json'), | ||
| 150 | dest='config_file', | ||
| 151 | help='Config file (default: ~/.pygitchecker.json)') | ||
| 152 | parser.add_argument( | ||
| 165 | '-f', '--full', | 153 | '-f', '--full', |
| 166 | action='store_true', | 154 | action='store_true', |
| 167 | dest='full_search', | 155 | dest='full_search', |
| @@ -210,10 +198,17 @@ def main(inargs=None): | |||
| 210 | if not selected_files: | 198 | if not selected_files: |
| 211 | print('No files selected') | 199 | print('No files selected') |
| 212 | sys.exit(0) | 200 | sys.exit(0) |
| 201 | # now run the real tests | ||
| 202 | try: | ||
| 203 | with open(args.config_file, 'r') as fp: | ||
| 204 | config_dict = json.load(fp) | ||
| 205 | except Exception as e: | ||
| 206 | eprint(f'Unable to parse {args.config_file}: {e}') | ||
| 207 | sys.exit(errno.EIO) | ||
| 213 | for target_file in selected_files: | 208 | for target_file in selected_files: |
| 214 | if args.verbose: | 209 | if args.verbose: |
| 215 | print(f'Validating {target_file}:') | 210 | print(f'Validating {target_file}:') |
| 216 | validate_python_file(target_file, args) | 211 | validate_python_file(target_file, config_dict.get('tests'), args) |
| 217 | 212 | ||
| 218 | 213 | ||
| 219 | if __name__ == '__main__': | 214 | if __name__ == '__main__': |
