Skip to content

Commit 0c0427b

Browse files
committed
Add duration to verbose run
1 parent 1074b39 commit 0c0427b

File tree

7 files changed

+74
-55
lines changed

7 files changed

+74
-55
lines changed

pre_commit/commands/run.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import os
55
import re
66
import subprocess
7+
import time
78

89
from identify.identify import tags_from_path
910

@@ -99,6 +100,7 @@ def _run_single_hook(classifier, hook, skips, cols, verbose, use_color):
99100
cols=cols,
100101
),
101102
)
103+
duration = None
102104
retcode = 0
103105
files_modified = False
104106
out = b''
@@ -113,6 +115,7 @@ def _run_single_hook(classifier, hook, skips, cols, verbose, use_color):
113115
cols=cols,
114116
),
115117
)
118+
duration = None
116119
retcode = 0
117120
files_modified = False
118121
out = b''
@@ -123,7 +126,9 @@ def _run_single_hook(classifier, hook, skips, cols, verbose, use_color):
123126
diff_cmd = ('git', 'diff', '--no-ext-diff')
124127
diff_before = cmd_output_b(*diff_cmd, retcode=None)
125128
filenames = tuple(filenames) if hook.pass_filenames else ()
129+
time_before = time.time()
126130
retcode, out = hook.run(filenames, use_color)
131+
duration = round(time.time() - time_before, 2) or 0
127132
diff_after = cmd_output_b(*diff_cmd, retcode=None)
128133

129134
# if the hook makes changes, fail the commit
@@ -141,6 +146,9 @@ def _run_single_hook(classifier, hook, skips, cols, verbose, use_color):
141146
if verbose or hook.verbose or retcode or files_modified:
142147
_subtle_line('- hook id: {}'.format(hook.id), use_color)
143148

149+
if (verbose or hook.verbose) and duration is not None:
150+
_subtle_line('- duration: {}s'.format(duration), use_color)
151+
144152
if retcode:
145153
_subtle_line('- exit code: {}'.format(retcode), use_color)
146154

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
- id: python3-hook
2-
name: Python 3 Hook
3-
entry: python3-hook
4-
language: python
5-
language_version: python3
1+
- id: hook
2+
name: hook
3+
entry: ./hook.sh
4+
language: script
65
files: \.py$
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/usr/bin/env bash
2+
# Intentionally write mixed encoding to the output. This should not crash
3+
# pre-commit and should write bytes to the output.
4+
# '☃'.encode('UTF-8') + '²'.encode('latin1')
5+
echo -e '\xe2\x98\x83\xb2'
6+
# exit 1 to trigger printing
7+
exit 1

testing/resources/arbitrary_bytes_repo/python3_hook.py

Lines changed: 0 additions & 13 deletions
This file was deleted.

testing/resources/arbitrary_bytes_repo/setup.py

Lines changed: 0 additions & 8 deletions
This file was deleted.

tests/commands/run_test.py

Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import os.path
66
import pipes
77
import sys
8+
import time
89

910
import mock
1011
import pytest
@@ -25,6 +26,7 @@
2526
from testing.fixtures import modify_config
2627
from testing.fixtures import read_config
2728
from testing.fixtures import sample_meta_config
29+
from testing.fixtures import write_config
2830
from testing.util import cmd_output_mocked_pre_commit_home
2931
from testing.util import cwd
3032
from testing.util import git_commit
@@ -163,36 +165,55 @@ def test_exclude_types_hook_repository(cap_out, store, tempdir_factory):
163165
assert b'exe' not in printed
164166

165167

