Merging upstream version 2.13.0.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
c2d1f037e4
commit
1e2278d3de
27 changed files with 1249 additions and 80 deletions
|
@ -526,9 +526,9 @@ def test_merge_conflict(cap_out, store, in_merge_conflict):
|
|||
|
||||
def test_merge_conflict_modified(cap_out, store, in_merge_conflict):
|
||||
# Touch another file so we have unstaged non-conflicting things
|
||||
assert os.path.exists('dummy')
|
||||
with open('dummy', 'w') as dummy_file:
|
||||
dummy_file.write('bar\nbaz\n')
|
||||
assert os.path.exists('placeholder')
|
||||
with open('placeholder', 'w') as placeholder_file:
|
||||
placeholder_file.write('bar\nbaz\n')
|
||||
|
||||
ret, printed = _do_run(cap_out, store, in_merge_conflict, run_opts())
|
||||
assert ret == 1
|
||||
|
@ -600,6 +600,29 @@ def test_skip_aliased_hook(cap_out, store, aliased_repo):
|
|||
assert printed.count(msg) == 1
|
||||
|
||||
|
||||
def test_skip_bypasses_installation(cap_out, store, repo_with_passing_hook):
|
||||
config = {
|
||||
'repo': 'local',
|
||||
'hooks': [
|
||||
{
|
||||
'id': 'skipme',
|
||||
'name': 'skipme',
|
||||
'entry': 'skipme',
|
||||
'language': 'python',
|
||||
'additional_dependencies': ['/pre-commit-does-not-exist'],
|
||||
},
|
||||
],
|
||||
}
|
||||
add_config_to_repo(repo_with_passing_hook, config)
|
||||
|
||||
ret, printed = _do_run(
|
||||
cap_out, store, repo_with_passing_hook,
|
||||
run_opts(all_files=True),
|
||||
{'SKIP': 'skipme'},
|
||||
)
|
||||
assert ret == 0
|
||||
|
||||
|
||||
def test_hook_id_not_in_non_verbose_output(
|
||||
cap_out, store, repo_with_passing_hook,
|
||||
):
|
||||
|
@ -808,9 +831,9 @@ def test_local_hook_passes(cap_out, store, repo_with_passing_hook):
|
|||
}
|
||||
add_config_to_repo(repo_with_passing_hook, config)
|
||||
|
||||
with open('dummy.py', 'w') as staged_file:
|
||||
with open('placeholder.py', 'w') as staged_file:
|
||||
staged_file.write('"""TODO: something"""\n')
|
||||
cmd_output('git', 'add', 'dummy.py')
|
||||
cmd_output('git', 'add', 'placeholder.py')
|
||||
|
||||
_test_run(
|
||||
cap_out,
|
||||
|
@ -835,9 +858,9 @@ def test_local_hook_fails(cap_out, store, repo_with_passing_hook):
|
|||
}
|
||||
add_config_to_repo(repo_with_passing_hook, config)
|
||||
|
||||
with open('dummy.py', 'w') as staged_file:
|
||||
with open('placeholder.py', 'w') as staged_file:
|
||||
staged_file.write('"""TODO: something"""\n')
|
||||
cmd_output('git', 'add', 'dummy.py')
|
||||
cmd_output('git', 'add', 'placeholder.py')
|
||||
|
||||
_test_run(
|
||||
cap_out,
|
||||
|
|
|
@ -90,8 +90,8 @@ def _make_conflict():
|
|||
@pytest.fixture
|
||||
def in_merge_conflict(tempdir_factory):
|
||||
path = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
|
||||
open(os.path.join(path, 'dummy'), 'a').close()
|
||||
cmd_output('git', 'add', 'dummy', cwd=path)
|
||||
open(os.path.join(path, 'placeholder'), 'a').close()
|
||||
cmd_output('git', 'add', 'placeholder', cwd=path)
|
||||
git_commit(msg=in_merge_conflict.__name__, cwd=path)
|
||||
|
||||
conflict_path = tempdir_factory.get()
|
||||
|
|
|
@ -1,14 +1,155 @@
|
|||
import builtins
|
||||
import json
|
||||
import ntpath
|
||||
import os.path
|
||||
import posixpath
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
|
||||
from pre_commit.languages import docker
|
||||
|
||||
|
||||
def test_docker_fallback_user():
|
||||
def invalid_attribute():
|
||||
raise AttributeError
|
||||
|
||||
with mock.patch.multiple(
|
||||
'os', create=True,
|
||||
getuid=invalid_attribute,
|
||||
getgid=invalid_attribute,
|
||||
'os', create=True,
|
||||
getuid=invalid_attribute,
|
||||
getgid=invalid_attribute,
|
||||
):
|
||||
assert docker.get_docker_user() == ()
|
||||
|
||||
|
||||
def test_in_docker_no_file():
|
||||
with mock.patch.object(builtins, 'open', side_effect=FileNotFoundError):
|
||||
assert docker._is_in_docker() is False
|
||||
|
||||
|
||||
def _mock_open(data):
|
||||
return mock.patch.object(
|
||||
builtins,
|
||||
'open',
|
||||
new_callable=mock.mock_open,
|
||||
read_data=data,
|
||||
)
|
||||
|
||||
|
||||
def test_in_docker_docker_in_file():
|
||||
docker_cgroup_example = b'''\
|
||||
12:hugetlb:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||
11:blkio:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||
10:freezer:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||
9:cpu,cpuacct:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||
8:pids:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||
7:rdma:/
|
||||
6:net_cls,net_prio:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||
5:cpuset:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||
4:devices:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||
3:memory:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||
2:perf_event:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||
1:name=systemd:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||
0::/system.slice/containerd.service
|
||||
''' # noqa: E501
|
||||
with _mock_open(docker_cgroup_example):
|
||||
assert docker._is_in_docker() is True
|
||||
|
||||
|
||||
def test_in_docker_docker_not_in_file():
|
||||
non_docker_cgroup_example = b'''\
|
||||
12:perf_event:/
|
||||
11:hugetlb:/
|
||||
10:devices:/
|
||||
9:blkio:/
|
||||
8:rdma:/
|
||||
7:cpuset:/
|
||||
6:cpu,cpuacct:/
|
||||
5:freezer:/
|
||||
4:memory:/
|
||||
3:pids:/
|
||||
2:net_cls,net_prio:/
|
||||
1:name=systemd:/init.scope
|
||||
0::/init.scope
|
||||
'''
|
||||
with _mock_open(non_docker_cgroup_example):
|
||||
assert docker._is_in_docker() is False
|
||||
|
||||
|
||||
def test_get_docker_path_not_in_docker_returns_same():
|
||||
with mock.patch.object(docker, '_is_in_docker', return_value=False):
|
||||
assert docker._get_docker_path('abc') == 'abc'
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def in_docker():
|
||||
with mock.patch.object(docker, '_is_in_docker', return_value=True):
|
||||
yield
|
||||
|
||||
|
||||
def _linux_commonpath():
|
||||
return mock.patch.object(os.path, 'commonpath', posixpath.commonpath)
|
||||
|
||||
|
||||
def _nt_commonpath():
|
||||
return mock.patch.object(os.path, 'commonpath', ntpath.commonpath)
|
||||
|
||||
|
||||
def _docker_output(out):
|
||||
ret = (0, out, b'')
|
||||
return mock.patch.object(docker, 'cmd_output_b', return_value=ret)
|
||||
|
||||
|
||||
def test_get_docker_path_in_docker_no_binds_same_path(in_docker):
|
||||
docker_out = json.dumps([{'Mounts': []}]).encode()
|
||||
|
||||
with _docker_output(docker_out):
|
||||
assert docker._get_docker_path('abc') == 'abc'
|
||||
|
||||
|
||||
def test_get_docker_path_in_docker_binds_path_equal(in_docker):
|
||||
binds_list = [{'Source': '/opt/my_code', 'Destination': '/project'}]
|
||||
docker_out = json.dumps([{'Mounts': binds_list}]).encode()
|
||||
|
||||
with _linux_commonpath(), _docker_output(docker_out):
|
||||
assert docker._get_docker_path('/project') == '/opt/my_code'
|
||||
|
||||
|
||||
def test_get_docker_path_in_docker_binds_path_complex(in_docker):
|
||||
binds_list = [{'Source': '/opt/my_code', 'Destination': '/project'}]
|
||||
docker_out = json.dumps([{'Mounts': binds_list}]).encode()
|
||||
|
||||
with _linux_commonpath(), _docker_output(docker_out):
|
||||
path = '/project/test/something'
|
||||
assert docker._get_docker_path(path) == '/opt/my_code/test/something'
|
||||
|
||||
|
||||
def test_get_docker_path_in_docker_no_substring(in_docker):
|
||||
binds_list = [{'Source': '/opt/my_code', 'Destination': '/project'}]
|
||||
docker_out = json.dumps([{'Mounts': binds_list}]).encode()
|
||||
|
||||
with _linux_commonpath(), _docker_output(docker_out):
|
||||
path = '/projectSuffix/test/something'
|
||||
assert docker._get_docker_path(path) == path
|
||||
|
||||
|
||||
def test_get_docker_path_in_docker_binds_path_many_binds(in_docker):
|
||||
binds_list = [
|
||||
{'Source': '/something_random', 'Destination': '/not-related'},
|
||||
{'Source': '/opt/my_code', 'Destination': '/project'},
|
||||
{'Source': '/something-random-2', 'Destination': '/not-related-2'},
|
||||
]
|
||||
docker_out = json.dumps([{'Mounts': binds_list}]).encode()
|
||||
|
||||
with _linux_commonpath(), _docker_output(docker_out):
|
||||
assert docker._get_docker_path('/project') == '/opt/my_code'
|
||||
|
||||
|
||||
def test_get_docker_path_in_docker_windows(in_docker):
|
||||
binds_list = [{'Source': r'c:\users\user', 'Destination': r'c:\folder'}]
|
||||
docker_out = json.dumps([{'Mounts': binds_list}]).encode()
|
||||
|
||||
with _nt_commonpath(), _docker_output(docker_out):
|
||||
path = r'c:\folder\test\something'
|
||||
expected = r'c:\users\user\test\something'
|
||||
assert docker._get_docker_path(path) == expected
|
||||
|
|
|
@ -14,10 +14,12 @@ def _test_r_parsing(
|
|||
hook_id,
|
||||
expected_hook_expr={},
|
||||
expected_args={},
|
||||
config={},
|
||||
expect_path_prefix=True,
|
||||
):
|
||||
repo_path = 'r_hooks_repo'
|
||||
path = make_repo(tempdir_factory, repo_path)
|
||||
config = make_config_from_repo(path)
|
||||
config = config or make_config_from_repo(path)
|
||||
hook = _get_hook_no_install(config, store, hook_id)
|
||||
ret = r._cmd_from_hook(hook)
|
||||
expected_cmd = 'Rscript'
|
||||
|
@ -25,7 +27,8 @@ def _test_r_parsing(
|
|||
'--no-save', '--no-restore', '--no-site-file', '--no-environ',
|
||||
)
|
||||
expected_path = os.path.join(
|
||||
hook.prefix.prefix_dir, '.'.join([hook_id, 'R']),
|
||||
hook.prefix.prefix_dir if expect_path_prefix else '',
|
||||
f'{hook_id}.R',
|
||||
)
|
||||
expected = (
|
||||
expected_cmd,
|
||||
|
@ -102,3 +105,25 @@ def test_r_parsing_expr_non_Rscirpt(tempdir_factory, store):
|
|||
|
||||
msg = execinfo.value.args
|
||||
assert msg == ('entry must start with `Rscript`.',)
|
||||
|
||||
|
||||
def test_r_parsing_file_local(tempdir_factory, store):
|
||||
path = 'path/to/script.R'
|
||||
hook_id = 'local-r'
|
||||
config = {
|
||||
'repo': 'local',
|
||||
'hooks': [{
|
||||
'id': hook_id,
|
||||
'name': 'local-r',
|
||||
'entry': f'Rscript {path}',
|
||||
'language': 'r',
|
||||
}],
|
||||
}
|
||||
_test_r_parsing(
|
||||
tempdir_factory,
|
||||
store,
|
||||
hook_id=hook_id,
|
||||
expected_hook_expr=(path,),
|
||||
config=config,
|
||||
expect_path_prefix=False,
|
||||
)
|
||||
|
|
|
@ -36,13 +36,13 @@ def test_uses_system_if_both_gem_and_ruby_are_available(find_exe_mck):
|
|||
def fake_gem_prefix(tmpdir):
|
||||
gemspec = '''\
|
||||
Gem::Specification.new do |s|
|
||||
s.name = 'pre_commit_dummy_package'
|
||||
s.name = 'pre_commit_placeholder_package'
|
||||
s.version = '0.0.0'
|
||||
s.summary = 'dummy gem for pre-commit hooks'
|
||||
s.summary = 'placeholder gem for pre-commit hooks'
|
||||
s.authors = ['Anthony Sottile']
|
||||
end
|
||||
'''
|
||||
tmpdir.join('dummy_gem.gemspec').write(gemspec)
|
||||
tmpdir.join('placeholder_gem.gemspec').write(gemspec)
|
||||
yield Prefix(tmpdir)
|
||||
|
||||
|
||||
|
@ -53,7 +53,7 @@ def test_install_ruby_system(fake_gem_prefix):
|
|||
# Should be able to activate and use rbenv install
|
||||
with ruby.in_env(fake_gem_prefix, 'system'):
|
||||
_, out, _ = cmd_output('gem', 'list')
|
||||
assert 'pre_commit_dummy_package' in out
|
||||
assert 'pre_commit_placeholder_package' in out
|
||||
|
||||
|
||||
@xfailif_windows # pragma: win32 no cover
|
||||
|
|
|
@ -186,7 +186,7 @@ def test_local_resources_reflects_reality():
|
|||
for res in os.listdir('pre_commit/resources')
|
||||
if res.startswith('empty_template_')
|
||||
}
|
||||
assert on_disk == set(Store.LOCAL_RESOURCES)
|
||||
assert on_disk == {os.path.basename(x) for x in Store.LOCAL_RESOURCES}
|
||||
|
||||
|
||||
def test_mark_config_as_used(store, tmpdir):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue