mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-02-20 01:24:42 +04:00
Merge pull request #105 from pre-commit/files_specified_in_hooks
Files specified in hooks
This commit is contained in:
commit
7edb438d76
37 changed files with 214 additions and 180 deletions
|
|
@ -1,24 +1,14 @@
|
||||||
- repo: git@github.com:pre-commit/pre-commit-hooks
|
- repo: git@github.com:pre-commit/pre-commit-hooks
|
||||||
sha: 59f23b7c556ce1cf66eb6dc574e10d2b4274be4b
|
sha: 7c003425b35fff516c0ee88f4040c8c208d474bd
|
||||||
hooks:
|
hooks:
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
files: \.(js|rb|md|py|sh|txt|yaml|yml)$
|
|
||||||
- id: end-of-file-fixer
|
- id: end-of-file-fixer
|
||||||
files: \.(js|rb|md|py|sh|txt|yaml|yml)$
|
|
||||||
- id: check-yaml
|
- id: check-yaml
|
||||||
files: \.(yaml|yml)$
|
|
||||||
- id: debug-statements
|
- id: debug-statements
|
||||||
files: \.py$
|
|
||||||
- id: name-tests-test
|
- id: name-tests-test
|
||||||
files: tests/.+\.py$
|
|
||||||
- id: flake8
|
- id: flake8
|
||||||
files: \.py$
|
|
||||||
args:
|
|
||||||
- --max-line-length=131
|
|
||||||
- repo: git@github.com:pre-commit/pre-commit
|
- repo: git@github.com:pre-commit/pre-commit
|
||||||
sha: c7cfed699245191e6b0d43d3890fd582157e3919
|
sha: 96174deac671b451ee2a3fbdc647ad9606415e15
|
||||||
hooks:
|
hooks:
|
||||||
- id: validate_config
|
- id: validate_config
|
||||||
files: ^\.pre-commit-config.yaml$
|
|
||||||
- id: validate_manifest
|
- id: validate_manifest
|
||||||
files: ^hooks.yaml$
|
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,13 @@
|
||||||
- id: my_hook
|
- id: my_hook
|
||||||
name: My Simple Hook
|
name: My Simple Hook
|
||||||
description: This is my simple hook that does blah
|
description: This is my simple hook that does blah
|
||||||
entry: my-simple-hook.py
|
entry: my-simple-hook
|
||||||
language: python
|
language: python
|
||||||
expected_return_value: 0
|
files: \.py$
|
||||||
- id: my_grep_based_hook
|
- id: my_grep_based_hook
|
||||||
name: My Bash Based Hook
|
name: My Bash Based Hook
|
||||||
description: This is a hook that uses grep to validate some stuff
|
description: This is a hook that uses grep to validate some stuff
|
||||||
entry: ./my_grep_based_hook.sh
|
entry: ./my_grep_based_hook.sh
|
||||||
language: script
|
language: script
|
||||||
|
files: \.(py|sh)$
|
||||||
expected_return_value: 1
|
expected_return_value: 1
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,5 @@
|
||||||
sha: cd74dc150c142c3be70b24eaf0b02cae9d235f37
|
sha: cd74dc150c142c3be70b24eaf0b02cae9d235f37
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyflakes
|
- id: pyflakes
|
||||||
files: '\.py$'
|
|
||||||
- id: jslint
|
- id: jslint
|
||||||
files: '\.js$'
|
|
||||||
- id: trim_trailing_whitespace
|
- id: trim_trailing_whitespace
|
||||||
files: '\.py$'
|
|
||||||
|
|
|
||||||
12
hooks.yaml
12
hooks.yaml
|
|
@ -1,10 +1,12 @@
|
||||||
- id: validate_manifest
|
|
||||||
name: Validate Pre-Commit Manifest
|
|
||||||
description: This validator validates a pre-commit hooks manifest file
|
|
||||||
entry: validate-manifest
|
|
||||||
language: python
|
|
||||||
- id: validate_config
|
- id: validate_config
|
||||||
name: Validate Pre-Commit Config
|
name: Validate Pre-Commit Config
|
||||||
description: This validator validates a pre-commit hooks config file
|
description: This validator validates a pre-commit hooks config file
|
||||||
entry: validate-config
|
entry: validate-config
|
||||||
language: python
|
language: python
|
||||||
|
files: ^\.pre-commit-config.yaml$
|
||||||
|
- id: validate_manifest
|
||||||
|
name: Validate Pre-Commit Manifest
|
||||||
|
description: This validator validates a pre-commit hooks manifest file
|
||||||
|
entry: validate-manifest
|
||||||
|
language: python
|
||||||
|
files: ^hooks.yaml$
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,21 @@ import argparse
|
||||||
import jsonschema
|
import jsonschema
|
||||||
import jsonschema.exceptions
|
import jsonschema.exceptions
|
||||||
import os.path
|
import os.path
|
||||||
|
import re
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from pre_commit.jsonschema_extensions import apply_defaults
|
from pre_commit.jsonschema_extensions import apply_defaults
|
||||||
from pre_commit.util import entry
|
from pre_commit.util import entry
|
||||||
|
|
||||||
|
|
||||||
|
def is_regex_valid(regex):
|
||||||
|
try:
|
||||||
|
re.compile(regex)
|
||||||
|
return True
|
||||||
|
except re.error:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def get_validator(
|
def get_validator(
|
||||||
json_schema,
|
json_schema,
|
||||||
exception_type,
|
exception_type,
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import re
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from pre_commit.clientlib.validate_base import get_run_function
|
from pre_commit.clientlib.validate_base import get_run_function
|
||||||
from pre_commit.clientlib.validate_base import get_validator
|
from pre_commit.clientlib.validate_base import get_validator
|
||||||
|
from pre_commit.clientlib.validate_base import is_regex_valid
|
||||||
|
|
||||||
|
|
||||||
class InvalidConfigError(ValueError):
|
class InvalidConfigError(ValueError):
|
||||||
|
|
@ -32,7 +32,7 @@ CONFIG_JSON_SCHEMA = {
|
||||||
'items': {'type': 'string'},
|
'items': {'type': 'string'},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'required': ['id', 'files'],
|
'required': ['id'],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -42,9 +42,7 @@ CONFIG_JSON_SCHEMA = {
|
||||||
|
|
||||||
|
|
||||||
def try_regex(repo, hook, value, field_name):
|
def try_regex(repo, hook, value, field_name):
|
||||||
try:
|
if not is_regex_valid(value):
|
||||||
re.compile(value)
|
|
||||||
except re.error:
|
|
||||||
raise InvalidConfigError(
|
raise InvalidConfigError(
|
||||||
'Invalid {0} regex at {1}, {2}: {3}'.format(
|
'Invalid {0} regex at {1}, {2}: {3}'.format(
|
||||||
field_name, repo, hook, value,
|
field_name, repo, hook, value,
|
||||||
|
|
@ -55,7 +53,7 @@ def try_regex(repo, hook, value, field_name):
|
||||||
def validate_config_extra(config):
|
def validate_config_extra(config):
|
||||||
for repo in config:
|
for repo in config:
|
||||||
for hook in repo['hooks']:
|
for hook in repo['hooks']:
|
||||||
try_regex(repo, hook['id'], hook['files'], 'files')
|
try_regex(repo, hook['id'], hook.get('files', ''), 'files')
|
||||||
try_regex(repo, hook['id'], hook['exclude'], 'exclude')
|
try_regex(repo, hook['id'], hook['exclude'], 'exclude')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import sys
|
||||||
|
|
||||||
from pre_commit.clientlib.validate_base import get_run_function
|
from pre_commit.clientlib.validate_base import get_run_function
|
||||||
from pre_commit.clientlib.validate_base import get_validator
|
from pre_commit.clientlib.validate_base import get_validator
|
||||||
|
from pre_commit.clientlib.validate_base import is_regex_valid
|
||||||
from pre_commit.languages.all import all_languages
|
from pre_commit.languages.all import all_languages
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -21,18 +22,16 @@ MANIFEST_JSON_SCHEMA = {
|
||||||
'entry': {'type': 'string'},
|
'entry': {'type': 'string'},
|
||||||
'language': {'type': 'string'},
|
'language': {'type': 'string'},
|
||||||
'language_version': {'type': 'string', 'default': 'default'},
|
'language_version': {'type': 'string', 'default': 'default'},
|
||||||
|
'files': {'type': 'string'},
|
||||||
'expected_return_value': {'type': 'number', 'default': 0},
|
'expected_return_value': {'type': 'number', 'default': 0},
|
||||||
},
|
},
|
||||||
'required': ['id', 'name', 'entry', 'language'],
|
'required': ['id', 'name', 'entry', 'language', 'files'],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def additional_manifest_check(obj):
|
def validate_languages(hook_config):
|
||||||
for hook_config in obj:
|
if hook_config['language'] not in all_languages:
|
||||||
language = hook_config['language']
|
|
||||||
|
|
||||||
if language not in all_languages:
|
|
||||||
raise InvalidManifestError(
|
raise InvalidManifestError(
|
||||||
'Expected language {0} for {1} to be one of {2!r}'.format(
|
'Expected language {0} for {1} to be one of {2!r}'.format(
|
||||||
hook_config['id'],
|
hook_config['id'],
|
||||||
|
|
@ -42,6 +41,22 @@ def additional_manifest_check(obj):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_files(hook_config):
|
||||||
|
if not is_regex_valid(hook_config['files']):
|
||||||
|
raise InvalidManifestError(
|
||||||
|
'Invalid files regex at {0}: {1}'.format(
|
||||||
|
hook_config['id'],
|
||||||
|
hook_config['files'],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def additional_manifest_check(obj):
|
||||||
|
for hook_config in obj:
|
||||||
|
validate_languages(hook_config)
|
||||||
|
validate_files(hook_config)
|
||||||
|
|
||||||
|
|
||||||
load_manifest = get_validator(
|
load_manifest = get_validator(
|
||||||
MANIFEST_JSON_SCHEMA,
|
MANIFEST_JSON_SCHEMA,
|
||||||
InvalidManifestError,
|
InvalidManifestError,
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,9 @@ logger = logging.getLogger('pre_commit')
|
||||||
|
|
||||||
def install(runner):
|
def install(runner):
|
||||||
"""Install the pre-commit hooks."""
|
"""Install the pre-commit hooks."""
|
||||||
pre_commit_file = pkg_resources.resource_filename('pre_commit', 'resources/pre-commit.sh')
|
pre_commit_file = pkg_resources.resource_filename(
|
||||||
|
'pre_commit', 'resources/pre-commit.sh',
|
||||||
|
)
|
||||||
with open(runner.pre_commit_path, 'w') as pre_commit_file_obj:
|
with open(runner.pre_commit_path, 'w') as pre_commit_file_obj:
|
||||||
pre_commit_file_obj.write(open(pre_commit_file).read())
|
pre_commit_file_obj.write(open(pre_commit_file).read())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,71 +8,3 @@ if PY2:
|
||||||
text = unicode # flake8: noqa
|
text = unicode # flake8: noqa
|
||||||
else:
|
else:
|
||||||
text = str
|
text = str
|
||||||
|
|
||||||
|
|
||||||
def n(obj):
|
|
||||||
"""Produce a native string.
|
|
||||||
|
|
||||||
Similar in behavior to str(), but uses US-ASCII encoding when necessary.
|
|
||||||
"""
|
|
||||||
if isinstance(obj, str):
|
|
||||||
return obj
|
|
||||||
elif PY2 and isinstance(obj, text):
|
|
||||||
return obj.encode('US-ASCII')
|
|
||||||
elif PY3 and isinstance(obj, bytes):
|
|
||||||
return obj.decode('US-ASCII')
|
|
||||||
else:
|
|
||||||
return str(obj)
|
|
||||||
|
|
||||||
|
|
||||||
def u(obj):
|
|
||||||
"""Produces text.
|
|
||||||
|
|
||||||
Similar in behavior to str() in python3 or unicode() in python2,
|
|
||||||
but uses US-ASCII encoding when necessary.
|
|
||||||
"""
|
|
||||||
if isinstance(obj, text):
|
|
||||||
return obj
|
|
||||||
elif isinstance(obj, bytes):
|
|
||||||
return obj.decode('US-ASCII')
|
|
||||||
else:
|
|
||||||
return text(obj)
|
|
||||||
|
|
||||||
|
|
||||||
def b(obj):
|
|
||||||
"""Produces bytes.
|
|
||||||
|
|
||||||
Similar in behavior to bytes(), but uses US-ASCII encoding when necessary.
|
|
||||||
"""
|
|
||||||
if isinstance(obj, bytes):
|
|
||||||
return obj
|
|
||||||
elif isinstance(obj, text):
|
|
||||||
return obj.encode('US-ASCII')
|
|
||||||
else:
|
|
||||||
return bytes(obj)
|
|
||||||
|
|
||||||
|
|
||||||
def udict(*args, **kwargs):
|
|
||||||
"""Similar to dict(), but keyword-keys are text."""
|
|
||||||
kwargs = dict([
|
|
||||||
(u(key), val)
|
|
||||||
for key, val in kwargs.items()
|
|
||||||
])
|
|
||||||
|
|
||||||
return dict(*args, **kwargs)
|
|
||||||
|
|
||||||
def ndict(*args, **kwargs):
|
|
||||||
"""Similar to dict(), but keyword-keys are forced to native strings."""
|
|
||||||
# I hate this :(
|
|
||||||
kwargs = dict([
|
|
||||||
(n(key), val)
|
|
||||||
for key, val in kwargs.items()
|
|
||||||
])
|
|
||||||
|
|
||||||
return dict(*args, **kwargs)
|
|
||||||
|
|
||||||
def open(*args, **kwargs):
|
|
||||||
"""Override the builtin open() to return text and use utf8 by default."""
|
|
||||||
from io import open
|
|
||||||
kwargs.setdefault('encoding', 'UTF-8')
|
|
||||||
return open(*args, **kwargs)
|
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,9 @@ def is_in_merge_conflict():
|
||||||
def parse_merge_msg_for_conflicts(merge_msg):
|
def parse_merge_msg_for_conflicts(merge_msg):
|
||||||
# Conflicted files start with tabs
|
# Conflicted files start with tabs
|
||||||
return [
|
return [
|
||||||
line.strip() for line in merge_msg.splitlines() if line.startswith('\t')
|
line.strip()
|
||||||
|
for line in merge_msg.splitlines()
|
||||||
|
if line.startswith('\t')
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,16 +9,19 @@ from pre_commit.languages import system
|
||||||
# # Use None for no environment
|
# # Use None for no environment
|
||||||
# ENVIRONMENT_DIR = 'foo_env'
|
# ENVIRONMENT_DIR = 'foo_env'
|
||||||
#
|
#
|
||||||
# def install_environment(repo_cmd_runner):
|
# def install_environment(repo_cmd_runner, version='default'):
|
||||||
# """Installs a repository in the given repository. Note that the current
|
# """Installs a repository in the given repository. Note that the current
|
||||||
# working directory will already be inside the repository.
|
# working directory will already be inside the repository.
|
||||||
#
|
#
|
||||||
# Args:
|
# Args:
|
||||||
# repo_cmd_runner - `PrefixedCommandRunner` bound to the repository.
|
# repo_cmd_runner - `PrefixedCommandRunner` bound to the repository.
|
||||||
|
# version - A version specified in the hook configuration or
|
||||||
|
# 'default'.
|
||||||
# """
|
# """
|
||||||
#
|
#
|
||||||
# def run_hook(repo_cmd_runner, hook, file_args):
|
# def run_hook(repo_cmd_runner, hook, file_args):
|
||||||
# """Runs a hook and returns the returncode and output of running that hook.
|
# """Runs a hook and returns the returncode and output of running that
|
||||||
|
# hook.
|
||||||
#
|
#
|
||||||
# Args:
|
# Args:
|
||||||
# repo_cmd_runner - `PrefixedCommandRunner` bound to the repository.
|
# repo_cmd_runner - `PrefixedCommandRunner` bound to the repository.
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,8 @@ def get_hook_message(
|
||||||
>>> print_hook_message('start', end_len=6)
|
>>> print_hook_message('start', end_len=6)
|
||||||
start...............................................................
|
start...............................................................
|
||||||
|
|
||||||
# Print `start` followed by dots with the end message colored if coloring is
|
# Print `start` followed by dots with the end message colored if coloring
|
||||||
# specified and a newline afterwards
|
# is specified and a newline afterwards
|
||||||
>>> print_hook_message(
|
>>> print_hook_message(
|
||||||
'start',
|
'start',
|
||||||
end_msg='end',
|
end_msg='end',
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@ import os
|
||||||
import os.path
|
import os.path
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from pre_commit import five
|
|
||||||
|
|
||||||
|
|
||||||
class CalledProcessError(RuntimeError):
|
class CalledProcessError(RuntimeError):
|
||||||
def __init__(self, returncode, cmd, expected_returncode, output=None):
|
def __init__(self, returncode, cmd, expected_returncode, output=None):
|
||||||
|
|
@ -42,7 +40,12 @@ class PrefixedCommandRunner(object):
|
||||||
|
|
||||||
will run ['/tmp/foo/foo.sh', 'bar', 'baz']
|
will run ['/tmp/foo/foo.sh', 'bar', 'baz']
|
||||||
"""
|
"""
|
||||||
def __init__(self, prefix_dir, popen=subprocess.Popen, makedirs=os.makedirs):
|
def __init__(
|
||||||
|
self,
|
||||||
|
prefix_dir,
|
||||||
|
popen=subprocess.Popen,
|
||||||
|
makedirs=os.makedirs
|
||||||
|
):
|
||||||
self.prefix_dir = prefix_dir.rstrip(os.sep) + os.sep
|
self.prefix_dir = prefix_dir.rstrip(os.sep) + os.sep
|
||||||
self.__popen = popen
|
self.__popen = popen
|
||||||
self.__makedirs = makedirs
|
self.__makedirs = makedirs
|
||||||
|
|
@ -65,11 +68,10 @@ class PrefixedCommandRunner(object):
|
||||||
replaced_cmd = _replace_cmd(cmd, prefix=self.prefix_dir)
|
replaced_cmd = _replace_cmd(cmd, prefix=self.prefix_dir)
|
||||||
proc = self.__popen(replaced_cmd, **popen_kwargs)
|
proc = self.__popen(replaced_cmd, **popen_kwargs)
|
||||||
stdout, stderr = proc.communicate(stdin)
|
stdout, stderr = proc.communicate(stdin)
|
||||||
# TODO: stdout, stderr = from_bytes(stdout), from_bytes(stderr)
|
|
||||||
if isinstance(stdout, bytes):
|
if isinstance(stdout, bytes):
|
||||||
stdout = five.text(stdout, 'utf-8')
|
stdout = stdout.decode('UTF-8')
|
||||||
if isinstance(stderr, bytes):
|
if isinstance(stderr, bytes):
|
||||||
stderr = five.text(stderr, 'utf-8')
|
stderr = stderr.decode('UTF-8')
|
||||||
returncode = proc.returncode
|
returncode = proc.returncode
|
||||||
|
|
||||||
if retcode is not None and retcode != returncode:
|
if retcode is not None and retcode != returncode:
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ class Repository(object):
|
||||||
def hooks(self):
|
def hooks(self):
|
||||||
# TODO: merging in manifest dicts is a smell imo
|
# TODO: merging in manifest dicts is a smell imo
|
||||||
return OrderedDict(
|
return OrderedDict(
|
||||||
(hook['id'], dict(hook, **self.manifest.hooks[hook['id']]))
|
(hook['id'], dict(self.manifest.hooks[hook['id']], **hook))
|
||||||
for hook in self.repo_config['hooks']
|
for hook in self.repo_config['hooks']
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,9 +35,13 @@ def run(argv):
|
||||||
'--no-stash', default=False, action='store_true',
|
'--no-stash', default=False, action='store_true',
|
||||||
help='Use this option to prevent auto stashing of unstaged files.',
|
help='Use this option to prevent auto stashing of unstaged files.',
|
||||||
)
|
)
|
||||||
run_parser.add_argument('--verbose', '-v', action='store_true', default=False)
|
run_parser.add_argument(
|
||||||
|
'--verbose', '-v', action='store_true', default=False,
|
||||||
|
)
|
||||||
|
|
||||||
help = subparsers.add_parser('help', help='Show help for a specific command.')
|
help = subparsers.add_parser(
|
||||||
|
'help', help='Show help for a specific command.'
|
||||||
|
)
|
||||||
help.add_argument('help_cmd', nargs='?', help='Command to show help for.')
|
help.add_argument('help_cmd', nargs='?', help='Command to show help for.')
|
||||||
|
|
||||||
# Argparse doesn't really provide a way to use a `default` subparser
|
# Argparse doesn't really provide a way to use a `default` subparser
|
||||||
|
|
|
||||||
5
setup.py
5
setup.py
|
|
@ -4,7 +4,10 @@ from setuptools import setup
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='pre_commit',
|
name='pre_commit',
|
||||||
description='A framework for managing and maintaining multi-language pre-commit hooks.',
|
description=(
|
||||||
|
'A framework for managing and maintaining multi-language pre-commit '
|
||||||
|
'hooks.'
|
||||||
|
),
|
||||||
url='https://github.com/pre-commit/pre-commit',
|
url='https://github.com/pre-commit/pre-commit',
|
||||||
version='0.0.0',
|
version='0.0.0',
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,12 @@
|
||||||
sha: bec87f6c87284ea15dbcf7801810404c8036bab4
|
sha: bec87f6c87284ea15dbcf7801810404c8036bab4
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyflakes
|
- id: pyflakes
|
||||||
files: \.py$
|
|
||||||
- id: debug-statements
|
- id: debug-statements
|
||||||
files: \.py$
|
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
files: \.(py|sh|yaml)$
|
|
||||||
- id: name-tests-test
|
- id: name-tests-test
|
||||||
files: tests/.+\.py$
|
|
||||||
- id: end-of-file-fixer
|
- id: end-of-file-fixer
|
||||||
files: \.(py|sh|yaml)$
|
|
||||||
- repo: git@github.com:pre-commit/pre-commit
|
- repo: git@github.com:pre-commit/pre-commit
|
||||||
sha: c62c1a3b513ab9e057e85a5e950bd7c438371076
|
sha: c62c1a3b513ab9e057e85a5e950bd7c438371076
|
||||||
hooks:
|
hooks:
|
||||||
- id: validate_manifest
|
- id: validate_manifest
|
||||||
files: ^hooks.yaml$
|
|
||||||
- id: validate_config
|
- id: validate_config
|
||||||
files: ^\.pre-commit-config.yaml$
|
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,4 @@
|
||||||
name: Failing hook
|
name: Failing hook
|
||||||
entry: bin/hook.sh
|
entry: bin/hook.sh
|
||||||
language: script
|
language: script
|
||||||
|
files: .
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,4 @@
|
||||||
name: Bar
|
name: Bar
|
||||||
entry: bar
|
entry: bar
|
||||||
language: python
|
language: python
|
||||||
|
files: \.py$
|
||||||
|
|
|
||||||
|
|
@ -3,3 +3,4 @@
|
||||||
entry: node-11-8-hook
|
entry: node-11-8-hook
|
||||||
language: node
|
language: node
|
||||||
language_version: 0.11.8
|
language_version: 0.11.8
|
||||||
|
files: \.js$
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,4 @@
|
||||||
name: Foo
|
name: Foo
|
||||||
entry: foo
|
entry: foo
|
||||||
language: node
|
language: node
|
||||||
|
files: \.js$
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,4 @@
|
||||||
name: Prints Cwd
|
name: Prints Cwd
|
||||||
entry: pwd
|
entry: pwd
|
||||||
language: system
|
language: system
|
||||||
|
files: \.sh$
|
||||||
|
|
|
||||||
|
|
@ -3,3 +3,4 @@
|
||||||
entry: python3-hook
|
entry: python3-hook
|
||||||
language: python
|
language: python
|
||||||
language_version: python3.3
|
language_version: python3.3
|
||||||
|
files: \.py$
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,4 @@
|
||||||
name: Foo
|
name: Foo
|
||||||
entry: foo
|
entry: foo
|
||||||
language: python
|
language: python
|
||||||
|
files: \.py$
|
||||||
|
|
|
||||||
|
|
@ -3,3 +3,4 @@
|
||||||
entry: ruby_hook
|
entry: ruby_hook
|
||||||
language: ruby
|
language: ruby
|
||||||
language_version: 1.9.3-p547
|
language_version: 1.9.3-p547
|
||||||
|
files: \.rb$
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,4 @@
|
||||||
name: Ruby Hook
|
name: Ruby Hook
|
||||||
entry: ruby_hook
|
entry: ruby_hook
|
||||||
language: ruby
|
language: ruby
|
||||||
|
files: \.rb$
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,4 @@
|
||||||
name: Bash hook
|
name: Bash hook
|
||||||
entry: bin/hook.sh
|
entry: bin/hook.sh
|
||||||
language: script
|
language: script
|
||||||
|
files: ''
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,4 @@
|
||||||
name: System hook with spaces
|
name: System hook with spaces
|
||||||
entry: /usr/bin/python -c 'import sys; print("Hello World")'
|
entry: /usr/bin/python -c 'import sys; print("Hello World")'
|
||||||
language: system
|
language: system
|
||||||
|
files: \.sh$
|
||||||
|
|
|
||||||
|
|
@ -3,4 +3,3 @@
|
||||||
- id: pyflakes
|
- id: pyflakes
|
||||||
- id: jslint
|
- id: jslint
|
||||||
- id: trim_trailing_whitespace
|
- id: trim_trailing_whitespace
|
||||||
files: '*.py'
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,9 @@ def test_raises_for_invalid_yaml_file(noop_validator):
|
||||||
|
|
||||||
def test_raises_for_failing_schema(array_validator):
|
def test_raises_for_failing_schema(array_validator):
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
array_validator(get_resource_path('valid_yaml_but_invalid_manifest.yaml'))
|
array_validator(
|
||||||
|
get_resource_path('valid_yaml_but_invalid_manifest.yaml')
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_passes_array_schema(array_validator):
|
def test_passes_array_schema(array_validator):
|
||||||
|
|
|
||||||
|
|
@ -28,38 +28,57 @@ def test_additional_manifest_check_raises_for_bad_language():
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
'obj', ([{'language': 'python'}], [{'language': 'ruby'}]),
|
'obj',
|
||||||
|
(
|
||||||
|
[{'language': 'python', 'files': ''}],
|
||||||
|
[{'language': 'ruby', 'files': ''}]
|
||||||
|
),
|
||||||
)
|
)
|
||||||
def test_additional_manifest_check_languages(obj):
|
def test_additional_manifest_check_passing(obj):
|
||||||
additional_manifest_check(obj)
|
additional_manifest_check(obj)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
'obj',
|
'obj',
|
||||||
(
|
(
|
||||||
[{'id': 'a', 'language': 'not a language'}],
|
[{'id': 'a', 'language': 'not a language', 'files': ''}],
|
||||||
[{'id': 'a', 'language': 'python3'}],
|
[{'id': 'a', 'language': 'python3', 'files': ''}],
|
||||||
|
[{'id': 'a', 'language': 'python', 'files': 'invalid regex('}],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
def test_additional_manifest_check_languages_failing(obj):
|
def test_additional_manifest_failing(obj):
|
||||||
with pytest.raises(InvalidManifestError):
|
with pytest.raises(InvalidManifestError):
|
||||||
additional_manifest_check(obj)
|
additional_manifest_check(obj)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(('manifest_obj', 'expected'), (
|
@pytest.mark.parametrize(
|
||||||
|
('manifest_obj', 'expected'),
|
||||||
|
(
|
||||||
([], False),
|
([], False),
|
||||||
([{'id': 'a', 'name': 'b', 'entry': 'c', 'language': 'python'}], True),
|
|
||||||
(
|
(
|
||||||
[{
|
[{
|
||||||
'id': 'a',
|
'id': 'a',
|
||||||
'name': 'b',
|
'name': 'b',
|
||||||
'entry': 'c',
|
'entry': 'c',
|
||||||
'language': 'python',
|
'language': 'python',
|
||||||
|
'files': r'\.py$'
|
||||||
|
}],
|
||||||
|
True,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
[{
|
||||||
|
'id': 'a',
|
||||||
|
'name': 'b',
|
||||||
|
'entry': 'c',
|
||||||
|
'language': 'python',
|
||||||
|
'language_version': 'python3.3',
|
||||||
|
'files': r'\.py$',
|
||||||
'expected_return_value': 0,
|
'expected_return_value': 0,
|
||||||
}],
|
}],
|
||||||
True,
|
True,
|
||||||
),
|
),
|
||||||
))
|
)
|
||||||
|
)
|
||||||
def test_is_valid_according_to_schema(manifest_obj, expected):
|
def test_is_valid_according_to_schema(manifest_obj, expected):
|
||||||
ret = is_valid_according_to_schema(manifest_obj, MANIFEST_JSON_SCHEMA)
|
ret = is_valid_according_to_schema(manifest_obj, MANIFEST_JSON_SCHEMA)
|
||||||
assert ret is expected
|
assert ret is expected
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,9 @@ def test_install_pre_commit(empty_git_dir):
|
||||||
assert ret == 0
|
assert ret == 0
|
||||||
assert os.path.exists(runner.pre_commit_path)
|
assert os.path.exists(runner.pre_commit_path)
|
||||||
pre_commit_contents = open(runner.pre_commit_path).read()
|
pre_commit_contents = open(runner.pre_commit_path).read()
|
||||||
pre_commit_sh = pkg_resources.resource_filename('pre_commit', 'resources/pre-commit.sh')
|
pre_commit_sh = pkg_resources.resource_filename(
|
||||||
|
'pre_commit', 'resources/pre-commit.sh',
|
||||||
|
)
|
||||||
expected_contents = open(pre_commit_sh).read()
|
expected_contents = open(pre_commit_sh).read()
|
||||||
assert pre_commit_contents == expected_contents
|
assert pre_commit_contents == expected_contents
|
||||||
stat_result = os.stat(runner.pre_commit_path)
|
stat_result = os.stat(runner.pre_commit_path)
|
||||||
|
|
@ -58,7 +60,7 @@ def up_to_date_repo(python_hooks_repo):
|
||||||
config = OrderedDict((
|
config = OrderedDict((
|
||||||
('repo', python_hooks_repo),
|
('repo', python_hooks_repo),
|
||||||
('sha', get_head_sha(python_hooks_repo)),
|
('sha', get_head_sha(python_hooks_repo)),
|
||||||
('hooks', [OrderedDict((('id', 'foo'), ('files', '')))]),
|
('hooks', [OrderedDict((('id', 'foo'),))]),
|
||||||
))
|
))
|
||||||
wrapped_config = apply_defaults([config], CONFIG_JSON_SCHEMA)
|
wrapped_config = apply_defaults([config], CONFIG_JSON_SCHEMA)
|
||||||
validate_config_extra(wrapped_config)
|
validate_config_extra(wrapped_config)
|
||||||
|
|
@ -132,7 +134,9 @@ def test_removes_defaults(out_of_date_repo, runner_with_mocked_store):
|
||||||
assert 'expected_return_value' not in ret['hooks'][0]
|
assert 'expected_return_value' not in ret['hooks'][0]
|
||||||
|
|
||||||
|
|
||||||
def test_autoupdate_out_of_date_repo(out_of_date_repo, mock_out_store_directory):
|
def test_autoupdate_out_of_date_repo(
|
||||||
|
out_of_date_repo, mock_out_store_directory
|
||||||
|
):
|
||||||
before = open(C.CONFIG_FILE).read()
|
before = open(C.CONFIG_FILE).read()
|
||||||
runner = Runner(out_of_date_repo.python_hooks_repo)
|
runner = Runner(out_of_date_repo.python_hooks_repo)
|
||||||
ret = commands.autoupdate(runner)
|
ret = commands.autoupdate(runner)
|
||||||
|
|
@ -147,12 +151,15 @@ def hook_disappearing_repo(python_hooks_repo):
|
||||||
config = OrderedDict((
|
config = OrderedDict((
|
||||||
('repo', python_hooks_repo),
|
('repo', python_hooks_repo),
|
||||||
('sha', get_head_sha(python_hooks_repo)),
|
('sha', get_head_sha(python_hooks_repo)),
|
||||||
('hooks', [OrderedDict((('id', 'foo'), ('files', '')))]),
|
('hooks', [OrderedDict((('id', 'foo'),))]),
|
||||||
))
|
))
|
||||||
config_wrapped = apply_defaults([config], CONFIG_JSON_SCHEMA)
|
config_wrapped = apply_defaults([config], CONFIG_JSON_SCHEMA)
|
||||||
validate_config_extra(config_wrapped)
|
validate_config_extra(config_wrapped)
|
||||||
config = config_wrapped[0]
|
config = config_wrapped[0]
|
||||||
shutil.copy(get_resource_path('manifest_without_foo.yaml'), C.MANIFEST_FILE)
|
shutil.copy(
|
||||||
|
get_resource_path('manifest_without_foo.yaml'),
|
||||||
|
C.MANIFEST_FILE,
|
||||||
|
)
|
||||||
local['git']['add', '.']()
|
local['git']['add', '.']()
|
||||||
local['git']['commit', '-m', 'Remove foo']()
|
local['git']['commit', '-m', 'Remove foo']()
|
||||||
|
|
||||||
|
|
@ -167,14 +174,18 @@ def hook_disappearing_repo(python_hooks_repo):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_hook_disppearing_repo_raises(hook_disappearing_repo, runner_with_mocked_store):
|
def test_hook_disppearing_repo_raises(
|
||||||
|
hook_disappearing_repo, runner_with_mocked_store
|
||||||
|
):
|
||||||
with pytest.raises(commands.RepositoryCannotBeUpdatedError):
|
with pytest.raises(commands.RepositoryCannotBeUpdatedError):
|
||||||
commands._update_repository(
|
commands._update_repository(
|
||||||
hook_disappearing_repo.repo_config, runner_with_mocked_store,
|
hook_disappearing_repo.repo_config, runner_with_mocked_store,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_autoupdate_hook_disappearing_repo(hook_disappearing_repo, mock_out_store_directory):
|
def test_autoupdate_hook_disappearing_repo(
|
||||||
|
hook_disappearing_repo, mock_out_store_directory
|
||||||
|
):
|
||||||
before = open(C.CONFIG_FILE).read()
|
before = open(C.CONFIG_FILE).read()
|
||||||
runner = Runner(hook_disappearing_repo.python_hooks_repo)
|
runner = Runner(hook_disappearing_repo.python_hooks_repo)
|
||||||
ret = commands.autoupdate(runner)
|
ret = commands.autoupdate(runner)
|
||||||
|
|
@ -206,7 +217,13 @@ def get_write_mock_output(write_mock):
|
||||||
return ''.join(call[0][0] for call in write_mock.call_args_list)
|
return ''.join(call[0][0] for call in write_mock.call_args_list)
|
||||||
|
|
||||||
|
|
||||||
def _get_opts(all_files=False, color=False, verbose=False, hook=None, no_stash=False):
|
def _get_opts(
|
||||||
|
all_files=False,
|
||||||
|
color=False,
|
||||||
|
verbose=False,
|
||||||
|
hook=None,
|
||||||
|
no_stash=False,
|
||||||
|
):
|
||||||
return auto_namedtuple(
|
return auto_namedtuple(
|
||||||
all_files=all_files,
|
all_files=all_files,
|
||||||
color=color,
|
color=color,
|
||||||
|
|
@ -234,7 +251,9 @@ def _test_run(repo, options, expected_outputs, expected_ret, stage):
|
||||||
assert expected_output_part in printed
|
assert expected_output_part in printed
|
||||||
|
|
||||||
|
|
||||||
def test_run_all_hooks_failing(repo_with_failing_hook, mock_out_store_directory):
|
def test_run_all_hooks_failing(
|
||||||
|
repo_with_failing_hook, mock_out_store_directory
|
||||||
|
):
|
||||||
_test_run(
|
_test_run(
|
||||||
repo_with_failing_hook,
|
repo_with_failing_hook,
|
||||||
{},
|
{},
|
||||||
|
|
@ -262,7 +281,14 @@ def test_run_all_hooks_failing(repo_with_failing_hook, mock_out_store_directory)
|
||||||
({}, ('Bash hook', '(no files to check)', 'Skipped'), 0, False),
|
({}, ('Bash hook', '(no files to check)', 'Skipped'), 0, False),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
def test_run(repo_with_passing_hook, options, outputs, expected_ret, stage, mock_out_store_directory):
|
def test_run(
|
||||||
|
repo_with_passing_hook,
|
||||||
|
options,
|
||||||
|
outputs,
|
||||||
|
expected_ret,
|
||||||
|
stage,
|
||||||
|
mock_out_store_directory,
|
||||||
|
):
|
||||||
_test_run(repo_with_passing_hook, options, outputs, expected_ret, stage)
|
_test_run(repo_with_passing_hook, options, outputs, expected_ret, stage)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -275,7 +301,13 @@ def test_run(repo_with_passing_hook, options, outputs, expected_ret, stage, mock
|
||||||
(False, False, True),
|
(False, False, True),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
def test_no_stash(repo_with_passing_hook, no_stash, all_files, expect_stash, mock_out_store_directory):
|
def test_no_stash(
|
||||||
|
repo_with_passing_hook,
|
||||||
|
no_stash,
|
||||||
|
all_files,
|
||||||
|
expect_stash,
|
||||||
|
mock_out_store_directory,
|
||||||
|
):
|
||||||
stage_a_file()
|
stage_a_file()
|
||||||
# Make unstaged changes
|
# Make unstaged changes
|
||||||
with open('foo.py', 'w') as foo_file:
|
with open('foo.py', 'w') as foo_file:
|
||||||
|
|
@ -347,11 +379,15 @@ def test_skip_hook(repo_with_passing_hook, mock_out_store_directory):
|
||||||
assert msg in printed
|
assert msg in printed
|
||||||
|
|
||||||
|
|
||||||
def test_hook_id_not_in_non_verbose_output(repo_with_passing_hook, mock_out_store_directory):
|
def test_hook_id_not_in_non_verbose_output(
|
||||||
|
repo_with_passing_hook, mock_out_store_directory
|
||||||
|
):
|
||||||
ret, printed = _do_run(repo_with_passing_hook, _get_opts(verbose=False))
|
ret, printed = _do_run(repo_with_passing_hook, _get_opts(verbose=False))
|
||||||
assert '[bash_hook]' not in printed
|
assert '[bash_hook]' not in printed
|
||||||
|
|
||||||
|
|
||||||
def test_hook_id_in_verbose_output(repo_with_passing_hook, mock_out_store_directory):
|
def test_hook_id_in_verbose_output(
|
||||||
|
repo_with_passing_hook, mock_out_store_directory
|
||||||
|
):
|
||||||
ret, printed = _do_run(repo_with_passing_hook, _get_opts(verbose=True))
|
ret, printed = _do_run(repo_with_passing_hook, _get_opts(verbose=True))
|
||||||
assert '[bash_hook] Bash hook' in printed
|
assert '[bash_hook] Bash hook' in printed
|
||||||
|
|
|
||||||
|
|
@ -122,11 +122,11 @@ def system_hook_with_spaces_repo(dummy_git_repo):
|
||||||
yield _make_repo(dummy_git_repo, 'system_hook_with_spaces_repo')
|
yield _make_repo(dummy_git_repo, 'system_hook_with_spaces_repo')
|
||||||
|
|
||||||
|
|
||||||
def _make_config(path, hook_id, file_regex):
|
def _make_config(path, hook_id):
|
||||||
config = {
|
config = {
|
||||||
'repo': path,
|
'repo': path,
|
||||||
'sha': get_head_sha(path),
|
'sha': get_head_sha(path),
|
||||||
'hooks': [{'id': hook_id, 'files': file_regex}],
|
'hooks': [{'id': hook_id}],
|
||||||
}
|
}
|
||||||
config_wrapped = apply_defaults([config], CONFIG_JSON_SCHEMA)
|
config_wrapped = apply_defaults([config], CONFIG_JSON_SCHEMA)
|
||||||
validate_config_extra(config_wrapped)
|
validate_config_extra(config_wrapped)
|
||||||
|
|
@ -135,48 +135,48 @@ def _make_config(path, hook_id, file_regex):
|
||||||
|
|
||||||
@pytest.yield_fixture
|
@pytest.yield_fixture
|
||||||
def config_for_node_hooks_repo(node_hooks_repo):
|
def config_for_node_hooks_repo(node_hooks_repo):
|
||||||
yield _make_config(node_hooks_repo, 'foo', '\\.js$')
|
yield _make_config(node_hooks_repo, 'foo')
|
||||||
|
|
||||||
|
|
||||||
@pytest.yield_fixture
|
@pytest.yield_fixture
|
||||||
def config_for_node_0_11_8_hooks_repo(node_0_11_8_hooks_repo):
|
def config_for_node_0_11_8_hooks_repo(node_0_11_8_hooks_repo):
|
||||||
yield _make_config(node_0_11_8_hooks_repo, 'node-11-8-hook', '\\.js$')
|
yield _make_config(node_0_11_8_hooks_repo, 'node-11-8-hook')
|
||||||
|
|
||||||
|
|
||||||
@pytest.yield_fixture
|
@pytest.yield_fixture
|
||||||
def config_for_ruby_hooks_repo(ruby_hooks_repo):
|
def config_for_ruby_hooks_repo(ruby_hooks_repo):
|
||||||
yield _make_config(ruby_hooks_repo, 'ruby_hook', '\\.rb$')
|
yield _make_config(ruby_hooks_repo, 'ruby_hook')
|
||||||
|
|
||||||
|
|
||||||
@pytest.yield_fixture
|
@pytest.yield_fixture
|
||||||
def config_for_ruby_1_9_3_p547_hooks_repo(ruby_1_9_3_p547_hooks_repo):
|
def config_for_ruby_1_9_3_p547_hooks_repo(ruby_1_9_3_p547_hooks_repo):
|
||||||
yield _make_config(ruby_1_9_3_p547_hooks_repo, 'ruby_hook', '\\.rb$')
|
yield _make_config(ruby_1_9_3_p547_hooks_repo, 'ruby_hook')
|
||||||
|
|
||||||
|
|
||||||
@pytest.yield_fixture
|
@pytest.yield_fixture
|
||||||
def config_for_python_hooks_repo(python_hooks_repo):
|
def config_for_python_hooks_repo(python_hooks_repo):
|
||||||
yield _make_config(python_hooks_repo, 'foo', '\\.py$')
|
yield _make_config(python_hooks_repo, 'foo')
|
||||||
|
|
||||||
|
|
||||||
@pytest.yield_fixture
|
@pytest.yield_fixture
|
||||||
def config_for_python3_hooks_repo(python3_hooks_repo):
|
def config_for_python3_hooks_repo(python3_hooks_repo):
|
||||||
yield _make_config(python3_hooks_repo, 'python3-hook', '\\.py$')
|
yield _make_config(python3_hooks_repo, 'python3-hook')
|
||||||
|
|
||||||
|
|
||||||
@pytest.yield_fixture
|
@pytest.yield_fixture
|
||||||
def config_for_prints_cwd_repo(prints_cwd_repo):
|
def config_for_prints_cwd_repo(prints_cwd_repo):
|
||||||
yield _make_config(prints_cwd_repo, 'prints_cwd', '^$')
|
yield _make_config(prints_cwd_repo, 'prints_cwd')
|
||||||
|
|
||||||
|
|
||||||
@pytest.yield_fixture
|
@pytest.yield_fixture
|
||||||
def config_for_script_hooks_repo(script_hooks_repo):
|
def config_for_script_hooks_repo(script_hooks_repo):
|
||||||
yield _make_config(script_hooks_repo, 'bash_hook', '')
|
yield _make_config(script_hooks_repo, 'bash_hook')
|
||||||
|
|
||||||
|
|
||||||
@pytest.yield_fixture
|
@pytest.yield_fixture
|
||||||
def config_for_system_hook_with_spaces(system_hook_with_spaces_repo):
|
def config_for_system_hook_with_spaces(system_hook_with_spaces_repo):
|
||||||
yield _make_config(
|
yield _make_config(
|
||||||
system_hook_with_spaces_repo, 'system-hook-with-spaces', '',
|
system_hook_with_spaces_repo, 'system-hook-with-spaces',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -198,7 +198,7 @@ def repo_with_passing_hook(config_for_script_hooks_repo, empty_git_dir):
|
||||||
|
|
||||||
@pytest.yield_fixture
|
@pytest.yield_fixture
|
||||||
def repo_with_failing_hook(failing_hook_repo, empty_git_dir):
|
def repo_with_failing_hook(failing_hook_repo, empty_git_dir):
|
||||||
_make_repo_from_configs(_make_config(failing_hook_repo, 'failing_hook', ''))
|
_make_repo_from_configs(_make_config(failing_hook_repo, 'failing_hook'))
|
||||||
yield empty_git_dir
|
yield empty_git_dir
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ def test_manifest_contents(manifest):
|
||||||
'description': '',
|
'description': '',
|
||||||
'entry': 'bin/hook.sh',
|
'entry': 'bin/hook.sh',
|
||||||
'expected_return_value': 0,
|
'expected_return_value': 0,
|
||||||
|
'files': '',
|
||||||
'id': 'bash_hook',
|
'id': 'bash_hook',
|
||||||
'language': 'script',
|
'language': 'script',
|
||||||
'language_version': 'default',
|
'language_version': 'default',
|
||||||
|
|
@ -29,6 +30,7 @@ def test_hooks(manifest):
|
||||||
'description': '',
|
'description': '',
|
||||||
'entry': 'bin/hook.sh',
|
'entry': 'bin/hook.sh',
|
||||||
'expected_return_value': 0,
|
'expected_return_value': 0,
|
||||||
|
'files': '',
|
||||||
'id': 'bash_hook',
|
'id': 'bash_hook',
|
||||||
'language': 'script',
|
'language': 'script',
|
||||||
'language_version': 'default',
|
'language_version': 'default',
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,9 @@ def test_init_normalizes_path_endings(input, expected_prefix):
|
||||||
|
|
||||||
|
|
||||||
def test_run_substitutes_prefix(popen_mock, makedirs_mock):
|
def test_run_substitutes_prefix(popen_mock, makedirs_mock):
|
||||||
instance = PrefixedCommandRunner('prefix', popen=popen_mock, makedirs=makedirs_mock)
|
instance = PrefixedCommandRunner(
|
||||||
|
'prefix', popen=popen_mock, makedirs=makedirs_mock,
|
||||||
|
)
|
||||||
ret = instance.run(['{prefix}bar', 'baz'], retcode=None)
|
ret = instance.run(['{prefix}bar', 'baz'], retcode=None)
|
||||||
popen_mock.assert_called_once_with(
|
popen_mock.assert_called_once_with(
|
||||||
['prefix/bar', 'baz'],
|
['prefix/bar', 'baz'],
|
||||||
|
|
@ -104,7 +106,9 @@ def test_from_command_runner(prefix, path_end, expected_output):
|
||||||
|
|
||||||
|
|
||||||
def test_from_command_runner_preserves_popen(popen_mock, makedirs_mock):
|
def test_from_command_runner_preserves_popen(popen_mock, makedirs_mock):
|
||||||
first = PrefixedCommandRunner('foo', popen=popen_mock, makedirs=makedirs_mock)
|
first = PrefixedCommandRunner(
|
||||||
|
'foo', popen=popen_mock, makedirs=makedirs_mock,
|
||||||
|
)
|
||||||
second = PrefixedCommandRunner.from_command_runner(first, 'bar')
|
second = PrefixedCommandRunner.from_command_runner(first, 'bar')
|
||||||
second.run(['foo/bar/baz'], retcode=None)
|
second.run(['foo/bar/baz'], retcode=None)
|
||||||
popen_mock.assert_called_once_with(
|
popen_mock.assert_called_once_with(
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ def test_run_versioned_hook(config_for_python3_hooks_repo, store):
|
||||||
assert ret[1] == "3.3\n['/dev/null']\nHello World\n"
|
assert ret[1] == "3.3\n['/dev/null']\nHello World\n"
|
||||||
|
|
||||||
|
|
||||||
|
@skipif_slowtests_false
|
||||||
@pytest.mark.integration
|
@pytest.mark.integration
|
||||||
def test_run_versioned_node_hook(config_for_node_0_11_8_hooks_repo, store):
|
def test_run_versioned_node_hook(config_for_node_0_11_8_hooks_repo, store):
|
||||||
repo = Repository.create(config_for_node_0_11_8_hooks_repo, store)
|
repo = Repository.create(config_for_node_0_11_8_hooks_repo, store)
|
||||||
|
|
@ -152,3 +153,13 @@ def test_really_long_file_paths(config_for_python_hooks_repo, store):
|
||||||
with local.cwd(path):
|
with local.cwd(path):
|
||||||
repo = Repository.create(config_for_python_hooks_repo, store)
|
repo = Repository.create(config_for_python_hooks_repo, store)
|
||||||
repo.require_installed()
|
repo.require_installed()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.integration
|
||||||
|
def test_config_overrides_repo_specifics(config_for_script_hooks_repo, store):
|
||||||
|
repo = Repository.create(config_for_script_hooks_repo, store)
|
||||||
|
assert repo.hooks['bash_hook']['files'] == ''
|
||||||
|
# Set the file regex to something else
|
||||||
|
config_for_script_hooks_repo['hooks'][0]['files'] = '\\.sh$'
|
||||||
|
repo = Repository.create(config_for_script_hooks_repo, store)
|
||||||
|
assert repo.hooks['bash_hook']['files'] == '\\.sh$'
|
||||||
|
|
|
||||||
3
tox.ini
3
tox.ini
|
|
@ -23,6 +23,3 @@ deps =
|
||||||
sphinx
|
sphinx
|
||||||
changedir = docs
|
changedir = docs
|
||||||
commands = sphinx-build -b html -d build/doctrees source build/html
|
commands = sphinx-build -b html -d build/doctrees source build/html
|
||||||
|
|
||||||
[flake8]
|
|
||||||
max-line-length=131
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue