1
0
Fork 0

Merging upstream version 3.0.2.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-09 21:36:17 +01:00
parent 962b6a60c2
commit 3904671ae3
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
107 changed files with 1775 additions and 2323 deletions

View file

@ -23,6 +23,7 @@ from pre_commit.languages import ruby
from pre_commit.languages import rust
from pre_commit.languages.all import languages
from pre_commit.prefix import Prefix
from pre_commit.repository import _hook_installed
from pre_commit.repository import all_hooks
from pre_commit.repository import install_hook_envs
from pre_commit.util import cmd_output
@ -32,10 +33,7 @@ from testing.fixtures import make_repo
from testing.fixtures import modify_manifest
from testing.util import cwd
from testing.util import get_resource_path
from testing.util import skipif_cant_run_coursier
from testing.util import skipif_cant_run_docker
from testing.util import skipif_cant_run_lua
from testing.util import skipif_cant_run_swift
from testing.util import xfailif_windows
@ -44,7 +42,16 @@ def _norm_out(b):
def _hook_run(hook, filenames, color):
return languages[hook.language].run_hook(hook, filenames, color)
with languages[hook.language].in_env(hook.prefix, hook.language_version):
return languages[hook.language].run_hook(
hook.prefix,
hook.entry,
hook.args,
filenames,
is_local=hook.src == 'local',
require_serial=hook.require_serial,
color=color,
)
def _get_hook_no_install(repo_config, store, hook_id):
@ -81,47 +88,6 @@ def _test_hook_repo(
assert _norm_out(out) == expected
def test_conda_hook(tempdir_factory, store):
_test_hook_repo(
tempdir_factory, store, 'conda_hooks_repo',
'sys-exec', [os.devnull],
b'conda-default\n',
)
def test_conda_with_additional_dependencies_hook(tempdir_factory, store):
_test_hook_repo(
tempdir_factory, store, 'conda_hooks_repo',
'additional-deps', [os.devnull],
b'OK\n',
config_kwargs={
'hooks': [{
'id': 'additional-deps',
'args': ['-c', 'import tzdata; print("OK")'],
'additional_dependencies': ['python-tzdata'],
}],
},
)
def test_local_conda_additional_dependencies(store):
config = {
'repo': 'local',
'hooks': [{
'id': 'local-conda',
'name': 'local-conda',
'entry': 'python',
'language': 'conda',
'args': ['-c', 'import botocore; print("OK")'],
'additional_dependencies': ['botocore'],
}],
}
hook = _get_hook(config, store, 'local-conda')
ret, out = _hook_run(hook, (), color=False)
assert ret == 0
assert _norm_out(out) == b'OK\n'
def test_python_hook(tempdir_factory, store):
_test_hook_repo(
tempdir_factory, store, 'python_hooks_repo',
@ -133,9 +99,11 @@ def test_python_hook(tempdir_factory, store):
def test_python_hook_default_version(tempdir_factory, store):
# make sure that this continues to work for platforms where default
# language detection does not work
returns_default = mock.Mock(return_value=C.DEFAULT)
lang = languages['python']._replace(get_default_version=returns_default)
with mock.patch.dict(languages, python=lang):
with mock.patch.object(
python,
'get_default_version',
return_value=C.DEFAULT,
):
test_python_hook(tempdir_factory, store)
@ -189,15 +157,6 @@ def test_language_versioned_python_hook(tempdir_factory, store):
)
@skipif_cant_run_coursier # pragma: win32 no cover
def test_run_a_coursier_hook(tempdir_factory, store):
_test_hook_repo(
tempdir_factory, store, 'coursier_hooks_repo',
'echo-java',
['Hello World from coursier'], b'Hello World from coursier\n',
)
@skipif_cant_run_docker # pragma: win32 no cover
def test_run_a_docker_hook(tempdir_factory, store):
_test_hook_repo(
@ -247,9 +206,11 @@ def test_run_a_node_hook(tempdir_factory, store):
def test_run_a_node_hook_default_version(tempdir_factory, store):
# make sure that this continues to work for platforms where node is not
# installed at the system
returns_default = mock.Mock(return_value=C.DEFAULT)
lang = languages['node']._replace(get_default_version=returns_default)
with mock.patch.dict(languages, node=lang):
with mock.patch.object(
node,
'get_default_version',
return_value=C.DEFAULT,
):
test_run_a_node_hook(tempdir_factory, store)
@ -267,54 +228,6 @@ def test_node_hook_with_npm_userconfig_set(tempdir_factory, store, tmpdir):
test_run_a_node_hook(tempdir_factory, store)
def test_r_hook(tempdir_factory, store):
_test_hook_repo(
tempdir_factory, store, 'r_hooks_repo',
'hello-world', [os.devnull],
b'Hello, World, from R!\n',
)
def test_r_inline_hook(tempdir_factory, store):
_test_hook_repo(
tempdir_factory, store, 'r_hooks_repo',
'hello-world-inline', ['some-file'],
b'Hi-there, some-file, from R!\n',
)
def test_r_with_additional_dependencies_hook(tempdir_factory, store):
_test_hook_repo(
tempdir_factory, store, 'r_hooks_repo',
'additional-deps', [os.devnull],
b'OK\n',
config_kwargs={
'hooks': [{
'id': 'additional-deps',
'additional_dependencies': ['cachem@1.0.4'],
}],
},
)
def test_r_local_with_additional_dependencies_hook(store):
config = {
'repo': 'local',
'hooks': [{
'id': 'local-r',
'name': 'local-r',
'entry': 'Rscript -e',
'language': 'r',
'args': ['if (packageVersion("R6") == "2.1.3") cat("OK\n")'],
'additional_dependencies': ['R6@2.1.3'],
}],
}
hook = _get_hook(config, store, 'local-r')
ret, out = _hook_run(hook, (), color=False)
assert ret == 0
assert _norm_out(out) == b'OK\n'
def test_run_a_ruby_hook(tempdir_factory, store):
_test_hook_repo(
tempdir_factory, store, 'ruby_hooks_repo',
@ -335,7 +248,7 @@ def test_run_versioned_ruby_hook(tempdir_factory, store):
tempdir_factory, store, 'ruby_versioned_hooks_repo',
'ruby_hook',
[os.devnull],
b'3.1.0\nHello world from a ruby hook\n',
b'3.2.0\nHello world from a ruby hook\n',
)
@ -357,7 +270,7 @@ def test_run_ruby_hook_with_disable_shared_gems(
tempdir_factory, store, 'ruby_versioned_hooks_repo',
'ruby_hook',
[os.devnull],
b'3.1.0\nHello world from a ruby hook\n',
b'3.2.0\nHello world from a ruby hook\n',
)
@ -368,25 +281,36 @@ def test_system_hook_with_spaces(tempdir_factory, store):
)
@skipif_cant_run_swift # pragma: win32 no cover
def test_swift_hook(tempdir_factory, store):
def test_golang_system_hook(tempdir_factory, store):
_test_hook_repo(
tempdir_factory, store, 'swift_hooks_repo',
'swift-hooks-repo', [], b'Hello, world!\n',
tempdir_factory, store, 'golang_hooks_repo',
'golang-hook', ['system'], b'hello world from system\n',
config_kwargs={
'hooks': [{
'id': 'golang-hook',
'language_version': 'system',
}],
},
)
def test_golang_hook(tempdir_factory, store):
def test_golang_versioned_hook(tempdir_factory, store):
_test_hook_repo(
tempdir_factory, store, 'golang_hooks_repo',
'golang-hook', [], b'hello world\n',
'golang-hook', [], b'hello world from go1.18.4\n',
config_kwargs={
'hooks': [{
'id': 'golang-hook',
'language_version': '1.18.4',
}],
},
)
def test_golang_hook_still_works_when_gobin_is_set(tempdir_factory, store):
gobin_dir = tempdir_factory.get()
with envcontext((('GOBIN', gobin_dir),)):
test_golang_hook(tempdir_factory, store)
test_golang_system_hook(tempdir_factory, store)
assert os.listdir(gobin_dir) == []
@ -459,11 +383,12 @@ def test_additional_rust_cli_dependencies_installed(
# A small rust package with no dependencies.
config['hooks'][0]['additional_dependencies'] = [dep]
hook = _get_hook(config, store, 'rust-hook')
binaries = os.listdir(
hook.prefix.path(
helpers.environment_dir(rust.ENVIRONMENT_DIR, 'system'), 'bin',
),
envdir = helpers.environment_dir(
hook.prefix,
rust.ENVIRONMENT_DIR,
'system',
)
binaries = os.listdir(os.path.join(envdir, 'bin'))
# normalize for windows
binaries = [os.path.splitext(binary)[0] for binary in binaries]
assert 'shellharden' in binaries
@ -478,11 +403,12 @@ def test_additional_rust_lib_dependencies_installed(
deps = ['shellharden:3.1.0', 'git-version']
config['hooks'][0]['additional_dependencies'] = deps
hook = _get_hook(config, store, 'rust-hook')
binaries = os.listdir(
hook.prefix.path(
helpers.environment_dir(rust.ENVIRONMENT_DIR, 'system'), 'bin',
),
envdir = helpers.environment_dir(
hook.prefix,
rust.ENVIRONMENT_DIR,
'system',
)
binaries = os.listdir(os.path.join(envdir, 'bin'))
# normalize for windows
binaries = [os.path.splitext(binary)[0] for binary in binaries]
assert 'rust-hello-world' in binaries
@ -638,6 +564,21 @@ def test_additional_dependencies_roll_forward(tempdir_factory, store):
assert 'mccabe' not in cmd_output('pip', 'freeze', '-l')[1]
@pytest.mark.parametrize('v', ('v1', 'v2'))
def test_repository_state_compatibility(tempdir_factory, store, v):
path = make_repo(tempdir_factory, 'python_hooks_repo')
config = make_config_from_repo(path)
hook = _get_hook(config, store, 'foo')
envdir = helpers.environment_dir(
hook.prefix,
python.ENVIRONMENT_DIR,
hook.language_version,
)
os.remove(os.path.join(envdir, f'.install_state_{v}'))
assert _hook_installed(hook) is True
def test_additional_ruby_dependencies_installed(tempdir_factory, store):
path = make_repo(tempdir_factory, 'ruby_hooks_repo')
config = make_config_from_repo(path)
@ -668,11 +609,12 @@ def test_additional_golang_dependencies_installed(
deps = ['golang.org/x/example/hello@latest']
config['hooks'][0]['additional_dependencies'] = deps
hook = _get_hook(config, store, 'golang-hook')
binaries = os.listdir(
hook.prefix.path(
helpers.environment_dir(golang.ENVIRONMENT_DIR, C.DEFAULT), 'bin',
),
envdir = helpers.environment_dir(
hook.prefix,
golang.ENVIRONMENT_DIR,
golang.get_default_version(),
)
binaries = os.listdir(os.path.join(envdir, 'bin'))
# normalize for windows
binaries = [os.path.splitext(binary)[0] for binary in binaries]
assert 'hello' in binaries
@ -788,10 +730,14 @@ def test_control_c_control_c_on_install(tempdir_factory, store):
# Should have made an environment, however this environment is broken!
hook, = hooks
assert hook.prefix.exists(
helpers.environment_dir(python.ENVIRONMENT_DIR, hook.language_version),
envdir = helpers.environment_dir(
hook.prefix,
python.ENVIRONMENT_DIR,
hook.language_version,
)
assert os.path.exists(envdir)
# However, it should be perfectly runnable (reinstall after botched
# install)
install_hook_envs(hooks, store)
@ -807,10 +753,12 @@ def test_invalidated_virtualenv(tempdir_factory, store):
hook = _get_hook(config, store, 'foo')
# Simulate breaking of the virtualenv
libdir = hook.prefix.path(
helpers.environment_dir(python.ENVIRONMENT_DIR, hook.language_version),
'lib', hook.language_version,
envdir = helpers.environment_dir(
hook.prefix,
python.ENVIRONMENT_DIR,
hook.language_version,
)
libdir = os.path.join(envdir, 'lib', hook.language_version)
paths = [
os.path.join(libdir, p) for p in ('site.py', 'site.pyc', '__pycache__')
]
@ -1001,30 +949,6 @@ def test_manifest_hooks(tempdir_factory, store):
)
def test_perl_hook(tempdir_factory, store):
_test_hook_repo(
tempdir_factory, store, 'perl_hooks_repo',
'perl-hook', [], b'Hello from perl-commit Perl!\n',
)
def test_local_perl_additional_dependencies(store):
config = {
'repo': 'local',
'hooks': [{
'id': 'hello',
'name': 'hello',
'entry': 'perltidy --version',
'language': 'perl',
'additional_dependencies': ['SHANCOCK/Perl-Tidy-20211029.tar.gz'],
}],
}
hook = _get_hook(config, store, 'hello')
ret, out = _hook_run(hook, (), color=False)
assert ret == 0
assert _norm_out(out).startswith(b'This is perltidy, v20211029')
@pytest.mark.parametrize(
'repo',
(
@ -1041,46 +965,6 @@ def test_dotnet_hook(tempdir_factory, store, repo):
)
def test_dart_hook(tempdir_factory, store):
_test_hook_repo(
tempdir_factory, store, 'dart_repo',
'hello-world-dart', [], b'hello hello world\n',
)
def test_local_dart_additional_dependencies(store):
config = {
'repo': 'local',
'hooks': [{
'id': 'local-dart',
'name': 'local-dart',
'entry': 'hello-world-dart',
'language': 'dart',
'additional_dependencies': ['hello_world_dart'],
}],
}
hook = _get_hook(config, store, 'local-dart')
ret, out = _hook_run(hook, (), color=False)
assert (ret, _norm_out(out)) == (0, b'hello hello world\n')
def test_local_dart_additional_dependencies_versioned(store):
config = {
'repo': 'local',
'hooks': [{
'id': 'local-dart',
'name': 'local-dart',
'entry': 'secure-random -l 4 -b 16',
'language': 'dart',
'additional_dependencies': ['encrypt:5.0.0'],
}],
}
hook = _get_hook(config, store, 'local-dart')
ret, out = _hook_run(hook, (), color=False)
assert ret == 0
re_assert.Matches('^[a-f0-9]{8}\r?\n$').assert_matches(out.decode())
def test_non_installable_hook_error_for_language_version(store, caplog):
config = {
'repo': 'local',
@ -1125,29 +1009,3 @@ def test_non_installable_hook_error_for_additional_dependencies(store, caplog):
'using language `system` which does not install an environment. '
'Perhaps you meant to use a specific language?'
)
@skipif_cant_run_lua # pragma: win32 no cover
def test_lua_hook(tempdir_factory, store):
_test_hook_repo(
tempdir_factory, store, 'lua_repo',
'hello-world-lua', [], b'hello world\n',
)
@skipif_cant_run_lua # pragma: win32 no cover
def test_local_lua_additional_dependencies(store):
config = {
'repo': 'local',
'hooks': [{
'id': 'local-lua',
'name': 'local-lua',
'entry': 'luacheck --version',
'language': 'lua',
'additional_dependencies': ['luacheck'],
}],
}
hook = _get_hook(config, store, 'local-lua')
ret, out = _hook_run(hook, (), color=False)
assert b'Luacheck' in out
assert ret == 0