166-
def test_global_exclude(cap_out, store, tempdir_factory):
167-
git_path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
168-
with cwd(git_path):
169-
with modify_config() as config:
170-
config['exclude'] = '^foo.py$'
171-
open('foo.py', 'a').close()
172-
open('bar.py', 'a').close()
173-
cmd_output('git', 'add', '.')
174-
opts = run_opts(verbose=True)
175-
ret, printed = _do_run(cap_out, store, git_path, opts)
176-
assert ret == 0
177-
# Does not contain foo.py since it was excluded
178-
expected = b'- hook id: bash_hook\n\nbar.py\nHello World\n\n'
179-
assert printed.endswith(expected)
168+
def test_global_exclude(cap_out, store, in_git_dir):
169+
config = {
170+
'exclude': r'^foo\.py$',
171+
'repos': [{'repo': 'meta', 'hooks': [{'id': 'identity'}]}],
172+
}
173+
write_config('.', config)
174+
open('foo.py', 'a').close()
175+
open('bar.py', 'a').close()
176+
cmd_output('git', 'add', '.')
177+
opts = run_opts(verbose=True)
178+
ret, printed = _do_run(cap_out, store, str(in_git_dir), opts)
179+
assert ret == 0
180+
# Does not contain foo.py since it was excluded
181+
assert printed.startswith(b'identity' + b'.' * 65 + b'Passed\n')
182+
assert printed.endswith(b'\n\n.pre-commit-config.yaml\nbar.py\n\n')
180183

181184

182-
def test_global_files(cap_out, store, tempdir_factory):
183-
git_path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
184-
with cwd(git_path):
185-
with modify_config() as config:
186-
config['files'] = '^bar.py$'
187-
open('foo.py', 'a').close()
188-
open('bar.py', 'a').close()
189-
cmd_output('git', 'add', '.')
190-
opts = run_opts(verbose=True)
191-
ret, printed = _do_run(cap_out, store, git_path, opts)
192-
assert ret == 0
193-
# Does not contain foo.py since it was not included
194-
expected = b'- hook id: bash_hook\n\nbar.py\nHello World\n\n'
195-
assert printed.endswith(expected)
185+
def test_global_files(cap_out, store, in_git_dir):
186+
config = {
187+
'files': r'^bar\.py$',
188+
'repos': [{'repo': 'meta', 'hooks': [{'id': 'identity'}]}],
189+
}
190+
write_config('.', config)
191+
open('foo.py', 'a').close()
192+
open('bar.py', 'a').close()
193+
cmd_output('git', 'add', '.')
194+
opts = run_opts(verbose=True)
195+
ret, printed = _do_run(cap_out, store, str(in_git_dir), opts)
196+
assert ret == 0
197+
# Does not contain foo.py since it was excluded
198+
assert printed.startswith(b'identity' + b'.' * 65 + b'Passed\n')
199+
assert printed.endswith(b'\n\nbar.py\n\n')
200+
201+
202+
@pytest.mark.parametrize(
203+
('t1', 't2', 'expected'),
204+
(
205+
(1.234, 2., b'\n- duration: 0.77s\n'),
206+
(1., 1., b'\n- duration: 0s\n'),
207+
),
208+
)
209+
def test_verbose_duration(cap_out, store, in_git_dir, t1, t2, expected):
210+
write_config('.', {'repo': 'meta', 'hooks': [{'id': 'identity'}]})
211+
cmd_output('git', 'add', '.')
212+
opts = run_opts(verbose=True)
213+
with mock.patch.object(time, 'time', side_effect=(t1, t2)):
214+
ret, printed = _do_run(cap_out, store, str(in_git_dir), opts)
215+
assert ret == 0
216+
assert expected in printed
196217

197218

198219
@pytest.mark.parametrize(

tests/commands/try_repo_test.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33

44
import os.path
55
import re
6+
import time
7+
8+
import mock
69

710
from pre_commit import git
811
from pre_commit.commands.try_repo import try_repo
@@ -40,7 +43,8 @@ def _run_try_repo(tempdir_factory, **kwargs):
4043

4144

4245
def test_try_repo_repo_only(cap_out, tempdir_factory):
43-
_run_try_repo(tempdir_factory, verbose=True)
46+
with mock.patch.object(time, 'time', return_value=0.0):
47+
_run_try_repo(tempdir_factory, verbose=True)
4448
start, config, rest = _get_out(cap_out)
4549
assert start == ''
4650
assert re.match(
@@ -58,6 +62,7 @@ def test_try_repo_repo_only(cap_out, tempdir_factory):
5862
- hook id: bash_hook
5963
Bash hook................................................................Passed
6064
- hook id: bash_hook2
65+
- duration: 0s
6166
6267
test-file
6368

0 commit comments

Comments
 (0)