Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f3b5886

Browse files
committed
Merge pull request #153 from pre-commit/error_handler
Error handler
2 parents 74e878d + 32817f3 commit f3b5886

15 files changed

Lines changed: 199 additions & 89 deletions

pre_commit/clientlib/validate_base.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
import jsonschema.exceptions
77
import os.path
88
import re
9+
import sys
910
import yaml
1011

1112
from pre_commit.jsonschema_extensions import apply_defaults
12-
from pre_commit.util import entry
1313

1414

1515
def is_regex_valid(regex):
@@ -64,8 +64,8 @@ def validate(filename, load_strategy=yaml.load):
6464

6565

6666
def get_run_function(filenames_help, validate_strategy, exception_cls):
67-
@entry
68-
def run(argv):
67+
def run(argv=None):
68+
argv = argv if argv is not None else sys.argv[1:]
6969
parser = argparse.ArgumentParser()
7070
parser.add_argument('filenames', nargs='*', help=filenames_help)
7171
args = parser.parse_args(argv)

pre_commit/clientlib/validate_config.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
from __future__ import unicode_literals
22

3-
import sys
4-
53
from pre_commit.clientlib.validate_base import get_run_function
64
from pre_commit.clientlib.validate_base import get_validator
75
from pre_commit.clientlib.validate_base import is_regex_valid
6+
from pre_commit.errors import FatalError
87

98

10-
class InvalidConfigError(ValueError):
9+
class InvalidConfigError(FatalError):
1110
pass
1211

1312

@@ -71,4 +70,4 @@ def validate_config_extra(config):
7170

7271

7372
if __name__ == '__main__':
74-
sys.exit(run())
73+
exit(run())

pre_commit/clientlib/validate_manifest.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
from __future__ import unicode_literals
22

3-
import sys
4-
53
from pre_commit.clientlib.validate_base import get_run_function
64
from pre_commit.clientlib.validate_base import get_validator
75
from pre_commit.clientlib.validate_base import is_regex_valid
@@ -74,4 +72,4 @@ def additional_manifest_check(obj):
7472

7573

7674
if __name__ == '__main__':
77-
sys.exit(run())
75+
exit(run())

pre_commit/error_handler.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from __future__ import absolute_import
2+
from __future__ import print_function
3+
from __future__ import unicode_literals
4+
5+
import contextlib
6+
import io
7+
import os.path
8+
import traceback
9+
10+
from pre_commit.errors import FatalError
11+
from pre_commit.store import Store
12+
13+
14+
# For testing purposes
15+
class PreCommitSystemExit(SystemExit):
16+
pass
17+
18+
19+
def _log_and_exit(msg, exc, formatted, print_fn=print):
20+
error_msg = '{0}: {1}: {2}'.format(msg, type(exc).__name__, exc)
21+
print_fn(error_msg)
22+
print_fn('Check the log at ~/.pre-commit/pre-commit.log')
23+
store = Store()
24+
store.require_created()
25+
with io.open(os.path.join(store.directory, 'pre-commit.log'), 'w') as log:
26+
log.write(error_msg + '\n')
27+
log.write(formatted + '\n')
28+
raise PreCommitSystemExit(1)
29+
30+
31+
@contextlib.contextmanager
32+
def error_handler():
33+
try:
34+
yield
35+
except FatalError as e:
36+
_log_and_exit('An error has occurred', e, traceback.format_exc())
37+
except Exception as e:
38+
_log_and_exit(
39+
'An unexpected error has occurred',
40+
e,
41+
traceback.format_exc(),
42+
)

pre_commit/errors.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from __future__ import absolute_import
2+
from __future__ import unicode_literals
3+
4+
5+
class FatalError(RuntimeError):
6+
pass

pre_commit/five.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from __future__ import unicode_literals
22

3-
"""five: six, redux"""
43
# pylint:disable=invalid-name
54
PY2 = str is bytes
65
PY3 = str is not bytes

pre_commit/git.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,24 @@
77
import re
88
from plumbum import local
99

10+
from pre_commit.errors import FatalError
1011
from pre_commit.util import memoize_by_cwd
1112

1213

1314
logger = logging.getLogger('pre_commit')
1415

1516

