mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-02-17 08:14:42 +04:00
Merge pull request #1668 from pre-commit/avoid_shims
don't use system for ruby/node if it is a shim exe
This commit is contained in:
commit
763dbc0ac6
4 changed files with 67 additions and 5 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
|
import re
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
@ -10,6 +11,7 @@ from typing import Tuple
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import pre_commit.constants as C
|
import pre_commit.constants as C
|
||||||
|
from pre_commit import parse_shebang
|
||||||
from pre_commit.hook import Hook
|
from pre_commit.hook import Hook
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
from pre_commit.util import cmd_output_b
|
from pre_commit.util import cmd_output_b
|
||||||
|
|
@ -20,6 +22,25 @@ if TYPE_CHECKING:
|
||||||
|
|
||||||
FIXED_RANDOM_SEED = 1542676187
|
FIXED_RANDOM_SEED = 1542676187
|
||||||
|
|
||||||
|
SHIMS_RE = re.compile(r'[/\\]shims[/\\]')
|
||||||
|
|
||||||
|
|
||||||
|
def exe_exists(exe: str) -> bool:
|
||||||
|
found = parse_shebang.find_executable(exe)
|
||||||
|
if found is None: # exe exists
|
||||||
|
return False
|
||||||
|
|
||||||
|
homedir = os.path.expanduser('~')
|
||||||
|
try:
|
||||||
|
common: Optional[str] = os.path.commonpath((found, homedir))
|
||||||
|
except ValueError: # on windows, different drives raises ValueError
|
||||||
|
common = None
|
||||||
|
|
||||||
|
return (
|
||||||
|
not SHIMS_RE.search(found) and # it is not in a /shims/ directory
|
||||||
|
common != homedir # it is not in the home directory
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def run_setup_cmd(prefix: Prefix, cmd: Tuple[str, ...]) -> None:
|
def run_setup_cmd(prefix: Prefix, cmd: Tuple[str, ...]) -> None:
|
||||||
cmd_output_b(*cmd, cwd=prefix.prefix_dir)
|
cmd_output_b(*cmd, cwd=prefix.prefix_dir)
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ from typing import Sequence
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
import pre_commit.constants as C
|
import pre_commit.constants as C
|
||||||
from pre_commit import parse_shebang
|
|
||||||
from pre_commit.envcontext import envcontext
|
from pre_commit.envcontext import envcontext
|
||||||
from pre_commit.envcontext import PatchesT
|
from pre_commit.envcontext import PatchesT
|
||||||
from pre_commit.envcontext import UNSET
|
from pre_commit.envcontext import UNSET
|
||||||
|
|
@ -31,7 +30,7 @@ def get_default_version() -> str:
|
||||||
return C.DEFAULT
|
return C.DEFAULT
|
||||||
# if node is already installed, we can save a bunch of setup time by
|
# if node is already installed, we can save a bunch of setup time by
|
||||||
# using the installed version
|
# using the installed version
|
||||||
elif all(parse_shebang.find_executable(exe) for exe in ('node', 'npm')):
|
elif all(helpers.exe_exists(exe) for exe in ('node', 'npm')):
|
||||||
return 'system'
|
return 'system'
|
||||||
else:
|
else:
|
||||||
return C.DEFAULT
|
return C.DEFAULT
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ from typing import Sequence
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
import pre_commit.constants as C
|
import pre_commit.constants as C
|
||||||
from pre_commit import parse_shebang
|
|
||||||
from pre_commit.envcontext import envcontext
|
from pre_commit.envcontext import envcontext
|
||||||
from pre_commit.envcontext import PatchesT
|
from pre_commit.envcontext import PatchesT
|
||||||
from pre_commit.envcontext import UNSET
|
from pre_commit.envcontext import UNSET
|
||||||
|
|
@ -26,7 +25,7 @@ healthy = helpers.basic_healthy
|
||||||
|
|
||||||
@functools.lru_cache(maxsize=1)
|
@functools.lru_cache(maxsize=1)
|
||||||
def get_default_version() -> str:
|
def get_default_version() -> str:
|
||||||
if all(parse_shebang.find_executable(exe) for exe in ('ruby', 'gem')):
|
if all(helpers.exe_exists(exe) for exe in ('ruby', 'gem')):
|
||||||
return 'system'
|
return 'system'
|
||||||
else:
|
else:
|
||||||
return C.DEFAULT
|
return C.DEFAULT
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,60 @@
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
import os
|
import os.path
|
||||||
import sys
|
import sys
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
import pre_commit.constants as C
|
import pre_commit.constants as C
|
||||||
|
from pre_commit import parse_shebang
|
||||||
from pre_commit.languages import helpers
|
from pre_commit.languages import helpers
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
from pre_commit.util import CalledProcessError
|
from pre_commit.util import CalledProcessError
|
||||||
from testing.auto_namedtuple import auto_namedtuple
|
from testing.auto_namedtuple import auto_namedtuple
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def find_exe_mck():
|
||||||
|
with mock.patch.object(parse_shebang, 'find_executable') as mck:
|
||||||
|
yield mck
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def homedir_mck():
|
||||||
|
def fake_expanduser(pth):
|
||||||
|
assert pth == '~'
|
||||||
|
return os.path.normpath('/home/me')
|
||||||
|
|
||||||
|
with mock.patch.object(os.path, 'expanduser', fake_expanduser):
|
||||||
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
def test_exe_exists_does_not_exist(find_exe_mck, homedir_mck):
|
||||||
|
find_exe_mck.return_value = None
|
||||||
|
assert helpers.exe_exists('ruby') is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_exe_exists_exists(find_exe_mck, homedir_mck):
|
||||||
|
find_exe_mck.return_value = os.path.normpath('/usr/bin/ruby')
|
||||||
|
assert helpers.exe_exists('ruby') is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_exe_exists_false_if_shim(find_exe_mck, homedir_mck):
|
||||||
|
find_exe_mck.return_value = os.path.normpath('/foo/shims/ruby')
|
||||||
|
assert helpers.exe_exists('ruby') is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_exe_exists_false_if_homedir(find_exe_mck, homedir_mck):
|
||||||
|
find_exe_mck.return_value = os.path.normpath('/home/me/somedir/ruby')
|
||||||
|
assert helpers.exe_exists('ruby') is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_exe_exists_commonpath_raises_ValueError(find_exe_mck, homedir_mck):
|
||||||
|
find_exe_mck.return_value = os.path.normpath('/usr/bin/ruby')
|
||||||
|
with mock.patch.object(os.path, 'commonpath', side_effect=ValueError):
|
||||||
|
assert helpers.exe_exists('ruby') is True
|
||||||
|
|
||||||
|
|
||||||
def test_basic_get_default_version():
|
def test_basic_get_default_version():
|
||||||
assert helpers.basic_get_default_version() == C.DEFAULT
|
assert helpers.basic_get_default_version() == C.DEFAULT
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue