1
0
Fork 0

Adding upstream version 3.1.0.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-09 21:37:46 +01:00
parent 4066ef5157
commit 897eb1bb2a
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
88 changed files with 1083 additions and 974 deletions

View file

@ -0,0 +1,27 @@
from __future__ import annotations
from pre_commit.languages import docker_image
from testing.language_helpers import run_language
from testing.util import xfailif_windows
@xfailif_windows # pragma: win32 no cover
def test_docker_image_hook_via_entrypoint(tmp_path):
ret = run_language(
tmp_path,
docker_image,
'--entrypoint echo ubuntu:22.04',
args=('hello hello world',),
)
assert ret == (0, b'hello hello world\n')
@xfailif_windows # pragma: win32 no cover
def test_docker_image_hook_via_args(tmp_path):
ret = run_language(
tmp_path,
docker_image,
'ubuntu:22.04 echo',
args=('hello hello world',),
)
assert ret == (0, b'hello hello world\n')

View file

@ -11,6 +11,8 @@ import pytest
from pre_commit.languages import docker
from pre_commit.util import CalledProcessError
from testing.language_helpers import run_language
from testing.util import xfailif_windows
DOCKER_CGROUP_EXAMPLE = b'''\
12:hugetlb:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
@ -181,3 +183,15 @@ def test_get_docker_path_in_docker_docker_in_docker(in_docker):
err = CalledProcessError(1, (), b'', b'')
with mock.patch.object(docker, 'cmd_output_b', side_effect=err):
assert docker._get_docker_path('/project') == '/project'
@xfailif_windows # pragma: win32 no cover
def test_docker_hook(tmp_path):
dockerfile = '''\
FROM ubuntu:22.04
CMD ["echo", "This is overwritten by the entry"']
'''
tmp_path.joinpath('Dockerfile').write_text(dockerfile)
ret = run_language(tmp_path, docker, 'echo hello hello world')
assert ret == (0, b'hello hello world\n')

View file

@ -0,0 +1,154 @@
from __future__ import annotations
from pre_commit.languages import dotnet
from testing.language_helpers import run_language
def _write_program_cs(tmp_path):
program_cs = '''\
using System;
namespace dotnet_tests
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello from dotnet!");
}
}
}
'''
tmp_path.joinpath('Program.cs').write_text(program_cs)
def _csproj(tool_name):
return f'''\
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6</TargetFramework>
<PackAsTool>true</PackAsTool>
<ToolCommandName>{tool_name}</ToolCommandName>
<PackageOutputPath>./nupkg</PackageOutputPath>
</PropertyGroup>
</Project>
'''
def test_dotnet_csproj(tmp_path):
csproj = _csproj('testeroni')
_write_program_cs(tmp_path)
tmp_path.joinpath('dotnet_csproj.csproj').write_text(csproj)
ret = run_language(tmp_path, dotnet, 'testeroni')
assert ret == (0, b'Hello from dotnet!\n')
def test_dotnet_csproj_prefix(tmp_path):
csproj = _csproj('testeroni.tool')
_write_program_cs(tmp_path)
tmp_path.joinpath('dotnet_hooks_csproj_prefix.csproj').write_text(csproj)
ret = run_language(tmp_path, dotnet, 'testeroni.tool')
assert ret == (0, b'Hello from dotnet!\n')
def test_dotnet_sln(tmp_path):
csproj = _csproj('testeroni')
sln = '''\
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26124.0
MinimumVisualStudioVersion = 15.0.26124.0
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet_hooks_sln_repo", "dotnet_hooks_sln_repo.csproj", "{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Debug|x64.ActiveCfg = Debug|Any CPU
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Debug|x64.Build.0 = Debug|Any CPU
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Debug|x86.ActiveCfg = Debug|Any CPU
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Debug|x86.Build.0 = Debug|Any CPU
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Release|Any CPU.Build.0 = Release|Any CPU
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Release|x64.ActiveCfg = Release|Any CPU
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Release|x64.Build.0 = Release|Any CPU
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Release|x86.ActiveCfg = Release|Any CPU
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
''' # noqa: E501
_write_program_cs(tmp_path)
tmp_path.joinpath('dotnet_hooks_sln_repo.csproj').write_text(csproj)
tmp_path.joinpath('dotnet_hooks_sln_repo.sln').write_text(sln)
ret = run_language(tmp_path, dotnet, 'testeroni')
assert ret == (0, b'Hello from dotnet!\n')
def _setup_dotnet_combo(tmp_path):
sln = '''\
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30114.105
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "proj1", "proj1\\proj1.csproj", "{38A939C3-DEA4-47D7-9B75-0418C4249662}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "proj2", "proj2\\proj2.csproj", "{4C9916CB-165C-4EF5-8A57-4CB6794C1EBF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{38A939C3-DEA4-47D7-9B75-0418C4249662}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38A939C3-DEA4-47D7-9B75-0418C4249662}.Debug|Any CPU.Build.0 = Debug|Any CPU
{38A939C3-DEA4-47D7-9B75-0418C4249662}.Release|Any CPU.ActiveCfg = Release|Any CPU
{38A939C3-DEA4-47D7-9B75-0418C4249662}.Release|Any CPU.Build.0 = Release|Any CPU
{4C9916CB-165C-4EF5-8A57-4CB6794C1EBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4C9916CB-165C-4EF5-8A57-4CB6794C1EBF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4C9916CB-165C-4EF5-8A57-4CB6794C1EBF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4C9916CB-165C-4EF5-8A57-4CB6794C1EBF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
''' # noqa: E501
tmp_path.joinpath('dotnet_hooks_combo_repo.sln').write_text(sln)
csproj1 = _csproj('proj1')
proj1 = tmp_path.joinpath('proj1')
proj1.mkdir()
proj1.joinpath('proj1.csproj').write_text(csproj1)
_write_program_cs(proj1)
csproj2 = _csproj('proj2')
proj2 = tmp_path.joinpath('proj2')
proj2.mkdir()
proj2.joinpath('proj2.csproj').write_text(csproj2)
_write_program_cs(proj2)
def test_dotnet_combo_proj1(tmp_path):
_setup_dotnet_combo(tmp_path)
ret = run_language(tmp_path, dotnet, 'proj1')
assert ret == (0, b'Hello from dotnet!\n')
def test_dotnet_combo_proj2(tmp_path):
_setup_dotnet_combo(tmp_path)
ret = run_language(tmp_path, dotnet, 'proj2')
assert ret == (0, b'Hello from dotnet!\n')

View file

@ -0,0 +1,14 @@
from __future__ import annotations
from pre_commit.languages import fail
from testing.language_helpers import run_language
def test_fail_hooks(tmp_path):
ret = run_language(
tmp_path,
fail,
'watch out for',
file_args=('bunnies',),
)
assert ret == (1, b'watch out for\n\nbunnies\n')

View file

@ -6,8 +6,11 @@ import pytest
import re_assert
import pre_commit.constants as C
from pre_commit import lang_base
from pre_commit.envcontext import envcontext
from pre_commit.languages import golang
from pre_commit.languages import helpers
from pre_commit.store import _make_local_repo
from testing.language_helpers import run_language
ACTUAL_GET_DEFAULT_VERSION = golang.get_default_version.__wrapped__
@ -15,7 +18,7 @@ ACTUAL_GET_DEFAULT_VERSION = golang.get_default_version.__wrapped__
@pytest.fixture
def exe_exists_mck():
with mock.patch.object(helpers, 'exe_exists') as mck:
with mock.patch.object(lang_base, 'exe_exists') as mck:
yield mck
@ -41,3 +44,93 @@ def test_golang_infer_go_version_default():
assert version != C.DEFAULT
re_assert.Matches(r'^\d+\.\d+(?:\.\d+)?$').assert_matches(version)
def _make_hello_world(tmp_path):
go_mod = '''\
module golang-hello-world
go 1.18
require github.com/BurntSushi/toml v1.1.0
'''
go_sum = '''\
github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
''' # noqa: E501
hello_world_go = '''\
package main
import (
"fmt"
"github.com/BurntSushi/toml"
)
type Config struct {
What string
}
func main() {
var conf Config
toml.Decode("What = 'world'\\n", &conf)
fmt.Printf("hello %v\\n", conf.What)
}
'''
tmp_path.joinpath('go.mod').write_text(go_mod)
tmp_path.joinpath('go.sum').write_text(go_sum)
mod_dir = tmp_path.joinpath('golang-hello-world')
mod_dir.mkdir()
main_file = mod_dir.joinpath('main.go')
main_file.write_text(hello_world_go)
def test_golang_system(tmp_path):
_make_hello_world(tmp_path)
ret = run_language(tmp_path, golang, 'golang-hello-world')
assert ret == (0, b'hello world\n')
def test_golang_default_version(tmp_path):
_make_hello_world(tmp_path)
ret = run_language(
tmp_path,
golang,
'golang-hello-world',
version=C.DEFAULT,
)
assert ret == (0, b'hello world\n')
def test_golang_versioned(tmp_path):
_make_local_repo(str(tmp_path))
ret, out = run_language(
tmp_path,
golang,
'go version',
version='1.18.4',
)
assert ret == 0
assert out.startswith(b'go version go1.18.4')
def test_local_golang_additional_deps(tmp_path):
_make_local_repo(str(tmp_path))
ret = run_language(
tmp_path,
golang,
'hello',
deps=('golang.org/x/example/hello@latest',),
)
assert ret == (0, b'Hello, Go examples!\n')
def test_golang_hook_still_works_when_gobin_is_set(tmp_path):
with envcontext((('GOBIN', str(tmp_path.joinpath('gobin'))),)):
test_golang_system(tmp_path)

View file

@ -1,135 +0,0 @@
from __future__ import annotations
import multiprocessing
import os.path
import sys
from unittest import mock
import pytest
import pre_commit.constants as C
from pre_commit import parse_shebang
from pre_commit.languages import helpers
from pre_commit.prefix import Prefix
from pre_commit.util import CalledProcessError
@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_exe_exists_true_when_homedir_is_slash(find_exe_mck):
find_exe_mck.return_value = os.path.normpath('/usr/bin/ruby')
with mock.patch.object(os.path, 'expanduser', return_value=os.sep):
assert helpers.exe_exists('ruby') is True
def test_basic_get_default_version():
assert helpers.basic_get_default_version() == C.DEFAULT
def test_basic_health_check():
assert helpers.basic_health_check(Prefix('.'), 'default') is None
def test_failed_setup_command_does_not_unicode_error():
script = (
'import sys\n'
"sys.stderr.buffer.write(b'\\x81\\xfe')\n"
'raise SystemExit(1)\n'
)
# an assertion that this does not raise `UnicodeError`
with pytest.raises(CalledProcessError):
helpers.run_setup_cmd(Prefix('.'), (sys.executable, '-c', script))
def test_assert_no_additional_deps():
with pytest.raises(AssertionError) as excinfo:
helpers.assert_no_additional_deps('lang', ['hmmm'])
msg, = excinfo.value.args
assert msg == (
'for now, pre-commit does not support additional_dependencies for '
'lang -- '
"you selected `additional_dependencies: ['hmmm']`"
)
def test_target_concurrency_normal():
with mock.patch.object(multiprocessing, 'cpu_count', return_value=123):
with mock.patch.dict(os.environ, {}, clear=True):
assert helpers.target_concurrency() == 123
def test_target_concurrency_testing_env_var():
with mock.patch.dict(
os.environ, {'PRE_COMMIT_NO_CONCURRENCY': '1'}, clear=True,
):
assert helpers.target_concurrency() == 1
def test_target_concurrency_on_travis():
with mock.patch.dict(os.environ, {'TRAVIS': '1'}, clear=True):
assert helpers.target_concurrency() == 2
def test_target_concurrency_cpu_count_not_implemented():
with mock.patch.object(
multiprocessing, 'cpu_count', side_effect=NotImplementedError,
):
with mock.patch.dict(os.environ, {}, clear=True):
assert helpers.target_concurrency() == 1
def test_shuffled_is_deterministic():
seq = [str(i) for i in range(10)]
expected = ['4', '0', '5', '1', '8', '6', '2', '3', '7', '9']
assert helpers._shuffled(seq) == expected
def test_xargs_require_serial_is_not_shuffled():
ret, out = helpers.run_xargs(
('echo',), [str(i) for i in range(10)],
require_serial=True,
color=False,
)
assert ret == 0
assert out.strip() == b'0 1 2 3 4 5 6 7 8 9'

View file

@ -3,6 +3,7 @@ from __future__ import annotations
import pytest
from pre_commit.languages import pygrep
from testing.language_helpers import run_language
@pytest.fixture
@ -13,6 +14,9 @@ def some_files(tmpdir):
tmpdir.join('f4').write_binary(b'foo\npattern\nbar\n')
tmpdir.join('f5').write_binary(b'[INFO] hi\npattern\nbar')
tmpdir.join('f6').write_binary(b"pattern\nbarwith'foo\n")
tmpdir.join('f7').write_binary(b"hello'hi\nworld\n")
tmpdir.join('f8').write_binary(b'foo\nbar\nbaz\n')
tmpdir.join('f9').write_binary(b'[WARN] hi\n')
with tmpdir.as_cwd():
yield
@ -125,3 +129,16 @@ def test_multiline_multiline_flag_is_enabled(cap_out):
out = cap_out.get()
assert ret == 1
assert out == 'f1:1:foo\nbar\n'
def test_grep_hook_matching(some_files, tmp_path):
ret = run_language(
tmp_path, pygrep, 'ello', file_args=('f7', 'f8', 'f9'),
)
assert ret == (1, b"f7:1:hello'hi\n")
@pytest.mark.parametrize('regex', ('nope', "foo'bar", r'^\[INFO\]'))
def test_grep_hook_not_matching(regex, some_files, tmp_path):
ret = run_language(tmp_path, pygrep, regex, file_args=('f7', 'f8', 'f9'))
assert ret == (0, b'')

View file

@ -12,6 +12,7 @@ from pre_commit.languages import python
from pre_commit.prefix import Prefix
from pre_commit.util import make_executable
from pre_commit.util import win_exe
from testing.language_helpers import run_language
def test_read_pyvenv_cfg(tmpdir):
@ -210,3 +211,25 @@ def test_unhealthy_then_replaced(python_dir):
os.replace(f'{py_exe}.tmp', py_exe)
assert python.health_check(prefix, C.DEFAULT) is None
def test_language_versioned_python_hook(tmp_path):
setup_py = '''\
from setuptools import setup
setup(
name='example',
py_modules=['mod'],
entry_points={'console_scripts': ['myexe=mod:main']},
)
'''
tmp_path.joinpath('setup.py').write_text(setup_py)
tmp_path.joinpath('mod.py').write_text('def main(): print("ohai")')
# we patch this to force virtualenv executing with `-p` since we can't
# reliably have multiple pythons available in CI
with mock.patch.object(
python,
'_sys_executable_matches',
return_value=False,
):
assert run_language(tmp_path, python, 'myexe') == (0, b'ohai\n')

View file

@ -9,8 +9,8 @@ import pre_commit.constants as C
from pre_commit import parse_shebang
from pre_commit.envcontext import envcontext
from pre_commit.languages import ruby
from pre_commit.languages.ruby import _resource_bytesio
from pre_commit.store import _make_local_repo
from pre_commit.util import resource_bytesio
from testing.language_helpers import run_language
from testing.util import cwd
from testing.util import xfailif_windows
@ -40,7 +40,7 @@ def test_uses_system_if_both_gem_and_ruby_are_available(find_exe_mck):
('rbenv.tar.gz', 'ruby-build.tar.gz', 'ruby-download.tar.gz'),
)
def test_archive_root_stat(filename):
with resource_bytesio(filename) as f:
with _resource_bytesio(filename) as f:
with tarfile.open(fileobj=f) as tarf:
root, _, _ = filename.partition('.')
assert oct(tarf.getmember(root).mode) == '0o755'

View file

@ -0,0 +1,14 @@
from __future__ import annotations
from pre_commit.languages import script
from pre_commit.util import make_executable
from testing.language_helpers import run_language
def test_script_language(tmp_path):
exe = tmp_path.joinpath('main')
exe.write_text('#!/usr/bin/env bash\necho hello hello world\n')
make_executable(exe)
expected = (0, b'hello hello world\n')
assert run_language(tmp_path, script, 'main') == expected

View file

@ -0,0 +1,9 @@
from __future__ import annotations
from pre_commit.languages import system
from testing.language_helpers import run_language
def test_system_language(tmp_path):
expected = (0, b'hello hello world\n')
assert run_language(tmp_path, system, 'echo hello hello world') == expected