Merging upstream version 2.11.0.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
e1036806b7
commit
b40b2e7e52
33 changed files with 586 additions and 19 deletions
|
@ -228,7 +228,8 @@ def test_warn_mutable_rev_invalid(caplog, rev):
|
|||
'Mutable references are never updated after first install and are '
|
||||
'not supported. '
|
||||
'See https://pre-commit.com/#using-the-latest-version-for-a-repository ' # noqa: E501
|
||||
'for more details.',
|
||||
'for more details. '
|
||||
'Hint: `pre-commit autoupdate` often fixes this.',
|
||||
),
|
||||
]
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@ def test_run_legacy_recursive(tmpdir):
|
|||
('pre-push', ['branch_name', 'remote_name']),
|
||||
('commit-msg', ['.git/COMMIT_EDITMSG']),
|
||||
('post-commit', []),
|
||||
('post-merge', ['1']),
|
||||
('post-checkout', ['old_head', 'new_head', '1']),
|
||||
# multiple choices for commit-editmsg
|
||||
('prepare-commit-msg', ['.git/COMMIT_EDITMSG']),
|
||||
|
@ -157,6 +158,14 @@ def test_run_ns_post_commit():
|
|||
assert ns.color is True
|
||||
|
||||
|
||||
def test_run_ns_post_merge():
|
||||
ns = hook_impl._run_ns('post-merge', True, ('1',), b'')
|
||||
assert ns is not None
|
||||
assert ns.hook_stage == 'post-merge'
|
||||
assert ns.color is True
|
||||
assert ns.is_squash_merge == '1'
|
||||
|
||||
|
||||
def test_run_ns_post_checkout():
|
||||
ns = hook_impl._run_ns('post-checkout', True, ('a', 'b', 'c'), b'')
|
||||
assert ns is not None
|
||||
|
|
|
@ -259,7 +259,10 @@ def _path_without_us():
|
|||
exe = find_executable('pre-commit', _environ=env)
|
||||
while exe:
|
||||
parts = env['PATH'].split(os.pathsep)
|
||||
after = [x for x in parts if x.lower() != os.path.dirname(exe).lower()]
|
||||
after = [
|
||||
x for x in parts
|
||||
if x.lower().rstrip(os.sep) != os.path.dirname(exe).lower()
|
||||
]
|
||||
if parts == after:
|
||||
raise AssertionError(exe, parts)
|
||||
env['PATH'] = os.pathsep.join(after)
|
||||
|
@ -759,6 +762,48 @@ def test_post_commit_integration(tempdir_factory, store):
|
|||
assert os.path.exists('post-commit.tmp')
|
||||
|
||||
|
||||
def test_post_merge_integration(tempdir_factory, store):
|
||||
path = git_dir(tempdir_factory)
|
||||
config = [
|
||||
{
|
||||
'repo': 'local',
|
||||
'hooks': [{
|
||||
'id': 'post-merge',
|
||||
'name': 'Post merge',
|
||||
'entry': 'touch post-merge.tmp',
|
||||
'language': 'system',
|
||||
'always_run': True,
|
||||
'verbose': True,
|
||||
'stages': ['post-merge'],
|
||||
}],
|
||||
},
|
||||
]
|
||||
write_config(path, config)
|
||||
with cwd(path):
|
||||
# create a simple diamond of commits for a non-trivial merge
|
||||
open('init', 'a').close()
|
||||
cmd_output('git', 'add', '.')
|
||||
git_commit()
|
||||
|
||||
open('master', 'a').close()
|
||||
cmd_output('git', 'add', '.')
|
||||
git_commit()
|
||||
|
||||
cmd_output('git', 'checkout', '-b', 'branch', 'HEAD^')
|
||||
open('branch', 'a').close()
|
||||
cmd_output('git', 'add', '.')
|
||||
git_commit()
|
||||
|
||||
cmd_output('git', 'checkout', 'master')
|
||||
install(C.CONFIG_FILE, store, hook_types=['post-merge'])
|
||||
retc, stdout, stderr = cmd_output_mocked_pre_commit_home(
|
||||
'git', 'merge', 'branch',
|
||||
tempdir_factory=tempdir_factory,
|
||||
)
|
||||
assert retc == 0
|
||||
assert os.path.exists('post-merge.tmp')
|
||||
|
||||
|
||||
def test_post_checkout_integration(tempdir_factory, store):
|
||||
path = git_dir(tempdir_factory)
|
||||
config = [
|
||||
|
|
|
@ -494,6 +494,15 @@ def test_all_push_options_ok(cap_out, store, repo_with_passing_hook):
|
|||
assert b'Specify both --from-ref and --to-ref.' not in printed
|
||||
|
||||
|
||||
def test_is_squash_merge(cap_out, store, repo_with_passing_hook):
|
||||
args = run_opts(is_squash_merge='1')
|
||||
environ: MutableMapping[str, str] = {}
|
||||
ret, printed = _do_run(
|
||||
cap_out, store, repo_with_passing_hook, args, environ,
|
||||
)
|
||||
assert environ['PRE_COMMIT_IS_SQUASH_MERGE'] == '1'
|
||||
|
||||
|
||||
def test_checkout_type(cap_out, store, repo_with_passing_hook):
|
||||
args = run_opts(from_ref='', to_ref='', checkout_type='1')
|
||||
environ: MutableMapping[str, str] = {}
|
||||
|
|
|
@ -38,6 +38,17 @@ def test_get_root_bare_worktree(tmpdir):
|
|||
assert git.get_root() == os.path.abspath('.')
|
||||
|
||||
|
||||
def test_get_root_worktree_in_git(tmpdir):
|
||||
src = tmpdir.join('src').ensure_dir()
|
||||
cmd_output('git', 'init', str(src))
|
||||
git_commit(cwd=str(src))
|
||||
|
||||
cmd_output('git', 'worktree', 'add', '.git/trees/foo', 'HEAD', cwd=src)
|
||||
|
||||
with src.join('.git/trees/foo').as_cwd():
|
||||
assert git.get_root() == os.path.abspath('.')
|
||||
|
||||
|
||||
def test_get_staged_files_deleted(in_git_dir):
|
||||
in_git_dir.join('test').ensure()
|
||||
cmd_output('git', 'add', 'test')
|
||||
|
|
104
tests/languages/r_test.py
Normal file
104
tests/languages/r_test.py
Normal file
|
@ -0,0 +1,104 @@
|
|||
import os.path
|
||||
|
||||
import pytest
|
||||
|
||||
from pre_commit.languages import r
|
||||
from testing.fixtures import make_config_from_repo
|
||||
from testing.fixtures import make_repo
|
||||
from tests.repository_test import _get_hook_no_install
|
||||
|
||||
|
||||
def _test_r_parsing(
|
||||
tempdir_factory,
|
||||
store,
|
||||
hook_id,
|
||||
expected_hook_expr={},
|
||||
expected_args={},
|
||||
):
|
||||
repo_path = 'r_hooks_repo'
|
||||
path = make_repo(tempdir_factory, repo_path)
|
||||
config = make_config_from_repo(path)
|
||||
hook = _get_hook_no_install(config, store, hook_id)
|
||||
ret = r._cmd_from_hook(hook)
|
||||
expected_cmd = 'Rscript'
|
||||
expected_opts = (
|
||||
'--no-save', '--no-restore', '--no-site-file', '--no-environ',
|
||||
)
|
||||
expected_path = os.path.join(
|
||||
hook.prefix.prefix_dir, '.'.join([hook_id, 'R']),
|
||||
)
|
||||
expected = (
|
||||
expected_cmd,
|
||||
*expected_opts,
|
||||
*(expected_hook_expr or (expected_path,)),
|
||||
*expected_args,
|
||||
)
|
||||
assert ret == expected
|
||||
|
||||
|
||||
def test_r_parsing_file_no_opts_no_args(tempdir_factory, store):
|
||||
hook_id = 'parse-file-no-opts-no-args'
|
||||
_test_r_parsing(tempdir_factory, store, hook_id)
|
||||
|
||||
|
||||
def test_r_parsing_file_opts_no_args(tempdir_factory, store):
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
r._entry_validate(['Rscript', '--no-init', '/path/to/file'])
|
||||
|
||||
msg = excinfo.value.args
|
||||
assert msg == (
|
||||
'The only valid syntax is `Rscript -e {expr}`',
|
||||
'or `Rscript path/to/hook/script`',
|
||||
)
|
||||
|
||||
|
||||
def test_r_parsing_file_no_opts_args(tempdir_factory, store):
|
||||
hook_id = 'parse-file-no-opts-args'
|
||||
expected_args = ['--no-cache']
|
||||
_test_r_parsing(
|
||||
tempdir_factory, store, hook_id, expected_args=expected_args,
|
||||
)
|
||||
|
||||
|
||||
def test_r_parsing_expr_no_opts_no_args1(tempdir_factory, store):
|
||||
hook_id = 'parse-expr-no-opts-no-args-1'
|
||||
_test_r_parsing(
|
||||
tempdir_factory, store, hook_id, expected_hook_expr=('-e', '1+1'),
|
||||
)
|
||||
|
||||
|
||||
def test_r_parsing_expr_no_opts_no_args2(tempdir_factory, store):
|
||||
with pytest.raises(ValueError) as execinfo:
|
||||
r._entry_validate(['Rscript', '-e', '1+1', '-e', 'letters'])
|
||||
msg = execinfo.value.args
|
||||
assert msg == ('You can supply at most one expression.',)
|
||||
|
||||
|
||||
def test_r_parsing_expr_opts_no_args2(tempdir_factory, store):
|
||||
with pytest.raises(ValueError) as execinfo:
|
||||
r._entry_validate(
|
||||
[
|
||||
'Rscript', '--vanilla', '-e', '1+1', '-e', 'letters',
|
||||
],
|
||||
)
|
||||
msg = execinfo.value.args
|
||||
assert msg == (
|
||||
'The only valid syntax is `Rscript -e {expr}`',
|
||||
'or `Rscript path/to/hook/script`',
|
||||
)
|
||||
|
||||
|
||||
def test_r_parsing_expr_args_in_entry2(tempdir_factory, store):
|
||||
with pytest.raises(ValueError) as execinfo:
|
||||
r._entry_validate(['Rscript', '-e', 'expr1', '--another-arg'])
|
||||
|
||||
msg = execinfo.value.args
|
||||
assert msg == ('You can supply at most one expression.',)
|
||||
|
||||
|
||||
def test_r_parsing_expr_non_Rscirpt(tempdir_factory, store):
|
||||
with pytest.raises(ValueError) as execinfo:
|
||||
r._entry_validate(['AnotherScript', '-e', '{{}}'])
|
||||
|
||||
msg = execinfo.value.args
|
||||
assert msg == ('entry must start with `Rscript`.',)
|
|
@ -7,7 +7,9 @@ import pytest
|
|||
import pre_commit.constants as C
|
||||
from pre_commit import main
|
||||
from pre_commit.errors import FatalError
|
||||
from pre_commit.util import cmd_output
|
||||
from testing.auto_namedtuple import auto_namedtuple
|
||||
from testing.util import cwd
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
@ -54,6 +56,17 @@ def test_adjust_args_and_chdir_relative_things(in_git_dir):
|
|||
assert args.files == [os.path.join('foo', 'f1'), os.path.join('foo', 'f2')]
|
||||
|
||||
|
||||
@pytest.mark.skipif(os.name != 'nt', reason='windows feature')
|
||||
def test_install_on_subst(in_git_dir, store): # pragma: posix no cover
|
||||
assert not os.path.exists('Z:')
|
||||
cmd_output('subst', 'Z:', str(in_git_dir))
|
||||
try:
|
||||
with cwd('Z:'):
|
||||
test_adjust_args_and_chdir_noop('Z:\\')
|
||||
finally:
|
||||
cmd_output('subst', '/d', 'Z:')
|
||||
|
||||
|
||||
def test_adjust_args_and_chdir_non_relative_config(in_git_dir):
|
||||
in_git_dir.join('foo').ensure_dir().chdir()
|
||||
|
||||
|
|
|
@ -279,6 +279,54 @@ 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',
|
||||
|
@ -953,7 +1001,7 @@ def test_manifest_hooks(tempdir_factory, store):
|
|||
require_serial=False,
|
||||
stages=(
|
||||
'commit', 'merge-commit', 'prepare-commit-msg', 'commit-msg',
|
||||
'post-commit', 'manual', 'post-checkout', 'push',
|
||||
'post-commit', 'manual', 'post-checkout', 'push', 'post-merge',
|
||||
),
|
||||
types=['file'],
|
||||
types_or=[],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue