mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-02-17 08:14:42 +04:00
Replace our implementation of shebang parsing with identify's
This commit is contained in:
parent
a58d99ac40
commit
f956f421be
2 changed files with 4 additions and 57 deletions
|
|
@ -1,13 +1,9 @@
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import io
|
|
||||||
import os.path
|
import os.path
|
||||||
import shlex
|
|
||||||
import string
|
|
||||||
|
|
||||||
|
from identify.identify import parse_shebang_from_file
|
||||||
printable = frozenset(string.printable)
|
|
||||||
|
|
||||||
|
|
||||||
class ExecutableNotFoundError(OSError):
|
class ExecutableNotFoundError(OSError):
|
||||||
|
|
@ -15,34 +11,11 @@ class ExecutableNotFoundError(OSError):
|
||||||
return (1, self.args[0].encode('UTF-8'), b'')
|
return (1, self.args[0].encode('UTF-8'), b'')
|
||||||
|
|
||||||
|
|
||||||
def parse_bytesio(bytesio):
|
|
||||||
"""Parse the shebang from a file opened for reading binary."""
|
|
||||||
if bytesio.read(2) != b'#!':
|
|
||||||
return ()
|
|
||||||
first_line = bytesio.readline()
|
|
||||||
try:
|
|
||||||
first_line = first_line.decode('US-ASCII')
|
|
||||||
except UnicodeDecodeError:
|
|
||||||
return ()
|
|
||||||
|
|
||||||
# Require only printable ascii
|
|
||||||
for c in first_line:
|
|
||||||
if c not in printable:
|
|
||||||
return ()
|
|
||||||
|
|
||||||
cmd = tuple(shlex.split(first_line))
|
|
||||||
if cmd[0] == '/usr/bin/env':
|
|
||||||
cmd = cmd[1:]
|
|
||||||
return cmd
|
|
||||||
|
|
||||||
|
|
||||||
def parse_filename(filename):
|
def parse_filename(filename):
|
||||||
"""Parse the shebang given a filename."""
|
if not os.path.exists(filename):
|
||||||
if not os.path.exists(filename) or not os.access(filename, os.X_OK):
|
|
||||||
return ()
|
return ()
|
||||||
|
else:
|
||||||
with io.open(filename, 'rb') as f:
|
return parse_shebang_from_file(filename)
|
||||||
return parse_bytesio(f)
|
|
||||||
|
|
||||||
|
|
||||||
def find_executable(exe, _environ=None):
|
def find_executable(exe, _environ=None):
|
||||||
|
|
|
||||||
|
|
@ -15,36 +15,10 @@ from pre_commit.envcontext import Var
|
||||||
from pre_commit.util import make_executable
|
from pre_commit.util import make_executable
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
('s', 'expected'),
|
|
||||||
(
|
|
||||||
(b'', ()),
|
|
||||||
(b'#!/usr/bin/python', ('/usr/bin/python',)),
|
|
||||||
(b'#!/usr/bin/env python', ('python',)),
|
|
||||||
(b'#! /usr/bin/python', ('/usr/bin/python',)),
|
|
||||||
(b'#!/usr/bin/foo python', ('/usr/bin/foo', 'python')),
|
|
||||||
(b'\xf9\x93\x01\x42\xcd', ()),
|
|
||||||
(b'#!\xf9\x93\x01\x42\xcd', ()),
|
|
||||||
(b'#!\x00\x00\x00\x00', ()),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
def test_parse_bytesio(s, expected):
|
|
||||||
assert parse_shebang.parse_bytesio(io.BytesIO(s)) == expected
|
|
||||||
|
|
||||||
|
|
||||||
def test_file_doesnt_exist():
|
def test_file_doesnt_exist():
|
||||||
assert parse_shebang.parse_filename('herp derp derp') == ()
|
assert parse_shebang.parse_filename('herp derp derp') == ()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(
|
|
||||||
sys.platform == 'win32', reason='Windows says everything is X_OK',
|
|
||||||
)
|
|
||||||
def test_file_not_executable(tmpdir):
|
|
||||||
x = tmpdir.join('f')
|
|
||||||
x.write_text('#!/usr/bin/env python', encoding='UTF-8')
|
|
||||||
assert parse_shebang.parse_filename(x.strpath) == ()
|
|
||||||
|
|
||||||
|
|
||||||
def test_simple_case(tmpdir):
|
def test_simple_case(tmpdir):
|
||||||
x = tmpdir.join('f')
|
x = tmpdir.join('f')
|
||||||
x.write_text('#!/usr/bin/env python', encoding='UTF-8')
|
x.write_text('#!/usr/bin/env python', encoding='UTF-8')
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue