Don't crash when an executable is not found

This commit is contained in:
Anthony Sottile 2016-05-20 13:22:13 -07:00
parent da7e85c851
commit 5a6b6e81e9
5 changed files with 37 additions and 13 deletions

View file

@ -12,6 +12,10 @@ from pre_commit import five
printable = frozenset(string.printable) printable = frozenset(string.printable)
class ExecutableNotFoundError(OSError):
pass
def parse_bytesio(bytesio): def parse_bytesio(bytesio):
"""Parse the shebang from a file opened for reading binary.""" """Parse the shebang from a file opened for reading binary."""
if bytesio.read(2) != b'#!': if bytesio.read(2) != b'#!':
@ -70,7 +74,9 @@ def normexe(orig_exe):
if os.sep not in orig_exe: if os.sep not in orig_exe:
exe = find_executable(orig_exe) exe = find_executable(orig_exe)
if exe is None: if exe is None:
raise OSError('Executable {0} not found'.format(orig_exe)) raise ExecutableNotFoundError(
'Executable `{0}` not found'.format(orig_exe),
)
return exe return exe
else: else:
return orig_exe return orig_exe

View file

@ -181,8 +181,11 @@ def cmd_output(*cmd, **kwargs):
for key, value in kwargs.pop('env', {}).items() for key, value in kwargs.pop('env', {}).items()
) or None ) or None
try:
cmd = parse_shebang.normalize_cmd(cmd) cmd = parse_shebang.normalize_cmd(cmd)
except parse_shebang.ExecutableNotFoundError as e:
returncode, stdout, stderr = (-1, e.args[0].encode('UTF-8'), b'')
else:
popen_kwargs.update(kwargs) popen_kwargs.update(kwargs)
proc = __popen(cmd, **popen_kwargs) proc = __popen(cmd, **popen_kwargs)
stdout, stderr = proc.communicate() stdout, stderr = proc.communicate()
@ -197,7 +200,7 @@ def cmd_output(*cmd, **kwargs):
returncode, cmd, retcode, output=(stdout, stderr), returncode, cmd, retcode, output=(stdout, stderr),
) )
return proc.returncode, stdout, stderr return returncode, stdout, stderr
def rmtree(path): def rmtree(path):

View file

@ -0,0 +1,5 @@
- id: not-found-exe
name: Not found exe
entry: i-dont-exist-lol
language: system
files: ''

View file

@ -108,7 +108,7 @@ def test_find_executable_path_ext(in_tmpdir):
def test_normexe_does_not_exist(): def test_normexe_does_not_exist():
with pytest.raises(OSError) as excinfo: with pytest.raises(OSError) as excinfo:
parse_shebang.normexe('i-dont-exist-lol') parse_shebang.normexe('i-dont-exist-lol')
assert excinfo.value.args == ('Executable i-dont-exist-lol not found',) assert excinfo.value.args == ('Executable `i-dont-exist-lol` not found',)
def test_normexe_already_full_path(): def test_normexe_already_full_path():

View file

@ -164,6 +164,16 @@ def test_system_hook_with_spaces(tempdir_factory, store):
) )
@pytest.mark.integration
def test_missing_executable(tempdir_factory, store):
_test_hook_repo(
tempdir_factory, store, 'not_found_exe',
'not-found-exe', ['/dev/null'],
b'Executable `i-dont-exist-lol` not found',
expected_return_code=1,
)
@pytest.mark.integration @pytest.mark.integration
def test_run_a_script_hook(tempdir_factory, store): def test_run_a_script_hook(tempdir_factory, store):
_test_hook_repo( _test_hook_repo(