diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2020-03-24 21:59:15 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2020-03-24 21:59:15 +0000 |
commit | 63fad53303381388673073de580a32088a4ef0fe (patch) | |
tree | a2c5c329ee5e79a220fac7e079283235fecc0cda /testing | |
parent | Initial commit. (diff) | |
download | pre-commit-63fad53303381388673073de580a32088a4ef0fe.tar.xz pre-commit-63fad53303381388673073de580a32088a4ef0fe.zip |
Adding upstream version 2.2.0.upstream/2.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing')
79 files changed, 736 insertions, 0 deletions
diff --git a/testing/__init__.py b/testing/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/testing/__init__.py diff --git a/testing/auto_namedtuple.py b/testing/auto_namedtuple.py new file mode 100644 index 0000000..0841094 --- /dev/null +++ b/testing/auto_namedtuple.py @@ -0,0 +1,11 @@ +import collections + + +def auto_namedtuple(classname='auto_namedtuple', **kwargs): + """Returns an automatic namedtuple object. + + Args: + classname - The class name for the returned object. + **kwargs - Properties to give the returned object. + """ + return (collections.namedtuple(classname, kwargs.keys())(**kwargs)) diff --git a/testing/fixtures.py b/testing/fixtures.py new file mode 100644 index 0000000..f7def08 --- /dev/null +++ b/testing/fixtures.py @@ -0,0 +1,146 @@ +import contextlib +import os.path +import shutil + +from cfgv import apply_defaults +from cfgv import validate + +import pre_commit.constants as C +from pre_commit import git +from pre_commit.clientlib import CONFIG_SCHEMA +from pre_commit.clientlib import load_manifest +from pre_commit.util import cmd_output +from pre_commit.util import yaml_dump +from pre_commit.util import yaml_load +from testing.util import get_resource_path +from testing.util import git_commit + + +def copy_tree_to_path(src_dir, dest_dir): + """Copies all of the things inside src_dir to an already existing dest_dir. + + This looks eerily similar to shutil.copytree, but copytree has no option + for not creating dest_dir. + """ + names = os.listdir(src_dir) + + for name in names: + srcname = os.path.join(src_dir, name) + destname = os.path.join(dest_dir, name) + + if os.path.isdir(srcname): + shutil.copytree(srcname, destname) + else: + shutil.copy(srcname, destname) + + +def git_dir(tempdir_factory): + path = tempdir_factory.get() + cmd_output('git', 'init', path) + return path + + +def make_repo(tempdir_factory, repo_source): + path = git_dir(tempdir_factory) + copy_tree_to_path(get_resource_path(repo_source), path) + cmd_output('git', 'add', '.', cwd=path) + git_commit(msg=make_repo.__name__, cwd=path) + return path + + +@contextlib.contextmanager +def modify_manifest(path, commit=True): + """Modify the manifest yielded by this context to write to + .pre-commit-hooks.yaml. + """ + manifest_path = os.path.join(path, C.MANIFEST_FILE) + with open(manifest_path) as f: + manifest = yaml_load(f.read()) + yield manifest + with open(manifest_path, 'w') as manifest_file: + manifest_file.write(yaml_dump(manifest)) + if commit: + git_commit(msg=modify_manifest.__name__, cwd=path) + + +@contextlib.contextmanager +def modify_config(path='.', commit=True): + """Modify the config yielded by this context to write to + .pre-commit-config.yaml + """ + config_path = os.path.join(path, C.CONFIG_FILE) + with open(config_path) as f: + config = yaml_load(f.read()) + yield config + with open(config_path, 'w', encoding='UTF-8') as config_file: + config_file.write(yaml_dump(config)) + if commit: + git_commit(msg=modify_config.__name__, cwd=path) + + +def sample_local_config(): + return { + 'repo': 'local', + 'hooks': [{ + 'id': 'do_not_commit', + 'name': 'Block if "DO NOT COMMIT" is found', + 'entry': 'DO NOT COMMIT', + 'language': 'pygrep', + }], + } + + +def sample_meta_config(): + return {'repo': 'meta', 'hooks': [{'id': 'check-useless-excludes'}]} + + +def make_config_from_repo(repo_path, rev=None, hooks=None, check=True): + manifest = load_manifest(os.path.join(repo_path, C.MANIFEST_FILE)) + config = { + 'repo': f'file://{repo_path}', + 'rev': rev or git.head_rev(repo_path), + 'hooks': hooks or [{'id': hook['id']} for hook in manifest], + } + + if check: + wrapped = validate({'repos': [config]}, CONFIG_SCHEMA) + wrapped = apply_defaults(wrapped, CONFIG_SCHEMA) + config, = wrapped['repos'] + return config + else: + return config + + +def read_config(directory, config_file=C.CONFIG_FILE): + config_path = os.path.join(directory, config_file) + with open(config_path) as f: + config = yaml_load(f.read()) + return config + + +def write_config(directory, config, config_file=C.CONFIG_FILE): + if type(config) is not list and 'repos' not in config: + assert isinstance(config, dict), config + config = {'repos': [config]} + with open(os.path.join(directory, config_file), 'w') as outfile: + outfile.write(yaml_dump(config)) + + +def add_config_to_repo(git_path, config, config_file=C.CONFIG_FILE): + write_config(git_path, config, config_file=config_file) + cmd_output('git', 'add', config_file, cwd=git_path) + git_commit(msg=add_config_to_repo.__name__, cwd=git_path) + return git_path + + +def remove_config_from_repo(git_path, config_file=C.CONFIG_FILE): + cmd_output('git', 'rm', config_file, cwd=git_path) + git_commit(msg=remove_config_from_repo.__name__, cwd=git_path) + return git_path + + +def make_consuming_repo(tempdir_factory, repo_source): + path = make_repo(tempdir_factory, repo_source) + config = make_config_from_repo(path) + git_path = git_dir(tempdir_factory) + return add_config_to_repo(git_path, config) diff --git a/testing/gen-languages-all b/testing/gen-languages-all new file mode 100755 index 0000000..6d0b26f --- /dev/null +++ b/testing/gen-languages-all @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 +import sys + +LANGUAGES = [ + 'conda', 'docker', 'docker_image', 'fail', 'golang', 'node', 'perl', + 'pygrep', 'python', 'python_venv', 'ruby', 'rust', 'script', 'swift', + 'system', +] +FIELDS = [ + 'ENVIRONMENT_DIR', 'get_default_version', 'healthy', 'install_environment', + 'run_hook', +] + + +def main() -> int: + print(f' # BEGIN GENERATED ({sys.argv[0]})') + for lang in LANGUAGES: + parts = [f' {lang!r}: Language(name={lang!r}'] + for k in FIELDS: + parts.append(f', {k}={lang}.{k}') + parts.append('), # noqa: E501') + print(''.join(parts)) + print(' # END GENERATED') + return 0 + + +if __name__ == '__main__': + exit(main()) diff --git a/testing/get-swift.sh b/testing/get-swift.sh new file mode 100755 index 0000000..e205d44 --- /dev/null +++ b/testing/get-swift.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# This is a script used in CI to install swift +set -euxo pipefail + +. /etc/lsb-release +if [ "$DISTRIB_CODENAME" = "bionic" ]; then + SWIFT_URL='https://swift.org/builds/swift-5.1.3-release/ubuntu1804/swift-5.1.3-RELEASE/swift-5.1.3-RELEASE-ubuntu18.04.tar.gz' + SWIFT_HASH='ac82ccd773fe3d586fc340814e31e120da1ff695c6a712f6634e9cc720769610' +else + echo "unknown dist: ${DISTRIB_CODENAME}" 1>&2 + exit 1 +fi + +check() { + echo "$SWIFT_HASH $TGZ" | sha256sum --check +} + +TGZ="$HOME/.swift/swift.tar.gz" +mkdir -p "$(dirname "$TGZ")" +if ! check >& /dev/null; then + rm -f "$TGZ" + curl --location --silent --output "$TGZ" "$SWIFT_URL" + check +fi + +mkdir -p /tmp/swift +tar -xf "$TGZ" --strip 1 --directory /tmp/swift diff --git a/testing/resources/arbitrary_bytes_repo/.pre-commit-hooks.yaml b/testing/resources/arbitrary_bytes_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..c2aec9b --- /dev/null +++ b/testing/resources/arbitrary_bytes_repo/.pre-commit-hooks.yaml @@ -0,0 +1,5 @@ +- id: hook + name: hook + entry: ./hook.sh + language: script + files: \.py$ diff --git a/testing/resources/arbitrary_bytes_repo/hook.sh b/testing/resources/arbitrary_bytes_repo/hook.sh new file mode 100755 index 0000000..9df0c5a --- /dev/null +++ b/testing/resources/arbitrary_bytes_repo/hook.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +# Intentionally write mixed encoding to the output. This should not crash +# pre-commit and should write bytes to the output. +# '☃'.encode() + '²'.encode('latin1') +echo -e '\xe2\x98\x83\xb2' +# exit 1 to trigger printing +exit 1 diff --git a/testing/resources/arg_per_line_hooks_repo/.pre-commit-hooks.yaml b/testing/resources/arg_per_line_hooks_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..4c101db --- /dev/null +++ b/testing/resources/arg_per_line_hooks_repo/.pre-commit-hooks.yaml @@ -0,0 +1,6 @@ +- id: arg-per-line + name: Args per line hook + entry: bin/hook.sh + language: script + files: '' + args: [hello, world] diff --git a/testing/resources/arg_per_line_hooks_repo/bin/hook.sh b/testing/resources/arg_per_line_hooks_repo/bin/hook.sh new file mode 100755 index 0000000..47fd21d --- /dev/null +++ b/testing/resources/arg_per_line_hooks_repo/bin/hook.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +for i in "$@"; do + echo "arg: $i" +done diff --git a/testing/resources/conda_hooks_repo/.pre-commit-hooks.yaml b/testing/resources/conda_hooks_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..a0d274c --- /dev/null +++ b/testing/resources/conda_hooks_repo/.pre-commit-hooks.yaml @@ -0,0 +1,10 @@ +- id: sys-exec + name: sys-exec + entry: python -c 'import os; import sys; print(sys.executable.split(os.path.sep)[-2]) if os.name == "nt" else print(sys.executable.split(os.path.sep)[-3])' + language: conda + files: \.py$ +- id: additional-deps + name: additional-deps + entry: python + language: conda + files: \.py$ diff --git a/testing/resources/conda_hooks_repo/environment.yml b/testing/resources/conda_hooks_repo/environment.yml new file mode 100644 index 0000000..e23c079 --- /dev/null +++ b/testing/resources/conda_hooks_repo/environment.yml @@ -0,0 +1,6 @@ +channels: + - conda-forge + - defaults +dependencies: + - python + - pip diff --git a/testing/resources/docker_hooks_repo/.pre-commit-hooks.yaml b/testing/resources/docker_hooks_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..5295739 --- /dev/null +++ b/testing/resources/docker_hooks_repo/.pre-commit-hooks.yaml @@ -0,0 +1,17 @@ +- id: docker-hook + name: Docker test hook + entry: echo + language: docker + files: \.txt$ + +- id: docker-hook-arg + name: Docker test hook + entry: echo -n + language: docker + files: \.txt$ + +- id: docker-hook-failing + name: Docker test hook with nonzero exit code + entry: bork + language: docker + files: \.txt$ diff --git a/testing/resources/docker_hooks_repo/Dockerfile b/testing/resources/docker_hooks_repo/Dockerfile new file mode 100644 index 0000000..841b151 --- /dev/null +++ b/testing/resources/docker_hooks_repo/Dockerfile @@ -0,0 +1,3 @@ +FROM cogniteev/echo + +CMD ["echo", "This is overwritten by the .pre-commit-hooks.yaml 'entry'"] diff --git a/testing/resources/docker_image_hooks_repo/.pre-commit-hooks.yaml b/testing/resources/docker_image_hooks_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..1b385aa --- /dev/null +++ b/testing/resources/docker_image_hooks_repo/.pre-commit-hooks.yaml @@ -0,0 +1,8 @@ +- id: echo-entrypoint + name: echo (via --entrypoint) + language: docker_image + entry: --entrypoint echo cogniteev/echo +- id: echo-cmd + name: echo (via cmd) + language: docker_image + entry: cogniteev/echo echo diff --git a/testing/resources/exclude_types_repo/.pre-commit-hooks.yaml b/testing/resources/exclude_types_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..ed8794f --- /dev/null +++ b/testing/resources/exclude_types_repo/.pre-commit-hooks.yaml @@ -0,0 +1,6 @@ +- id: python-files + name: Python files + entry: bin/hook.sh + language: script + types: [python] + exclude_types: [python3] diff --git a/testing/resources/exclude_types_repo/bin/hook.sh b/testing/resources/exclude_types_repo/bin/hook.sh new file mode 100755 index 0000000..bdade51 --- /dev/null +++ b/testing/resources/exclude_types_repo/bin/hook.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +echo $@ +exit 1 diff --git a/testing/resources/failing_hook_repo/.pre-commit-hooks.yaml b/testing/resources/failing_hook_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..118cc8b --- /dev/null +++ b/testing/resources/failing_hook_repo/.pre-commit-hooks.yaml @@ -0,0 +1,5 @@ +- id: failing_hook + name: Failing hook + entry: bin/hook.sh + language: script + files: . diff --git a/testing/resources/failing_hook_repo/bin/hook.sh b/testing/resources/failing_hook_repo/bin/hook.sh new file mode 100755 index 0000000..229ccaf --- /dev/null +++ b/testing/resources/failing_hook_repo/bin/hook.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +echo 'Fail' +echo $@ +exit 1 diff --git a/testing/resources/golang_hooks_repo/.pre-commit-hooks.yaml b/testing/resources/golang_hooks_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..206733b --- /dev/null +++ b/testing/resources/golang_hooks_repo/.pre-commit-hooks.yaml @@ -0,0 +1,5 @@ +- id: golang-hook + name: golang example hook + entry: golang-hello-world + language: golang + files: '' diff --git a/testing/resources/golang_hooks_repo/golang-hello-world/main.go b/testing/resources/golang_hooks_repo/golang-hello-world/main.go new file mode 100644 index 0000000..1e3c591 --- /dev/null +++ b/testing/resources/golang_hooks_repo/golang-hello-world/main.go @@ -0,0 +1,17 @@ +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) +} diff --git a/testing/resources/img1.jpg b/testing/resources/img1.jpg Binary files differnew file mode 100644 index 0000000..dea4262 --- /dev/null +++ b/testing/resources/img1.jpg diff --git a/testing/resources/img2.jpg b/testing/resources/img2.jpg Binary files differnew file mode 100644 index 0000000..68568e5 --- /dev/null +++ b/testing/resources/img2.jpg diff --git a/testing/resources/img3.jpg b/testing/resources/img3.jpg Binary files differnew file mode 100644 index 0000000..392d2cf --- /dev/null +++ b/testing/resources/img3.jpg diff --git a/testing/resources/logfile_repo/.pre-commit-hooks.yaml b/testing/resources/logfile_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..dcaba2e --- /dev/null +++ b/testing/resources/logfile_repo/.pre-commit-hooks.yaml @@ -0,0 +1,6 @@ +- id: logfile test hook + name: Logfile test hook + entry: bin/hook.sh + language: script + files: . + log_file: test.log diff --git a/testing/resources/logfile_repo/bin/hook.sh b/testing/resources/logfile_repo/bin/hook.sh new file mode 100755 index 0000000..890d941 --- /dev/null +++ b/testing/resources/logfile_repo/bin/hook.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +echo "This is STDOUT output" +echo "This is STDERR output" 1>&2 + +exit 1 diff --git a/testing/resources/modified_file_returns_zero_repo/.pre-commit-hooks.yaml b/testing/resources/modified_file_returns_zero_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..8d79ef3 --- /dev/null +++ b/testing/resources/modified_file_returns_zero_repo/.pre-commit-hooks.yaml @@ -0,0 +1,15 @@ +- id: bash_hook + name: Bash hook + entry: bin/hook.sh + language: script + files: 'foo.py' +- id: bash_hook2 + name: Bash hook + entry: bin/hook2.sh + language: script + files: '' +- id: bash_hook3 + name: Bash hook + entry: bin/hook3.sh + language: script + files: 'bar.py' diff --git a/testing/resources/modified_file_returns_zero_repo/bin/hook.sh b/testing/resources/modified_file_returns_zero_repo/bin/hook.sh new file mode 100755 index 0000000..98b05f9 --- /dev/null +++ b/testing/resources/modified_file_returns_zero_repo/bin/hook.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +for f in $@; do + # Non UTF-8 bytes + echo -e '\x01\x97' > "$f" + echo "Modified: $f!" +done diff --git a/testing/resources/modified_file_returns_zero_repo/bin/hook2.sh b/testing/resources/modified_file_returns_zero_repo/bin/hook2.sh new file mode 100755 index 0000000..5af177a --- /dev/null +++ b/testing/resources/modified_file_returns_zero_repo/bin/hook2.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +echo $@ diff --git a/testing/resources/modified_file_returns_zero_repo/bin/hook3.sh b/testing/resources/modified_file_returns_zero_repo/bin/hook3.sh new file mode 100755 index 0000000..3180eb3 --- /dev/null +++ b/testing/resources/modified_file_returns_zero_repo/bin/hook3.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +for f in $@; do + # Non UTF-8 bytes + echo -e '\x01\x97' > "$f" +done diff --git a/testing/resources/node_hooks_repo/.pre-commit-hooks.yaml b/testing/resources/node_hooks_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..257698a --- /dev/null +++ b/testing/resources/node_hooks_repo/.pre-commit-hooks.yaml @@ -0,0 +1,5 @@ +- id: foo + name: Foo + entry: foo + language: node + files: \.js$ diff --git a/testing/resources/node_hooks_repo/bin/main.js b/testing/resources/node_hooks_repo/bin/main.js new file mode 100644 index 0000000..8e0f025 --- /dev/null +++ b/testing/resources/node_hooks_repo/bin/main.js @@ -0,0 +1,3 @@ +#!/usr/bin/env node + +console.log('Hello World'); diff --git a/testing/resources/node_hooks_repo/package.json b/testing/resources/node_hooks_repo/package.json new file mode 100644 index 0000000..050b630 --- /dev/null +++ b/testing/resources/node_hooks_repo/package.json @@ -0,0 +1,5 @@ +{ + "name": "foo", + "version": "0.0.1", + "bin": {"foo": "./bin/main.js"} +} diff --git a/testing/resources/node_versioned_hooks_repo/.pre-commit-hooks.yaml b/testing/resources/node_versioned_hooks_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..e7ad5ea --- /dev/null +++ b/testing/resources/node_versioned_hooks_repo/.pre-commit-hooks.yaml @@ -0,0 +1,6 @@ +- id: versioned-node-hook + name: Versioned node hook + entry: versioned-node-hook + language: node + language_version: 9.3.0 + files: \.js$ diff --git a/testing/resources/node_versioned_hooks_repo/bin/main.js b/testing/resources/node_versioned_hooks_repo/bin/main.js new file mode 100644 index 0000000..df12cbe --- /dev/null +++ b/testing/resources/node_versioned_hooks_repo/bin/main.js @@ -0,0 +1,4 @@ +#!/usr/bin/env node + +console.log(process.version); +console.log('Hello World'); diff --git a/testing/resources/node_versioned_hooks_repo/package.json b/testing/resources/node_versioned_hooks_repo/package.json new file mode 100644 index 0000000..18c7787 --- /dev/null +++ b/testing/resources/node_versioned_hooks_repo/package.json @@ -0,0 +1,5 @@ +{ + "name": "versioned-node-hook", + "version": "0.0.1", + "bin": {"versioned-node-hook": "./bin/main.js"} +} diff --git a/testing/resources/not_found_exe/.pre-commit-hooks.yaml b/testing/resources/not_found_exe/.pre-commit-hooks.yaml new file mode 100644 index 0000000..566f3c1 --- /dev/null +++ b/testing/resources/not_found_exe/.pre-commit-hooks.yaml @@ -0,0 +1,5 @@ +- id: not-found-exe + name: Not found exe + entry: i-dont-exist-lol + language: system + files: '' diff --git a/testing/resources/perl_hooks_repo/.gitignore b/testing/resources/perl_hooks_repo/.gitignore new file mode 100644 index 0000000..7af9940 --- /dev/null +++ b/testing/resources/perl_hooks_repo/.gitignore @@ -0,0 +1,7 @@ +/MYMETA.json +/MYMETA.yml +/Makefile +/PreCommitHello-*.tar.* +/PreCommitHello-*/ +/blib/ +/pm_to_blib diff --git a/testing/resources/perl_hooks_repo/.pre-commit-hooks.yaml b/testing/resources/perl_hooks_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..11e6f6c --- /dev/null +++ b/testing/resources/perl_hooks_repo/.pre-commit-hooks.yaml @@ -0,0 +1,5 @@ +- id: perl-hook + name: perl example hook + entry: pre-commit-perl-hello + language: perl + files: '' diff --git a/testing/resources/perl_hooks_repo/MANIFEST b/testing/resources/perl_hooks_repo/MANIFEST new file mode 100644 index 0000000..4a20084 --- /dev/null +++ b/testing/resources/perl_hooks_repo/MANIFEST @@ -0,0 +1,4 @@ +MANIFEST +Makefile.PL +bin/pre-commit-perl-hello +lib/PreCommitHello.pm diff --git a/testing/resources/perl_hooks_repo/Makefile.PL b/testing/resources/perl_hooks_repo/Makefile.PL new file mode 100644 index 0000000..6c70e10 --- /dev/null +++ b/testing/resources/perl_hooks_repo/Makefile.PL @@ -0,0 +1,10 @@ +use strict; +use warnings; + +use ExtUtils::MakeMaker; + +WriteMakefile( + NAME => "PreCommitHello", + VERSION_FROM => "lib/PreCommitHello.pm", + EXE_FILES => [qw(bin/pre-commit-perl-hello)], +); diff --git a/testing/resources/perl_hooks_repo/bin/pre-commit-perl-hello b/testing/resources/perl_hooks_repo/bin/pre-commit-perl-hello new file mode 100755 index 0000000..9474009 --- /dev/null +++ b/testing/resources/perl_hooks_repo/bin/pre-commit-perl-hello @@ -0,0 +1,7 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use PreCommitHello; + +PreCommitHello::hello(); diff --git a/testing/resources/perl_hooks_repo/lib/PreCommitHello.pm b/testing/resources/perl_hooks_repo/lib/PreCommitHello.pm new file mode 100644 index 0000000..c76521c --- /dev/null +++ b/testing/resources/perl_hooks_repo/lib/PreCommitHello.pm @@ -0,0 +1,12 @@ +package PreCommitHello; + +use strict; +use warnings; + +our $VERSION = "0.1.0"; + +sub hello { + print "Hello from perl-commit Perl!\n"; +} + +1; diff --git a/testing/resources/prints_cwd_repo/.pre-commit-hooks.yaml b/testing/resources/prints_cwd_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..7092379 --- /dev/null +++ b/testing/resources/prints_cwd_repo/.pre-commit-hooks.yaml @@ -0,0 +1,5 @@ +- id: prints_cwd + name: Prints Cwd + entry: pwd + language: system + files: \.sh$ diff --git a/testing/resources/python3_hooks_repo/.pre-commit-hooks.yaml b/testing/resources/python3_hooks_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..2c23700 --- /dev/null +++ b/testing/resources/python3_hooks_repo/.pre-commit-hooks.yaml @@ -0,0 +1,6 @@ +- id: python3-hook + name: Python 3 Hook + entry: python3-hook + language: python + language_version: python3 + files: \.py$ diff --git a/testing/resources/python3_hooks_repo/py3_hook.py b/testing/resources/python3_hooks_repo/py3_hook.py new file mode 100644 index 0000000..8c9cda4 --- /dev/null +++ b/testing/resources/python3_hooks_repo/py3_hook.py @@ -0,0 +1,8 @@ +import sys + + +def main(): + print(sys.version_info[0]) + print(repr(sys.argv[1:])) + print('Hello World') + return 0 diff --git a/testing/resources/python3_hooks_repo/setup.py b/testing/resources/python3_hooks_repo/setup.py new file mode 100644 index 0000000..9125dc1 --- /dev/null +++ b/testing/resources/python3_hooks_repo/setup.py @@ -0,0 +1,8 @@ +from setuptools import setup + +setup( + name='python3_hook', + version='0.0.0', + py_modules=['py3_hook'], + entry_points={'console_scripts': ['python3-hook = py3_hook:main']}, +) diff --git a/testing/resources/python_hooks_repo/.pre-commit-hooks.yaml b/testing/resources/python_hooks_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..e10ad50 --- /dev/null +++ b/testing/resources/python_hooks_repo/.pre-commit-hooks.yaml @@ -0,0 +1,5 @@ +- id: foo + name: Foo + entry: foo + language: python + files: \.py$ diff --git a/testing/resources/python_hooks_repo/foo.py b/testing/resources/python_hooks_repo/foo.py new file mode 100644 index 0000000..9c4368e --- /dev/null +++ b/testing/resources/python_hooks_repo/foo.py @@ -0,0 +1,7 @@ +import sys + + +def main(): + print(repr(sys.argv[1:])) + print('Hello World') + return 0 diff --git a/testing/resources/python_hooks_repo/setup.py b/testing/resources/python_hooks_repo/setup.py new file mode 100644 index 0000000..0559271 --- /dev/null +++ b/testing/resources/python_hooks_repo/setup.py @@ -0,0 +1,8 @@ +from setuptools import setup + +setup( + name='foo', + version='0.0.0', + py_modules=['foo'], + entry_points={'console_scripts': ['foo = foo:main']}, +) diff --git a/testing/resources/python_venv_hooks_repo/.pre-commit-hooks.yaml b/testing/resources/python_venv_hooks_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..a666ed8 --- /dev/null +++ b/testing/resources/python_venv_hooks_repo/.pre-commit-hooks.yaml @@ -0,0 +1,5 @@ +- id: foo + name: Foo + entry: foo + language: python_venv + files: \.py$ diff --git a/testing/resources/python_venv_hooks_repo/foo.py b/testing/resources/python_venv_hooks_repo/foo.py new file mode 100644 index 0000000..9c4368e --- /dev/null +++ b/testing/resources/python_venv_hooks_repo/foo.py @@ -0,0 +1,7 @@ +import sys + + +def main(): + print(repr(sys.argv[1:])) + print('Hello World') + return 0 diff --git a/testing/resources/python_venv_hooks_repo/setup.py b/testing/resources/python_venv_hooks_repo/setup.py new file mode 100644 index 0000000..0559271 --- /dev/null +++ b/testing/resources/python_venv_hooks_repo/setup.py @@ -0,0 +1,8 @@ +from setuptools import setup + +setup( + name='foo', + version='0.0.0', + py_modules=['foo'], + entry_points={'console_scripts': ['foo = foo:main']}, +) diff --git a/testing/resources/ruby_hooks_repo/.gitignore b/testing/resources/ruby_hooks_repo/.gitignore new file mode 100644 index 0000000..c111b33 --- /dev/null +++ b/testing/resources/ruby_hooks_repo/.gitignore @@ -0,0 +1 @@ +*.gem diff --git a/testing/resources/ruby_hooks_repo/.pre-commit-hooks.yaml b/testing/resources/ruby_hooks_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..aa15872 --- /dev/null +++ b/testing/resources/ruby_hooks_repo/.pre-commit-hooks.yaml @@ -0,0 +1,5 @@ +- id: ruby_hook + name: Ruby Hook + entry: ruby_hook + language: ruby + files: \.rb$ diff --git a/testing/resources/ruby_hooks_repo/bin/ruby_hook b/testing/resources/ruby_hooks_repo/bin/ruby_hook new file mode 100755 index 0000000..5a7e5ed --- /dev/null +++ b/testing/resources/ruby_hooks_repo/bin/ruby_hook @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby + +puts 'Hello world from a ruby hook' diff --git a/testing/resources/ruby_hooks_repo/lib/.gitignore b/testing/resources/ruby_hooks_repo/lib/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/testing/resources/ruby_hooks_repo/lib/.gitignore diff --git a/testing/resources/ruby_hooks_repo/ruby_hook.gemspec b/testing/resources/ruby_hooks_repo/ruby_hook.gemspec new file mode 100644 index 0000000..75f4e8f --- /dev/null +++ b/testing/resources/ruby_hooks_repo/ruby_hook.gemspec @@ -0,0 +1,9 @@ +Gem::Specification.new do |s| + s.name = 'ruby_hook' + s.version = '0.1.0' + s.authors = ['Anthony Sottile'] + s.summary = 'A ruby hook!' + s.description = 'A ruby hook!' + s.files = ['bin/ruby_hook'] + s.executables = ['ruby_hook'] +end diff --git a/testing/resources/ruby_versioned_hooks_repo/.gitignore b/testing/resources/ruby_versioned_hooks_repo/.gitignore new file mode 100644 index 0000000..c111b33 --- /dev/null +++ b/testing/resources/ruby_versioned_hooks_repo/.gitignore @@ -0,0 +1 @@ +*.gem diff --git a/testing/resources/ruby_versioned_hooks_repo/.pre-commit-hooks.yaml b/testing/resources/ruby_versioned_hooks_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..63e1dd4 --- /dev/null +++ b/testing/resources/ruby_versioned_hooks_repo/.pre-commit-hooks.yaml @@ -0,0 +1,6 @@ +- id: ruby_hook + name: Ruby Hook + entry: ruby_hook + language: ruby + language_version: 2.5.1 + files: \.rb$ diff --git a/testing/resources/ruby_versioned_hooks_repo/bin/ruby_hook b/testing/resources/ruby_versioned_hooks_repo/bin/ruby_hook new file mode 100755 index 0000000..2406f04 --- /dev/null +++ b/testing/resources/ruby_versioned_hooks_repo/bin/ruby_hook @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby + +puts RUBY_VERSION +puts 'Hello world from a ruby hook' diff --git a/testing/resources/ruby_versioned_hooks_repo/lib/.gitignore b/testing/resources/ruby_versioned_hooks_repo/lib/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/testing/resources/ruby_versioned_hooks_repo/lib/.gitignore diff --git a/testing/resources/ruby_versioned_hooks_repo/ruby_hook.gemspec b/testing/resources/ruby_versioned_hooks_repo/ruby_hook.gemspec new file mode 100644 index 0000000..75f4e8f --- /dev/null +++ b/testing/resources/ruby_versioned_hooks_repo/ruby_hook.gemspec @@ -0,0 +1,9 @@ +Gem::Specification.new do |s| + s.name = 'ruby_hook' + s.version = '0.1.0' + s.authors = ['Anthony Sottile'] + s.summary = 'A ruby hook!' + s.description = 'A ruby hook!' + s.files = ['bin/ruby_hook'] + s.executables = ['ruby_hook'] +end diff --git a/testing/resources/rust_hooks_repo/.pre-commit-hooks.yaml b/testing/resources/rust_hooks_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..df1269f --- /dev/null +++ b/testing/resources/rust_hooks_repo/.pre-commit-hooks.yaml @@ -0,0 +1,5 @@ +- id: rust-hook + name: rust example hook + entry: rust-hello-world + language: rust + files: '' diff --git a/testing/resources/rust_hooks_repo/Cargo.lock b/testing/resources/rust_hooks_repo/Cargo.lock new file mode 100644 index 0000000..36fbfda --- /dev/null +++ b/testing/resources/rust_hooks_repo/Cargo.lock @@ -0,0 +1,3 @@ +[[package]] +name = "rust-hello-world" +version = "0.1.0" diff --git a/testing/resources/rust_hooks_repo/Cargo.toml b/testing/resources/rust_hooks_repo/Cargo.toml new file mode 100644 index 0000000..cd83b43 --- /dev/null +++ b/testing/resources/rust_hooks_repo/Cargo.toml @@ -0,0 +1,3 @@ +[package] +name = "rust-hello-world" +version = "0.1.0" diff --git a/testing/resources/rust_hooks_repo/src/main.rs b/testing/resources/rust_hooks_repo/src/main.rs new file mode 100644 index 0000000..ad379d6 --- /dev/null +++ b/testing/resources/rust_hooks_repo/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("hello world"); +} diff --git a/testing/resources/script_hooks_repo/.pre-commit-hooks.yaml b/testing/resources/script_hooks_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..21cad4a --- /dev/null +++ b/testing/resources/script_hooks_repo/.pre-commit-hooks.yaml @@ -0,0 +1,5 @@ +- id: bash_hook + name: Bash hook + entry: bin/hook.sh + language: script + files: '' diff --git a/testing/resources/script_hooks_repo/bin/hook.sh b/testing/resources/script_hooks_repo/bin/hook.sh new file mode 100755 index 0000000..6565ee4 --- /dev/null +++ b/testing/resources/script_hooks_repo/bin/hook.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +echo $@ +echo 'Hello World' diff --git a/testing/resources/stdout_stderr_repo/.pre-commit-hooks.yaml b/testing/resources/stdout_stderr_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..6800d25 --- /dev/null +++ b/testing/resources/stdout_stderr_repo/.pre-commit-hooks.yaml @@ -0,0 +1,8 @@ +- id: stdout-stderr + name: stdout-stderr + language: script + entry: ./stdout-stderr-entry +- id: tty-check + name: tty-check + language: script + entry: ./tty-check-entry diff --git a/testing/resources/stdout_stderr_repo/stdout-stderr-entry b/testing/resources/stdout_stderr_repo/stdout-stderr-entry new file mode 100755 index 0000000..7563df5 --- /dev/null +++ b/testing/resources/stdout_stderr_repo/stdout-stderr-entry @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +echo 0 +echo 1 1>&2 +echo 2 +echo 3 1>&2 +echo 4 +echo 5 1>&2 diff --git a/testing/resources/stdout_stderr_repo/tty-check-entry b/testing/resources/stdout_stderr_repo/tty-check-entry new file mode 100755 index 0000000..01a9d38 --- /dev/null +++ b/testing/resources/stdout_stderr_repo/tty-check-entry @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +t() { + if [ -t "$1" ]; then + echo "$2: True" + else + echo "$2: False" + fi +} +t 0 stdin +t 1 stdout +t 2 stderr diff --git a/testing/resources/swift_hooks_repo/.gitignore b/testing/resources/swift_hooks_repo/.gitignore new file mode 100644 index 0000000..02c0875 --- /dev/null +++ b/testing/resources/swift_hooks_repo/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +/.build +/Packages +/*.xcodeproj diff --git a/testing/resources/swift_hooks_repo/.pre-commit-hooks.yaml b/testing/resources/swift_hooks_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..c08df87 --- /dev/null +++ b/testing/resources/swift_hooks_repo/.pre-commit-hooks.yaml @@ -0,0 +1,6 @@ +- id: swift-hooks-repo + name: Swift hooks repo example + description: Runs the hello world app generated by swift package init --type executable (binary called swift_hooks_repo here) + entry: swift_hooks_repo + language: swift + files: \.(swift)$ diff --git a/testing/resources/swift_hooks_repo/Package.swift b/testing/resources/swift_hooks_repo/Package.swift new file mode 100644 index 0000000..04976d3 --- /dev/null +++ b/testing/resources/swift_hooks_repo/Package.swift @@ -0,0 +1,7 @@ +// swift-tools-version:5.0 +import PackageDescription + +let package = Package( + name: "swift_hooks_repo", + targets: [.target(name: "swift_hooks_repo")] +) diff --git a/testing/resources/swift_hooks_repo/Sources/swift_hooks_repo/main.swift b/testing/resources/swift_hooks_repo/Sources/swift_hooks_repo/main.swift new file mode 100644 index 0000000..f7cf60e --- /dev/null +++ b/testing/resources/swift_hooks_repo/Sources/swift_hooks_repo/main.swift @@ -0,0 +1 @@ +print("Hello, world!") diff --git a/testing/resources/system_hook_with_spaces_repo/.pre-commit-hooks.yaml b/testing/resources/system_hook_with_spaces_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..b2c347c --- /dev/null +++ b/testing/resources/system_hook_with_spaces_repo/.pre-commit-hooks.yaml @@ -0,0 +1,5 @@ +- id: system-hook-with-spaces + name: System hook with spaces + entry: bash -c 'echo "Hello World"' + language: system + files: \.sh$ diff --git a/testing/resources/types_repo/.pre-commit-hooks.yaml b/testing/resources/types_repo/.pre-commit-hooks.yaml new file mode 100644 index 0000000..2e5e4a6 --- /dev/null +++ b/testing/resources/types_repo/.pre-commit-hooks.yaml @@ -0,0 +1,5 @@ +- id: python-files + name: Python files + entry: bin/hook.sh + language: script + types: [python] diff --git a/testing/resources/types_repo/bin/hook.sh b/testing/resources/types_repo/bin/hook.sh new file mode 100755 index 0000000..bdade51 --- /dev/null +++ b/testing/resources/types_repo/bin/hook.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +echo $@ +exit 1 diff --git a/testing/util.py b/testing/util.py new file mode 100644 index 0000000..439bee7 --- /dev/null +++ b/testing/util.py @@ -0,0 +1,113 @@ +import contextlib +import os.path +import subprocess + +import pytest + +from pre_commit import parse_shebang +from pre_commit.languages.docker import docker_is_running +from pre_commit.util import cmd_output +from testing.auto_namedtuple import auto_namedtuple + + +TESTING_DIR = os.path.abspath(os.path.dirname(__file__)) + + +def get_resource_path(path): + return os.path.join(TESTING_DIR, 'resources', path) + + +def cmd_output_mocked_pre_commit_home( + *args, tempdir_factory, pre_commit_home=None, env=None, **kwargs, +): + if pre_commit_home is None: + pre_commit_home = tempdir_factory.get() + env = env if env is not None else os.environ + kwargs.setdefault('stderr', subprocess.STDOUT) + # Don't want to write to the home directory + env = dict(env, PRE_COMMIT_HOME=pre_commit_home) + ret, out, _ = cmd_output(*args, env=env, **kwargs) + return ret, out.replace('\r\n', '\n'), None + + +skipif_cant_run_docker = pytest.mark.skipif( + os.name == 'nt' or not docker_is_running(), + reason="Docker isn't running or can't be accessed", +) +skipif_cant_run_swift = pytest.mark.skipif( + parse_shebang.find_executable('swift') is None, + reason="swift isn't installed or can't be found", +) +xfailif_windows_no_ruby = pytest.mark.xfail( + os.name == 'nt', + reason='Ruby support not yet implemented on windows.', +) +xfailif_windows = pytest.mark.xfail(os.name == 'nt', reason='windows') + + +def supports_venv(): # pragma: no cover (platform specific) + try: + __import__('ensurepip') + __import__('venv') + return True + except ImportError: + return False + + +xfailif_no_venv = pytest.mark.xfail( + not supports_venv(), reason='Does not support venv module', +) + + +def run_opts( + all_files=False, + files=(), + color=False, + verbose=False, + hook=None, + from_ref='', + to_ref='', + remote_name='', + remote_url='', + hook_stage='commit', + show_diff_on_failure=False, + commit_msg_filename='', + checkout_type='', +): + # These are mutually exclusive + assert not (all_files and files) + return auto_namedtuple( + all_files=all_files, + files=files, + color=color, + verbose=verbose, + hook=hook, + from_ref=from_ref, + to_ref=to_ref, + remote_name=remote_name, + remote_url=remote_url, + hook_stage=hook_stage, + show_diff_on_failure=show_diff_on_failure, + commit_msg_filename=commit_msg_filename, + checkout_type=checkout_type, + ) + + +@contextlib.contextmanager +def cwd(path): + original_cwd = os.getcwd() + os.chdir(path) + try: + yield + finally: + os.chdir(original_cwd) + + +def git_commit(*args, fn=cmd_output, msg='commit!', **kwargs): + kwargs.setdefault('stderr', subprocess.STDOUT) + + cmd = ('git', 'commit', '--allow-empty', '--no-gpg-sign', '-a') + args + if msg is not None: # allow skipping `-m` with `msg=None` + cmd += ('-m', msg) + ret, out, _ = fn(*cmd, **kwargs) + return ret, out.replace('\r\n', '\n') |