summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--.pre-commit-config.yaml10
-rw-r--r--CHANGELOG.md33
-rw-r--r--azure-pipelines.yml4
-rw-r--r--pre_commit/clientlib.py47
-rw-r--r--pre_commit/commands/install_uninstall.py32
-rw-r--r--pre_commit/commands/run.py3
-rw-r--r--pre_commit/error_handler.py5
-rw-r--r--pre_commit/languages/all.py2
-rw-r--r--pre_commit/languages/conda.py15
-rw-r--r--pre_commit/languages/golang.py6
-rw-r--r--pre_commit/languages/lua.py90
-rw-r--r--pre_commit/languages/r.py11
-rw-r--r--pre_commit/resources/empty_template_pre-commit-package-dev-1.rockspec12
-rw-r--r--pre_commit/resources/rbenv.tar.gzbin32678 -> 32551 bytes
-rw-r--r--pre_commit/resources/ruby-build.tar.gzbin68689 -> 71151 bytes
-rw-r--r--pre_commit/store.py3
-rw-r--r--requirements-dev.txt2
-rw-r--r--setup.cfg2
-rwxr-xr-xtesting/gen-languages-all2
-rwxr-xr-xtesting/get-lua.sh5
-rwxr-xr-xtesting/make-archives4
-rw-r--r--testing/resources/docker_hooks_repo/Dockerfile2
-rw-r--r--testing/resources/docker_image_hooks_repo/.pre-commit-hooks.yaml4
-rw-r--r--testing/resources/lua_repo/.pre-commit-hooks.yaml4
-rwxr-xr-xtesting/resources/lua_repo/bin/hello-world-lua3
-rw-r--r--testing/resources/lua_repo/hello-dev-1.rockspec15
-rw-r--r--testing/util.py4
-rwxr-xr-xtesting/zipapp/make2
-rw-r--r--tests/clientlib_test.py17
-rw-r--r--tests/commands/install_uninstall_test.py43
-rw-r--r--tests/error_handler_test.py1
-rw-r--r--tests/languages/conda_test.py38
-rw-r--r--tests/languages/helpers_test.py4
-rw-r--r--tests/repository_test.py27
34 files changed, 336 insertions, 116 deletions
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 49517c3..66b50a4 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.0.1
+ rev: v4.1.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
@@ -17,15 +17,15 @@ repos:
- id: flake8
additional_dependencies: [flake8-typing-imports==1.10.0]
- repo: https://github.com/pre-commit/mirrors-autopep8
- rev: v1.5.7
+ rev: v1.6.0
hooks:
- id: autopep8
- repo: https://github.com/pre-commit/pre-commit
- rev: v2.16.0
+ rev: v2.17.0
hooks:
- id: validate_manifest
- repo: https://github.com/asottile/pyupgrade
- rev: v2.29.1
+ rev: v2.31.0
hooks:
- id: pyupgrade
args: [--py36-plus]
@@ -44,7 +44,7 @@ repos:
hooks:
- id: setup-cfg-fmt
- repo: https://github.com/pre-commit/mirrors-mypy
- rev: v0.910-1
+ rev: v0.931
hooks:
- id: mypy
additional_dependencies: [types-all]
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 55f46d9..d0cccc6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,36 @@
+2.17.0 - 2022-01-18
+===================
+
+### Features
+- add warnings for regexes containing `[\\/]`.
+ - #2151 issue by @sanjioh.
+ - #2154 PR by @kuviokelluja.
+- upgrade supported ruby versions.
+ - #2205 PR by @jalessio.
+- allow `language: conda` to use `mamba` or `micromamba` via
+ `PRE_COMMIT_USE_MAMBA=1` or `PRE_COMMIT_USE_MICROMAMBA=1` respectively.
+ - #2204 issue by @janjagusch.
+ - #2207 PR by @xhochy.
+- display `git --version` in error report.
+ - #2210 PR by @asottile.
+- add `language: lua` as a supported language.
+ - #2158 PR by @mblayman.
+
+### Fixes
+- temporarily add `setuptools` to the zipapp.
+ - #2122 issue by @andreoliwa.
+ - a737d5f commit by @asottile.
+- use `go install` instead of `go get` for go 1.18+ support.
+ - #2161 PR by @schmir.
+- fix `language: r` with a local renv and `RENV_PROJECT` set.
+ - #2170 PR by @lorenzwalthert.
+- forbid overriding `entry` in `language: meta` hooks which breaks them.
+ - #2180 issue by @DanKaplanSES.
+ - #2181 PR by @asottile.
+- always use `#!/bin/sh` on windows for hook script.
+ - #2182 issue by @hushigome-visco.
+ - #2187 PR by @asottile.
+
2.16.0 - 2021-11-30
===================
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index a468e8a..d8cbd11 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -42,6 +42,8 @@ jobs:
displayName: install coursier
- bash: testing/get-dart.sh
displayName: install dart
+ - bash: testing/get-lua.sh
+ displayName: install lua
- bash: testing/get-swift.sh
displayName: install swift
- bash: testing/get-r.sh
@@ -56,6 +58,8 @@ jobs:
displayName: install coursier
- bash: testing/get-dart.sh
displayName: install dart
+ - bash: testing/get-lua.sh
+ displayName: install lua
- bash: testing/get-swift.sh
displayName: install swift
- bash: testing/get-r.sh
diff --git a/pre_commit/clientlib.py b/pre_commit/clientlib.py
index 6377a8b..47ebd54 100644
--- a/pre_commit/clientlib.py
+++ b/pre_commit/clientlib.py
@@ -144,18 +144,13 @@ class OptionalSensibleRegexAtHook(cfgv.OptionalNoDefault):
f"regex, not a glob -- matching '/*' probably isn't what you "
f'want here',
)
- if r'[\/]' in dct.get(self.key, ''):
- logger.warning(
- fr'pre-commit normalizes slashes in the {self.key!r} field '
- fr'in hook {dct.get("id")!r} to forward slashes, so you '
- fr'can use / instead of [\/]',
- )
- if r'[/\\]' in dct.get(self.key, ''):
- logger.warning(
- fr'pre-commit normalizes slashes in the {self.key!r} field '
- fr'in hook {dct.get("id")!r} to forward slashes, so you '
- fr'can use / instead of [/\\]',
- )
+ for fwd_slash_re in (r'[\\/]', r'[\/]', r'[/\\]'):
+ if fwd_slash_re in dct.get(self.key, ''):
+ logger.warning(
+ fr'pre-commit normalizes slashes in the {self.key!r} '
+ fr'field in hook {dct.get("id")!r} to forward slashes, '
+ fr'so you can use / instead of {fwd_slash_re}',
+ )
class OptionalSensibleRegexAtTop(cfgv.OptionalNoDefault):
@@ -167,18 +162,13 @@ class OptionalSensibleRegexAtTop(cfgv.OptionalNoDefault):
f'The top-level {self.key!r} field is a regex, not a glob -- '
f"matching '/*' probably isn't what you want here",
)
- if r'[\/]' in dct.get(self.key, ''):
- logger.warning(
- fr'pre-commit normalizes the slashes in the top-level '
- fr'{self.key!r} field to forward slashes, so you can use / '
- fr'instead of [\/]',
- )
- if r'[/\\]' in dct.get(self.key, ''):
- logger.warning(
- fr'pre-commit normalizes the slashes in the top-level '
- fr'{self.key!r} field to forward slashes, so you can use / '
- fr'instead of [/\\]',
- )
+ for fwd_slash_re in (r'[\\/]', r'[\/]', r'[/\\]'):
+ if fwd_slash_re in dct.get(self.key, ''):
+ logger.warning(
+ fr'pre-commit normalizes the slashes in the top-level '
+ fr'{self.key!r} field to forward slashes, so you '
+ fr'can use / instead of {fwd_slash_re}',
+ )
class MigrateShaToRev:
@@ -261,12 +251,21 @@ _meta = (
),
)
+
+class NotAllowed(cfgv.OptionalNoDefault):
+ def check(self, dct: Dict[str, Any]) -> None:
+ if self.key in dct:
+ raise cfgv.ValidationError(f'{self.key!r} cannot be overridden')
+
+
META_HOOK_DICT = cfgv.Map(
'Hook', 'id',
cfgv.Required('id', cfgv.check_string),
cfgv.Required('id', cfgv.check_one_of(tuple(k for k, _ in _meta))),
# language must be system
cfgv.Optional('language', cfgv.check_one_of({'system'}), 'system'),
+ # entry cannot be overridden
+ NotAllowed('entry', cfgv.check_any),
*(
# default to the hook definition for the meta hooks
cfgv.ConditionalOptional(key, cfgv.check_any, value, 'id', hook_id)
diff --git a/pre_commit/commands/install_uninstall.py b/pre_commit/commands/install_uninstall.py
index 7974423..50c6443 100644
--- a/pre_commit/commands/install_uninstall.py
+++ b/pre_commit/commands/install_uninstall.py
@@ -1,4 +1,3 @@
-import itertools
import logging
import os.path
import shlex
@@ -31,10 +30,6 @@ PRIOR_HASHES = (
CURRENT_HASH = b'138fd403232d2ddd5efb44317e38bf03'
TEMPLATE_START = '# start templated\n'
TEMPLATE_END = '# end templated\n'
-# Homebrew/homebrew-core#35825: be more timid about appropriate `PATH`
-# #1312 os.defpath is too restrictive on BSD
-POSIX_SEARCH_PATH = ('/usr/local/bin', '/usr/bin', '/bin')
-SYS_EXE = os.path.basename(os.path.realpath(sys.executable))
def _hook_paths(
@@ -54,26 +49,6 @@ def is_our_script(filename: str) -> bool:
return any(h in contents for h in (CURRENT_HASH,) + PRIOR_HASHES)
-def shebang() -> str:
- if sys.platform == 'win32':
- py, _ = os.path.splitext(SYS_EXE)
- else:
- exe_choices = [
- f'python{sys.version_info[0]}.{sys.version_info[1]}',
- f'python{sys.version_info[0]}',
- ]
- # avoid searching for bare `python` as it's likely to be python 2
- if SYS_EXE != 'python':
- exe_choices.append(SYS_EXE)
- for path, exe in itertools.product(POSIX_SEARCH_PATH, exe_choices):
- if os.access(os.path.join(path, exe), os.X_OK):
- py = exe
- break
- else:
- py = SYS_EXE
- return f'#!/usr/bin/env {py}'
-
-
def _install_hook_script(
config_file: str,
hook_type: str,
@@ -107,6 +82,13 @@ def _install_hook_script(
before, rest = contents.split(TEMPLATE_START)
_, after = rest.split(TEMPLATE_END)
+ # on windows always use `/bin/sh` since `bash` might not be on PATH
+ # though we use bash-specific features `sh` on windows is actually
+ # bash in "POSIXLY_CORRECT" mode which still supports the features we
+ # use: subshells / arrays
+ if sys.platform == 'win32': # pragma: win32 cover
+ hook_file.write('#!/bin/sh\n')
+
hook_file.write(before + TEMPLATE_START)
hook_file.write(f'INSTALL_PYTHON={shlex.quote(sys.executable)}\n')
# TODO: python3.8+: shlex.join
diff --git a/pre_commit/commands/run.py b/pre_commit/commands/run.py
index 2714faf..f8ced0f 100644
--- a/pre_commit/commands/run.py
+++ b/pre_commit/commands/run.py
@@ -275,7 +275,6 @@ def _run_hooks(
hooks: Sequence[Hook],
skips: Set[str],
args: argparse.Namespace,
- environ: MutableMapping[str, str],
) -> int:
"""Actually run the hooks."""
cols = _compute_cols(hooks)
@@ -416,7 +415,7 @@ def run(
to_install = [hook for hook in hooks if hook.id not in skips]
install_hook_envs(to_install, store)
- return _run_hooks(config, hooks, skips, args, environ)
+ return _run_hooks(config, hooks, skips, args)
# https://github.com/python/mypy/issues/7726
raise AssertionError('unreachable')
diff --git a/pre_commit/error_handler.py b/pre_commit/error_handler.py
index 023dd35..7e74b95 100644
--- a/pre_commit/error_handler.py
+++ b/pre_commit/error_handler.py
@@ -9,6 +9,7 @@ import pre_commit.constants as C
from pre_commit import output
from pre_commit.errors import FatalError
from pre_commit.store import Store
+from pre_commit.util import cmd_output_b
from pre_commit.util import force_bytes
@@ -21,6 +22,9 @@ def _log_and_exit(
error_msg = f'{msg}: {type(exc).__name__}: '.encode() + force_bytes(exc)
output.write_line_b(error_msg)
+ _, git_version_b, _ = cmd_output_b('git', '--version', retcode=None)
+ git_version = git_version_b.decode(errors='backslashreplace').rstrip()
+
storedir = Store().directory
log_path = os.path.join(storedir, 'pre-commit.log')
with contextlib.ExitStack() as ctx:
@@ -38,6 +42,7 @@ def _log_and_exit(
_log_line()
_log_line('```')
_log_line(f'pre-commit version: {C.VERSION}')
+ _log_line(f'git --version: {git_version}')
_log_line('sys.version:')
for line in sys.version.splitlines():
_log_line(f' {line}')
diff --git a/pre_commit/languages/all.py b/pre_commit/languages/all.py
index d8a364c..0bcedd6 100644
--- a/pre_commit/languages/all.py
+++ b/pre_commit/languages/all.py
@@ -13,6 +13,7 @@ from pre_commit.languages import docker_image
from pre_commit.languages import dotnet
from pre_commit.languages import fail
from pre_commit.languages import golang
+from pre_commit.languages import lua
from pre_commit.languages import node
from pre_commit.languages import perl
from pre_commit.languages import pygrep
@@ -51,6 +52,7 @@ languages = {
'dotnet': Language(name='dotnet', ENVIRONMENT_DIR=dotnet.ENVIRONMENT_DIR, get_default_version=dotnet.get_default_version, healthy=dotnet.healthy, install_environment=dotnet.install_environment, run_hook=dotnet.run_hook), # noqa: E501
'fail': Language(name='fail', ENVIRONMENT_DIR=fail.ENVIRONMENT_DIR, get_default_version=fail.get_default_version, healthy=fail.healthy, install_environment=fail.install_environment, run_hook=fail.run_hook), # noqa: E501
'golang': Language(name='golang', ENVIRONMENT_DIR=golang.ENVIRONMENT_DIR, get_default_version=golang.get_default_version, healthy=golang.healthy, install_environment=golang.install_environment, run_hook=golang.run_hook), # noqa: E501
+ 'lua': Language(name='lua', ENVIRONMENT_DIR=lua.ENVIRONMENT_DIR, get_default_version=lua.get_default_version, healthy=lua.healthy, install_environment=lua.install_environment, run_hook=lua.run_hook), # noqa: E501
'node': Language(name='node', ENVIRONMENT_DIR=node.ENVIRONMENT_DIR, get_default_version=node.get_default_version, healthy=node.healthy, install_environment=node.install_environment, run_hook=node.run_hook), # noqa: E501
'perl': Language(name='perl', ENVIRONMENT_DIR=perl.ENVIRONMENT_DIR, get_default_version=perl.get_default_version, healthy=perl.healthy, install_environment=perl.install_environment, run_hook=perl.run_hook), # noqa: E501
'pygrep': Language(name='pygrep', ENVIRONMENT_DIR=pygrep.ENVIRONMENT_DIR, get_default_version=pygrep.get_default_version, healthy=pygrep.healthy, install_environment=pygrep.install_environment, run_hook=pygrep.run_hook), # noqa: E501
diff --git a/pre_commit/languages/conda.py b/pre_commit/languages/conda.py
index d634e49..97e2f69 100644
--- a/pre_commit/languages/conda.py
+++ b/pre_commit/languages/conda.py
@@ -50,6 +50,15 @@ def in_env(
yield
+def _conda_exe() -> str:
+ if os.environ.get('PRE_COMMIT_USE_MICROMAMBA'):
+ return 'micromamba'
+ elif os.environ.get('PRE_COMMIT_USE_MAMBA'):
+ return 'mamba'
+ else:
+ return 'conda'
+
+
def install_environment(
prefix: Prefix,
version: str,
@@ -58,15 +67,17 @@ def install_environment(
helpers.assert_version_default('conda', version)
directory = helpers.environment_dir(ENVIRONMENT_DIR, version)
+ conda_exe = _conda_exe()
+
env_dir = prefix.path(directory)
with clean_path_on_failure(env_dir):
cmd_output_b(
- 'conda', 'env', 'create', '-p', env_dir, '--file',
+ conda_exe, 'env', 'create', '-p', env_dir, '--file',
'environment.yml', cwd=prefix.prefix_dir,
)
if additional_dependencies:
cmd_output_b(
- 'conda', 'install', '-p', env_dir, *additional_dependencies,
+ conda_exe, 'install', '-p', env_dir, *additional_dependencies,
cwd=prefix.prefix_dir,
)
diff --git a/pre_commit/languages/golang.py b/pre_commit/languages/golang.py
index d6165d9..10ebc62 100644
--- a/pre_commit/languages/golang.py
+++ b/pre_commit/languages/golang.py
@@ -79,9 +79,11 @@ def install_environment(
gopath = directory
env = dict(os.environ, GOPATH=gopath)
env.pop('GOBIN', None)
- cmd_output_b('go', 'get', './...', cwd=repo_src_dir, env=env)
+ cmd_output_b('go', 'install', './...', cwd=repo_src_dir, env=env)
for dependency in additional_dependencies:
- cmd_output_b('go', 'get', dependency, cwd=repo_src_dir, env=env)
+ cmd_output_b(
+ 'go', 'install', dependency, cwd=repo_src_dir, env=env,
+ )
# Same some disk space, we don't need these after installation
rmtree(prefix.path(directory, 'src'))
pkgdir = prefix.path(directory, 'pkg')
diff --git a/pre_commit/languages/lua.py b/pre_commit/languages/lua.py
new file mode 100644
index 0000000..f699937
--- /dev/null
+++ b/pre_commit/languages/lua.py
@@ -0,0 +1,90 @@
+import contextlib
+import os
+import sys
+from typing import Generator
+from typing import Sequence
+from typing import Tuple
+
+import pre_commit.constants as C
+from pre_commit.envcontext import envcontext
+from pre_commit.envcontext import PatchesT
+from pre_commit.envcontext import Var
+from pre_commit.hook import Hook
+from pre_commit.languages import helpers
+from pre_commit.prefix import Prefix
+from pre_commit.util import clean_path_on_failure
+from pre_commit.util import cmd_output
+
+ENVIRONMENT_DIR = 'lua_env'
+get_default_version = helpers.basic_get_default_version
+healthy = helpers.basic_healthy
+
+
+def _get_lua_version() -> str: # pragma: win32 no cover
+ """Get the Lua version used in file paths."""
+ _, stdout, _ = cmd_output('luarocks', 'config', '--lua-ver')
+ return stdout.strip()
+
+
+def get_env_patch(d: str) -> PatchesT: # pragma: win32 no cover
+ version = _get_lua_version()
+ so_ext = 'dll' if sys.platform == 'win32' else 'so'
+ return (
+ ('PATH', (os.path.join(d, 'bin'), os.pathsep, Var('PATH'))),
+ (
+ 'LUA_PATH', (
+ os.path.join(d, 'share', 'lua', version, '?.lua;'),
+ os.path.join(d, 'share', 'lua', version, '?', 'init.lua;;'),
+ ),
+ ),
+ (
+ 'LUA_CPATH',
+ (os.path.join(d, 'lib', 'lua', version, f'?.{so_ext};;'),),
+ ),
+ )
+
+
+def _envdir(prefix: Prefix) -> str: # pragma: win32 no cover
+ directory = helpers.environment_dir(ENVIRONMENT_DIR, C.DEFAULT)
+ return prefix.path(directory)
+
+
+@contextlib.contextmanager # pragma: win32 no cover
+def in_env(prefix: Prefix) -> Generator[None, None, None]:
+ with envcontext(get_env_patch(_envdir(prefix))):
+ yield
+
+
+def install_environment(
+ prefix: Prefix,
+ version: str,
+ additional_dependencies: Sequence[str],
+) -> None: # pragma: win32 no cover
+ helpers.assert_version_default('lua', version)
+
+ envdir = _envdir(prefix)
+ with clean_path_on_failure(envdir):
+ with in_env(prefix):
+ # luarocks doesn't bootstrap a tree prior to installing
+ # so ensure the directory exists.
+ os.makedirs(envdir, exist_ok=True)
+
+ # Older luarocks (e.g., 2.4.2) expect the rockspec as an arg
+ for rockspec in prefix.star('.rockspec'):
+ make_cmd = ('luarocks', '--tree', envdir, 'make', rockspec)
+ helpers.run_setup_cmd(prefix, make_cmd)
+
+ # luarocks can't install multiple packages at once
+ # so install them individually.
+ for dependency in additional_dependencies:
+ cmd = ('luarocks', '--tree', envdir, 'install', dependency)
+ helpers.run_setup_cmd(prefix, cmd)
+
+
+def run_hook(
+ hook: Hook,
+ file_args: Sequence[str],
+ color: bool,
+) -> Tuple[int, bytes]: # pragma: win32 no cover
+ with in_env(hook.prefix):
+ return helpers.run_xargs(hook, hook.cmd, file_args, color=color)
diff --git a/pre_commit/languages/r.py b/pre_commit/languages/r.py
index d573775..e034e39 100644
--- a/pre_commit/languages/r.py
+++ b/pre_commit/languages/r.py
@@ -8,6 +8,7 @@ from typing import Tuple
from pre_commit.envcontext import envcontext
from pre_commit.envcontext import PatchesT
+from pre_commit.envcontext import UNSET
from pre_commit.hook import Hook
from pre_commit.languages import helpers
from pre_commit.prefix import Prefix
@@ -23,6 +24,7 @@ healthy = helpers.basic_healthy
def get_env_patch(venv: str) -> PatchesT:
return (
('R_PROFILE_USER', os.path.join(venv, 'activate.R')),
+ ('RENV_PROJECT', UNSET),
)
@@ -55,6 +57,10 @@ def _prefix_if_non_local_file_entry(
return (path,)
+def _rscript_exec() -> str:
+ return os.path.join(os.getenv('R_HOME', ''), 'Rscript')
+
+
def _entry_validate(entry: Sequence[str]) -> None:
"""
Allowed entries:
@@ -95,8 +101,9 @@ def install_environment(
os.makedirs(env_dir, exist_ok=True)
shutil.copy(prefix.path('renv.lock'), env_dir)
shutil.copytree(prefix.path('renv'), os.path.join(env_dir, 'renv'))
+
cmd_output_b(
- 'Rscript', '--vanilla', '-e',
+ _rscript_exec(), '--vanilla', '-e',
f"""\
prefix_dir <- {prefix.prefix_dir!r}
options(
@@ -130,7 +137,7 @@ def install_environment(
if additional_dependencies:
with in_env(prefix, version):
cmd_output_b(
- 'Rscript', *RSCRIPT_OPTS, '-e',
+ _rscript_exec(), *RSCRIPT_OPTS, '-e',
'renv::install(commandArgs(trailingOnly = TRUE))',
*additional_dependencies,
cwd=env_dir,
diff --git a/pre_commit/resources/empty_template_pre-commit-package-dev-1.rockspec b/pre_commit/resources/empty_template_pre-commit-package-dev-1.rockspec
new file mode 100644
index 0000000..f063c8e
--- /dev/null
+++ b/pre_commit/resources/empty_template_pre-commit-package-dev-1.rockspec
@@ -0,0 +1,12 @@
+package = "pre-commit-package"
+version = "dev-1"
+
+source = {
+ url = "git+ssh://git@github.com/pre-commit/pre-commit.git"
+}
+description = {}
+dependencies = {}
+build = {
+ type = "builtin",
+ modules = {},
+}
diff --git a/pre_commit/resources/rbenv.tar.gz b/pre_commit/resources/rbenv.tar.gz
index 98b7e0f..da2514e 100644
--- a/pre_commit/resources/rbenv.tar.gz
+++ b/pre_commit/resources/rbenv.tar.gz
Binary files differ
diff --git a/pre_commit/resources/ruby-build.tar.gz b/pre_commit/resources/ruby-build.tar.gz
index afec5db..01867be 100644
--- a/pre_commit/resources/ruby-build.tar.gz
+++ b/pre_commit/resources/ruby-build.tar.gz
Binary files differ
diff --git a/pre_commit/store.py b/pre_commit/store.py
index fc3bc51..27d8553 100644
--- a/pre_commit/store.py
+++ b/pre_commit/store.py
@@ -188,7 +188,8 @@ class Store:
LOCAL_RESOURCES = (
'Cargo.toml', 'main.go', 'go.mod', 'main.rs', '.npmignore',
- 'package.json', 'pre_commit_placeholder_package.gemspec', 'setup.py',
+ 'package.json', 'pre-commit-package-dev-1.rockspec',
+ 'pre_commit_placeholder_package.gemspec', 'setup.py',
'environment.yml', 'Makefile.PL', 'pubspec.yaml',
'renv.lock', 'renv/activate.R', 'renv/LICENSE.renv',
)
diff --git a/requirements-dev.txt b/requirements-dev.txt
index 3a7b11c..a23a373 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -1,4 +1,4 @@
-covdefaults>=2.1
+covdefaults>=2.2
coverage
distlib
pytest
diff --git a/setup.cfg b/setup.cfg
index 02669c7..ef55b7c 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
[metadata]
name = pre_commit
-version = 2.16.0
+version = 2.17.0
description = A framework for managing and maintaining multi-language pre-commit hooks.
long_description = file: README.md
long_description_content_type = text/markdown
diff --git a/testing/gen-languages-all b/testing/gen-languages-all
index c933c14..152cf3c 100755
--- a/testing/gen-languages-all
+++ b/testing/gen-languages-all
@@ -3,7 +3,7 @@ import sys
LANGUAGES = [
'conda', 'coursier', 'dart', 'docker', 'docker_image', 'dotnet', 'fail',
- 'golang', 'node', 'perl', 'pygrep', 'python', 'r', 'ruby', 'rust',
+ 'golang', 'lua', 'node', 'perl', 'pygrep', 'python', 'r', 'ruby', 'rust',
'script', 'swift', 'system',
]
FIELDS = [
diff --git a/testing/get-lua.sh b/testing/get-lua.sh
new file mode 100755
index 0000000..580e247
--- /dev/null
+++ b/testing/get-lua.sh
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+# Install the runtime and package manager.
+sudo apt install lua5.3 liblua5.3-dev luarocks
diff --git a/testing/make-archives b/testing/make-archives
index 707fd88..ce098ba 100755
--- a/testing/make-archives
+++ b/testing/make-archives
@@ -15,8 +15,8 @@ from typing import Sequence
REPOS = (
- ('rbenv', 'https://github.com/rbenv/rbenv', '585ed84'),
- ('ruby-build', 'https://github.com/rbenv/ruby-build', 'e9fa4bf'),
+ ('rbenv', 'https://github.com/rbenv/rbenv', '38e1fbb'),
+ ('ruby-build', 'https://github.com/rbenv/ruby-build', '8663d2f'),
(
'ruby-download',
'https://github.com/garnieretienne/rvm-download',
diff --git a/testing/resources/docker_hooks_repo/Dockerfile b/testing/resources/docker_hooks_repo/Dockerfile
index 841b151..0bd1de0 100644
--- a/testing/resources/docker_hooks_repo/Dockerfile
+++ b/testing/resources/docker_hooks_repo/Dockerfile
@@ -1,3 +1,3 @@
-FROM cogniteev/echo
+FROM ubuntu:focal
CMD ["echo", "This is overwritten by the .pre-commit-hooks.yaml 'entry'"]
diff --git a/testing/resources/docker_image_hooks_repo/.pre-commit-hooks.yaml b/testing/resources/docker_image_hooks_repo/.pre-commit-hooks.yaml
index 1b385aa..e9fb245 100644
--- a/testing/resources/docker_image_hooks_repo/.pre-commit-hooks.yaml
+++ b/testing/resources/docker_image_hooks_repo/.pre-commit-hooks.yaml
@@ -1,8 +1,8 @@
- id: echo-entrypoint
name: echo (via --entrypoint)
language: docker_image
- entry: --entrypoint echo cogniteev/echo
+ entry: --entrypoint echo ubuntu:focal
- id: echo-cmd
name: echo (via cmd)
language: docker_image
- entry: cogniteev/echo echo
+ entry: ubuntu:focal echo
diff --git a/testing/resources/lua_repo/.pre-commit-hooks.yaml b/testing/resources/lua_repo/.pre-commit-hooks.yaml
new file mode 100644
index 0000000..767ef97
--- /dev/null
+++ b/testing/resources/lua_repo/.pre-commit-hooks.yaml
@@ -0,0 +1,4 @@
+- id: hello-world-lua
+ name: hello world lua
+ entry: hello-world-lua
+ language: lua
diff --git a/testing/resources/lua_repo/bin/hello-world-lua b/testing/resources/lua_repo/bin/hello-world-lua
new file mode 100755
index 0000000..2a0e002
--- /dev/null
+++ b/testing/resources/lua_repo/bin/hello-world-lua
@@ -0,0 +1,3 @@
+#!/usr/bin/env lua
+
+print('hello world')
diff --git a/testing/resources/lua_repo/hello-dev-1.rockspec b/testing/resources/lua_repo/hello-dev-1.rockspec
new file mode 100644
index 0000000..82486e0
--- /dev/null
+++ b/testing/resources/lua_repo/hello-dev-1.rockspec
@@ -0,0 +1,15 @@
+package = "hello"
+version = "dev-1"
+
+source = {
+ url = "git+ssh://git@github.com/pre-commit/pre-commit.git"
+}
+description = {}
+dependencies = {}
+build = {
+ type = "builtin",
+ modules = {},
+ install = {
+ bin = {"bin/hello-world-lua"}
+ },
+}
diff --git a/testing/util.py b/testing/util.py
index 791a2b9..283ed47 100644
--- a/testing/util.py
+++ b/testing/util.py
@@ -48,6 +48,10 @@ skipif_cant_run_docker = pytest.mark.skipif(
os.name == 'nt' or not docker_is_running(),
reason="Docker isn't running or can't be accessed",
)
+skipif_cant_run_lua = pytest.mark.skipif(
+ os.name == 'nt',
+ reason="lua isn't installed or can't be found",
+)
skipif_cant_run_swift = pytest.mark.skipif(
parse_shebang.find_executable('swift') is None,
reason="swift isn't installed or can't be found",
diff --git a/testing/zipapp/make b/testing/zipapp/make
index 55b6d2c..effc812 100755
--- a/testing/zipapp/make
+++ b/testing/zipapp/make
@@ -71,7 +71,7 @@ def main() -> int:
_msg('populating wheels...')
_exit_if_retv(
'podman', 'run', '--rm', '--volume', f'{wheeldir}:/wheels:rw', IMG,
- 'pip', 'wheel', f'pre_commit=={args.version}',
+ 'pip', 'wheel', f'pre_commit=={args.version}', 'setuptools',
'--wheel-dir', '/wheels',
)
diff --git a/tests/clientlib_test.py b/tests/clientlib_test.py
index 5427b1d..39a3716 100644
--- a/tests/clientlib_test.py
+++ b/tests/clientlib_test.py
@@ -265,6 +265,11 @@ def test_warn_mutable_rev_conditional():
r"pre-commit normalizes slashes in the 'files' field in hook "
r"'flake8' to forward slashes, so you can use / instead of [/\\]",
),
+ (
+ r'dir[\\/].*\.py',
+ r"pre-commit normalizes slashes in the 'files' field in hook "
+ r"'flake8' to forward slashes, so you can use / instead of [\\/]",
+ ),
),
)
def test_validate_optional_sensible_regex_at_hook(caplog, regex, warning):
@@ -295,6 +300,11 @@ def test_validate_optional_sensible_regex_at_hook(caplog, regex, warning):
r"pre-commit normalizes the slashes in the top-level 'files' "
r'field to forward slashes, so you can use / instead of [/\\]',
),
+ (
+ r'dir[\\/].*\.py',
+ r"pre-commit normalizes the slashes in the top-level 'files' "
+ r'field to forward slashes, so you can use / instead of [\\/]',
+ ),
),
)
def test_validate_optional_sensible_regex_at_top_level(caplog, regex, warning):
@@ -413,6 +423,13 @@ def test_migrate_to_sha_ok():
{'repo': 'meta', 'hooks': [{'id': 'identity', 'language': 'python'}]},
# name override must be string
{'repo': 'meta', 'hooks': [{'id': 'identity', 'name': False}]},
+ pytest.param(
+ {
+ 'repo': 'meta',
+ 'hooks': [{'id': 'identity', 'entry': 'echo hi'}],
+ },
+ id='cannot override entry for meta hooks',
+ ),
),
)
def test_meta_hook_invalid(config_repo):
diff --git a/tests/commands/install_uninstall_test.py b/tests/commands/install_uninstall_test.py
index 8339903..0b2e248 100644
--- a/tests/commands/install_uninstall_test.py
+++ b/tests/commands/install_uninstall_test.py
@@ -1,19 +1,15 @@
import os.path
import re
-import sys
-from unittest import mock
import re_assert
import pre_commit.constants as C
from pre_commit import git
-from pre_commit.commands import install_uninstall
from pre_commit.commands.install_uninstall import CURRENT_HASH
from pre_commit.commands.install_uninstall import install
from pre_commit.commands.install_uninstall import install_hooks
from pre_commit.commands.install_uninstall import is_our_script
from pre_commit.commands.install_uninstall import PRIOR_HASHES
-from pre_commit.commands.install_uninstall import shebang
from pre_commit.commands.install_uninstall import uninstall
from pre_commit.parse_shebang import find_executable
from pre_commit.util import cmd_output
@@ -43,43 +39,6 @@ def test_is_previous_pre_commit(tmpdir):
assert is_our_script(f.strpath)
-def patch_platform(platform):
- return mock.patch.object(sys, 'platform', platform)
-
-
-def patch_lookup_path(path):
- return mock.patch.object(install_uninstall, 'POSIX_SEARCH_PATH', path)
-
-
-def patch_sys_exe(exe):
- return mock.patch.object(install_uninstall, 'SYS_EXE', exe)
-
-
-def test_shebang_windows():
- with patch_platform('win32'), patch_sys_exe('python'):
- assert shebang() == '#!/usr/bin/env python'
-
-
-def test_shebang_windows_drop_ext():
- with patch_platform('win32'), patch_sys_exe('python.exe'):
- assert shebang() == '#!/usr/bin/env python'
-
-
-def test_shebang_posix_not_on_path():
- with patch_platform('posix'), patch_lookup_path(()):
- with patch_sys_exe('python3.6'):
- assert shebang() == '#!/usr/bin/env python3.6'
-
-
-def test_shebang_posix_on_path(tmpdir):
- exe = tmpdir.join(f'python{sys.version_info[0]}').ensure()
- make_executable(exe)
-
- with patch_platform('posix'), patch_lookup_path((tmpdir.strpath,)):
- with patch_sys_exe('python'):
- assert shebang() == f'#!/usr/bin/env python{sys.version_info[0]}'
-
-
def test_install_pre_commit(in_git_dir, store):
assert not install(C.CONFIG_FILE, store, hook_types=['pre-commit'])
assert os.access(in_git_dir.join('.git/hooks/pre-commit').strpath, os.X_OK)
@@ -336,7 +295,7 @@ EXISTING_COMMIT_RUN = re_assert.Matches(
def _write_legacy_hook(path):
os.makedirs(os.path.join(path, '.git/hooks'), exist_ok=True)
with open(os.path.join(path, '.git/hooks/pre-commit'), 'w') as f:
- f.write(f'{shebang()}\nprint("legacy hook")\n')
+ f.write('#!/usr/bin/env bash\necho legacy hook\n')
make_executable(f.name)
diff --git a/tests/error_handler_test.py b/tests/error_handler_test.py
index 6b0bb86..cb76dcf 100644
--- a/tests/error_handler_test.py
+++ b/tests/error_handler_test.py
@@ -122,6 +122,7 @@ def test_log_and_exit(cap_out, mock_store_dir):
r'\n'
r'```\n'
r'pre-commit version: \d+\.\d+\.\d+\n'
+ r'git --version: git version .+\n'
r'sys.version:\n'
r'( .*\n)*'
r'sys.executable: .*\n'
diff --git a/tests/languages/conda_test.py b/tests/languages/conda_test.py
new file mode 100644
index 0000000..6faa78f
--- /dev/null
+++ b/tests/languages/conda_test.py
@@ -0,0 +1,38 @@
+import pytest
+
+from pre_commit import envcontext
+from pre_commit.languages.conda import _conda_exe
+
+
+@pytest.mark.parametrize(
+ ('ctx', 'expected'),
+ (
+ pytest.param(
+ (
+ ('PRE_COMMIT_USE_MICROMAMBA', envcontext.UNSET),
+ ('PRE_COMMIT_USE_MAMBA', envcontext.UNSET),
+ ),
+ 'conda',
+ id='default',
+ ),
+ pytest.param(
+ (
+ ('PRE_COMMIT_USE_MICROMAMBA', '1'),
+ ('PRE_COMMIT_USE_MAMBA', ''),
+ ),
+ 'micromamba',
+ id='default',
+ ),
+ pytest.param(
+ (
+ ('PRE_COMMIT_USE_MICROMAMBA', ''),
+ ('PRE_COMMIT_USE_MAMBA', '1'),
+ ),
+ 'mamba',
+ id='default',
+ ),
+ ),
+)
+def test_conda_exe(ctx, expected):
+ with envcontext.envcontext(ctx):
+ assert _conda_exe() == expected
diff --git a/tests/languages/helpers_test.py b/tests/languages/helpers_test.py
index 669cd33..fd9b9a4 100644
--- a/tests/languages/helpers_test.py
+++ b/tests/languages/helpers_test.py
@@ -72,8 +72,8 @@ def test_basic_healthy():
def test_failed_setup_command_does_not_unicode_error():
script = (
'import sys\n'
- "getattr(sys.stderr, 'buffer', sys.stderr).write(b'\\x81\\xfe')\n"
- 'exit(1)\n'
+ "sys.stderr.buffer.write(b'\\x81\\xfe')\n"
+ 'raise SystemExit(1)\n'
)
# an assertion that this does not raise `UnicodeError`
diff --git a/tests/repository_test.py b/tests/repository_test.py
index 36268e1..8569ba9 100644
--- a/tests/repository_test.py
+++ b/tests/repository_test.py
@@ -34,6 +34,7 @@ from testing.util import cwd
from testing.util import get_resource_path
from testing.util import skipif_cant_run_coursier
from testing.util import skipif_cant_run_docker
+from testing.util import skipif_cant_run_lua
from testing.util import skipif_cant_run_swift
from testing.util import xfailif_windows
@@ -1128,3 +1129,29 @@ def test_non_installable_hook_error_for_additional_dependencies(store, caplog):
'using language `system` which does not install an environment. '
'Perhaps you meant to use a specific language?'
)
+
+
+@skipif_cant_run_lua # pragma: win32 no cover
+def test_lua_hook(tempdir_factory, store):
+ _test_hook_repo(
+ tempdir_factory, store, 'lua_repo',
+ 'hello-world-lua', [], b'hello world\n',
+ )
+
+
+@skipif_cant_run_lua # pragma: win32 no cover
+def test_local_lua_additional_dependencies(store):
+ config = {
+ 'repo': 'local',
+ 'hooks': [{
+ 'id': 'local-lua',
+ 'name': 'local-lua',
+ 'entry': 'luacheck --version',
+ 'language': 'lua',
+ 'additional_dependencies': ['luacheck'],
+ }],
+ }
+ hook = _get_hook(config, store, 'local-lua')
+ ret, out = _hook_run(hook, (), color=False)
+ assert b'Luacheck' in out
+ assert ret == 0