mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-02-17 08:14:42 +04:00
Better project structure
This commit is contained in:
parent
f31f092f9b
commit
1746a97e24
52 changed files with 221 additions and 189 deletions
36
.coveragerc
36
.coveragerc
|
|
@ -1,19 +1,29 @@
|
||||||
|
[run]
|
||||||
|
branch = True
|
||||||
|
timid = True
|
||||||
|
source =
|
||||||
|
.
|
||||||
|
omit =
|
||||||
|
.tox/*
|
||||||
|
/usr/*
|
||||||
|
*/tmp*
|
||||||
|
setup.py
|
||||||
|
|
||||||
[report]
|
[report]
|
||||||
exclude_lines =
|
exclude_lines =
|
||||||
# Don't complain about defensive assertions
|
# Have to re-enable the standard pragma
|
||||||
raise NotImplementedError
|
\#\s*pragma: no cover
|
||||||
raise AssertionError
|
|
||||||
|
|
||||||
# Don't complain about non-runnable code
|
# Don't complain if tests don't hit defensive assertion code:
|
||||||
if __name__ == .__main__.:
|
^\s*raise AssertionError\b
|
||||||
|
^\s*raise NotImplementedError\b
|
||||||
|
^\s*return NotImplemented\b
|
||||||
|
^\s*raise$
|
||||||
|
|
||||||
omit =
|
# Don't complain if non-runnable code isn't run:
|
||||||
/usr/*
|
^if __name__ == ['"]__main__['"]:$
|
||||||
py_env/*
|
|
||||||
*/__init__.py
|
|
||||||
|
|
||||||
# Ignore test coverage
|
[html]
|
||||||
tests/*
|
directory = coverage-html
|
||||||
|
|
||||||
# Don't complain about our pre-commit file
|
# vim:ft=dosini
|
||||||
pre-commit.py
|
|
||||||
|
|
|
||||||
21
.gitignore
vendored
21
.gitignore
vendored
|
|
@ -1,12 +1,13 @@
|
||||||
*.pyc
|
|
||||||
.pydevproject
|
|
||||||
.pre-commit-files
|
|
||||||
.project
|
|
||||||
.coverage
|
|
||||||
/py_env
|
|
||||||
*.db
|
|
||||||
.idea
|
|
||||||
build
|
|
||||||
dist
|
|
||||||
*.egg-info
|
*.egg-info
|
||||||
*.iml
|
*.iml
|
||||||
|
*.py[co]
|
||||||
|
.*.sw[a-z]
|
||||||
|
.coverage
|
||||||
|
.idea
|
||||||
|
.pre-commit-files
|
||||||
|
.project
|
||||||
|
.pydevproject
|
||||||
|
.tox
|
||||||
|
/venv*
|
||||||
|
coverage-html
|
||||||
|
dist
|
||||||
|
|
|
||||||
13
.travis.yml
13
.travis.yml
|
|
@ -1,13 +1,12 @@
|
||||||
language: python
|
language: python
|
||||||
|
env: # These should match the tox env list
|
||||||
python:
|
- TOXENV=py26
|
||||||
- 2.6
|
- TOXENV=py27
|
||||||
- 2.7
|
install: pip install tox --use-mirrors
|
||||||
|
script: tox
|
||||||
install: pip install virtualenv
|
|
||||||
script: make coverage
|
|
||||||
|
|
||||||
|
|
||||||
|
# Special snowflake. Our tests depend on making real commits.
|
||||||
before_install:
|
before_install:
|
||||||
- git config --global user.name "Travis CI"
|
- git config --global user.name "Travis CI"
|
||||||
- git config --global user.email "user@example.com"
|
- git config --global user.email "user@example.com"
|
||||||
|
|
|
||||||
48
Makefile
48
Makefile
|
|
@ -1,41 +1,17 @@
|
||||||
|
.PHONY: all
|
||||||
|
all: venv test
|
||||||
|
|
||||||
TEST_TARGETS =
|
.PHONY: venv
|
||||||
ITEST_TARGETS = -m integration
|
venv:
|
||||||
UTEST_TARGETS = -m "not(integration)"
|
tox -e venv
|
||||||
|
|
||||||
DEBUG=
|
.PHONY: tests test
|
||||||
|
|
||||||
all: _tests
|
|
||||||
|
|
||||||
integration:
|
|
||||||
$(eval TEST_TARGETS := $(ITEST_TARGETS))
|
|
||||||
|
|
||||||
unit:
|
|
||||||
$(eval TEST_TARGETS := $(UTEST_TARGETS))
|
|
||||||
|
|
||||||
utests: test
|
|
||||||
utest: test
|
|
||||||
tests: test
|
tests: test
|
||||||
test: unit _tests
|
test:
|
||||||
itests: itest
|
tox
|
||||||
itest: integration _tests
|
|
||||||
|
|
||||||
_tests: py_env
|
|
||||||
bash -c 'source py_env/bin/activate && py.test tests $(TEST_TARGETS) $(DEBUG)'
|
|
||||||
|
|
||||||
ucoverage: unit coverage
|
|
||||||
icoverage: integration coverage
|
|
||||||
|
|
||||||
coverage: py_env
|
|
||||||
bash -c 'source py_env/bin/activate && \
|
|
||||||
coverage erase && \
|
|
||||||
coverage run `which py.test` tests $(TEST_TARGETS) && \
|
|
||||||
coverage report -m'
|
|
||||||
|
|
||||||
py_env: requirements.txt setup.py
|
|
||||||
rm -rf py_env
|
|
||||||
virtualenv py_env
|
|
||||||
bash -c 'source py_env/bin/activate && pip install -r requirements.txt'
|
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
rm -rf py_env
|
find . -iname '*.pyc' | xargs rm -f
|
||||||
|
rm -rf .tox
|
||||||
|
rm -rf ./venv-*
|
||||||
|
|
|
||||||
24
UNLICENSE
Normal file
24
UNLICENSE
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
|
distribute this software, either in source code form or as a compiled
|
||||||
|
binary, for any purpose, commercial or non-commercial, and by any
|
||||||
|
means.
|
||||||
|
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors
|
||||||
|
of this software dedicate any and all copyright interest in the
|
||||||
|
software to the public domain. We make this dedication for the benefit
|
||||||
|
of the public at large and to the detriment of our heirs and
|
||||||
|
successors. We intend this dedication to be an overt act of
|
||||||
|
relinquishment in perpetuity of all present and future rights to this
|
||||||
|
software under copyright law.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
For more information, please refer to <http://unlicense.org/>
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
# Hooks are set up as follows
|
# Hooks are set up as follows
|
||||||
# - id: hook_id
|
# - id: hook_id
|
||||||
# name: 'Readable name'
|
# name: 'Readable name'
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
- repo: git@github.com:pre-commit/pre-commit-hooks
|
- repo: git@github.com:pre-commit/pre-commit-hooks
|
||||||
sha: cd74dc150c142c3be70b24eaf0b02cae9d235f37
|
sha: cd74dc150c142c3be70b24eaf0b02cae9d235f37
|
||||||
hooks:
|
hooks:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
@ -6,7 +5,8 @@ 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
|
||||||
|
|
||||||
|
|
||||||
class InvalidConfigError(ValueError): pass
|
class InvalidConfigError(ValueError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
CONFIG_JSON_SCHEMA = {
|
CONFIG_JSON_SCHEMA = {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from pre_commit.clientlib.validate_base import get_run_function
|
from pre_commit.clientlib.validate_base import get_run_function
|
||||||
|
|
@ -6,7 +5,8 @@ from pre_commit.clientlib.validate_base import get_validator
|
||||||
from pre_commit.languages.all import all_languages
|
from pre_commit.languages.all import all_languages
|
||||||
|
|
||||||
|
|
||||||
class InvalidManifestError(ValueError): pass
|
class InvalidManifestError(ValueError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
MANIFEST_JSON_SCHEMA = {
|
MANIFEST_JSON_SCHEMA = {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
RED = '\033[41m'
|
RED = '\033[41m'
|
||||||
|
|
@ -8,18 +7,19 @@ TURQUOISE = '\033[46;30m'
|
||||||
NORMAL = '\033[0m'
|
NORMAL = '\033[0m'
|
||||||
|
|
||||||
|
|
||||||
class InvalidColorSetting(ValueError): pass
|
class InvalidColorSetting(ValueError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def format_color(text, color, use_color):
|
def format_color(text, color, use_color_setting):
|
||||||
"""Format text with color.
|
"""Format text with color.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
text - Text to be formatted with color if `use_color`
|
text - Text to be formatted with color if `use_color`
|
||||||
color - The color start string
|
color - The color start string
|
||||||
use_color - Whether or not to color
|
use_color_setting - Whether or not to color
|
||||||
"""
|
"""
|
||||||
if not use_color:
|
if not use_color_setting:
|
||||||
return text
|
return text
|
||||||
else:
|
else:
|
||||||
return u'{0}{1}{2}'.format(color, text, NORMAL)
|
return u'{0}{1}{2}'.format(color, text, NORMAL)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
@ -42,7 +41,8 @@ def uninstall(runner):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
class RepositoryCannotBeUpdatedError(RuntimeError): pass
|
class RepositoryCannotBeUpdatedError(RuntimeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def _update_repository(repo_config):
|
def _update_repository(repo_config):
|
||||||
|
|
@ -95,8 +95,8 @@ def autoupdate(runner):
|
||||||
print('Updating {0}...'.format(repo_config['repo']), end='')
|
print('Updating {0}...'.format(repo_config['repo']), end='')
|
||||||
try:
|
try:
|
||||||
new_repo_config = _update_repository(repo_config)
|
new_repo_config = _update_repository(repo_config)
|
||||||
except RepositoryCannotBeUpdatedError as e:
|
except RepositoryCannotBeUpdatedError as error:
|
||||||
print(e.args[0])
|
print(error.args[0])
|
||||||
output_configs.append(repo_config)
|
output_configs.append(repo_config)
|
||||||
retv = 1
|
retv = 1
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
CONFIG_FILE = '.pre-commit-config.yaml'
|
CONFIG_FILE = '.pre-commit-config.yaml'
|
||||||
|
|
||||||
HOOKS_WORKSPACE = '.pre-commit-files'
|
HOOKS_WORKSPACE = '.pre-commit-files'
|
||||||
|
|
|
||||||
|
|
@ -43,14 +43,15 @@ def get_files_matching(all_file_list_strategy):
|
||||||
def wrapper(include_expr, exclude_expr):
|
def wrapper(include_expr, exclude_expr):
|
||||||
include_regex = re.compile(include_expr)
|
include_regex = re.compile(include_expr)
|
||||||
exclude_regex = re.compile(exclude_expr)
|
exclude_regex = re.compile(exclude_expr)
|
||||||
return set(filter(os.path.exists, (
|
return set(
|
||||||
filename
|
filename
|
||||||
for filename in all_file_list_strategy()
|
for filename in all_file_list_strategy()
|
||||||
if (
|
if (
|
||||||
include_regex.search(filename) and
|
include_regex.search(filename) and
|
||||||
not exclude_regex.search(filename)
|
not exclude_regex.search(filename) and
|
||||||
|
os.path.exists(filename)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)))
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
import os.path
|
import os.path
|
||||||
from plumbum import local
|
from plumbum import local
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import jsonschema
|
import jsonschema
|
||||||
import jsonschema.validators
|
import jsonschema.validators
|
||||||
|
|
@ -21,7 +20,6 @@ def extend_validator_cls(validator_cls, modify):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def default_values(properties, instance):
|
def default_values(properties, instance):
|
||||||
for property, subschema in properties.iteritems():
|
for property, subschema in properties.iteritems():
|
||||||
if 'default' in subschema:
|
if 'default' in subschema:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
from pre_commit.languages import node
|
from pre_commit.languages import node
|
||||||
from pre_commit.languages import python
|
from pre_commit.languages import python
|
||||||
from pre_commit.languages import ruby
|
from pre_commit.languages import ruby
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
|
|
||||||
from pre_commit.languages import helpers
|
from pre_commit.languages import helpers
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
|
|
||||||
from pre_commit.languages import helpers
|
from pre_commit.languages import helpers
|
||||||
|
|
@ -11,7 +10,7 @@ ENVIRONMENT_DIR = 'rvm_env'
|
||||||
class RubyEnv(helpers.Environment):
|
class RubyEnv(helpers.Environment):
|
||||||
@property
|
@property
|
||||||
def env_prefix(self):
|
def env_prefix(self):
|
||||||
return '. {{prefix}}{0}/bin/activate &&'.format(ENVIRONMENT_DIR)
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
ENVIRONMENT_DIR = None
|
ENVIRONMENT_DIR = None
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
ENVIRONMENT_DIR = None
|
ENVIRONMENT_DIR = None
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
import logging
|
import logging
|
||||||
from plumbum import local
|
from plumbum import local
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|
@ -56,7 +55,6 @@ def _run_single_hook(runner, repository, hook_id, args):
|
||||||
print_color = color.GREEN
|
print_color = color.GREEN
|
||||||
pass_fail = 'Passed'
|
pass_fail = 'Passed'
|
||||||
|
|
||||||
|
|
||||||
print(color.format_color(pass_fail, print_color, args.color))
|
print(color.format_color(pass_fail, print_color, args.color))
|
||||||
|
|
||||||
if output and (retcode or args.verbose):
|
if output and (retcode or args.verbose):
|
||||||
|
|
@ -111,14 +109,14 @@ def run(argv):
|
||||||
|
|
||||||
subparsers.add_parser('autoupdate', help='Auto-update hooks config.')
|
subparsers.add_parser('autoupdate', help='Auto-update hooks config.')
|
||||||
|
|
||||||
run = subparsers.add_parser('run', help='Run hooks.')
|
run_parser = subparsers.add_parser('run', help='Run hooks.')
|
||||||
run.add_argument('hook', nargs='?', help='A single hook-id to run'),
|
run_parser.add_argument('hook', nargs='?', help='A single hook-id to run')
|
||||||
run.add_argument(
|
run_parser.add_argument(
|
||||||
'--all-files', '-a', action='store_true', default=False,
|
'--all-files', '-a', action='store_true', default=False,
|
||||||
help='Run on all the files in the repo.',
|
help='Run on all the files in the repo.',
|
||||||
)
|
)
|
||||||
run.add_argument('--verbose', '-v', action='store_true', default=False)
|
run_parser.add_argument('--verbose', '-v', action='store_true', default=False)
|
||||||
run.add_argument(
|
run_parser.add_argument(
|
||||||
'--color', default='auto', type=color.use_color,
|
'--color', default='auto', type=color.use_color,
|
||||||
help='Whether to use color in output. Defaults to `auto`',
|
help='Whether to use color in output. Defaults to `auto`',
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
|
|
@ -40,7 +39,7 @@ class Runner(object):
|
||||||
def repositories(self):
|
def repositories(self):
|
||||||
"""Returns a tuple of the configured repositories."""
|
"""Returns a tuple of the configured repositories."""
|
||||||
config = load_config(self.config_file_path)
|
config = load_config(self.config_file_path)
|
||||||
return tuple(map(Repository, config))
|
return tuple(Repository(x) for x in config)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def pre_commit_path(self):
|
def pre_commit_path(self):
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
import functools
|
import functools
|
||||||
import os
|
import os
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from pre_commit.ordereddict import OrderedDict
|
from pre_commit.ordereddict import OrderedDict
|
||||||
|
|
@ -6,23 +5,27 @@ from pre_commit.ordereddict import OrderedDict
|
||||||
|
|
||||||
# Adapted from http://stackoverflow.com/a/21912744/812183
|
# Adapted from http://stackoverflow.com/a/21912744/812183
|
||||||
|
|
||||||
def ordered_load(s):
|
def ordered_load(stream):
|
||||||
class OrderedLoader(yaml.loader.Loader): pass
|
class OrderedLoader(yaml.loader.Loader):
|
||||||
|
pass
|
||||||
|
|
||||||
def constructor(loader, node):
|
def constructor(loader, node):
|
||||||
return OrderedDict(loader.construct_pairs(node))
|
return OrderedDict(loader.construct_pairs(node))
|
||||||
OrderedLoader.add_constructor(
|
OrderedLoader.add_constructor(
|
||||||
yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
|
yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
|
||||||
constructor,
|
constructor,
|
||||||
)
|
)
|
||||||
return yaml.load(s, Loader=OrderedLoader)
|
return yaml.load(stream, Loader=OrderedLoader)
|
||||||
|
|
||||||
|
|
||||||
def ordered_dump(s, **kwargs):
|
def ordered_dump(obj, **kwargs):
|
||||||
class OrderedDumper(yaml.dumper.SafeDumper): pass
|
class OrderedDumper(yaml.dumper.SafeDumper):
|
||||||
|
pass
|
||||||
|
|
||||||
def dict_representer(dumper, data):
|
def dict_representer(dumper, data):
|
||||||
return dumper.represent_mapping(
|
return dumper.represent_mapping(
|
||||||
yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
|
yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
|
||||||
data.items(),
|
data.items(),
|
||||||
)
|
)
|
||||||
OrderedDumper.add_representer(OrderedDict, dict_representer)
|
OrderedDumper.add_representer(OrderedDict, dict_representer)
|
||||||
return yaml.dump(s, Dumper=OrderedDumper, **kwargs)
|
return yaml.dump(obj, Dumper=OrderedDumper, **kwargs)
|
||||||
|
|
|
||||||
19
pylintrc
Normal file
19
pylintrc
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
[MESSAGES CONTROL]
|
||||||
|
disable=missing-docstring,abstract-method,redefined-builtin,useless-else-on-loop,redefined-outer-name,invalid-name
|
||||||
|
|
||||||
|
[REPORTS]
|
||||||
|
output-format=colorized
|
||||||
|
reports=no
|
||||||
|
|
||||||
|
[BASIC]
|
||||||
|
const-rgx=(([A-Za-z_][A-Za-z0-9_]*)|(__.*__))$
|
||||||
|
|
||||||
|
[FORMAT]
|
||||||
|
max-line-length=131
|
||||||
|
|
||||||
|
[TYPECHECK]
|
||||||
|
ignored-classes=pytest
|
||||||
|
|
||||||
|
[DESIGN]
|
||||||
|
min-public-methods=0
|
||||||
|
|
||||||
|
|
@ -1,10 +1 @@
|
||||||
-e .
|
.
|
||||||
|
|
||||||
# Testing requirements
|
|
||||||
coverage
|
|
||||||
# Fuck you ipython
|
|
||||||
ipython<2.0.0
|
|
||||||
ipdb
|
|
||||||
mock
|
|
||||||
pyflakes
|
|
||||||
pytest
|
|
||||||
|
|
|
||||||
7
requirements_dev.txt
Normal file
7
requirements_dev.txt
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
-e .
|
||||||
|
|
||||||
|
coverage
|
||||||
|
flake8
|
||||||
|
mock
|
||||||
|
pylint
|
||||||
|
pytest
|
||||||
13
setup.py
13
setup.py
|
|
@ -18,7 +18,20 @@ if sys.version_info < (2, 7):
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='pre_commit',
|
name='pre_commit',
|
||||||
|
description='A framework for managing and maintaining multi-language pre-commit hooks.',
|
||||||
|
url='http://github.com/pre-commit/pre-commit',
|
||||||
version='0.0.0',
|
version='0.0.0',
|
||||||
|
|
||||||
|
author='Anthony Sottile',
|
||||||
|
author_email='asottile@umich.edu',
|
||||||
|
|
||||||
|
platforms='linux',
|
||||||
|
classifiers=[
|
||||||
|
'License :: Public Domain',
|
||||||
|
'Programming Language :: Python :: 2.6',
|
||||||
|
'Programming Language :: Python :: 2.7',
|
||||||
|
],
|
||||||
|
|
||||||
packages=find_packages('.', exclude=('tests*', 'testing*')),
|
packages=find_packages('.', exclude=('tests*', 'testing*')),
|
||||||
package_data={
|
package_data={
|
||||||
'pre_commit': [
|
'pre_commit': [
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
def auto_namedtuple(classname='auto_namedtuple', **kwargs):
|
def auto_namedtuple(classname='auto_namedtuple', **kwargs):
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
- repo: git@github.com:pre-commit/pre-commit-hooks
|
- repo: git@github.com:pre-commit/pre-commit-hooks
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyflakes
|
- id: pyflakes
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
|
import jsonschema
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import shutil
|
import shutil
|
||||||
|
|
@ -27,3 +27,10 @@ def copy_tree_to_path(src_dir, dest_dir):
|
||||||
shutil.copytree(srcname, destname)
|
shutil.copytree(srcname, destname)
|
||||||
else:
|
else:
|
||||||
shutil.copy(srcname, destname)
|
shutil.copy(srcname, destname)
|
||||||
|
|
||||||
|
def is_valid_according_to_schema(obj, schema):
|
||||||
|
try:
|
||||||
|
jsonschema.validate(obj, schema)
|
||||||
|
return True
|
||||||
|
except jsonschema.exceptions.ValidationError:
|
||||||
|
return False
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from pre_commit.clientlib.validate_base import get_validator
|
from pre_commit.clientlib.validate_base import get_validator
|
||||||
|
|
@ -7,7 +6,8 @@ from pre_commit.yaml_extensions import ordered_load
|
||||||
from testing.util import get_resource_path
|
from testing.util import get_resource_path
|
||||||
|
|
||||||
|
|
||||||
class AdditionalValidatorError(ValueError): pass
|
class AdditionalValidatorError(ValueError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
|
@ -22,7 +22,7 @@ def array_validator():
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def additional_validator():
|
def additional_validator():
|
||||||
def raises_always(obj):
|
def raises_always(_):
|
||||||
raise AdditionalValidatorError
|
raise AdditionalValidatorError
|
||||||
|
|
||||||
return get_validator(
|
return get_validator(
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
|
|
||||||
import jsonschema
|
|
||||||
import jsonschema.exceptions
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from pre_commit.clientlib.validate_config import CONFIG_JSON_SCHEMA
|
from pre_commit.clientlib.validate_config import CONFIG_JSON_SCHEMA
|
||||||
|
|
@ -8,6 +5,7 @@ from pre_commit.clientlib.validate_config import InvalidConfigError
|
||||||
from pre_commit.clientlib.validate_config import run
|
from pre_commit.clientlib.validate_config import run
|
||||||
from pre_commit.clientlib.validate_config import validate_config_extra
|
from pre_commit.clientlib.validate_config import validate_config_extra
|
||||||
from pre_commit.jsonschema_extensions import apply_defaults
|
from pre_commit.jsonschema_extensions import apply_defaults
|
||||||
|
from testing.util import is_valid_according_to_schema
|
||||||
|
|
||||||
|
|
||||||
def test_returns_0_for_valid_config():
|
def test_returns_0_for_valid_config():
|
||||||
|
|
@ -22,21 +20,13 @@ def test_returns_1_for_failing():
|
||||||
assert run(['tests/data/valid_yaml_but_invalid_config.yaml']) == 1
|
assert run(['tests/data/valid_yaml_but_invalid_config.yaml']) == 1
|
||||||
|
|
||||||
|
|
||||||
def is_valid_according_to_schema(obj, schema):
|
|
||||||
try:
|
|
||||||
jsonschema.validate(obj, schema)
|
|
||||||
return True
|
|
||||||
except jsonschema.exceptions.ValidationError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(('manifest_obj', 'expected'), (
|
@pytest.mark.parametrize(('manifest_obj', 'expected'), (
|
||||||
([], False),
|
([], False),
|
||||||
(
|
(
|
||||||
[{
|
[{
|
||||||
'repo': 'git@github.com:pre-commit/pre-commit-hooks',
|
'repo': 'git@github.com:pre-commit/pre-commit-hooks',
|
||||||
'sha': 'cd74dc150c142c3be70b24eaf0b02cae9d235f37',
|
'sha': 'cd74dc150c142c3be70b24eaf0b02cae9d235f37',
|
||||||
'hooks': [{'id': 'pyflakes', 'files': '\.py$'}],
|
'hooks': [{'id': 'pyflakes', 'files': '\\.py$'}],
|
||||||
}],
|
}],
|
||||||
True,
|
True,
|
||||||
),
|
),
|
||||||
|
|
@ -47,7 +37,7 @@ def is_valid_according_to_schema(obj, schema):
|
||||||
'hooks': [
|
'hooks': [
|
||||||
{
|
{
|
||||||
'id': 'pyflakes',
|
'id': 'pyflakes',
|
||||||
'files': '\.py$',
|
'files': '\\.py$',
|
||||||
'args': ['foo', 'bar', 'baz'],
|
'args': ['foo', 'bar', 'baz'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
@ -61,7 +51,7 @@ def is_valid_according_to_schema(obj, schema):
|
||||||
'hooks': [
|
'hooks': [
|
||||||
{
|
{
|
||||||
'id': 'pyflakes',
|
'id': 'pyflakes',
|
||||||
'files': '\.py$',
|
'files': '\\.py$',
|
||||||
# Exclude pattern must be a string
|
# Exclude pattern must be a string
|
||||||
'exclude': 0,
|
'exclude': 0,
|
||||||
'args': ['foo', 'bar', 'baz'],
|
'args': ['foo', 'bar', 'baz'],
|
||||||
|
|
@ -95,7 +85,7 @@ def test_config_with_ok_regexes_passes():
|
||||||
[{
|
[{
|
||||||
'repo': 'foo',
|
'repo': 'foo',
|
||||||
'sha': 'foo',
|
'sha': 'foo',
|
||||||
'hooks': [{'id': 'hook_id', 'files': '\.py$'}],
|
'hooks': [{'id': 'hook_id', 'files': '\\.py$'}],
|
||||||
}],
|
}],
|
||||||
CONFIG_JSON_SCHEMA,
|
CONFIG_JSON_SCHEMA,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,10 @@
|
||||||
|
|
||||||
import jsonschema
|
|
||||||
import jsonschema.exceptions
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from pre_commit.clientlib.validate_manifest import additional_manifest_check
|
from pre_commit.clientlib.validate_manifest import additional_manifest_check
|
||||||
from pre_commit.clientlib.validate_manifest import InvalidManifestError
|
from pre_commit.clientlib.validate_manifest import InvalidManifestError
|
||||||
from pre_commit.clientlib.validate_manifest import MANIFEST_JSON_SCHEMA
|
from pre_commit.clientlib.validate_manifest import MANIFEST_JSON_SCHEMA
|
||||||
from pre_commit.clientlib.validate_manifest import run
|
from pre_commit.clientlib.validate_manifest import run
|
||||||
|
from testing.util import is_valid_according_to_schema
|
||||||
|
|
||||||
|
|
||||||
def test_returns_0_for_valid_manifest():
|
def test_returns_0_for_valid_manifest():
|
||||||
|
|
@ -34,14 +32,6 @@ def test_additional_manifest_check_languages(obj):
|
||||||
additional_manifest_check(obj)
|
additional_manifest_check(obj)
|
||||||
|
|
||||||
|
|
||||||
def is_valid_according_to_schema(obj, schema):
|
|
||||||
try:
|
|
||||||
jsonschema.validate(obj, schema)
|
|
||||||
return True
|
|
||||||
except jsonschema.exceptions.ValidationError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
@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', 'name': 'b', 'entry': 'c', 'language': 'python'}], True),
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
import pytest
|
import pytest
|
||||||
import sys
|
import sys
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
|
||||||
|
|
@ -81,12 +81,12 @@ 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', '\\.js$')
|
||||||
|
|
||||||
|
|
||||||
@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', '\\.py$')
|
||||||
|
|
||||||
|
|
||||||
@pytest.yield_fixture
|
@pytest.yield_fixture
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from plumbum import local
|
from plumbum import local
|
||||||
|
|
||||||
|
|
@ -38,7 +37,7 @@ def test_get_files_matching_base(get_files_matching_func):
|
||||||
|
|
||||||
|
|
||||||
def test_get_files_matching_total_match(get_files_matching_func):
|
def test_get_files_matching_total_match(get_files_matching_func):
|
||||||
ret = get_files_matching_func('^.*\.py$', '^$')
|
ret = get_files_matching_func('^.*\\.py$', '^$')
|
||||||
assert ret == set([
|
assert ret == set([
|
||||||
'pre_commit/run.py',
|
'pre_commit/run.py',
|
||||||
'pre_commit/git.py',
|
'pre_commit/git.py',
|
||||||
|
|
@ -46,7 +45,7 @@ def test_get_files_matching_total_match(get_files_matching_func):
|
||||||
|
|
||||||
|
|
||||||
def test_does_search_instead_of_match(get_files_matching_func):
|
def test_does_search_instead_of_match(get_files_matching_func):
|
||||||
ret = get_files_matching_func('\.yaml$', '^$')
|
ret = get_files_matching_func('\\.yaml$', '^$')
|
||||||
assert ret == set(['hooks.yaml'])
|
assert ret == set(['hooks.yaml'])
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -56,5 +55,5 @@ def test_does_not_include_deleted_fileS(get_files_matching_func):
|
||||||
|
|
||||||
|
|
||||||
def test_exclude_removes_files(get_files_matching_func):
|
def test_exclude_removes_files(get_files_matching_func):
|
||||||
ret = get_files_matching_func('', '\.py$')
|
ret = get_files_matching_func('', '\\.py$')
|
||||||
assert ret == set(['hooks.yaml'])
|
assert ret == set(['hooks.yaml'])
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
from pre_commit.jsonschema_extensions import apply_defaults
|
from pre_commit.jsonschema_extensions import apply_defaults
|
||||||
from pre_commit.jsonschema_extensions import remove_defaults
|
from pre_commit.jsonschema_extensions import remove_defaults
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from pre_commit.languages.all import all_languages
|
from pre_commit.languages.all import all_languages
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import mock
|
import mock
|
||||||
import pytest
|
import pytest
|
||||||
|
|
@ -94,7 +93,8 @@ def test_path_multiple_args():
|
||||||
assert ret == 'foo/bar/baz'
|
assert ret == 'foo/bar/baz'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(('prefix', 'path_end', 'expected_output'),
|
@pytest.mark.parametrize(
|
||||||
|
('prefix', 'path_end', 'expected_output'),
|
||||||
tuple(
|
tuple(
|
||||||
(prefix, path_end, expected_output + os.sep)
|
(prefix, path_end, expected_output + os.sep)
|
||||||
for prefix, path_end, expected_output in PATH_TESTS
|
for prefix, path_end, expected_output in PATH_TESTS
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ def test_create_repo_in_env(dummy_repo_config, dummy_git_repo):
|
||||||
os.path.join(dummy_git_repo, C.HOOKS_WORKSPACE, repo.sha),
|
os.path.join(dummy_git_repo, C.HOOKS_WORKSPACE, repo.sha),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.integration
|
@pytest.mark.integration
|
||||||
def test_install_python_repo_in_env(config_for_python_hooks_repo):
|
def test_install_python_repo_in_env(config_for_python_hooks_repo):
|
||||||
repo = Repository(config_for_python_hooks_repo)
|
repo = Repository(config_for_python_hooks_repo)
|
||||||
|
|
@ -110,7 +111,7 @@ def mock_repo_config():
|
||||||
'sha': '5e713f8878b7d100c0e059f8cc34be4fc2e8f897',
|
'sha': '5e713f8878b7d100c0e059f8cc34be4fc2e8f897',
|
||||||
'hooks': [{
|
'hooks': [{
|
||||||
'id': 'pyflakes',
|
'id': 'pyflakes',
|
||||||
'files': '\.py$',
|
'files': '\\.py$',
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
config_wrapped = apply_defaults([config], CONFIG_JSON_SCHEMA)
|
config_wrapped = apply_defaults([config], CONFIG_JSON_SCHEMA)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import pytest
|
import pytest
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
import pytest
|
import pytest
|
||||||
import shutil
|
import shutil
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
import pytest
|
import pytest
|
||||||
import os
|
import os
|
||||||
|
|
@ -17,7 +16,7 @@ from pre_commit.util import memoize_by_cwd
|
||||||
def class_with_cached_property():
|
def class_with_cached_property():
|
||||||
class Foo(object):
|
class Foo(object):
|
||||||
@cached_property
|
@cached_property
|
||||||
def foo(self):
|
def my_property(self):
|
||||||
return "Foo" + str(random.getrandbits(64))
|
return "Foo" + str(random.getrandbits(64))
|
||||||
|
|
||||||
return Foo
|
return Foo
|
||||||
|
|
@ -25,14 +24,14 @@ def class_with_cached_property():
|
||||||
|
|
||||||
def test_cached_property(class_with_cached_property):
|
def test_cached_property(class_with_cached_property):
|
||||||
instance = class_with_cached_property()
|
instance = class_with_cached_property()
|
||||||
val = instance.foo
|
val = instance.my_property
|
||||||
val2 = instance.foo
|
val2 = instance.my_property
|
||||||
assert val is val2
|
assert val is val2
|
||||||
|
|
||||||
|
|
||||||
def test_unbound_cached_property(class_with_cached_property):
|
def test_unbound_cached_property(class_with_cached_property):
|
||||||
# Make sure we don't blow up when accessing the property unbound
|
# Make sure we don't blow up when accessing the property unbound
|
||||||
prop = class_with_cached_property.foo
|
prop = class_with_cached_property.my_property
|
||||||
assert isinstance(prop, cached_property)
|
assert isinstance(prop, cached_property)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -90,7 +89,8 @@ def test_no_arguments_passed_uses_argv(entry_func):
|
||||||
|
|
||||||
|
|
||||||
def test_clean_on_failure_noop(in_tmpdir):
|
def test_clean_on_failure_noop(in_tmpdir):
|
||||||
with clean_path_on_failure('foo'): pass
|
with clean_path_on_failure('foo'):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def test_clean_path_on_failure_does_nothing_when_not_raising(in_tmpdir):
|
def test_clean_path_on_failure_does_nothing_when_not_raising(in_tmpdir):
|
||||||
|
|
@ -100,7 +100,8 @@ def test_clean_path_on_failure_does_nothing_when_not_raising(in_tmpdir):
|
||||||
|
|
||||||
|
|
||||||
def test_clean_path_on_failure_cleans_for_normal_exception(in_tmpdir):
|
def test_clean_path_on_failure_cleans_for_normal_exception(in_tmpdir):
|
||||||
class MyException(Exception): pass
|
class MyException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
with pytest.raises(MyException):
|
with pytest.raises(MyException):
|
||||||
with clean_path_on_failure('foo'):
|
with clean_path_on_failure('foo'):
|
||||||
|
|
@ -111,7 +112,8 @@ def test_clean_path_on_failure_cleans_for_normal_exception(in_tmpdir):
|
||||||
|
|
||||||
|
|
||||||
def test_clean_path_on_failure_cleans_for_system_exit(in_tmpdir):
|
def test_clean_path_on_failure_cleans_for_system_exit(in_tmpdir):
|
||||||
class MySystemExit(SystemExit): pass
|
class MySystemExit(SystemExit):
|
||||||
|
pass
|
||||||
|
|
||||||
with pytest.raises(MySystemExit):
|
with pytest.raises(MySystemExit):
|
||||||
with clean_path_on_failure('foo'):
|
with clean_path_on_failure('foo'):
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import pre_commit.constants as C
|
import pre_commit.constants as C
|
||||||
from pre_commit.ordereddict import OrderedDict
|
from pre_commit.ordereddict import OrderedDict
|
||||||
from pre_commit.yaml_extensions import ordered_dump
|
from pre_commit.yaml_extensions import ordered_dump
|
||||||
|
|
|
||||||
28
tox.ini
Normal file
28
tox.ini
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
[tox]
|
||||||
|
project = pre_commit
|
||||||
|
# These should match the travis env list
|
||||||
|
envlist = py26,py27
|
||||||
|
|
||||||
|
[testenv]
|
||||||
|
install_command = pip install --use-wheel {opts} {packages}
|
||||||
|
deps = -rrequirements_dev.txt
|
||||||
|
commands =
|
||||||
|
coverage erase
|
||||||
|
coverage run -m pytest {posargs:tests}
|
||||||
|
coverage report --show-missing --fail-under 90
|
||||||
|
flake8 {[tox]project} tests setup.py
|
||||||
|
# pylint {[tox]project} tests setup.py
|
||||||
|
|
||||||
|
[testenv:venv]
|
||||||
|
envdir = venv-{[tox]project}
|
||||||
|
commands =
|
||||||
|
|
||||||
|
[testenv:docs]
|
||||||
|
deps =
|
||||||
|
{[testenv]deps}
|
||||||
|
sphinx
|
||||||
|
changedir = docs
|
||||||
|
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