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

Skip to content

Commit 7496151

Browse files
committed
Merge pull request #64 from pre-commit/color_63
Wire in color for pre-commit
2 parents e98d2e1 + 73e0111 commit 7496151

3 files changed

Lines changed: 102 additions & 36 deletions

File tree

pre_commit/color.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
2+
import sys
3+
4+
RED = '\033[41m'
5+
GREEN = '\033[42m'
6+
NORMAL = '\033[0m'
7+
8+
9+
class InvalidColorSetting(ValueError): pass
10+
11+
12+
def format_color(text, color, use_color):
13+
"""Format text with color.
14+
15+
Args:
16+
text - Text to be formatted with color if `use_color`
17+
color - The color start string
18+
use_color - Whether or not to color
19+
"""
20+
if not use_color:
21+
return text
22+
else:
23+
return u'{0}{1}{2}'.format(color, text, NORMAL)
24+
25+
26+
def use_color(setting):
27+
"""Choose whether to use color based on the command argument.
28+
29+
Args:
30+
setting - Either `auto`, `always`, or `never`
31+
"""
32+
if setting not in ('auto', 'always', 'never'):
33+
raise InvalidColorSetting(setting)
34+
35+
return (
36+
setting == 'always' or
37+
(setting == 'auto' and sys.stdout.isatty())
38+
)

pre_commit/run.py

Lines changed: 23 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,20 @@
55
import subprocess
66
import sys
77

8+
from pre_commit import color
89
from pre_commit import commands
910
from pre_commit import git
1011
from pre_commit.runner import Runner
1112
from pre_commit.util import entry
1213

1314

14-
RED = '\033[41m'
15-
GREEN = '\033[42m'
16-
NORMAL = '\033[0m'
1715
COLS = int(subprocess.Popen(['tput', 'cols'], stdout=subprocess.PIPE).communicate()[0])
1816

1917
PASS_FAIL_LENGTH = 6
2018

2119

22-
def _run_single_hook(runner, repository, hook_id, all_files=False, verbose=False):
23-
if all_files:
20+
def _run_single_hook(runner, repository, hook_id, args):
21+
if args.all_files:
2422
get_filenames = git.get_all_files_matching
2523
else:
2624
get_filenames = git.get_staged_files_matching
@@ -46,54 +44,49 @@ def _run_single_hook(runner, repository, hook_id, all_files=False, verbose=False
4644
output = '\n'.join([stdout, stderr]).strip()
4745
if retcode != repository.hooks[hook_id]['expected_return_value']:
4846
retcode = 1
49-
color = RED
47+
print_color = color.RED
5048
pass_fail = 'Failed'
5149
else:
5250
retcode = 0
53-
color = GREEN
51+
print_color = color.GREEN
5452
pass_fail = 'Passed'
5553

5654

57-
print('{0}{1}{2}'.format(color, pass_fail, NORMAL))
55+
print(color.format_color(pass_fail, print_color, args.color))
5856

59-
if output and (retcode or verbose):
57+
if output and (retcode or args.verbose):
6058
print('\n' + output)
6159

6260
return retcode
6361

6462

65-
def run_hooks(runner, all_files=False, verbose=False):
63+
def run_hooks(runner, args):
6664
"""Actually run the hooks."""
6765
retval = 0
6866

6967
for repo in runner.repositories:
7068
for hook_id in repo.hooks:
71-
retval |= _run_single_hook(
72-
runner,
73-
repo,
74-
hook_id,
75-
all_files=all_files,
76-
verbose=verbose,
77-
)
69+
retval |= _run_single_hook(runner, repo, hook_id, args)
7870

7971
return retval
8072

8173

82-
def run_single_hook(runner, hook_id, all_files=False, verbose=False):
74+
def run_single_hook(runner, hook_id, args):
8375
for repo in runner.repositories:
8476
if hook_id in repo.hooks:
85-
return _run_single_hook(
86-
runner,
87-
repo,
88-
hook_id,
89-
all_files=all_files,
90-
verbose=verbose,
91-
)
77+
return _run_single_hook(runner, repo, hook_id, args)
9278
else:
9379
print('No hook with id `{0}`'.format(hook_id))
9480
return 1
9581

9682

83+
def _run(runner, args):
84+
if args.hook:
85+
return run_single_hook(runner, args.hook, args)
86+
else:
87+
return run_hooks(runner, args)
88+
89+
9790
@entry
9891
def run(argv):
9992
parser = argparse.ArgumentParser()
@@ -115,6 +108,10 @@ def run(argv):
115108
help='Run on all the files in the repo.',
116109
)
117110
run.add_argument('--verbose', '-v', action='store_true', default=False)
111+
run.add_argument(
112+
'--color', default='auto', type=color.use_color,
113+
help='Whether to use color in output. Defaults to `auto`',
114+
)
118115

119116
help = subparsers.add_parser('help', help='Show help for a specific command.')
120117
help.add_argument('help_cmd', nargs='?', help='Command to show help for.')
@@ -135,17 +132,7 @@ def run(argv):
135132
elif args.command == 'autoupdate':
136133
return commands.autoupdate(runner)
137134
elif args.command == 'run':
138-
if args.hook:
139-
return run_single_hook(
140-
runner,
141-
args.hook,
142-
all_files=args.all_files,
143-
verbose=args.verbose,
144-
)
145-
else:
146-
return run_hooks(
147-
runner, all_files=args.all_files, verbose=args.verbose,
148-
)
135+
return _run(runner, args)
149136
elif args.command == 'help':
150137
if args.help_cmd:
151138
parser.parse_args([args.help_cmd, '--help'])

tests/color_test.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
import mock
3+
import pytest
4+
import sys
5+
6+
from pre_commit.color import format_color
7+
from pre_commit.color import GREEN
8+
from pre_commit.color import InvalidColorSetting
9+
from pre_commit.color import use_color
10+
11+
12+
@pytest.mark.parametrize(('in_text', 'in_color', 'in_use_color', 'expected'), (
13+
('foo', GREEN, True, '{0}foo\033[0m'.format(GREEN)),
14+
('foo', GREEN, False, 'foo'),
15+
))
16+
def test_format_color(in_text, in_color, in_use_color, expected):
17+
ret = format_color(in_text, in_color, in_use_color)
18+
assert ret == expected
19+
20+
21+
def test_use_color_never():
22+
assert use_color('never') is False
23+
24+
25+
def test_use_color_always():
26+
assert use_color('always') is True
27+
28+
29+
def test_use_color_no_tty():
30+
with mock.patch.object(sys.stdout, 'isatty', return_value=False):
31+
assert use_color('auto') is False
32+
33+
34+
def test_use_color_tty():
35+
with mock.patch.object(sys.stdout, 'isatty', return_value=True):
36+
assert use_color('auto') is True
37+
38+
39+
def test_use_color_raises_if_given_shenanigans():
40+
with pytest.raises(InvalidColorSetting):
41+
use_color('herpaderp')

0 commit comments

Comments
 (0)