diff --git a/.coveragerc b/.coveragerc index 418c1f15..82a7f6c3 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,19 +1,29 @@ +[run] +branch = True +timid = True +source = + . +omit = + .tox/* + /usr/* + */tmp* + setup.py + [report] exclude_lines = - # Don't complain about defensive assertions - raise NotImplementedError - raise AssertionError + # Have to re-enable the standard pragma + \#\s*pragma: no cover - # Don't complain about non-runnable code - if __name__ == .__main__.: + # Don't complain if tests don't hit defensive assertion code: + ^\s*raise AssertionError\b + ^\s*raise NotImplementedError\b + ^\s*return NotImplemented\b + ^\s*raise$ -omit = - /usr/* - py_env/* - */__init__.py + # Don't complain if non-runnable code isn't run: + ^if __name__ == ['"]__main__['"]:$ - # Ignore test coverage - tests/* +[html] +directory = coverage-html - # Don't complain about our pre-commit file - pre-commit.py +# vim:ft=dosini diff --git a/.gitignore b/.gitignore index e20fc65c..3c8c00ad 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,13 @@ -*.pyc -.pydevproject -.pre-commit-files -.project -.coverage -/py_env -*.db -.idea -build -dist *.egg-info *.iml +*.py[co] +.*.sw[a-z] +.coverage +.idea +.pre-commit-files +.project +.pydevproject +.tox +/venv* +coverage-html +dist diff --git a/.travis.yml b/.travis.yml index f5f7a807..d3316a1b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,12 @@ language: python - -python: - - 2.6 - - 2.7 - -install: pip install virtualenv -script: make coverage +env: # These should match the tox env list + - TOXENV=py26 + - TOXENV=py27 +install: pip install tox --use-mirrors +script: tox +# Special snowflake. Our tests depend on making real commits. before_install: - git config --global user.name "Travis CI" - git config --global user.email "user@example.com" diff --git a/Makefile b/Makefile index 08bd8b3c..5eff62ea 100644 --- a/Makefile +++ b/Makefile @@ -1,41 +1,17 @@ +.PHONY: all +all: venv test -TEST_TARGETS = -ITEST_TARGETS = -m integration -UTEST_TARGETS = -m "not(integration)" +.PHONY: venv +venv: + tox -e venv -DEBUG= - -all: _tests - -integration: - $(eval TEST_TARGETS := $(ITEST_TARGETS)) - -unit: - $(eval TEST_TARGETS := $(UTEST_TARGETS)) - -utests: test -utest: test +.PHONY: tests test tests: test -test: unit _tests -itests: itest -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' +test: + tox +.PHONY: clean clean: - rm -rf py_env + find . -iname '*.pyc' | xargs rm -f + rm -rf .tox + rm -rf ./venv-* diff --git a/UNLICENSE b/UNLICENSE new file mode 100644 index 00000000..68a49daa --- /dev/null +++ b/UNLICENSE @@ -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 diff --git a/example_hooks.yaml b/example_hooks.yaml index 05be1940..cb341036 100644 --- a/example_hooks.yaml +++ b/example_hooks.yaml @@ -1,4 +1,3 @@ - # Hooks are set up as follows # - id: hook_id # name: 'Readable name' diff --git a/example_pre-commit-config.yaml b/example_pre-commit-config.yaml index a73564aa..bfaea849 100644 --- a/example_pre-commit-config.yaml +++ b/example_pre-commit-config.yaml @@ -1,4 +1,3 @@ - - repo: git@github.com:pre-commit/pre-commit-hooks sha: cd74dc150c142c3be70b24eaf0b02cae9d235f37 hooks: diff --git a/pre_commit/clientlib/validate_base.py b/pre_commit/clientlib/validate_base.py index 4d33db18..1b8856aa 100644 --- a/pre_commit/clientlib/validate_base.py +++ b/pre_commit/clientlib/validate_base.py @@ -1,4 +1,3 @@ - from __future__ import print_function import argparse diff --git a/pre_commit/clientlib/validate_config.py b/pre_commit/clientlib/validate_config.py index 8019ae0d..53d2e81b 100644 --- a/pre_commit/clientlib/validate_config.py +++ b/pre_commit/clientlib/validate_config.py @@ -1,4 +1,3 @@ - import re 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 -class InvalidConfigError(ValueError): pass +class InvalidConfigError(ValueError): + pass CONFIG_JSON_SCHEMA = { diff --git a/pre_commit/clientlib/validate_manifest.py b/pre_commit/clientlib/validate_manifest.py index d21be1dd..0bfb4a5a 100644 --- a/pre_commit/clientlib/validate_manifest.py +++ b/pre_commit/clientlib/validate_manifest.py @@ -1,4 +1,3 @@ - import sys 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 -class InvalidManifestError(ValueError): pass +class InvalidManifestError(ValueError): + pass MANIFEST_JSON_SCHEMA = { diff --git a/pre_commit/color.py b/pre_commit/color.py index b9808ad4..eaf7d3c3 100644 --- a/pre_commit/color.py +++ b/pre_commit/color.py @@ -1,4 +1,3 @@ - import sys RED = '\033[41m' @@ -8,18 +7,19 @@ TURQUOISE = '\033[46;30m' 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. Args: text - Text to be formatted with color if `use_color` 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 else: return u'{0}{1}{2}'.format(color, text, NORMAL) diff --git a/pre_commit/commands.py b/pre_commit/commands.py index 96847cf3..e43a0878 100644 --- a/pre_commit/commands.py +++ b/pre_commit/commands.py @@ -1,4 +1,3 @@ - from __future__ import print_function import os @@ -42,7 +41,8 @@ def uninstall(runner): return 0 -class RepositoryCannotBeUpdatedError(RuntimeError): pass +class RepositoryCannotBeUpdatedError(RuntimeError): + pass def _update_repository(repo_config): @@ -95,8 +95,8 @@ def autoupdate(runner): print('Updating {0}...'.format(repo_config['repo']), end='') try: new_repo_config = _update_repository(repo_config) - except RepositoryCannotBeUpdatedError as e: - print(e.args[0]) + except RepositoryCannotBeUpdatedError as error: + print(error.args[0]) output_configs.append(repo_config) retv = 1 continue diff --git a/pre_commit/constants.py b/pre_commit/constants.py index 1e9137ba..02c9c2b7 100644 --- a/pre_commit/constants.py +++ b/pre_commit/constants.py @@ -1,4 +1,3 @@ - CONFIG_FILE = '.pre-commit-config.yaml' HOOKS_WORKSPACE = '.pre-commit-files' diff --git a/pre_commit/git.py b/pre_commit/git.py index 692dbc23..6c359b66 100644 --- a/pre_commit/git.py +++ b/pre_commit/git.py @@ -43,14 +43,15 @@ def get_files_matching(all_file_list_strategy): def wrapper(include_expr, exclude_expr): include_regex = re.compile(include_expr) exclude_regex = re.compile(exclude_expr) - return set(filter(os.path.exists, ( + return set( filename for filename in all_file_list_strategy() if ( include_regex.search(filename) and - not exclude_regex.search(filename) + not exclude_regex.search(filename) and + os.path.exists(filename) ) - ))) + ) return wrapper diff --git a/pre_commit/hooks_workspace.py b/pre_commit/hooks_workspace.py index 50c41d3e..c44bebfd 100644 --- a/pre_commit/hooks_workspace.py +++ b/pre_commit/hooks_workspace.py @@ -1,4 +1,3 @@ - import contextlib import os.path from plumbum import local diff --git a/pre_commit/jsonschema_extensions.py b/pre_commit/jsonschema_extensions.py index e9fd68a5..5217843c 100644 --- a/pre_commit/jsonschema_extensions.py +++ b/pre_commit/jsonschema_extensions.py @@ -1,4 +1,3 @@ - import copy import jsonschema import jsonschema.validators @@ -21,7 +20,6 @@ def extend_validator_cls(validator_cls, modify): ) - def default_values(properties, instance): for property, subschema in properties.iteritems(): if 'default' in subschema: diff --git a/pre_commit/languages/all.py b/pre_commit/languages/all.py index 2a4ae1da..27565e42 100644 --- a/pre_commit/languages/all.py +++ b/pre_commit/languages/all.py @@ -1,4 +1,3 @@ - from pre_commit.languages import node from pre_commit.languages import python from pre_commit.languages import ruby diff --git a/pre_commit/languages/python.py b/pre_commit/languages/python.py index db233b51..c7fb518f 100644 --- a/pre_commit/languages/python.py +++ b/pre_commit/languages/python.py @@ -1,4 +1,3 @@ - import contextlib from pre_commit.languages import helpers diff --git a/pre_commit/languages/ruby.py b/pre_commit/languages/ruby.py index 6448bf58..083cd7f7 100644 --- a/pre_commit/languages/ruby.py +++ b/pre_commit/languages/ruby.py @@ -1,4 +1,3 @@ - import contextlib from pre_commit.languages import helpers @@ -11,7 +10,7 @@ ENVIRONMENT_DIR = 'rvm_env' class RubyEnv(helpers.Environment): @property def env_prefix(self): - return '. {{prefix}}{0}/bin/activate &&'.format(ENVIRONMENT_DIR) + raise NotImplementedError @contextlib.contextmanager diff --git a/pre_commit/languages/script.py b/pre_commit/languages/script.py index 626e81c9..9031410e 100644 --- a/pre_commit/languages/script.py +++ b/pre_commit/languages/script.py @@ -1,4 +1,3 @@ - ENVIRONMENT_DIR = None diff --git a/pre_commit/languages/system.py b/pre_commit/languages/system.py index c3848f2b..18f2ca77 100644 --- a/pre_commit/languages/system.py +++ b/pre_commit/languages/system.py @@ -1,4 +1,3 @@ - ENVIRONMENT_DIR = None diff --git a/pre_commit/logging_handler.py b/pre_commit/logging_handler.py index 70b61e73..1d3fdca0 100644 --- a/pre_commit/logging_handler.py +++ b/pre_commit/logging_handler.py @@ -1,4 +1,3 @@ - from __future__ import print_function import logging diff --git a/pre_commit/prefixed_command_runner.py b/pre_commit/prefixed_command_runner.py index ed88f219..91bb474a 100644 --- a/pre_commit/prefixed_command_runner.py +++ b/pre_commit/prefixed_command_runner.py @@ -1,4 +1,3 @@ - import os import os.path import subprocess diff --git a/pre_commit/repository.py b/pre_commit/repository.py index a8611f79..dd5faadb 100644 --- a/pre_commit/repository.py +++ b/pre_commit/repository.py @@ -1,4 +1,3 @@ - import contextlib import logging from plumbum import local diff --git a/pre_commit/run.py b/pre_commit/run.py index 17aa2aa9..dc88e368 100644 --- a/pre_commit/run.py +++ b/pre_commit/run.py @@ -1,4 +1,3 @@ - from __future__ import print_function import argparse @@ -56,7 +55,6 @@ def _run_single_hook(runner, repository, hook_id, args): print_color = color.GREEN pass_fail = 'Passed' - print(color.format_color(pass_fail, print_color, args.color)) if output and (retcode or args.verbose): @@ -111,14 +109,14 @@ def run(argv): subparsers.add_parser('autoupdate', help='Auto-update hooks config.') - run = subparsers.add_parser('run', help='Run hooks.') - run.add_argument('hook', nargs='?', help='A single hook-id to run'), - run.add_argument( + run_parser = subparsers.add_parser('run', help='Run hooks.') + run_parser.add_argument('hook', nargs='?', help='A single hook-id to run') + run_parser.add_argument( '--all-files', '-a', action='store_true', default=False, help='Run on all the files in the repo.', ) - run.add_argument('--verbose', '-v', action='store_true', default=False) - run.add_argument( + run_parser.add_argument('--verbose', '-v', action='store_true', default=False) + run_parser.add_argument( '--color', default='auto', type=color.use_color, help='Whether to use color in output. Defaults to `auto`', ) diff --git a/pre_commit/runner.py b/pre_commit/runner.py index 93507f22..1787164c 100644 --- a/pre_commit/runner.py +++ b/pre_commit/runner.py @@ -1,4 +1,3 @@ - import os import os.path @@ -40,7 +39,7 @@ class Runner(object): def repositories(self): """Returns a tuple of the configured repositories.""" config = load_config(self.config_file_path) - return tuple(map(Repository, config)) + return tuple(Repository(x) for x in config) @cached_property def pre_commit_path(self): diff --git a/pre_commit/staged_files_only.py b/pre_commit/staged_files_only.py index 8a38ae11..f3e34829 100644 --- a/pre_commit/staged_files_only.py +++ b/pre_commit/staged_files_only.py @@ -1,4 +1,3 @@ - import contextlib import logging import time diff --git a/pre_commit/util.py b/pre_commit/util.py index 3599d0b4..fb4a8764 100644 --- a/pre_commit/util.py +++ b/pre_commit/util.py @@ -1,4 +1,3 @@ - import contextlib import functools import os diff --git a/pre_commit/yaml_extensions.py b/pre_commit/yaml_extensions.py index af19a646..2b9cd6ee 100644 --- a/pre_commit/yaml_extensions.py +++ b/pre_commit/yaml_extensions.py @@ -1,4 +1,3 @@ - import yaml from pre_commit.ordereddict import OrderedDict @@ -6,23 +5,27 @@ from pre_commit.ordereddict import OrderedDict # Adapted from http://stackoverflow.com/a/21912744/812183 -def ordered_load(s): - class OrderedLoader(yaml.loader.Loader): pass +def ordered_load(stream): + class OrderedLoader(yaml.loader.Loader): + pass + def constructor(loader, node): return OrderedDict(loader.construct_pairs(node)) OrderedLoader.add_constructor( yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, constructor, ) - return yaml.load(s, Loader=OrderedLoader) + return yaml.load(stream, Loader=OrderedLoader) -def ordered_dump(s, **kwargs): - class OrderedDumper(yaml.dumper.SafeDumper): pass +def ordered_dump(obj, **kwargs): + class OrderedDumper(yaml.dumper.SafeDumper): + pass + def dict_representer(dumper, data): return dumper.represent_mapping( yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, data.items(), ) OrderedDumper.add_representer(OrderedDict, dict_representer) - return yaml.dump(s, Dumper=OrderedDumper, **kwargs) + return yaml.dump(obj, Dumper=OrderedDumper, **kwargs) diff --git a/pylintrc b/pylintrc new file mode 100644 index 00000000..f82bfd76 --- /dev/null +++ b/pylintrc @@ -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 + diff --git a/requirements.txt b/requirements.txt index 05941327..9c558e35 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1 @@ --e . - -# Testing requirements -coverage -# Fuck you ipython -ipython<2.0.0 -ipdb -mock -pyflakes -pytest +. diff --git a/requirements_dev.txt b/requirements_dev.txt new file mode 100644 index 00000000..0d448cab --- /dev/null +++ b/requirements_dev.txt @@ -0,0 +1,7 @@ +-e . + +coverage +flake8 +mock +pylint +pytest diff --git a/setup.py b/setup.py index 54a12168..c284d317 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,20 @@ if sys.version_info < (2, 7): setup( 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', + + 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*')), package_data={ 'pre_commit': [ diff --git a/testing/auto_namedtuple.py b/testing/auto_namedtuple.py index cd0c30a6..b585e6da 100644 --- a/testing/auto_namedtuple.py +++ b/testing/auto_namedtuple.py @@ -1,4 +1,3 @@ - import collections def auto_namedtuple(classname='auto_namedtuple', **kwargs): diff --git a/testing/resources/valid_yaml_but_invalid_config.yaml b/testing/resources/valid_yaml_but_invalid_config.yaml index e3258d80..81ccd6a6 100644 --- a/testing/resources/valid_yaml_but_invalid_config.yaml +++ b/testing/resources/valid_yaml_but_invalid_config.yaml @@ -1,4 +1,3 @@ - - repo: git@github.com:pre-commit/pre-commit-hooks hooks: - id: pyflakes diff --git a/testing/util.py b/testing/util.py index 4e5acf77..90459952 100644 --- a/testing/util.py +++ b/testing/util.py @@ -1,4 +1,4 @@ - +import jsonschema import os import os.path import shutil @@ -27,3 +27,10 @@ def copy_tree_to_path(src_dir, dest_dir): shutil.copytree(srcname, destname) else: 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 diff --git a/tests/clientlib/validate_base_test.py b/tests/clientlib/validate_base_test.py index 4957457d..abd727ad 100644 --- a/tests/clientlib/validate_base_test.py +++ b/tests/clientlib/validate_base_test.py @@ -1,4 +1,3 @@ - import pytest 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 -class AdditionalValidatorError(ValueError): pass +class AdditionalValidatorError(ValueError): + pass @pytest.fixture @@ -22,7 +22,7 @@ def array_validator(): @pytest.fixture def additional_validator(): - def raises_always(obj): + def raises_always(_): raise AdditionalValidatorError return get_validator( diff --git a/tests/clientlib/validate_config_test.py b/tests/clientlib/validate_config_test.py index f3ccc4df..581e3827 100644 --- a/tests/clientlib/validate_config_test.py +++ b/tests/clientlib/validate_config_test.py @@ -1,6 +1,3 @@ - -import jsonschema -import jsonschema.exceptions import pytest 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 validate_config_extra from pre_commit.jsonschema_extensions import apply_defaults +from testing.util import is_valid_according_to_schema 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 -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'), ( ([], False), ( [{ - 'repo': 'git@github.com:pre-commit/pre-commit-hooks', - 'sha': 'cd74dc150c142c3be70b24eaf0b02cae9d235f37', - 'hooks': [{'id': 'pyflakes', 'files': '\.py$'}], + 'repo': 'git@github.com:pre-commit/pre-commit-hooks', + 'sha': 'cd74dc150c142c3be70b24eaf0b02cae9d235f37', + 'hooks': [{'id': 'pyflakes', 'files': '\\.py$'}], }], True, ), @@ -47,7 +37,7 @@ def is_valid_according_to_schema(obj, schema): 'hooks': [ { 'id': 'pyflakes', - 'files': '\.py$', + 'files': '\\.py$', 'args': ['foo', 'bar', 'baz'], }, ], @@ -61,7 +51,7 @@ def is_valid_according_to_schema(obj, schema): 'hooks': [ { 'id': 'pyflakes', - 'files': '\.py$', + 'files': '\\.py$', # Exclude pattern must be a string 'exclude': 0, 'args': ['foo', 'bar', 'baz'], @@ -95,7 +85,7 @@ def test_config_with_ok_regexes_passes(): [{ 'repo': 'foo', 'sha': 'foo', - 'hooks': [{'id': 'hook_id', 'files': '\.py$'}], + 'hooks': [{'id': 'hook_id', 'files': '\\.py$'}], }], CONFIG_JSON_SCHEMA, ) diff --git a/tests/clientlib/validate_manifest_test.py b/tests/clientlib/validate_manifest_test.py index a1c10580..d8d5b180 100644 --- a/tests/clientlib/validate_manifest_test.py +++ b/tests/clientlib/validate_manifest_test.py @@ -1,12 +1,10 @@ - -import jsonschema -import jsonschema.exceptions import pytest 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 MANIFEST_JSON_SCHEMA from pre_commit.clientlib.validate_manifest import run +from testing.util import is_valid_according_to_schema def test_returns_0_for_valid_manifest(): @@ -34,24 +32,16 @@ def test_additional_manifest_check_languages(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'), ( ([], False), ([{'id': 'a', 'name': 'b', 'entry': 'c', 'language': 'python'}], True), ( [{ - 'id': 'a', - 'name': 'b', - 'entry': 'c', - 'language': 'python', - 'expected_return_value': 0, + 'id': 'a', + 'name': 'b', + 'entry': 'c', + 'language': 'python', + 'expected_return_value': 0, }], True, ), diff --git a/tests/color_test.py b/tests/color_test.py index 44d9b170..0897793e 100644 --- a/tests/color_test.py +++ b/tests/color_test.py @@ -1,4 +1,3 @@ - import mock import pytest import sys diff --git a/tests/commands_test.py b/tests/commands_test.py index 5f61845e..e5b44e98 100644 --- a/tests/commands_test.py +++ b/tests/commands_test.py @@ -1,4 +1,3 @@ - import os import os.path import pkg_resources diff --git a/tests/conftest.py b/tests/conftest.py index 4a81830f..6c0ee1e0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -81,12 +81,12 @@ def _make_config(path, hook_id, file_regex): @pytest.yield_fixture 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 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 diff --git a/tests/git_test.py b/tests/git_test.py index a6ecc574..4dd01f99 100644 --- a/tests/git_test.py +++ b/tests/git_test.py @@ -1,4 +1,3 @@ - import pytest 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): - ret = get_files_matching_func('^.*\.py$', '^$') + ret = get_files_matching_func('^.*\\.py$', '^$') assert ret == set([ 'pre_commit/run.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): - ret = get_files_matching_func('\.yaml$', '^$') + ret = get_files_matching_func('\\.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): - ret = get_files_matching_func('', '\.py$') + ret = get_files_matching_func('', '\\.py$') assert ret == set(['hooks.yaml']) diff --git a/tests/jsonschema_extensions_test.py b/tests/jsonschema_extensions_test.py index c3da64c9..5680a333 100644 --- a/tests/jsonschema_extensions_test.py +++ b/tests/jsonschema_extensions_test.py @@ -1,4 +1,3 @@ - from pre_commit.jsonschema_extensions import apply_defaults from pre_commit.jsonschema_extensions import remove_defaults diff --git a/tests/languages/all_test.py b/tests/languages/all_test.py index 91e252a8..aeba7cc1 100644 --- a/tests/languages/all_test.py +++ b/tests/languages/all_test.py @@ -1,4 +1,3 @@ - import pytest from pre_commit.languages.all import all_languages diff --git a/tests/prefixed_command_runner_test.py b/tests/prefixed_command_runner_test.py index a6cee09d..07745a41 100644 --- a/tests/prefixed_command_runner_test.py +++ b/tests/prefixed_command_runner_test.py @@ -1,4 +1,3 @@ - import os import mock import pytest @@ -94,7 +93,8 @@ def test_path_multiple_args(): assert ret == 'foo/bar/baz' -@pytest.mark.parametrize(('prefix', 'path_end', 'expected_output'), +@pytest.mark.parametrize( + ('prefix', 'path_end', 'expected_output'), tuple( (prefix, path_end, expected_output + os.sep) for prefix, path_end, expected_output in PATH_TESTS diff --git a/tests/repository_test.py b/tests/repository_test.py index eb840c2c..7079e301 100644 --- a/tests/repository_test.py +++ b/tests/repository_test.py @@ -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), ) + @pytest.mark.integration def test_install_python_repo_in_env(config_for_python_hooks_repo): repo = Repository(config_for_python_hooks_repo) @@ -110,7 +111,7 @@ def mock_repo_config(): 'sha': '5e713f8878b7d100c0e059f8cc34be4fc2e8f897', 'hooks': [{ 'id': 'pyflakes', - 'files': '\.py$', + 'files': '\\.py$', }], } config_wrapped = apply_defaults([config], CONFIG_JSON_SCHEMA) diff --git a/tests/runner_test.py b/tests/runner_test.py index e6138df1..4bc50e7f 100644 --- a/tests/runner_test.py +++ b/tests/runner_test.py @@ -1,4 +1,3 @@ - import os import os.path import pytest diff --git a/tests/staged_files_only_test.py b/tests/staged_files_only_test.py index ebada7f1..065c73df 100644 --- a/tests/staged_files_only_test.py +++ b/tests/staged_files_only_test.py @@ -1,4 +1,3 @@ - import os.path import pytest import shutil diff --git a/tests/util_test.py b/tests/util_test.py index fe0170e9..10f22935 100644 --- a/tests/util_test.py +++ b/tests/util_test.py @@ -1,4 +1,3 @@ - import mock import pytest import os @@ -17,7 +16,7 @@ from pre_commit.util import memoize_by_cwd def class_with_cached_property(): class Foo(object): @cached_property - def foo(self): + def my_property(self): return "Foo" + str(random.getrandbits(64)) return Foo @@ -25,14 +24,14 @@ def class_with_cached_property(): def test_cached_property(class_with_cached_property): instance = class_with_cached_property() - val = instance.foo - val2 = instance.foo + val = instance.my_property + val2 = instance.my_property assert val is val2 def test_unbound_cached_property(class_with_cached_property): # 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) @@ -90,7 +89,8 @@ def test_no_arguments_passed_uses_argv(entry_func): 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): @@ -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): - class MyException(Exception): pass + class MyException(Exception): + pass with pytest.raises(MyException): 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): - class MySystemExit(SystemExit): pass + class MySystemExit(SystemExit): + pass with pytest.raises(MySystemExit): with clean_path_on_failure('foo'): diff --git a/tests/yaml_extensions_test.py b/tests/yaml_extensions_test.py index 098d9300..0559c878 100644 --- a/tests/yaml_extensions_test.py +++ b/tests/yaml_extensions_test.py @@ -1,4 +1,3 @@ - import pre_commit.constants as C from pre_commit.ordereddict import OrderedDict from pre_commit.yaml_extensions import ordered_dump diff --git a/tox.ini b/tox.ini new file mode 100644 index 00000000..8f29214f --- /dev/null +++ b/tox.ini @@ -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