Skip to content

Commit f2644a4

Browse files
Alex HuttonAlex Hutton
authored andcommitted
Adds support for 'log_file' in hook config
Specify a filename on a per hook basis and pre-commit will write the STDOUT and STDERR of that hook into the file. Useful for CI. Resolves pre-commit#499.
1 parent 5d43b05 commit f2644a4

File tree

6 files changed

+59
-6
lines changed

6 files changed

+59
-6
lines changed

pre_commit/clientlib.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ def _make_argparser(filenames_help):
5353
'^$',
5454
),
5555
schema.Optional('language_version', schema.check_string, 'default'),
56+
schema.OptionalNoDefault('log_file', schema.check_string),
5657
schema.Optional('minimum_pre_commit_version', schema.check_string, '0'),
5758
schema.Optional('stages', schema.check_array(schema.check_string), []),
5859
)

pre_commit/commands/run.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,10 @@ def _run_single_hook(hook, repo, args, skips, cols):
121121
for out in (stdout, stderr):
122122
assert type(out) is bytes, type(out)
123123
if out.strip():
124-
output.write_line(out.strip())
124+
output.write_line(
125+
out.strip(),
126+
logfile_name=hook.get('log_file'),
127+
)
125128
output.write_line()
126129

127130
return retcode

pre_commit/output.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,17 @@ def write(s, stream=stdout_byte_stream):
7171
stream.flush()
7272

7373

74-
def write_line(s=None, stream=stdout_byte_stream):
75-
if s is not None:
76-
stream.write(five.to_bytes(s))
77-
stream.write(b'\n')
78-
stream.flush()
74+
def write_line(s=None, stream=stdout_byte_stream, logfile_name=None):
75+
def output_streams():
76+
yield stream
77+
try:
78+
with open(logfile_name, 'ab') as logfile:
79+
yield logfile
80+
except (TypeError, IOError):
81+
pass
82+
83+
for output_stream in output_streams():
84+
if s is not None:
85+
output_stream.write(five.to_bytes(s))
86+
output_stream.write(b'\n')
87+
output_stream.flush()
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
- id: logfile test hook
2+
name: Logfile test hook
3+
entry: bin/hook.sh
4+
language: script
5+
files: .
6+
log_file: test.log
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env bash
2+
echo "This is STDOUT output"
3+
echo "This is STDERR output" 1>&2
4+
5+
exit 1

tests/commands/run_test.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,35 @@ def test_run(
211211
)
212212

213213

214+
def test_run_output_logfile(
215+
cap_out,
216+
tempdir_factory,
217+
mock_out_store_directory,
218+
):
219+
220+
expected_output = (
221+
b'This is STDOUT output\n',
222+
b'This is STDERR output\n',
223+
)
224+
225+
git_path = make_consuming_repo(tempdir_factory, 'logfile_repo')
226+
with cwd(git_path):
227+
_test_run(
228+
cap_out,
229+
git_path, {},
230+
expected_output,
231+
expected_ret=1,
232+
stage=True
233+
)
234+
logfile_path = os.path.join(git_path, 'test.log')
235+
assert os.path.exists(logfile_path)
236+
with open(logfile_path, 'rb') as logfile:
237+
logfile_content = logfile.readlines()
238+
239+
for expected_output_part in expected_output:
240+
assert expected_output_part in logfile_content
241+
242+
214243
def test_always_run(
215244
cap_out, repo_with_passing_hook, mock_out_store_directory,
216245
):

0 commit comments

Comments
 (0)