16-
@memoize_by_cwd
1717
def get_root():
1818
path = os.getcwd()
1919
while len(path) > 1:
2020
if os.path.exists(os.path.join(path, '.git')):
2121
return path
2222
else:
2323
path = os.path.normpath(os.path.join(path, '../'))
24-
raise AssertionError('called from outside of the gits')
24+
raise FatalError(
25+
'Called from outside of the gits. '
26+
'Please cd to a git repository.'
27+
)
2528

2629

2730
def is_in_merge_conflict():

pre_commit/jsonschema_extensions.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,20 @@ def new_properties(validator, properties, instance, schema):
2020

2121

2222
def default_values(properties, instance):
23-
for property, subschema in properties.items():
23+
for prop, subschema in properties.items():
2424
if 'default' in subschema:
2525
instance.setdefault(
26-
property, copy.deepcopy(subschema['default']),
26+
prop, copy.deepcopy(subschema['default']),
2727
)
2828

2929

3030
def remove_default_values(properties, instance):
31-
for property, subschema in properties.items():
31+
for prop, subschema in properties.items():
3232
if (
33-
'default' in subschema and
34-
instance.get(property) == subschema['default']
33+
'default' in subschema and
34+
instance.get(prop) == subschema['default']
3535
):
36-
del instance[property]
36+
del instance[prop]
3737

3838

3939
_AddDefaultsValidator = extend_validator_cls(

pre_commit/main.py

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@
22

33
import argparse
44
import pkg_resources
5+
import sys
56

67
from pre_commit import color
78
from pre_commit.commands.autoupdate import autoupdate
89
from pre_commit.commands.clean import clean
910
from pre_commit.commands.install_uninstall import install
1011
from pre_commit.commands.install_uninstall import uninstall
1112
from pre_commit.commands.run import run
13+
from pre_commit.error_handler import error_handler
1214
from pre_commit.runner import Runner
13-
from pre_commit.util import entry
1415

1516

16-
@entry
17-
def main(argv):
17+
def main(argv=None):
18+
argv = argv if argv is not None else sys.argv[1:]
1819
parser = argparse.ArgumentParser()
1920

2021
# http://stackoverflow.com/a/8521644/812183
@@ -83,29 +84,30 @@ def main(argv):
8384
else:
8485
parser.parse_args(['--help'])
8586

86-
runner = Runner.create()
87+
with error_handler():
88+
runner = Runner.create()
89+
90+
if args.command == 'install':
91+
return install(
92+
runner, overwrite=args.overwrite, hooks=args.install_hooks,
93+
)
94+
elif args.command == 'uninstall':
95+
return uninstall(runner)
96+
elif args.command == 'clean':
97+
return clean(runner)
98+
elif args.command == 'autoupdate':
99+
return autoupdate(runner)
100+
elif args.command == 'run':
101+
return run(runner, args)
102+
else:
103+
raise NotImplementedError(
104+
'Command {0} not implemented.'.format(args.command)
105+
)
87106

88-
if args.command == 'install':
89-
return install(
90-
runner, overwrite=args.overwrite, hooks=args.install_hooks,
91-
)
92-
elif args.command == 'uninstall':
93-
return uninstall(runner)
94-
elif args.command == 'clean':
95-
return clean(runner)
96-
elif args.command == 'autoupdate':
97-
return autoupdate(runner)
98-
elif args.command == 'run':
99-
return run(runner, args)
100-
else:
101-
raise NotImplementedError(
102-
'Command {0} not implemented.'.format(args.command)
107+
raise AssertionError(
108+
'Command {0} failed to exit with a returncode'.format(args.command)
103109
)
104110

105-
raise AssertionError(
106-
'Command {0} failed to exit with a returncode'.format(args.command)
107-
)
108-
109111

110112
if __name__ == '__main__':
111113
exit(main())

pre_commit/output.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616

1717

1818
def get_hook_message(
19-
start,
20-
postfix='',
21-
end_msg=None,
22-
end_len=0,
23-
end_color=None,
24-
use_color=None,
25-
cols=COLS,
19+
start,
20+
postfix='',
21+
end_msg=None,
22+
end_len=0,
23+
end_color=None,
24+
use_color=None,
25+
cols=COLS,
2626
):
2727
"""Prints a message for running a hook.
2828

0 commit comments

Comments
 (0)