Adding upstream version 3.1.0.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
4066ef5157
commit
897eb1bb2a
88 changed files with 1083 additions and 974 deletions
|
@ -16,6 +16,12 @@ body:
|
||||||
placeholder: ...
|
placeholder: ...
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
95% of issues created are duplicates.
|
||||||
|
please try extra hard to find them first.
|
||||||
|
it's very unlikely your problem is unique.
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: freeform
|
id: freeform
|
||||||
attributes:
|
attributes:
|
38
.github/ISSUE_TEMPLATE/01_feature.yaml
vendored
Normal file
38
.github/ISSUE_TEMPLATE/01_feature.yaml
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
name: feature request
|
||||||
|
description: something new
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
this is for issues for `pre-commit` (the framework).
|
||||||
|
if you are reporting an issue for [pre-commit.ci] please report it at [pre-commit-ci/issues]
|
||||||
|
|
||||||
|
[pre-commit.ci]: https://pre-commit.ci
|
||||||
|
[pre-commit-ci/issues]: https://github.com/pre-commit-ci/issues
|
||||||
|
- type: input
|
||||||
|
id: search
|
||||||
|
attributes:
|
||||||
|
label: search you tried in the issue tracker
|
||||||
|
placeholder: ...
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
95% of issues created are duplicates.
|
||||||
|
please try extra hard to find them first.
|
||||||
|
it's very unlikely your feature idea is a new one.
|
||||||
|
- type: textarea
|
||||||
|
id: freeform
|
||||||
|
attributes:
|
||||||
|
label: describe your actual problem
|
||||||
|
placeholder: 'I want to do ... I tried ... It does not work because ...'
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: version
|
||||||
|
attributes:
|
||||||
|
label: pre-commit --version
|
||||||
|
placeholder: pre-commit x.x.x
|
||||||
|
validations:
|
||||||
|
required: true
|
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: documentation
|
||||||
|
url: https://pre-commit.com
|
||||||
|
about: please check the docs first
|
||||||
|
- name: pre-commit.ci issues
|
||||||
|
url: https://github.com/pre-commit-ci/issues
|
||||||
|
about: please report issues about pre-commit.ci here
|
31
.github/actions/pre-test/action.yml
vendored
31
.github/actions/pre-test/action.yml
vendored
|
@ -5,36 +5,5 @@ inputs:
|
||||||
runs:
|
runs:
|
||||||
using: composite
|
using: composite
|
||||||
steps:
|
steps:
|
||||||
- name: setup (windows)
|
|
||||||
shell: bash
|
|
||||||
if: runner.os == 'Windows'
|
|
||||||
run: |
|
|
||||||
set -x
|
|
||||||
|
|
||||||
echo 'TEMP=C:\TEMP' >> "$GITHUB_ENV"
|
|
||||||
|
|
||||||
echo "$CONDA\Scripts" >> "$GITHUB_PATH"
|
|
||||||
|
|
||||||
echo 'C:\Strawberry\perl\bin' >> "$GITHUB_PATH"
|
|
||||||
echo 'C:\Strawberry\perl\site\bin' >> "$GITHUB_PATH"
|
|
||||||
echo 'C:\Strawberry\c\bin' >> "$GITHUB_PATH"
|
|
||||||
|
|
||||||
testing/get-coursier.sh
|
|
||||||
testing/get-dart.sh
|
|
||||||
- name: setup (linux)
|
|
||||||
shell: bash
|
|
||||||
if: runner.os == 'Linux'
|
|
||||||
run: |
|
|
||||||
set -x
|
|
||||||
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y --no-install-recommends \
|
|
||||||
lua5.3 \
|
|
||||||
liblua5.3-dev \
|
|
||||||
luarocks
|
|
||||||
|
|
||||||
testing/get-coursier.sh
|
|
||||||
testing/get-dart.sh
|
|
||||||
testing/get-swift.sh
|
|
||||||
- uses: asottile/workflows/.github/actions/latest-git@v1.4.0
|
- uses: asottile/workflows/.github/actions/latest-git@v1.4.0
|
||||||
if: inputs.env == 'py38' && runner.os == 'Linux'
|
if: inputs.env == 'py38' && runner.os == 'Linux'
|
||||||
|
|
82
.github/workflows/languages.yaml
vendored
Normal file
82
.github/workflows/languages.yaml
vendored
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
name: languages
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main, test-me-*]
|
||||||
|
tags:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
vars:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
languages: ${{ steps.vars.outputs.languages }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: 3.8
|
||||||
|
- name: install deps
|
||||||
|
run: python -mpip install -e . -r requirements-dev.txt
|
||||||
|
- name: vars
|
||||||
|
run: testing/languages ${{ github.event_name == 'push' && '--all' || '' }}
|
||||||
|
id: vars
|
||||||
|
language:
|
||||||
|
needs: [vars]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
if: needs.vars.outputs.languages != '[]'
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include: ${{ fromJSON(needs.vars.outputs.languages) }}
|
||||||
|
steps:
|
||||||
|
- uses: asottile/workflows/.github/actions/fast-checkout@v1.4.0
|
||||||
|
- uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: 3.8
|
||||||
|
|
||||||
|
- run: echo "$CONDA\Scripts" >> "$GITHUB_PATH"
|
||||||
|
shell: bash
|
||||||
|
if: matrix.os == 'windows-latest' && matrix.language == 'conda'
|
||||||
|
- run: testing/get-coursier.sh
|
||||||
|
shell: bash
|
||||||
|
if: matrix.language == 'coursier'
|
||||||
|
- run: testing/get-dart.sh
|
||||||
|
shell: bash
|
||||||
|
if: matrix.language == 'dart'
|
||||||
|
- run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y --no-install-recommends \
|
||||||
|
lua5.3 \
|
||||||
|
liblua5.3-dev \
|
||||||
|
luarocks
|
||||||
|
if: matrix.os == 'ubuntu-latest' && matrix.language == 'lua'
|
||||||
|
- run: |
|
||||||
|
echo 'C:\Strawberry\perl\bin' >> "$GITHUB_PATH"
|
||||||
|
echo 'C:\Strawberry\perl\site\bin' >> "$GITHUB_PATH"
|
||||||
|
echo 'C:\Strawberry\c\bin' >> "$GITHUB_PATH"
|
||||||
|
shell: bash
|
||||||
|
if: matrix.os == 'windows-latest' && matrix.language == 'perl'
|
||||||
|
- run: testing/get-swift.sh
|
||||||
|
if: matrix.os == 'ubuntu-latest' && matrix.language == 'swift'
|
||||||
|
|
||||||
|
- name: install deps
|
||||||
|
run: python -mpip install -e . -r requirements-dev.txt
|
||||||
|
- name: run tests
|
||||||
|
run: coverage run -m pytest tests/languages/${{ matrix.language }}_test.py
|
||||||
|
- name: check coverage
|
||||||
|
run: coverage report --include pre_commit/languages/${{ matrix.language }}.py,tests/languages/${{ matrix.language }}_test.py
|
||||||
|
collector:
|
||||||
|
needs: [language]
|
||||||
|
if: always()
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: check for failures
|
||||||
|
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
|
||||||
|
run: echo job failed && exit 1
|
|
@ -38,7 +38,7 @@ repos:
|
||||||
hooks:
|
hooks:
|
||||||
- id: flake8
|
- id: flake8
|
||||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||||
rev: v0.991
|
rev: v1.0.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: mypy
|
- id: mypy
|
||||||
additional_dependencies: [types-all]
|
additional_dependencies: [types-all]
|
||||||
|
|
18
CHANGELOG.md
18
CHANGELOG.md
|
@ -1,3 +1,21 @@
|
||||||
|
3.1.0 - 2023-02-22
|
||||||
|
==================
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Fix `dotnet` for `.sln`-based hooks for dotnet>=7.0.200.
|
||||||
|
- #2763 PR by @m-rsha.
|
||||||
|
- Prevent stashing when `diff` fails to execute.
|
||||||
|
- #2774 PR by @asottile.
|
||||||
|
- #2773 issue by @strubbly.
|
||||||
|
- Dependencies are no longer sorted in repository key.
|
||||||
|
- #2776 PR by @asottile.
|
||||||
|
|
||||||
|
### Updating
|
||||||
|
- Deprecate `language: python_venv`. Use `language: python` instead.
|
||||||
|
- #2746 PR by @asottile.
|
||||||
|
- #2734 issue by @asottile.
|
||||||
|
|
||||||
|
|
||||||
3.0.4 - 2023-02-03
|
3.0.4 - 2023-02-03
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
|
|
@ -64,10 +64,10 @@ to implement. The current implemented languages are at varying levels:
|
||||||
- 0th class - pre-commit does not require any dependencies for these languages
|
- 0th class - pre-commit does not require any dependencies for these languages
|
||||||
as they're not actually languages (current examples: fail, pygrep)
|
as they're not actually languages (current examples: fail, pygrep)
|
||||||
- 1st class - pre-commit will bootstrap a full interpreter requiring nothing to
|
- 1st class - pre-commit will bootstrap a full interpreter requiring nothing to
|
||||||
be installed globally (current examples: node, ruby, rust)
|
be installed globally (current examples: go, node, ruby, rust)
|
||||||
- 2nd class - pre-commit requires the user to install the language globally but
|
- 2nd class - pre-commit requires the user to install the language globally but
|
||||||
will install tools in an isolated fashion (current examples: python, go,
|
will install tools in an isolated fashion (current examples: python, swift,
|
||||||
swift, docker).
|
docker).
|
||||||
- 3rd class - pre-commit requires the user to install both the tool and the
|
- 3rd class - pre-commit requires the user to install both the tool and the
|
||||||
language globally (current examples: script, system)
|
language globally (current examples: script, system)
|
||||||
|
|
||||||
|
|
48
pre_commit/all_languages.py
Normal file
48
pre_commit/all_languages.py
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pre_commit.lang_base import Language
|
||||||
|
from pre_commit.languages import conda
|
||||||
|
from pre_commit.languages import coursier
|
||||||
|
from pre_commit.languages import dart
|
||||||
|
from pre_commit.languages import docker
|
||||||
|
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
|
||||||
|
from pre_commit.languages import python
|
||||||
|
from pre_commit.languages import r
|
||||||
|
from pre_commit.languages import ruby
|
||||||
|
from pre_commit.languages import rust
|
||||||
|
from pre_commit.languages import script
|
||||||
|
from pre_commit.languages import swift
|
||||||
|
from pre_commit.languages import system
|
||||||
|
|
||||||
|
|
||||||
|
languages: dict[str, Language] = {
|
||||||
|
'conda': conda,
|
||||||
|
'coursier': coursier,
|
||||||
|
'dart': dart,
|
||||||
|
'docker': docker,
|
||||||
|
'docker_image': docker_image,
|
||||||
|
'dotnet': dotnet,
|
||||||
|
'fail': fail,
|
||||||
|
'golang': golang,
|
||||||
|
'lua': lua,
|
||||||
|
'node': node,
|
||||||
|
'perl': perl,
|
||||||
|
'pygrep': pygrep,
|
||||||
|
'python': python,
|
||||||
|
'r': r,
|
||||||
|
'ruby': ruby,
|
||||||
|
'rust': rust,
|
||||||
|
'script': script,
|
||||||
|
'swift': swift,
|
||||||
|
'system': system,
|
||||||
|
# TODO: fully deprecate `python_venv`
|
||||||
|
'python_venv': python,
|
||||||
|
}
|
||||||
|
language_names = sorted(languages)
|
|
@ -12,8 +12,8 @@ import cfgv
|
||||||
from identify.identify import ALL_TAGS
|
from identify.identify import ALL_TAGS
|
||||||
|
|
||||||
import pre_commit.constants as C
|
import pre_commit.constants as C
|
||||||
|
from pre_commit.all_languages import language_names
|
||||||
from pre_commit.errors import FatalError
|
from pre_commit.errors import FatalError
|
||||||
from pre_commit.languages.all import all_languages
|
|
||||||
from pre_commit.yaml import yaml_load
|
from pre_commit.yaml import yaml_load
|
||||||
|
|
||||||
logger = logging.getLogger('pre_commit')
|
logger = logging.getLogger('pre_commit')
|
||||||
|
@ -49,7 +49,7 @@ MANIFEST_HOOK_DICT = cfgv.Map(
|
||||||
cfgv.Required('id', cfgv.check_string),
|
cfgv.Required('id', cfgv.check_string),
|
||||||
cfgv.Required('name', cfgv.check_string),
|
cfgv.Required('name', cfgv.check_string),
|
||||||
cfgv.Required('entry', cfgv.check_string),
|
cfgv.Required('entry', cfgv.check_string),
|
||||||
cfgv.Required('language', cfgv.check_one_of(all_languages)),
|
cfgv.Required('language', cfgv.check_one_of(language_names)),
|
||||||
cfgv.Optional('alias', cfgv.check_string, ''),
|
cfgv.Optional('alias', cfgv.check_string, ''),
|
||||||
|
|
||||||
cfgv.Optional('files', check_string_regex, ''),
|
cfgv.Optional('files', check_string_regex, ''),
|
||||||
|
@ -281,8 +281,8 @@ CONFIG_REPO_DICT = cfgv.Map(
|
||||||
)
|
)
|
||||||
DEFAULT_LANGUAGE_VERSION = cfgv.Map(
|
DEFAULT_LANGUAGE_VERSION = cfgv.Map(
|
||||||
'DefaultLanguageVersion', None,
|
'DefaultLanguageVersion', None,
|
||||||
cfgv.NoAdditionalKeys(all_languages),
|
cfgv.NoAdditionalKeys(language_names),
|
||||||
*(cfgv.Optional(x, cfgv.check_string, C.DEFAULT) for x in all_languages),
|
*(cfgv.Optional(x, cfgv.check_string, C.DEFAULT) for x in language_names),
|
||||||
)
|
)
|
||||||
CONFIG_SCHEMA = cfgv.Map(
|
CONFIG_SCHEMA = cfgv.Map(
|
||||||
'Config', None,
|
'Config', None,
|
||||||
|
|
|
@ -42,6 +42,14 @@ def _migrate_sha_to_rev(contents: str) -> str:
|
||||||
return re.sub(r'(\n\s+)sha:', r'\1rev:', contents)
|
return re.sub(r'(\n\s+)sha:', r'\1rev:', contents)
|
||||||
|
|
||||||
|
|
||||||
|
def _migrate_python_venv(contents: str) -> str:
|
||||||
|
return re.sub(
|
||||||
|
r'(\n\s+)language: python_venv\b',
|
||||||
|
r'\1language: python',
|
||||||
|
contents,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def migrate_config(config_file: str, quiet: bool = False) -> int:
|
def migrate_config(config_file: str, quiet: bool = False) -> int:
|
||||||
with open(config_file) as f:
|
with open(config_file) as f:
|
||||||
orig_contents = contents = f.read()
|
orig_contents = contents = f.read()
|
||||||
|
@ -55,6 +63,7 @@ def migrate_config(config_file: str, quiet: bool = False) -> int:
|
||||||
|
|
||||||
contents = _migrate_map(contents)
|
contents = _migrate_map(contents)
|
||||||
contents = _migrate_sha_to_rev(contents)
|
contents = _migrate_sha_to_rev(contents)
|
||||||
|
contents = _migrate_python_venv(contents)
|
||||||
|
|
||||||
if contents != orig_contents:
|
if contents != orig_contents:
|
||||||
with open(config_file, 'w') as f:
|
with open(config_file, 'w') as f:
|
||||||
|
|
|
@ -19,9 +19,9 @@ from identify.identify import tags_from_path
|
||||||
from pre_commit import color
|
from pre_commit import color
|
||||||
from pre_commit import git
|
from pre_commit import git
|
||||||
from pre_commit import output
|
from pre_commit import output
|
||||||
|
from pre_commit.all_languages import languages
|
||||||
from pre_commit.clientlib import load_config
|
from pre_commit.clientlib import load_config
|
||||||
from pre_commit.hook import Hook
|
from pre_commit.hook import Hook
|
||||||
from pre_commit.languages.all import languages
|
|
||||||
from pre_commit.repository import all_hooks
|
from pre_commit.repository import all_hooks
|
||||||
from pre_commit.repository import install_hook_envs
|
from pre_commit.repository import install_hook_envs
|
||||||
from pre_commit.staged_files_only import staged_files_only
|
from pre_commit.staged_files_only import staged_files_only
|
||||||
|
|
|
@ -7,8 +7,10 @@ import random
|
||||||
import re
|
import re
|
||||||
import shlex
|
import shlex
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
from typing import ContextManager
|
||||||
from typing import Generator
|
from typing import Generator
|
||||||
from typing import NoReturn
|
from typing import NoReturn
|
||||||
|
from typing import Protocol
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
import pre_commit.constants as C
|
import pre_commit.constants as C
|
||||||
|
@ -22,6 +24,42 @@ FIXED_RANDOM_SEED = 1542676187
|
||||||
SHIMS_RE = re.compile(r'[/\\]shims[/\\]')
|
SHIMS_RE = re.compile(r'[/\\]shims[/\\]')
|
||||||
|
|
||||||
|
|
||||||
|
class Language(Protocol):
|
||||||
|
# Use `None` for no installation / environment
|
||||||
|
@property
|
||||||
|
def ENVIRONMENT_DIR(self) -> str | None: ...
|
||||||
|
# return a value to replace `'default` for `language_version`
|
||||||
|
def get_default_version(self) -> str: ...
|
||||||
|
# return whether the environment is healthy (or should be rebuilt)
|
||||||
|
def health_check(self, prefix: Prefix, version: str) -> str | None: ...
|
||||||
|
|
||||||
|
# install a repository for the given language and language_version
|
||||||
|
def install_environment(
|
||||||
|
self,
|
||||||
|
prefix: Prefix,
|
||||||
|
version: str,
|
||||||
|
additional_dependencies: Sequence[str],
|
||||||
|
) -> None:
|
||||||
|
...
|
||||||
|
|
||||||
|
# modify the environment for hook execution
|
||||||
|
def in_env(self, prefix: Prefix, version: str) -> ContextManager[None]: ...
|
||||||
|
|
||||||
|
# execute a hook and return the exit code and output
|
||||||
|
def run_hook(
|
||||||
|
self,
|
||||||
|
prefix: Prefix,
|
||||||
|
entry: str,
|
||||||
|
args: Sequence[str],
|
||||||
|
file_args: Sequence[str],
|
||||||
|
*,
|
||||||
|
is_local: bool,
|
||||||
|
require_serial: bool,
|
||||||
|
color: bool,
|
||||||
|
) -> tuple[int, bytes]:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
def exe_exists(exe: str) -> bool:
|
def exe_exists(exe: str) -> bool:
|
||||||
found = parse_shebang.find_executable(exe)
|
found = parse_shebang.find_executable(exe)
|
||||||
if found is None: # exe exists
|
if found is None: # exe exists
|
||||||
|
@ -45,7 +83,7 @@ def exe_exists(exe: str) -> bool:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def run_setup_cmd(prefix: Prefix, cmd: tuple[str, ...], **kwargs: Any) -> None:
|
def setup_cmd(prefix: Prefix, cmd: tuple[str, ...], **kwargs: Any) -> None:
|
||||||
cmd_output_b(*cmd, cwd=prefix.prefix_dir, **kwargs)
|
cmd_output_b(*cmd, cwd=prefix.prefix_dir, **kwargs)
|
||||||
|
|
||||||
|
|
|
@ -1,99 +0,0 @@
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from typing import ContextManager
|
|
||||||
from typing import Protocol
|
|
||||||
from typing import Sequence
|
|
||||||
|
|
||||||
from pre_commit.languages import conda
|
|
||||||
from pre_commit.languages import coursier
|
|
||||||
from pre_commit.languages import dart
|
|
||||||
from pre_commit.languages import docker
|
|
||||||
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
|
|
||||||
from pre_commit.languages import python
|
|
||||||
from pre_commit.languages import r
|
|
||||||
from pre_commit.languages import ruby
|
|
||||||
from pre_commit.languages import rust
|
|
||||||
from pre_commit.languages import script
|
|
||||||
from pre_commit.languages import swift
|
|
||||||
from pre_commit.languages import system
|
|
||||||
from pre_commit.prefix import Prefix
|
|
||||||
|
|
||||||
|
|
||||||
class Language(Protocol):
|
|
||||||
# Use `None` for no installation / environment
|
|
||||||
@property
|
|
||||||
def ENVIRONMENT_DIR(self) -> str | None: ...
|
|
||||||
# return a value to replace `'default` for `language_version`
|
|
||||||
def get_default_version(self) -> str: ...
|
|
||||||
|
|
||||||
# return whether the environment is healthy (or should be rebuilt)
|
|
||||||
def health_check(
|
|
||||||
self,
|
|
||||||
prefix: Prefix,
|
|
||||||
language_version: str,
|
|
||||||
) -> str | None:
|
|
||||||
...
|
|
||||||
|
|
||||||
# install a repository for the given language and language_version
|
|
||||||
def install_environment(
|
|
||||||
self,
|
|
||||||
prefix: Prefix,
|
|
||||||
version: str,
|
|
||||||
additional_dependencies: Sequence[str],
|
|
||||||
) -> None:
|
|
||||||
...
|
|
||||||
|
|
||||||
# modify the environment for hook execution
|
|
||||||
def in_env(
|
|
||||||
self,
|
|
||||||
prefix: Prefix,
|
|
||||||
version: str,
|
|
||||||
) -> ContextManager[None]:
|
|
||||||
...
|
|
||||||
|
|
||||||
# execute a hook and return the exit code and output
|
|
||||||
def run_hook(
|
|
||||||
self,
|
|
||||||
prefix: Prefix,
|
|
||||||
entry: str,
|
|
||||||
args: Sequence[str],
|
|
||||||
file_args: Sequence[str],
|
|
||||||
*,
|
|
||||||
is_local: bool,
|
|
||||||
require_serial: bool,
|
|
||||||
color: bool,
|
|
||||||
) -> tuple[int, bytes]:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
languages: dict[str, Language] = {
|
|
||||||
'conda': conda,
|
|
||||||
'coursier': coursier,
|
|
||||||
'dart': dart,
|
|
||||||
'docker': docker,
|
|
||||||
'docker_image': docker_image,
|
|
||||||
'dotnet': dotnet,
|
|
||||||
'fail': fail,
|
|
||||||
'golang': golang,
|
|
||||||
'lua': lua,
|
|
||||||
'node': node,
|
|
||||||
'perl': perl,
|
|
||||||
'pygrep': pygrep,
|
|
||||||
'python': python,
|
|
||||||
'r': r,
|
|
||||||
'ruby': ruby,
|
|
||||||
'rust': rust,
|
|
||||||
'script': script,
|
|
||||||
'swift': swift,
|
|
||||||
'system': system,
|
|
||||||
# TODO: fully deprecate `python_venv`
|
|
||||||
'python_venv': python,
|
|
||||||
}
|
|
||||||
all_languages = sorted(languages)
|
|
|
@ -5,19 +5,19 @@ import os
|
||||||
from typing import Generator
|
from typing import Generator
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
|
from pre_commit import lang_base
|
||||||
from pre_commit.envcontext import envcontext
|
from pre_commit.envcontext import envcontext
|
||||||
from pre_commit.envcontext import PatchesT
|
from pre_commit.envcontext import PatchesT
|
||||||
from pre_commit.envcontext import SubstitutionT
|
from pre_commit.envcontext import SubstitutionT
|
||||||
from pre_commit.envcontext import UNSET
|
from pre_commit.envcontext import UNSET
|
||||||
from pre_commit.envcontext import Var
|
from pre_commit.envcontext import Var
|
||||||
from pre_commit.languages import helpers
|
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
from pre_commit.util import cmd_output_b
|
from pre_commit.util import cmd_output_b
|
||||||
|
|
||||||
ENVIRONMENT_DIR = 'conda'
|
ENVIRONMENT_DIR = 'conda'
|
||||||
get_default_version = helpers.basic_get_default_version
|
get_default_version = lang_base.basic_get_default_version
|
||||||
health_check = helpers.basic_health_check
|
health_check = lang_base.basic_health_check
|
||||||
run_hook = helpers.basic_run_hook
|
run_hook = lang_base.basic_run_hook
|
||||||
|
|
||||||
|
|
||||||
def get_env_patch(env: str) -> PatchesT:
|
def get_env_patch(env: str) -> PatchesT:
|
||||||
|
@ -41,7 +41,7 @@ def get_env_patch(env: str) -> PatchesT:
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
with envcontext(get_env_patch(envdir)):
|
with envcontext(get_env_patch(envdir)):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
@ -60,11 +60,11 @@ def install_environment(
|
||||||
version: str,
|
version: str,
|
||||||
additional_dependencies: Sequence[str],
|
additional_dependencies: Sequence[str],
|
||||||
) -> None:
|
) -> None:
|
||||||
helpers.assert_version_default('conda', version)
|
lang_base.assert_version_default('conda', version)
|
||||||
|
|
||||||
conda_exe = _conda_exe()
|
conda_exe = _conda_exe()
|
||||||
|
|
||||||
env_dir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
env_dir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
cmd_output_b(
|
cmd_output_b(
|
||||||
conda_exe, 'env', 'create', '-p', env_dir, '--file',
|
conda_exe, 'env', 'create', '-p', env_dir, '--file',
|
||||||
'environment.yml', cwd=prefix.prefix_dir,
|
'environment.yml', cwd=prefix.prefix_dir,
|
||||||
|
|
|
@ -5,19 +5,19 @@ import os.path
|
||||||
from typing import Generator
|
from typing import Generator
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
|
from pre_commit import lang_base
|
||||||
from pre_commit.envcontext import envcontext
|
from pre_commit.envcontext import envcontext
|
||||||
from pre_commit.envcontext import PatchesT
|
from pre_commit.envcontext import PatchesT
|
||||||
from pre_commit.envcontext import Var
|
from pre_commit.envcontext import Var
|
||||||
from pre_commit.errors import FatalError
|
from pre_commit.errors import FatalError
|
||||||
from pre_commit.languages import helpers
|
|
||||||
from pre_commit.parse_shebang import find_executable
|
from pre_commit.parse_shebang import find_executable
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
|
|
||||||
ENVIRONMENT_DIR = 'coursier'
|
ENVIRONMENT_DIR = 'coursier'
|
||||||
|
|
||||||
get_default_version = helpers.basic_get_default_version
|
get_default_version = lang_base.basic_get_default_version
|
||||||
health_check = helpers.basic_health_check
|
health_check = lang_base.basic_health_check
|
||||||
run_hook = helpers.basic_run_hook
|
run_hook = lang_base.basic_run_hook
|
||||||
|
|
||||||
|
|
||||||
def install_environment(
|
def install_environment(
|
||||||
|
@ -25,7 +25,7 @@ def install_environment(
|
||||||
version: str,
|
version: str,
|
||||||
additional_dependencies: Sequence[str],
|
additional_dependencies: Sequence[str],
|
||||||
) -> None:
|
) -> None:
|
||||||
helpers.assert_version_default('coursier', version)
|
lang_base.assert_version_default('coursier', version)
|
||||||
|
|
||||||
# Support both possible executable names (either "cs" or "coursier")
|
# Support both possible executable names (either "cs" or "coursier")
|
||||||
cs = find_executable('cs') or find_executable('coursier')
|
cs = find_executable('cs') or find_executable('coursier')
|
||||||
|
@ -35,12 +35,12 @@ def install_environment(
|
||||||
'executables in the application search path',
|
'executables in the application search path',
|
||||||
)
|
)
|
||||||
|
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
|
|
||||||
def _install(*opts: str) -> None:
|
def _install(*opts: str) -> None:
|
||||||
assert cs is not None
|
assert cs is not None
|
||||||
helpers.run_setup_cmd(prefix, (cs, 'fetch', *opts))
|
lang_base.setup_cmd(prefix, (cs, 'fetch', *opts))
|
||||||
helpers.run_setup_cmd(prefix, (cs, 'install', '--dir', envdir, *opts))
|
lang_base.setup_cmd(prefix, (cs, 'install', '--dir', envdir, *opts))
|
||||||
|
|
||||||
with in_env(prefix, version):
|
with in_env(prefix, version):
|
||||||
channel = prefix.path('.pre-commit-channel')
|
channel = prefix.path('.pre-commit-channel')
|
||||||
|
@ -71,6 +71,6 @@ def get_env_patch(target_dir: str) -> PatchesT:
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
with envcontext(get_env_patch(envdir)):
|
with envcontext(get_env_patch(envdir)):
|
||||||
yield
|
yield
|
||||||
|
|
|
@ -7,19 +7,19 @@ import tempfile
|
||||||
from typing import Generator
|
from typing import Generator
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
|
from pre_commit import lang_base
|
||||||
from pre_commit.envcontext import envcontext
|
from pre_commit.envcontext import envcontext
|
||||||
from pre_commit.envcontext import PatchesT
|
from pre_commit.envcontext import PatchesT
|
||||||
from pre_commit.envcontext import Var
|
from pre_commit.envcontext import Var
|
||||||
from pre_commit.languages import helpers
|
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
from pre_commit.util import win_exe
|
from pre_commit.util import win_exe
|
||||||
from pre_commit.yaml import yaml_load
|
from pre_commit.yaml import yaml_load
|
||||||
|
|
||||||
ENVIRONMENT_DIR = 'dartenv'
|
ENVIRONMENT_DIR = 'dartenv'
|
||||||
|
|
||||||
get_default_version = helpers.basic_get_default_version
|
get_default_version = lang_base.basic_get_default_version
|
||||||
health_check = helpers.basic_health_check
|
health_check = lang_base.basic_health_check
|
||||||
run_hook = helpers.basic_run_hook
|
run_hook = lang_base.basic_run_hook
|
||||||
|
|
||||||
|
|
||||||
def get_env_patch(venv: str) -> PatchesT:
|
def get_env_patch(venv: str) -> PatchesT:
|
||||||
|
@ -30,7 +30,7 @@ def get_env_patch(venv: str) -> PatchesT:
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
with envcontext(get_env_patch(envdir)):
|
with envcontext(get_env_patch(envdir)):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
@ -40,9 +40,9 @@ def install_environment(
|
||||||
version: str,
|
version: str,
|
||||||
additional_dependencies: Sequence[str],
|
additional_dependencies: Sequence[str],
|
||||||
) -> None:
|
) -> None:
|
||||||
helpers.assert_version_default('dart', version)
|
lang_base.assert_version_default('dart', version)
|
||||||
|
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
bin_dir = os.path.join(envdir, 'bin')
|
bin_dir = os.path.join(envdir, 'bin')
|
||||||
|
|
||||||
def _install_dir(prefix_p: Prefix, pub_cache: str) -> None:
|
def _install_dir(prefix_p: Prefix, pub_cache: str) -> None:
|
||||||
|
@ -51,10 +51,10 @@ def install_environment(
|
||||||
with open(prefix_p.path('pubspec.yaml')) as f:
|
with open(prefix_p.path('pubspec.yaml')) as f:
|
||||||
pubspec_contents = yaml_load(f)
|
pubspec_contents = yaml_load(f)
|
||||||
|
|
||||||
helpers.run_setup_cmd(prefix_p, ('dart', 'pub', 'get'), env=dart_env)
|
lang_base.setup_cmd(prefix_p, ('dart', 'pub', 'get'), env=dart_env)
|
||||||
|
|
||||||
for executable in pubspec_contents['executables']:
|
for executable in pubspec_contents['executables']:
|
||||||
helpers.run_setup_cmd(
|
lang_base.setup_cmd(
|
||||||
prefix_p,
|
prefix_p,
|
||||||
(
|
(
|
||||||
'dart', 'compile', 'exe',
|
'dart', 'compile', 'exe',
|
||||||
|
@ -77,7 +77,7 @@ def install_environment(
|
||||||
else:
|
else:
|
||||||
dep_cmd = (dep,)
|
dep_cmd = (dep,)
|
||||||
|
|
||||||
helpers.run_setup_cmd(
|
lang_base.setup_cmd(
|
||||||
prefix,
|
prefix,
|
||||||
('dart', 'pub', 'cache', 'add', *dep_cmd),
|
('dart', 'pub', 'cache', 'add', *dep_cmd),
|
||||||
env={**os.environ, 'PUB_CACHE': dep_tmp},
|
env={**os.environ, 'PUB_CACHE': dep_tmp},
|
||||||
|
|
|
@ -5,16 +5,16 @@ import json
|
||||||
import os
|
import os
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
from pre_commit.languages import helpers
|
from pre_commit import lang_base
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
from pre_commit.util import CalledProcessError
|
from pre_commit.util import CalledProcessError
|
||||||
from pre_commit.util import cmd_output_b
|
from pre_commit.util import cmd_output_b
|
||||||
|
|
||||||
ENVIRONMENT_DIR = 'docker'
|
ENVIRONMENT_DIR = 'docker'
|
||||||
PRE_COMMIT_LABEL = 'PRE_COMMIT'
|
PRE_COMMIT_LABEL = 'PRE_COMMIT'
|
||||||
get_default_version = helpers.basic_get_default_version
|
get_default_version = lang_base.basic_get_default_version
|
||||||
health_check = helpers.basic_health_check
|
health_check = lang_base.basic_health_check
|
||||||
in_env = helpers.no_env # no special environment for docker
|
in_env = lang_base.no_env # no special environment for docker
|
||||||
|
|
||||||
|
|
||||||
def _is_in_docker() -> bool:
|
def _is_in_docker() -> bool:
|
||||||
|
@ -84,16 +84,16 @@ def build_docker_image(
|
||||||
cmd += ('--pull',)
|
cmd += ('--pull',)
|
||||||
# This must come last for old versions of docker. See #477
|
# This must come last for old versions of docker. See #477
|
||||||
cmd += ('.',)
|
cmd += ('.',)
|
||||||
helpers.run_setup_cmd(prefix, cmd)
|
lang_base.setup_cmd(prefix, cmd)
|
||||||
|
|
||||||
|
|
||||||
def install_environment(
|
def install_environment(
|
||||||
prefix: Prefix, version: str, additional_dependencies: Sequence[str],
|
prefix: Prefix, version: str, additional_dependencies: Sequence[str],
|
||||||
) -> None: # pragma: win32 no cover
|
) -> None: # pragma: win32 no cover
|
||||||
helpers.assert_version_default('docker', version)
|
lang_base.assert_version_default('docker', version)
|
||||||
helpers.assert_no_additional_deps('docker', additional_dependencies)
|
lang_base.assert_no_additional_deps('docker', additional_dependencies)
|
||||||
|
|
||||||
directory = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
directory = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
|
|
||||||
# Docker doesn't really have relevant disk environment, but pre-commit
|
# Docker doesn't really have relevant disk environment, but pre-commit
|
||||||
# still needs to cleanup its state files on failure
|
# still needs to cleanup its state files on failure
|
||||||
|
@ -135,12 +135,11 @@ def run_hook(
|
||||||
# automated cleanup of docker images.
|
# automated cleanup of docker images.
|
||||||
build_docker_image(prefix, pull=False)
|
build_docker_image(prefix, pull=False)
|
||||||
|
|
||||||
entry_exe, *cmd_rest = helpers.hook_cmd(entry, args)
|
entry_exe, *cmd_rest = lang_base.hook_cmd(entry, args)
|
||||||
|
|
||||||
entry_tag = ('--entrypoint', entry_exe, docker_tag(prefix))
|
entry_tag = ('--entrypoint', entry_exe, docker_tag(prefix))
|
||||||
cmd = (*docker_cmd(), *entry_tag, *cmd_rest)
|
return lang_base.run_xargs(
|
||||||
return helpers.run_xargs(
|
(*docker_cmd(), *entry_tag, *cmd_rest),
|
||||||
cmd,
|
|
||||||
file_args,
|
file_args,
|
||||||
require_serial=require_serial,
|
require_serial=require_serial,
|
||||||
color=color,
|
color=color,
|
||||||
|
|
|
@ -2,15 +2,15 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
from pre_commit.languages import helpers
|
from pre_commit import lang_base
|
||||||
from pre_commit.languages.docker import docker_cmd
|
from pre_commit.languages.docker import docker_cmd
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
|
|
||||||
ENVIRONMENT_DIR = None
|
ENVIRONMENT_DIR = None
|
||||||
get_default_version = helpers.basic_get_default_version
|
get_default_version = lang_base.basic_get_default_version
|
||||||
health_check = helpers.basic_health_check
|
health_check = lang_base.basic_health_check
|
||||||
install_environment = helpers.no_install
|
install_environment = lang_base.no_install
|
||||||
in_env = helpers.no_env
|
in_env = lang_base.no_env
|
||||||
|
|
||||||
|
|
||||||
def run_hook(
|
def run_hook(
|
||||||
|
@ -23,8 +23,8 @@ def run_hook(
|
||||||
require_serial: bool,
|
require_serial: bool,
|
||||||
color: bool,
|
color: bool,
|
||||||
) -> tuple[int, bytes]: # pragma: win32 no cover
|
) -> tuple[int, bytes]: # pragma: win32 no cover
|
||||||
cmd = docker_cmd() + helpers.hook_cmd(entry, args)
|
cmd = docker_cmd() + lang_base.hook_cmd(entry, args)
|
||||||
return helpers.run_xargs(
|
return lang_base.run_xargs(
|
||||||
cmd,
|
cmd,
|
||||||
file_args,
|
file_args,
|
||||||
require_serial=require_serial,
|
require_serial=require_serial,
|
||||||
|
|
|
@ -9,18 +9,18 @@ import zipfile
|
||||||
from typing import Generator
|
from typing import Generator
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
|
from pre_commit import lang_base
|
||||||
from pre_commit.envcontext import envcontext
|
from pre_commit.envcontext import envcontext
|
||||||
from pre_commit.envcontext import PatchesT
|
from pre_commit.envcontext import PatchesT
|
||||||
from pre_commit.envcontext import Var
|
from pre_commit.envcontext import Var
|
||||||
from pre_commit.languages import helpers
|
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
|
|
||||||
ENVIRONMENT_DIR = 'dotnetenv'
|
ENVIRONMENT_DIR = 'dotnetenv'
|
||||||
BIN_DIR = 'bin'
|
BIN_DIR = 'bin'
|
||||||
|
|
||||||
get_default_version = helpers.basic_get_default_version
|
get_default_version = lang_base.basic_get_default_version
|
||||||
health_check = helpers.basic_health_check
|
health_check = lang_base.basic_health_check
|
||||||
run_hook = helpers.basic_run_hook
|
run_hook = lang_base.basic_run_hook
|
||||||
|
|
||||||
|
|
||||||
def get_env_patch(venv: str) -> PatchesT:
|
def get_env_patch(venv: str) -> PatchesT:
|
||||||
|
@ -31,7 +31,7 @@ def get_env_patch(venv: str) -> PatchesT:
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
with envcontext(get_env_patch(envdir)):
|
with envcontext(get_env_patch(envdir)):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
@ -57,19 +57,19 @@ def install_environment(
|
||||||
version: str,
|
version: str,
|
||||||
additional_dependencies: Sequence[str],
|
additional_dependencies: Sequence[str],
|
||||||
) -> None:
|
) -> None:
|
||||||
helpers.assert_version_default('dotnet', version)
|
lang_base.assert_version_default('dotnet', version)
|
||||||
helpers.assert_no_additional_deps('dotnet', additional_dependencies)
|
lang_base.assert_no_additional_deps('dotnet', additional_dependencies)
|
||||||
|
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
build_dir = 'pre-commit-build'
|
build_dir = prefix.path('pre-commit-build')
|
||||||
|
|
||||||
# Build & pack nupkg file
|
# Build & pack nupkg file
|
||||||
helpers.run_setup_cmd(
|
lang_base.setup_cmd(
|
||||||
prefix,
|
prefix,
|
||||||
(
|
(
|
||||||
'dotnet', 'pack',
|
'dotnet', 'pack',
|
||||||
'--configuration', 'Release',
|
'--configuration', 'Release',
|
||||||
'--output', build_dir,
|
'--property', f'PackageOutputPath={build_dir}',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ def install_environment(
|
||||||
|
|
||||||
# Install to bin dir
|
# Install to bin dir
|
||||||
with _nuget_config_no_sources() as nuget_config:
|
with _nuget_config_no_sources() as nuget_config:
|
||||||
helpers.run_setup_cmd(
|
lang_base.setup_cmd(
|
||||||
prefix,
|
prefix,
|
||||||
(
|
(
|
||||||
'dotnet', 'tool', 'install',
|
'dotnet', 'tool', 'install',
|
||||||
|
@ -109,7 +109,3 @@ def install_environment(
|
||||||
tool_id,
|
tool_id,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Clean the git dir, ignoring the environment dir
|
|
||||||
clean_cmd = ('git', 'clean', '-ffxd', '-e', f'{ENVIRONMENT_DIR}-*')
|
|
||||||
helpers.run_setup_cmd(prefix, clean_cmd)
|
|
||||||
|
|
|
@ -2,14 +2,14 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
from pre_commit.languages import helpers
|
from pre_commit import lang_base
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
|
|
||||||
ENVIRONMENT_DIR = None
|
ENVIRONMENT_DIR = None
|
||||||
get_default_version = helpers.basic_get_default_version
|
get_default_version = lang_base.basic_get_default_version
|
||||||
health_check = helpers.basic_health_check
|
health_check = lang_base.basic_health_check
|
||||||
install_environment = helpers.no_install
|
install_environment = lang_base.no_install
|
||||||
in_env = helpers.no_env
|
in_env = lang_base.no_env
|
||||||
|
|
||||||
|
|
||||||
def run_hook(
|
def run_hook(
|
||||||
|
|
|
@ -19,17 +19,17 @@ from typing import Protocol
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
import pre_commit.constants as C
|
import pre_commit.constants as C
|
||||||
|
from pre_commit import lang_base
|
||||||
from pre_commit.envcontext import envcontext
|
from pre_commit.envcontext import envcontext
|
||||||
from pre_commit.envcontext import PatchesT
|
from pre_commit.envcontext import PatchesT
|
||||||
from pre_commit.envcontext import Var
|
from pre_commit.envcontext import Var
|
||||||
from pre_commit.languages import helpers
|
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
from pre_commit.util import cmd_output
|
from pre_commit.util import cmd_output
|
||||||
from pre_commit.util import rmtree
|
from pre_commit.util import rmtree
|
||||||
|
|
||||||
ENVIRONMENT_DIR = 'golangenv'
|
ENVIRONMENT_DIR = 'golangenv'
|
||||||
health_check = helpers.basic_health_check
|
health_check = lang_base.basic_health_check
|
||||||
run_hook = helpers.basic_run_hook
|
run_hook = lang_base.basic_run_hook
|
||||||
|
|
||||||
_ARCH_ALIASES = {
|
_ARCH_ALIASES = {
|
||||||
'x86_64': 'amd64',
|
'x86_64': 'amd64',
|
||||||
|
@ -60,7 +60,7 @@ else: # pragma: win32 no cover
|
||||||
|
|
||||||
@functools.lru_cache(maxsize=1)
|
@functools.lru_cache(maxsize=1)
|
||||||
def get_default_version() -> str:
|
def get_default_version() -> str:
|
||||||
if helpers.exe_exists('go'):
|
if lang_base.exe_exists('go'):
|
||||||
return 'system'
|
return 'system'
|
||||||
else:
|
else:
|
||||||
return C.DEFAULT
|
return C.DEFAULT
|
||||||
|
@ -121,7 +121,7 @@ def _install_go(version: str, dest: str) -> None:
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
with envcontext(get_env_patch(envdir, version)):
|
with envcontext(get_env_patch(envdir, version)):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ def install_environment(
|
||||||
version: str,
|
version: str,
|
||||||
additional_dependencies: Sequence[str],
|
additional_dependencies: Sequence[str],
|
||||||
) -> None:
|
) -> None:
|
||||||
env_dir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
env_dir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
|
|
||||||
if version != 'system':
|
if version != 'system':
|
||||||
_install_go(version, env_dir)
|
_install_go(version, env_dir)
|
||||||
|
@ -149,9 +149,9 @@ def install_environment(
|
||||||
os.path.join(env_dir, '.go', 'bin'), os.environ['PATH'],
|
os.path.join(env_dir, '.go', 'bin'), os.environ['PATH'],
|
||||||
))
|
))
|
||||||
|
|
||||||
helpers.run_setup_cmd(prefix, ('go', 'install', './...'), env=env)
|
lang_base.setup_cmd(prefix, ('go', 'install', './...'), env=env)
|
||||||
for dependency in additional_dependencies:
|
for dependency in additional_dependencies:
|
||||||
helpers.run_setup_cmd(prefix, ('go', 'install', dependency), env=env)
|
lang_base.setup_cmd(prefix, ('go', 'install', dependency), env=env)
|
||||||
|
|
||||||
# save some disk space -- we don't need this after installation
|
# save some disk space -- we don't need this after installation
|
||||||
pkgdir = os.path.join(env_dir, 'pkg')
|
pkgdir = os.path.join(env_dir, 'pkg')
|
||||||
|
|
|
@ -6,17 +6,17 @@ import sys
|
||||||
from typing import Generator
|
from typing import Generator
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
|
from pre_commit import lang_base
|
||||||
from pre_commit.envcontext import envcontext
|
from pre_commit.envcontext import envcontext
|
||||||
from pre_commit.envcontext import PatchesT
|
from pre_commit.envcontext import PatchesT
|
||||||
from pre_commit.envcontext import Var
|
from pre_commit.envcontext import Var
|
||||||
from pre_commit.languages import helpers
|
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
from pre_commit.util import cmd_output
|
from pre_commit.util import cmd_output
|
||||||
|
|
||||||
ENVIRONMENT_DIR = 'lua_env'
|
ENVIRONMENT_DIR = 'lua_env'
|
||||||
get_default_version = helpers.basic_get_default_version
|
get_default_version = lang_base.basic_get_default_version
|
||||||
health_check = helpers.basic_health_check
|
health_check = lang_base.basic_health_check
|
||||||
run_hook = helpers.basic_run_hook
|
run_hook = lang_base.basic_run_hook
|
||||||
|
|
||||||
|
|
||||||
def _get_lua_version() -> str: # pragma: win32 no cover
|
def _get_lua_version() -> str: # pragma: win32 no cover
|
||||||
|
@ -45,7 +45,7 @@ def get_env_patch(d: str) -> PatchesT: # pragma: win32 no cover
|
||||||
|
|
||||||
@contextlib.contextmanager # pragma: win32 no cover
|
@contextlib.contextmanager # pragma: win32 no cover
|
||||||
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
with envcontext(get_env_patch(envdir)):
|
with envcontext(get_env_patch(envdir)):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
@ -55,9 +55,9 @@ def install_environment(
|
||||||
version: str,
|
version: str,
|
||||||
additional_dependencies: Sequence[str],
|
additional_dependencies: Sequence[str],
|
||||||
) -> None: # pragma: win32 no cover
|
) -> None: # pragma: win32 no cover
|
||||||
helpers.assert_version_default('lua', version)
|
lang_base.assert_version_default('lua', version)
|
||||||
|
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
with in_env(prefix, version):
|
with in_env(prefix, version):
|
||||||
# luarocks doesn't bootstrap a tree prior to installing
|
# luarocks doesn't bootstrap a tree prior to installing
|
||||||
# so ensure the directory exists.
|
# so ensure the directory exists.
|
||||||
|
@ -66,10 +66,10 @@ def install_environment(
|
||||||
# Older luarocks (e.g., 2.4.2) expect the rockspec as an arg
|
# Older luarocks (e.g., 2.4.2) expect the rockspec as an arg
|
||||||
for rockspec in prefix.star('.rockspec'):
|
for rockspec in prefix.star('.rockspec'):
|
||||||
make_cmd = ('luarocks', '--tree', envdir, 'make', rockspec)
|
make_cmd = ('luarocks', '--tree', envdir, 'make', rockspec)
|
||||||
helpers.run_setup_cmd(prefix, make_cmd)
|
lang_base.setup_cmd(prefix, make_cmd)
|
||||||
|
|
||||||
# luarocks can't install multiple packages at once
|
# luarocks can't install multiple packages at once
|
||||||
# so install them individually.
|
# so install them individually.
|
||||||
for dependency in additional_dependencies:
|
for dependency in additional_dependencies:
|
||||||
cmd = ('luarocks', '--tree', envdir, 'install', dependency)
|
cmd = ('luarocks', '--tree', envdir, 'install', dependency)
|
||||||
helpers.run_setup_cmd(prefix, cmd)
|
lang_base.setup_cmd(prefix, cmd)
|
||||||
|
|
|
@ -8,11 +8,11 @@ from typing import Generator
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
import pre_commit.constants as C
|
import pre_commit.constants as C
|
||||||
|
from pre_commit import lang_base
|
||||||
from pre_commit.envcontext import envcontext
|
from pre_commit.envcontext import envcontext
|
||||||
from pre_commit.envcontext import PatchesT
|
from pre_commit.envcontext import PatchesT
|
||||||
from pre_commit.envcontext import UNSET
|
from pre_commit.envcontext import UNSET
|
||||||
from pre_commit.envcontext import Var
|
from pre_commit.envcontext import Var
|
||||||
from pre_commit.languages import helpers
|
|
||||||
from pre_commit.languages.python import bin_dir
|
from pre_commit.languages.python import bin_dir
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
from pre_commit.util import cmd_output
|
from pre_commit.util import cmd_output
|
||||||
|
@ -20,7 +20,7 @@ from pre_commit.util import cmd_output_b
|
||||||
from pre_commit.util import rmtree
|
from pre_commit.util import rmtree
|
||||||
|
|
||||||
ENVIRONMENT_DIR = 'node_env'
|
ENVIRONMENT_DIR = 'node_env'
|
||||||
run_hook = helpers.basic_run_hook
|
run_hook = lang_base.basic_run_hook
|
||||||
|
|
||||||
|
|
||||||
@functools.lru_cache(maxsize=1)
|
@functools.lru_cache(maxsize=1)
|
||||||
|
@ -30,7 +30,7 @@ def get_default_version() -> str:
|
||||||
return C.DEFAULT
|
return C.DEFAULT
|
||||||
# if node is already installed, we can save a bunch of setup time by
|
# if node is already installed, we can save a bunch of setup time by
|
||||||
# using the installed version
|
# using the installed version
|
||||||
elif all(helpers.exe_exists(exe) for exe in ('node', 'npm')):
|
elif all(lang_base.exe_exists(exe) for exe in ('node', 'npm')):
|
||||||
return 'system'
|
return 'system'
|
||||||
else:
|
else:
|
||||||
return C.DEFAULT
|
return C.DEFAULT
|
||||||
|
@ -60,13 +60,13 @@ def get_env_patch(venv: str) -> PatchesT:
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
with envcontext(get_env_patch(envdir)):
|
with envcontext(get_env_patch(envdir)):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
def health_check(prefix: Prefix, language_version: str) -> str | None:
|
def health_check(prefix: Prefix, version: str) -> str | None:
|
||||||
with in_env(prefix, language_version):
|
with in_env(prefix, version):
|
||||||
retcode, _, _ = cmd_output_b('node', '--version', check=False)
|
retcode, _, _ = cmd_output_b('node', '--version', check=False)
|
||||||
if retcode != 0: # pragma: win32 no cover
|
if retcode != 0: # pragma: win32 no cover
|
||||||
return f'`node --version` returned {retcode}'
|
return f'`node --version` returned {retcode}'
|
||||||
|
@ -78,7 +78,7 @@ def install_environment(
|
||||||
prefix: Prefix, version: str, additional_dependencies: Sequence[str],
|
prefix: Prefix, version: str, additional_dependencies: Sequence[str],
|
||||||
) -> None:
|
) -> None:
|
||||||
assert prefix.exists('package.json')
|
assert prefix.exists('package.json')
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
|
|
||||||
# https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx?f=255&MSPPError=-2147217396#maxpath
|
# https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx?f=255&MSPPError=-2147217396#maxpath
|
||||||
if sys.platform == 'win32': # pragma: no cover
|
if sys.platform == 'win32': # pragma: no cover
|
||||||
|
@ -96,13 +96,13 @@ def install_environment(
|
||||||
'npm', 'install', '--dev', '--prod',
|
'npm', 'install', '--dev', '--prod',
|
||||||
'--ignore-prepublish', '--no-progress', '--no-save',
|
'--ignore-prepublish', '--no-progress', '--no-save',
|
||||||
)
|
)
|
||||||
helpers.run_setup_cmd(prefix, local_install_cmd)
|
lang_base.setup_cmd(prefix, local_install_cmd)
|
||||||
|
|
||||||
_, pkg, _ = cmd_output('npm', 'pack', cwd=prefix.prefix_dir)
|
_, pkg, _ = cmd_output('npm', 'pack', cwd=prefix.prefix_dir)
|
||||||
pkg = prefix.path(pkg.strip())
|
pkg = prefix.path(pkg.strip())
|
||||||
|
|
||||||
install = ('npm', 'install', '-g', pkg, *additional_dependencies)
|
install = ('npm', 'install', '-g', pkg, *additional_dependencies)
|
||||||
helpers.run_setup_cmd(prefix, install)
|
lang_base.setup_cmd(prefix, install)
|
||||||
|
|
||||||
# clean these up after installation
|
# clean these up after installation
|
||||||
if prefix.exists('node_modules'): # pragma: win32 no cover
|
if prefix.exists('node_modules'): # pragma: win32 no cover
|
||||||
|
|
|
@ -6,16 +6,16 @@ import shlex
|
||||||
from typing import Generator
|
from typing import Generator
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
|
from pre_commit import lang_base
|
||||||
from pre_commit.envcontext import envcontext
|
from pre_commit.envcontext import envcontext
|
||||||
from pre_commit.envcontext import PatchesT
|
from pre_commit.envcontext import PatchesT
|
||||||
from pre_commit.envcontext import Var
|
from pre_commit.envcontext import Var
|
||||||
from pre_commit.languages import helpers
|
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
|
|
||||||
ENVIRONMENT_DIR = 'perl_env'
|
ENVIRONMENT_DIR = 'perl_env'
|
||||||
get_default_version = helpers.basic_get_default_version
|
get_default_version = lang_base.basic_get_default_version
|
||||||
health_check = helpers.basic_health_check
|
health_check = lang_base.basic_health_check
|
||||||
run_hook = helpers.basic_run_hook
|
run_hook = lang_base.basic_run_hook
|
||||||
|
|
||||||
|
|
||||||
def get_env_patch(venv: str) -> PatchesT:
|
def get_env_patch(venv: str) -> PatchesT:
|
||||||
|
@ -34,7 +34,7 @@ def get_env_patch(venv: str) -> PatchesT:
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
with envcontext(get_env_patch(envdir)):
|
with envcontext(get_env_patch(envdir)):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
@ -42,9 +42,9 @@ def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
||||||
def install_environment(
|
def install_environment(
|
||||||
prefix: Prefix, version: str, additional_dependencies: Sequence[str],
|
prefix: Prefix, version: str, additional_dependencies: Sequence[str],
|
||||||
) -> None:
|
) -> None:
|
||||||
helpers.assert_version_default('perl', version)
|
lang_base.assert_version_default('perl', version)
|
||||||
|
|
||||||
with in_env(prefix, version):
|
with in_env(prefix, version):
|
||||||
helpers.run_setup_cmd(
|
lang_base.setup_cmd(
|
||||||
prefix, ('cpan', '-T', '.', *additional_dependencies),
|
prefix, ('cpan', '-T', '.', *additional_dependencies),
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,16 +7,16 @@ from typing import NamedTuple
|
||||||
from typing import Pattern
|
from typing import Pattern
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
|
from pre_commit import lang_base
|
||||||
from pre_commit import output
|
from pre_commit import output
|
||||||
from pre_commit.languages import helpers
|
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
from pre_commit.xargs import xargs
|
from pre_commit.xargs import xargs
|
||||||
|
|
||||||
ENVIRONMENT_DIR = None
|
ENVIRONMENT_DIR = None
|
||||||
get_default_version = helpers.basic_get_default_version
|
get_default_version = lang_base.basic_get_default_version
|
||||||
health_check = helpers.basic_health_check
|
health_check = lang_base.basic_health_check
|
||||||
install_environment = helpers.no_install
|
install_environment = lang_base.no_install
|
||||||
in_env = helpers.no_env
|
in_env = lang_base.no_env
|
||||||
|
|
||||||
|
|
||||||
def _process_filename_by_line(pattern: Pattern[bytes], filename: str) -> int:
|
def _process_filename_by_line(pattern: Pattern[bytes], filename: str) -> int:
|
||||||
|
|
|
@ -8,11 +8,11 @@ from typing import Generator
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
import pre_commit.constants as C
|
import pre_commit.constants as C
|
||||||
|
from pre_commit import lang_base
|
||||||
from pre_commit.envcontext import envcontext
|
from pre_commit.envcontext import envcontext
|
||||||
from pre_commit.envcontext import PatchesT
|
from pre_commit.envcontext import PatchesT
|
||||||
from pre_commit.envcontext import UNSET
|
from pre_commit.envcontext import UNSET
|
||||||
from pre_commit.envcontext import Var
|
from pre_commit.envcontext import Var
|
||||||
from pre_commit.languages import helpers
|
|
||||||
from pre_commit.parse_shebang import find_executable
|
from pre_commit.parse_shebang import find_executable
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
from pre_commit.util import CalledProcessError
|
from pre_commit.util import CalledProcessError
|
||||||
|
@ -21,7 +21,7 @@ from pre_commit.util import cmd_output_b
|
||||||
from pre_commit.util import win_exe
|
from pre_commit.util import win_exe
|
||||||
|
|
||||||
ENVIRONMENT_DIR = 'py_env'
|
ENVIRONMENT_DIR = 'py_env'
|
||||||
run_hook = helpers.basic_run_hook
|
run_hook = lang_base.basic_run_hook
|
||||||
|
|
||||||
|
|
||||||
@functools.lru_cache(maxsize=None)
|
@functools.lru_cache(maxsize=None)
|
||||||
|
@ -153,13 +153,13 @@ def norm_version(version: str) -> str | None:
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
with envcontext(get_env_patch(envdir)):
|
with envcontext(get_env_patch(envdir)):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
def health_check(prefix: Prefix, language_version: str) -> str | None:
|
def health_check(prefix: Prefix, version: str) -> str | None:
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, language_version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
pyvenv_cfg = os.path.join(envdir, 'pyvenv.cfg')
|
pyvenv_cfg = os.path.join(envdir, 'pyvenv.cfg')
|
||||||
|
|
||||||
# created with "old" virtualenv
|
# created with "old" virtualenv
|
||||||
|
@ -202,7 +202,7 @@ def install_environment(
|
||||||
version: str,
|
version: str,
|
||||||
additional_dependencies: Sequence[str],
|
additional_dependencies: Sequence[str],
|
||||||
) -> None:
|
) -> None:
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
venv_cmd = [sys.executable, '-mvirtualenv', envdir]
|
venv_cmd = [sys.executable, '-mvirtualenv', envdir]
|
||||||
python = norm_version(version)
|
python = norm_version(version)
|
||||||
if python is not None:
|
if python is not None:
|
||||||
|
@ -211,4 +211,4 @@ def install_environment(
|
||||||
|
|
||||||
cmd_output_b(*venv_cmd, cwd='/')
|
cmd_output_b(*venv_cmd, cwd='/')
|
||||||
with in_env(prefix, version):
|
with in_env(prefix, version):
|
||||||
helpers.run_setup_cmd(prefix, install_cmd)
|
lang_base.setup_cmd(prefix, install_cmd)
|
||||||
|
|
|
@ -7,18 +7,18 @@ import shutil
|
||||||
from typing import Generator
|
from typing import Generator
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
|
from pre_commit import lang_base
|
||||||
from pre_commit.envcontext import envcontext
|
from pre_commit.envcontext import envcontext
|
||||||
from pre_commit.envcontext import PatchesT
|
from pre_commit.envcontext import PatchesT
|
||||||
from pre_commit.envcontext import UNSET
|
from pre_commit.envcontext import UNSET
|
||||||
from pre_commit.languages import helpers
|
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
from pre_commit.util import cmd_output_b
|
from pre_commit.util import cmd_output_b
|
||||||
from pre_commit.util import win_exe
|
from pre_commit.util import win_exe
|
||||||
|
|
||||||
ENVIRONMENT_DIR = 'renv'
|
ENVIRONMENT_DIR = 'renv'
|
||||||
RSCRIPT_OPTS = ('--no-save', '--no-restore', '--no-site-file', '--no-environ')
|
RSCRIPT_OPTS = ('--no-save', '--no-restore', '--no-site-file', '--no-environ')
|
||||||
get_default_version = helpers.basic_get_default_version
|
get_default_version = lang_base.basic_get_default_version
|
||||||
health_check = helpers.basic_health_check
|
health_check = lang_base.basic_health_check
|
||||||
|
|
||||||
|
|
||||||
def get_env_patch(venv: str) -> PatchesT:
|
def get_env_patch(venv: str) -> PatchesT:
|
||||||
|
@ -30,7 +30,7 @@ def get_env_patch(venv: str) -> PatchesT:
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
with envcontext(get_env_patch(envdir)):
|
with envcontext(get_env_patch(envdir)):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ def install_environment(
|
||||||
version: str,
|
version: str,
|
||||||
additional_dependencies: Sequence[str],
|
additional_dependencies: Sequence[str],
|
||||||
) -> None:
|
) -> None:
|
||||||
env_dir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
env_dir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
os.makedirs(env_dir, exist_ok=True)
|
os.makedirs(env_dir, exist_ok=True)
|
||||||
shutil.copy(prefix.path('renv.lock'), env_dir)
|
shutil.copy(prefix.path('renv.lock'), env_dir)
|
||||||
shutil.copytree(prefix.path('renv'), os.path.join(env_dir, 'renv'))
|
shutil.copytree(prefix.path('renv'), os.path.join(env_dir, 'renv'))
|
||||||
|
@ -166,7 +166,7 @@ def run_hook(
|
||||||
color: bool,
|
color: bool,
|
||||||
) -> tuple[int, bytes]:
|
) -> tuple[int, bytes]:
|
||||||
cmd = _cmd_from_hook(prefix, entry, args, is_local=is_local)
|
cmd = _cmd_from_hook(prefix, entry, args, is_local=is_local)
|
||||||
return helpers.run_xargs(
|
return lang_base.run_xargs(
|
||||||
cmd,
|
cmd,
|
||||||
file_args,
|
file_args,
|
||||||
require_serial=require_serial,
|
require_serial=require_serial,
|
||||||
|
|
|
@ -2,30 +2,35 @@ from __future__ import annotations
|
||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
import functools
|
import functools
|
||||||
|
import importlib.resources
|
||||||
import os.path
|
import os.path
|
||||||
import shutil
|
import shutil
|
||||||
import tarfile
|
import tarfile
|
||||||
from typing import Generator
|
from typing import Generator
|
||||||
|
from typing import IO
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
import pre_commit.constants as C
|
import pre_commit.constants as C
|
||||||
|
from pre_commit import lang_base
|
||||||
from pre_commit.envcontext import envcontext
|
from pre_commit.envcontext import envcontext
|
||||||
from pre_commit.envcontext import PatchesT
|
from pre_commit.envcontext import PatchesT
|
||||||
from pre_commit.envcontext import UNSET
|
from pre_commit.envcontext import UNSET
|
||||||
from pre_commit.envcontext import Var
|
from pre_commit.envcontext import Var
|
||||||
from pre_commit.languages import helpers
|
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
from pre_commit.util import CalledProcessError
|
from pre_commit.util import CalledProcessError
|
||||||
from pre_commit.util import resource_bytesio
|
|
||||||
|
|
||||||
ENVIRONMENT_DIR = 'rbenv'
|
ENVIRONMENT_DIR = 'rbenv'
|
||||||
health_check = helpers.basic_health_check
|
health_check = lang_base.basic_health_check
|
||||||
run_hook = helpers.basic_run_hook
|
run_hook = lang_base.basic_run_hook
|
||||||
|
|
||||||
|
|
||||||
|
def _resource_bytesio(filename: str) -> IO[bytes]:
|
||||||
|
return importlib.resources.open_binary('pre_commit.resources', filename)
|
||||||
|
|
||||||
|
|
||||||
@functools.lru_cache(maxsize=1)
|
@functools.lru_cache(maxsize=1)
|
||||||
def get_default_version() -> str:
|
def get_default_version() -> str:
|
||||||
if all(helpers.exe_exists(exe) for exe in ('ruby', 'gem')):
|
if all(lang_base.exe_exists(exe) for exe in ('ruby', 'gem')):
|
||||||
return 'system'
|
return 'system'
|
||||||
else:
|
else:
|
||||||
return C.DEFAULT
|
return C.DEFAULT
|
||||||
|
@ -68,13 +73,13 @@ def get_env_patch(
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
with envcontext(get_env_patch(envdir, version)):
|
with envcontext(get_env_patch(envdir, version)):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
def _extract_resource(filename: str, dest: str) -> None:
|
def _extract_resource(filename: str, dest: str) -> None:
|
||||||
with resource_bytesio(filename) as bio:
|
with _resource_bytesio(filename) as bio:
|
||||||
with tarfile.open(fileobj=bio) as tf:
|
with tarfile.open(fileobj=bio) as tf:
|
||||||
tf.extractall(dest)
|
tf.extractall(dest)
|
||||||
|
|
||||||
|
@ -83,7 +88,7 @@ def _install_rbenv(
|
||||||
prefix: Prefix,
|
prefix: Prefix,
|
||||||
version: str,
|
version: str,
|
||||||
) -> None: # pragma: win32 no cover
|
) -> None: # pragma: win32 no cover
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
|
|
||||||
_extract_resource('rbenv.tar.gz', prefix.path('.'))
|
_extract_resource('rbenv.tar.gz', prefix.path('.'))
|
||||||
shutil.move(prefix.path('rbenv'), envdir)
|
shutil.move(prefix.path('rbenv'), envdir)
|
||||||
|
@ -100,10 +105,10 @@ def _install_ruby(
|
||||||
version: str,
|
version: str,
|
||||||
) -> None: # pragma: win32 no cover
|
) -> None: # pragma: win32 no cover
|
||||||
try:
|
try:
|
||||||
helpers.run_setup_cmd(prefix, ('rbenv', 'download', version))
|
lang_base.setup_cmd(prefix, ('rbenv', 'download', version))
|
||||||
except CalledProcessError: # pragma: no cover (usually find with download)
|
except CalledProcessError: # pragma: no cover (usually find with download)
|
||||||
# Failed to download from mirror for some reason, build it instead
|
# Failed to download from mirror for some reason, build it instead
|
||||||
helpers.run_setup_cmd(prefix, ('rbenv', 'install', version))
|
lang_base.setup_cmd(prefix, ('rbenv', 'install', version))
|
||||||
|
|
||||||
|
|
||||||
def install_environment(
|
def install_environment(
|
||||||
|
@ -114,17 +119,17 @@ def install_environment(
|
||||||
with in_env(prefix, version):
|
with in_env(prefix, version):
|
||||||
# Need to call this before installing so rbenv's directories
|
# Need to call this before installing so rbenv's directories
|
||||||
# are set up
|
# are set up
|
||||||
helpers.run_setup_cmd(prefix, ('rbenv', 'init', '-'))
|
lang_base.setup_cmd(prefix, ('rbenv', 'init', '-'))
|
||||||
if version != C.DEFAULT:
|
if version != C.DEFAULT:
|
||||||
_install_ruby(prefix, version)
|
_install_ruby(prefix, version)
|
||||||
# Need to call this after installing to set up the shims
|
# Need to call this after installing to set up the shims
|
||||||
helpers.run_setup_cmd(prefix, ('rbenv', 'rehash'))
|
lang_base.setup_cmd(prefix, ('rbenv', 'rehash'))
|
||||||
|
|
||||||
with in_env(prefix, version):
|
with in_env(prefix, version):
|
||||||
helpers.run_setup_cmd(
|
lang_base.setup_cmd(
|
||||||
prefix, ('gem', 'build', *prefix.star('.gemspec')),
|
prefix, ('gem', 'build', *prefix.star('.gemspec')),
|
||||||
)
|
)
|
||||||
helpers.run_setup_cmd(
|
lang_base.setup_cmd(
|
||||||
prefix,
|
prefix,
|
||||||
(
|
(
|
||||||
'gem', 'install',
|
'gem', 'install',
|
||||||
|
|
|
@ -11,19 +11,19 @@ from typing import Generator
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
import pre_commit.constants as C
|
import pre_commit.constants as C
|
||||||
|
from pre_commit import lang_base
|
||||||
from pre_commit import parse_shebang
|
from pre_commit import parse_shebang
|
||||||
from pre_commit.envcontext import envcontext
|
from pre_commit.envcontext import envcontext
|
||||||
from pre_commit.envcontext import PatchesT
|
from pre_commit.envcontext import PatchesT
|
||||||
from pre_commit.envcontext import Var
|
from pre_commit.envcontext import Var
|
||||||
from pre_commit.languages import helpers
|
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
from pre_commit.util import cmd_output_b
|
from pre_commit.util import cmd_output_b
|
||||||
from pre_commit.util import make_executable
|
from pre_commit.util import make_executable
|
||||||
from pre_commit.util import win_exe
|
from pre_commit.util import win_exe
|
||||||
|
|
||||||
ENVIRONMENT_DIR = 'rustenv'
|
ENVIRONMENT_DIR = 'rustenv'
|
||||||
health_check = helpers.basic_health_check
|
health_check = lang_base.basic_health_check
|
||||||
run_hook = helpers.basic_run_hook
|
run_hook = lang_base.basic_run_hook
|
||||||
|
|
||||||
|
|
||||||
@functools.lru_cache(maxsize=1)
|
@functools.lru_cache(maxsize=1)
|
||||||
|
@ -63,7 +63,7 @@ def get_env_patch(target_dir: str, version: str) -> PatchesT:
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
with envcontext(get_env_patch(envdir, version)):
|
with envcontext(get_env_patch(envdir, version)):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ def _add_dependencies(
|
||||||
crate = f'{name}@{spec or "*"}'
|
crate = f'{name}@{spec or "*"}'
|
||||||
crates.append(crate)
|
crates.append(crate)
|
||||||
|
|
||||||
helpers.run_setup_cmd(prefix, ('cargo', 'add', *crates))
|
lang_base.setup_cmd(prefix, ('cargo', 'add', *crates))
|
||||||
|
|
||||||
|
|
||||||
def install_rust_with_toolchain(toolchain: str) -> None:
|
def install_rust_with_toolchain(toolchain: str) -> None:
|
||||||
|
@ -116,7 +116,7 @@ def install_environment(
|
||||||
version: str,
|
version: str,
|
||||||
additional_dependencies: Sequence[str],
|
additional_dependencies: Sequence[str],
|
||||||
) -> None:
|
) -> None:
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
|
|
||||||
# There are two cases where we might want to specify more dependencies:
|
# There are two cases where we might want to specify more dependencies:
|
||||||
# as dependencies for the library being built, and as binary packages
|
# as dependencies for the library being built, and as binary packages
|
||||||
|
|
|
@ -2,14 +2,14 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
from pre_commit.languages import helpers
|
from pre_commit import lang_base
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
|
|
||||||
ENVIRONMENT_DIR = None
|
ENVIRONMENT_DIR = None
|
||||||
get_default_version = helpers.basic_get_default_version
|
get_default_version = lang_base.basic_get_default_version
|
||||||
health_check = helpers.basic_health_check
|
health_check = lang_base.basic_health_check
|
||||||
install_environment = helpers.no_install
|
install_environment = lang_base.no_install
|
||||||
in_env = helpers.no_env
|
in_env = lang_base.no_env
|
||||||
|
|
||||||
|
|
||||||
def run_hook(
|
def run_hook(
|
||||||
|
@ -22,9 +22,9 @@ def run_hook(
|
||||||
require_serial: bool,
|
require_serial: bool,
|
||||||
color: bool,
|
color: bool,
|
||||||
) -> tuple[int, bytes]:
|
) -> tuple[int, bytes]:
|
||||||
cmd = helpers.hook_cmd(entry, args)
|
cmd = lang_base.hook_cmd(entry, args)
|
||||||
cmd = (prefix.path(cmd[0]), *cmd[1:])
|
cmd = (prefix.path(cmd[0]), *cmd[1:])
|
||||||
return helpers.run_xargs(
|
return lang_base.run_xargs(
|
||||||
cmd,
|
cmd,
|
||||||
file_args,
|
file_args,
|
||||||
require_serial=require_serial,
|
require_serial=require_serial,
|
||||||
|
|
|
@ -5,10 +5,10 @@ import os
|
||||||
from typing import Generator
|
from typing import Generator
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
|
from pre_commit import lang_base
|
||||||
from pre_commit.envcontext import envcontext
|
from pre_commit.envcontext import envcontext
|
||||||
from pre_commit.envcontext import PatchesT
|
from pre_commit.envcontext import PatchesT
|
||||||
from pre_commit.envcontext import Var
|
from pre_commit.envcontext import Var
|
||||||
from pre_commit.languages import helpers
|
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
from pre_commit.util import cmd_output_b
|
from pre_commit.util import cmd_output_b
|
||||||
|
|
||||||
|
@ -16,9 +16,9 @@ BUILD_DIR = '.build'
|
||||||
BUILD_CONFIG = 'release'
|
BUILD_CONFIG = 'release'
|
||||||
|
|
||||||
ENVIRONMENT_DIR = 'swift_env'
|
ENVIRONMENT_DIR = 'swift_env'
|
||||||
get_default_version = helpers.basic_get_default_version
|
get_default_version = lang_base.basic_get_default_version
|
||||||
health_check = helpers.basic_health_check
|
health_check = lang_base.basic_health_check
|
||||||
run_hook = helpers.basic_run_hook
|
run_hook = lang_base.basic_run_hook
|
||||||
|
|
||||||
|
|
||||||
def get_env_patch(venv: str) -> PatchesT: # pragma: win32 no cover
|
def get_env_patch(venv: str) -> PatchesT: # pragma: win32 no cover
|
||||||
|
@ -28,7 +28,7 @@ def get_env_patch(venv: str) -> PatchesT: # pragma: win32 no cover
|
||||||
|
|
||||||
@contextlib.contextmanager # pragma: win32 no cover
|
@contextlib.contextmanager # pragma: win32 no cover
|
||||||
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
with envcontext(get_env_patch(envdir)):
|
with envcontext(get_env_patch(envdir)):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
@ -36,9 +36,9 @@ def in_env(prefix: Prefix, version: str) -> Generator[None, None, None]:
|
||||||
def install_environment(
|
def install_environment(
|
||||||
prefix: Prefix, version: str, additional_dependencies: Sequence[str],
|
prefix: Prefix, version: str, additional_dependencies: Sequence[str],
|
||||||
) -> None: # pragma: win32 no cover
|
) -> None: # pragma: win32 no cover
|
||||||
helpers.assert_version_default('swift', version)
|
lang_base.assert_version_default('swift', version)
|
||||||
helpers.assert_no_additional_deps('swift', additional_dependencies)
|
lang_base.assert_no_additional_deps('swift', additional_dependencies)
|
||||||
envdir = helpers.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
||||||
|
|
||||||
# Build the swift package
|
# Build the swift package
|
||||||
os.mkdir(envdir)
|
os.mkdir(envdir)
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from pre_commit.languages import helpers
|
from pre_commit import lang_base
|
||||||
|
|
||||||
ENVIRONMENT_DIR = None
|
ENVIRONMENT_DIR = None
|
||||||
get_default_version = helpers.basic_get_default_version
|
get_default_version = lang_base.basic_get_default_version
|
||||||
health_check = helpers.basic_health_check
|
health_check = lang_base.basic_health_check
|
||||||
install_environment = helpers.no_install
|
install_environment = lang_base.no_install
|
||||||
in_env = helpers.no_env
|
in_env = lang_base.no_env
|
||||||
run_hook = helpers.basic_run_hook
|
run_hook = lang_base.basic_run_hook
|
||||||
|
|
|
@ -3,17 +3,18 @@ from __future__ import annotations
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import shlex
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
import pre_commit.constants as C
|
import pre_commit.constants as C
|
||||||
|
from pre_commit.all_languages import languages
|
||||||
from pre_commit.clientlib import load_manifest
|
from pre_commit.clientlib import load_manifest
|
||||||
from pre_commit.clientlib import LOCAL
|
from pre_commit.clientlib import LOCAL
|
||||||
from pre_commit.clientlib import META
|
from pre_commit.clientlib import META
|
||||||
from pre_commit.clientlib import parse_version
|
from pre_commit.clientlib import parse_version
|
||||||
from pre_commit.hook import Hook
|
from pre_commit.hook import Hook
|
||||||
from pre_commit.languages.all import languages
|
from pre_commit.lang_base import environment_dir
|
||||||
from pre_commit.languages.helpers import environment_dir
|
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
from pre_commit.store import Store
|
from pre_commit.store import Store
|
||||||
from pre_commit.util import clean_path_on_failure
|
from pre_commit.util import clean_path_on_failure
|
||||||
|
@ -32,7 +33,7 @@ def _state_filename_v2(venv: str) -> str:
|
||||||
|
|
||||||
|
|
||||||
def _state(additional_deps: Sequence[str]) -> object:
|
def _state(additional_deps: Sequence[str]) -> object:
|
||||||
return {'additional_dependencies': sorted(additional_deps)}
|
return {'additional_dependencies': additional_deps}
|
||||||
|
|
||||||
|
|
||||||
def _read_state(venv: str) -> object | None:
|
def _read_state(venv: str) -> object | None:
|
||||||
|
@ -68,6 +69,14 @@ def _hook_install(hook: Hook) -> None:
|
||||||
logger.info('Once installed this environment will be reused.')
|
logger.info('Once installed this environment will be reused.')
|
||||||
logger.info('This may take a few minutes...')
|
logger.info('This may take a few minutes...')
|
||||||
|
|
||||||
|
if hook.language == 'python_venv':
|
||||||
|
logger.warning(
|
||||||
|
f'`repo: {hook.src}` uses deprecated `language: python_venv`. '
|
||||||
|
f'This is an alias for `language: python`. '
|
||||||
|
f'Often `pre-commit autoupdate --repo {shlex.quote(hook.src)}` '
|
||||||
|
f'will fix this.',
|
||||||
|
)
|
||||||
|
|
||||||
lang = languages[hook.language]
|
lang = languages[hook.language]
|
||||||
assert lang.ENVIRONMENT_DIR is not None
|
assert lang.ENVIRONMENT_DIR is not None
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import time
|
||||||
from typing import Generator
|
from typing import Generator
|
||||||
|
|
||||||
from pre_commit import git
|
from pre_commit import git
|
||||||
|
from pre_commit.errors import FatalError
|
||||||
from pre_commit.util import CalledProcessError
|
from pre_commit.util import CalledProcessError
|
||||||
from pre_commit.util import cmd_output
|
from pre_commit.util import cmd_output
|
||||||
from pre_commit.util import cmd_output_b
|
from pre_commit.util import cmd_output_b
|
||||||
|
@ -49,12 +50,16 @@ def _intent_to_add_cleared() -> Generator[None, None, None]:
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def _unstaged_changes_cleared(patch_dir: str) -> Generator[None, None, None]:
|
def _unstaged_changes_cleared(patch_dir: str) -> Generator[None, None, None]:
|
||||||
tree = cmd_output('git', 'write-tree')[1].strip()
|
tree = cmd_output('git', 'write-tree')[1].strip()
|
||||||
retcode, diff_stdout_binary, _ = cmd_output_b(
|
diff_cmd = (
|
||||||
'git', 'diff-index', '--ignore-submodules', '--binary',
|
'git', 'diff-index', '--ignore-submodules', '--binary',
|
||||||
'--exit-code', '--no-color', '--no-ext-diff', tree, '--',
|
'--exit-code', '--no-color', '--no-ext-diff', tree, '--',
|
||||||
check=False,
|
|
||||||
)
|
)
|
||||||
if retcode and diff_stdout_binary.strip():
|
retcode, diff_stdout, diff_stderr = cmd_output_b(*diff_cmd, check=False)
|
||||||
|
if retcode == 0:
|
||||||
|
# There weren't any staged files so we don't need to do anything
|
||||||
|
# special
|
||||||
|
yield
|
||||||
|
elif retcode == 1 and diff_stdout.strip():
|
||||||
patch_filename = f'patch{int(time.time())}-{os.getpid()}'
|
patch_filename = f'patch{int(time.time())}-{os.getpid()}'
|
||||||
patch_filename = os.path.join(patch_dir, patch_filename)
|
patch_filename = os.path.join(patch_dir, patch_filename)
|
||||||
logger.warning('Unstaged files detected.')
|
logger.warning('Unstaged files detected.')
|
||||||
|
@ -62,7 +67,7 @@ def _unstaged_changes_cleared(patch_dir: str) -> Generator[None, None, None]:
|
||||||
# Save the current unstaged changes as a patch
|
# Save the current unstaged changes as a patch
|
||||||
os.makedirs(patch_dir, exist_ok=True)
|
os.makedirs(patch_dir, exist_ok=True)
|
||||||
with open(patch_filename, 'wb') as patch_file:
|
with open(patch_filename, 'wb') as patch_file:
|
||||||
patch_file.write(diff_stdout_binary)
|
patch_file.write(diff_stdout)
|
||||||
|
|
||||||
# prevent recursive post-checkout hooks (#1418)
|
# prevent recursive post-checkout hooks (#1418)
|
||||||
no_checkout_env = dict(os.environ, _PRE_COMMIT_SKIP_POST_CHECKOUT='1')
|
no_checkout_env = dict(os.environ, _PRE_COMMIT_SKIP_POST_CHECKOUT='1')
|
||||||
|
@ -86,10 +91,12 @@ def _unstaged_changes_cleared(patch_dir: str) -> Generator[None, None, None]:
|
||||||
_git_apply(patch_filename)
|
_git_apply(patch_filename)
|
||||||
|
|
||||||
logger.info(f'Restored changes from {patch_filename}.')
|
logger.info(f'Restored changes from {patch_filename}.')
|
||||||
else:
|
else: # pragma: win32 no cover
|
||||||
# There weren't any staged files so we don't need to do anything
|
# some error occurred while requesting the diff
|
||||||
# special
|
e = CalledProcessError(retcode, diff_cmd, b'', diff_stderr)
|
||||||
yield
|
raise FatalError(
|
||||||
|
f'pre-commit failed to diff -- perhaps due to permissions?\n\n{e}',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
|
|
|
@ -125,7 +125,7 @@ class Store:
|
||||||
@classmethod
|
@classmethod
|
||||||
def db_repo_name(cls, repo: str, deps: Sequence[str]) -> str:
|
def db_repo_name(cls, repo: str, deps: Sequence[str]) -> str:
|
||||||
if deps:
|
if deps:
|
||||||
return f'{repo}:{",".join(sorted(deps))}'
|
return f'{repo}:{",".join(deps)}'
|
||||||
else:
|
else:
|
||||||
return repo
|
return repo
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ from types import TracebackType
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
from typing import Generator
|
from typing import Generator
|
||||||
from typing import IO
|
|
||||||
|
|
||||||
from pre_commit import parse_shebang
|
from pre_commit import parse_shebang
|
||||||
|
|
||||||
|
@ -36,10 +35,6 @@ def clean_path_on_failure(path: str) -> Generator[None, None, None]:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
def resource_bytesio(filename: str) -> IO[bytes]:
|
|
||||||
return importlib.resources.open_binary('pre_commit.resources', filename)
|
|
||||||
|
|
||||||
|
|
||||||
def resource_text(filename: str) -> str:
|
def resource_text(filename: str) -> str:
|
||||||
return importlib.resources.read_text('pre_commit.resources', filename)
|
return importlib.resources.read_text('pre_commit.resources', filename)
|
||||||
|
|
||||||
|
@ -67,7 +62,7 @@ class CalledProcessError(RuntimeError):
|
||||||
def __bytes__(self) -> bytes:
|
def __bytes__(self) -> bytes:
|
||||||
def _indent_or_none(part: bytes | None) -> bytes:
|
def _indent_or_none(part: bytes | None) -> bytes:
|
||||||
if part:
|
if part:
|
||||||
return b'\n ' + part.replace(b'\n', b'\n ')
|
return b'\n ' + part.replace(b'\n', b'\n ').rstrip()
|
||||||
else:
|
else:
|
||||||
return b' (none)'
|
return b' (none)'
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[metadata]
|
[metadata]
|
||||||
name = pre_commit
|
name = pre_commit
|
||||||
version = 3.0.4
|
version = 3.1.0
|
||||||
description = A framework for managing and maintaining multi-language pre-commit hooks.
|
description = A framework for managing and maintaining multi-language pre-commit hooks.
|
||||||
long_description = file: README.md
|
long_description = file: README.md
|
||||||
long_description_content_type = text/markdown
|
long_description_content_type = text/markdown
|
||||||
|
|
|
@ -3,7 +3,7 @@ from __future__ import annotations
|
||||||
import os
|
import os
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
from pre_commit.languages.all import Language
|
from pre_commit.lang_base import Language
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,13 +16,16 @@ def run_language(
|
||||||
version: str | None = None,
|
version: str | None = None,
|
||||||
deps: Sequence[str] = (),
|
deps: Sequence[str] = (),
|
||||||
is_local: bool = False,
|
is_local: bool = False,
|
||||||
|
require_serial: bool = True,
|
||||||
|
color: bool = False,
|
||||||
) -> tuple[int, bytes]:
|
) -> tuple[int, bytes]:
|
||||||
prefix = Prefix(str(path))
|
prefix = Prefix(str(path))
|
||||||
version = version or language.get_default_version()
|
version = version or language.get_default_version()
|
||||||
|
|
||||||
language.install_environment(prefix, version, deps)
|
if language.ENVIRONMENT_DIR is not None:
|
||||||
health_error = language.health_check(prefix, version)
|
language.install_environment(prefix, version, deps)
|
||||||
assert health_error is None, health_error
|
health_error = language.health_check(prefix, version)
|
||||||
|
assert health_error is None, health_error
|
||||||
with language.in_env(prefix, version):
|
with language.in_env(prefix, version):
|
||||||
ret, out = language.run_hook(
|
ret, out = language.run_hook(
|
||||||
prefix,
|
prefix,
|
||||||
|
@ -30,8 +33,8 @@ def run_language(
|
||||||
args,
|
args,
|
||||||
file_args,
|
file_args,
|
||||||
is_local=is_local,
|
is_local=is_local,
|
||||||
require_serial=True,
|
require_serial=require_serial,
|
||||||
color=False,
|
color=color,
|
||||||
)
|
)
|
||||||
out = out.replace(b'\r\n', b'\n')
|
out = out.replace(b'\r\n', b'\n')
|
||||||
return ret, out
|
return ret, out
|
||||||
|
|
79
testing/languages
Executable file
79
testing/languages
Executable file
|
@ -0,0 +1,79 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import concurrent.futures
|
||||||
|
import json
|
||||||
|
import os.path
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
EXCLUDED = frozenset((
|
||||||
|
('windows-latest', 'docker'),
|
||||||
|
('windows-latest', 'docker_image'),
|
||||||
|
('windows-latest', 'lua'),
|
||||||
|
('windows-latest', 'swift'),
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
def _lang_files(lang: str) -> frozenset[str]:
|
||||||
|
prog = f'''\
|
||||||
|
import json
|
||||||
|
import os.path
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import pre_commit.languages.{lang}
|
||||||
|
import tests.languages.{lang}_test
|
||||||
|
|
||||||
|
modules = sorted(
|
||||||
|
os.path.relpath(v.__file__)
|
||||||
|
for k, v in sys.modules.items()
|
||||||
|
if k.startswith(('pre_commit.', 'tests.', 'testing.'))
|
||||||
|
)
|
||||||
|
print(json.dumps(modules))
|
||||||
|
'''
|
||||||
|
out = json.loads(subprocess.check_output((sys.executable, '-c', prog)))
|
||||||
|
return frozenset(out)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('--all', action='store_true')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
langs = [
|
||||||
|
os.path.splitext(fname)[0]
|
||||||
|
for fname in sorted(os.listdir('pre_commit/languages'))
|
||||||
|
if fname.endswith('.py') and fname != '__init__.py'
|
||||||
|
]
|
||||||
|
|
||||||
|
if not args.all:
|
||||||
|
with concurrent.futures.ThreadPoolExecutor(os.cpu_count()) as exe:
|
||||||
|
by_lang = {
|
||||||
|
lang: files
|
||||||
|
for lang, files in zip(langs, exe.map(_lang_files, langs))
|
||||||
|
}
|
||||||
|
|
||||||
|
diff_cmd = ('git', 'diff', '--name-only', 'origin/main...HEAD')
|
||||||
|
files = set(subprocess.check_output(diff_cmd).decode().splitlines())
|
||||||
|
|
||||||
|
langs = [
|
||||||
|
lang
|
||||||
|
for lang, lang_files in by_lang.items()
|
||||||
|
if lang_files & files
|
||||||
|
]
|
||||||
|
|
||||||
|
matched = [
|
||||||
|
{'os': os, 'language': lang}
|
||||||
|
for os in ('windows-latest', 'ubuntu-latest')
|
||||||
|
for lang in langs
|
||||||
|
if (os, lang) not in EXCLUDED
|
||||||
|
]
|
||||||
|
|
||||||
|
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
|
||||||
|
f.write(f'languages={json.dumps(matched)}\n')
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
raise SystemExit(main())
|
|
@ -1,17 +0,0 @@
|
||||||
- id: docker-hook
|
|
||||||
name: Docker test hook
|
|
||||||
entry: echo
|
|
||||||
language: docker
|
|
||||||
files: \.txt$
|
|
||||||
|
|
||||||
- id: docker-hook-arg
|
|
||||||
name: Docker test hook
|
|
||||||
entry: echo -n
|
|
||||||
language: docker
|
|
||||||
files: \.txt$
|
|
||||||
|
|
||||||
- id: docker-hook-failing
|
|
||||||
name: Docker test hook with nonzero exit code
|
|
||||||
entry: bork
|
|
||||||
language: docker
|
|
||||||
files: \.txt$
|
|
|
@ -1,3 +0,0 @@
|
||||||
FROM ubuntu:focal
|
|
||||||
|
|
||||||
CMD ["echo", "This is overwritten by the .pre-commit-hooks.yaml 'entry'"]
|
|
|
@ -1,8 +0,0 @@
|
||||||
- id: echo-entrypoint
|
|
||||||
name: echo (via --entrypoint)
|
|
||||||
language: docker_image
|
|
||||||
entry: --entrypoint echo ubuntu:focal
|
|
||||||
- id: echo-cmd
|
|
||||||
name: echo (via cmd)
|
|
||||||
language: docker_image
|
|
||||||
entry: ubuntu:focal echo
|
|
|
@ -1,12 +0,0 @@
|
||||||
- id: dotnet-example-hook
|
|
||||||
name: Test Project 1
|
|
||||||
description: Test Project 1
|
|
||||||
entry: proj1
|
|
||||||
language: dotnet
|
|
||||||
stages: [commit]
|
|
||||||
- id: proj2
|
|
||||||
name: Test Project 2
|
|
||||||
description: Test Project 2
|
|
||||||
entry: proj2
|
|
||||||
language: dotnet
|
|
||||||
stages: [commit]
|
|
|
@ -1,28 +0,0 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio Version 16
|
|
||||||
VisualStudioVersion = 16.0.30114.105
|
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "proj1", "proj1\proj1.csproj", "{38A939C3-DEA4-47D7-9B75-0418C4249662}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "proj2", "proj2\proj2.csproj", "{4C9916CB-165C-4EF5-8A57-4CB6794C1EBF}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Any CPU = Debug|Any CPU
|
|
||||||
Release|Any CPU = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{38A939C3-DEA4-47D7-9B75-0418C4249662}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{38A939C3-DEA4-47D7-9B75-0418C4249662}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{38A939C3-DEA4-47D7-9B75-0418C4249662}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{38A939C3-DEA4-47D7-9B75-0418C4249662}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{4C9916CB-165C-4EF5-8A57-4CB6794C1EBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{4C9916CB-165C-4EF5-8A57-4CB6794C1EBF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{4C9916CB-165C-4EF5-8A57-4CB6794C1EBF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{4C9916CB-165C-4EF5-8A57-4CB6794C1EBF}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
|
@ -1,12 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace proj1
|
|
||||||
{
|
|
||||||
class Program
|
|
||||||
{
|
|
||||||
static void Main(string[] args)
|
|
||||||
{
|
|
||||||
Console.Write("Hello from dotnet!\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net6</TargetFramework>
|
|
||||||
|
|
||||||
<PackAsTool>true</PackAsTool>
|
|
||||||
<ToolCommandName>proj1</ToolCommandName>
|
|
||||||
<PackageOutputPath>./nupkg</PackageOutputPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,12 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace proj2
|
|
||||||
{
|
|
||||||
class Program
|
|
||||||
{
|
|
||||||
static void Main(string[] args)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Hello World!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net6</TargetFramework>
|
|
||||||
|
|
||||||
<PackAsTool>true</PackAsTool>
|
|
||||||
<ToolCommandName>proj2</ToolCommandName>
|
|
||||||
<PackageOutputPath>./nupkg</PackageOutputPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,3 +0,0 @@
|
||||||
bin/
|
|
||||||
obj/
|
|
||||||
nupkg/
|
|
|
@ -1,5 +0,0 @@
|
||||||
- id: dotnet-example-hook
|
|
||||||
name: dotnet example hook
|
|
||||||
entry: testeroni.tool
|
|
||||||
language: dotnet
|
|
||||||
files: ''
|
|
|
@ -1,12 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace dotnet_hooks_repo
|
|
||||||
{
|
|
||||||
class Program
|
|
||||||
{
|
|
||||||
static void Main(string[] args)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Hello from dotnet!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
|
||||||
<PackAsTool>true</PackAsTool>
|
|
||||||
<ToolCommandName>testeroni.tool</ToolCommandName>
|
|
||||||
<PackageOutputPath>./nupkg</PackageOutputPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
</Project>
|
|
|
@ -1,3 +0,0 @@
|
||||||
bin/
|
|
||||||
obj/
|
|
||||||
nupkg/
|
|
|
@ -1,5 +0,0 @@
|
||||||
- id: dotnet-example-hook
|
|
||||||
name: dotnet example hook
|
|
||||||
entry: testeroni
|
|
||||||
language: dotnet
|
|
||||||
files: ''
|
|
|
@ -1,12 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace dotnet_hooks_repo
|
|
||||||
{
|
|
||||||
class Program
|
|
||||||
{
|
|
||||||
static void Main(string[] args)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Hello from dotnet!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net6</TargetFramework>
|
|
||||||
<PackAsTool>true</PackAsTool>
|
|
||||||
<ToolCommandName>testeroni</ToolCommandName>
|
|
||||||
<PackageOutputPath>./nupkg</PackageOutputPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
</Project>
|
|
|
@ -1,3 +0,0 @@
|
||||||
bin/
|
|
||||||
obj/
|
|
||||||
nupkg/
|
|
|
@ -1,5 +0,0 @@
|
||||||
- id: dotnet-example-hook
|
|
||||||
name: dotnet example hook
|
|
||||||
entry: testeroni
|
|
||||||
language: dotnet
|
|
||||||
files: ''
|
|
|
@ -1,12 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace dotnet_hooks_sln_repo
|
|
||||||
{
|
|
||||||
class Program
|
|
||||||
{
|
|
||||||
static void Main(string[] args)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Hello from dotnet!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net6</TargetFramework>
|
|
||||||
<PackAsTool>true</PackAsTool>
|
|
||||||
<ToolCommandName>testeroni</ToolCommandName>
|
|
||||||
<PackageOutputPath>./nupkg</PackageOutputPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
</Project>
|
|
|
@ -1,34 +0,0 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio 15
|
|
||||||
VisualStudioVersion = 15.0.26124.0
|
|
||||||
MinimumVisualStudioVersion = 15.0.26124.0
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet_hooks_sln_repo", "dotnet_hooks_sln_repo.csproj", "{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Any CPU = Debug|Any CPU
|
|
||||||
Debug|x64 = Debug|x64
|
|
||||||
Debug|x86 = Debug|x86
|
|
||||||
Release|Any CPU = Release|Any CPU
|
|
||||||
Release|x64 = Release|x64
|
|
||||||
Release|x86 = Release|x86
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
|
@ -1,5 +0,0 @@
|
||||||
- id: golang-hook
|
|
||||||
name: golang example hook
|
|
||||||
entry: golang-hello-world
|
|
||||||
language: golang
|
|
||||||
files: ''
|
|
|
@ -1,5 +0,0 @@
|
||||||
module golang-hello-world
|
|
||||||
|
|
||||||
go 1.18
|
|
||||||
|
|
||||||
require github.com/BurntSushi/toml v1.1.0
|
|
|
@ -1,2 +0,0 @@
|
||||||
github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
|
|
||||||
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
|
|
@ -1,23 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"runtime"
|
|
||||||
"github.com/BurntSushi/toml"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
What string
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
message := runtime.Version()
|
|
||||||
if len(os.Args) > 1 {
|
|
||||||
message = os.Args[1]
|
|
||||||
}
|
|
||||||
var conf Config
|
|
||||||
toml.Decode("What = 'world'\n", &conf)
|
|
||||||
fmt.Printf("hello %v from %s\n", conf.What, message)
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
- id: foo
|
|
||||||
name: Foo
|
|
||||||
entry: foo
|
|
||||||
language: python_venv
|
|
||||||
files: \.py$
|
|
|
@ -1,9 +0,0 @@
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
print(repr(sys.argv[1:]))
|
|
||||||
print('Hello World')
|
|
||||||
return 0
|
|
|
@ -1,10 +0,0 @@
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from setuptools import setup
|
|
||||||
|
|
||||||
setup(
|
|
||||||
name='foo',
|
|
||||||
version='0.0.0',
|
|
||||||
py_modules=['foo'],
|
|
||||||
entry_points={'console_scripts': ['foo = foo:main']},
|
|
||||||
)
|
|
|
@ -6,24 +6,13 @@ import subprocess
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from pre_commit.util import CalledProcessError
|
|
||||||
from pre_commit.util import cmd_output
|
from pre_commit.util import cmd_output
|
||||||
from pre_commit.util import cmd_output_b
|
|
||||||
from testing.auto_namedtuple import auto_namedtuple
|
from testing.auto_namedtuple import auto_namedtuple
|
||||||
|
|
||||||
|
|
||||||
TESTING_DIR = os.path.abspath(os.path.dirname(__file__))
|
TESTING_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
|
||||||
|
|
||||||
def docker_is_running() -> bool: # pragma: win32 no cover
|
|
||||||
try:
|
|
||||||
cmd_output_b('docker', 'ps')
|
|
||||||
except CalledProcessError: # pragma: no cover
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def get_resource_path(path):
|
def get_resource_path(path):
|
||||||
return os.path.join(TESTING_DIR, 'resources', path)
|
return os.path.join(TESTING_DIR, 'resources', path)
|
||||||
|
|
||||||
|
@ -41,10 +30,6 @@ def cmd_output_mocked_pre_commit_home(
|
||||||
return ret, out.replace('\r\n', '\n'), None
|
return ret, out.replace('\r\n', '\n'), None
|
||||||
|
|
||||||
|
|
||||||
skipif_cant_run_docker = pytest.mark.skipif(
|
|
||||||
os.name == 'nt' or not docker_is_running(),
|
|
||||||
reason="Docker isn't running or can't be accessed",
|
|
||||||
)
|
|
||||||
xfailif_windows = pytest.mark.xfail(os.name == 'nt', reason='windows')
|
xfailif_windows = pytest.mark.xfail(os.name == 'nt', reason='windows')
|
||||||
|
|
||||||
|
|
||||||
|
|
7
tests/all_languages_test.py
Normal file
7
tests/all_languages_test.py
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pre_commit.all_languages import languages
|
||||||
|
|
||||||
|
|
||||||
|
def test_python_venv_is_an_alias_to_python():
|
||||||
|
assert languages['python_venv'] is languages['python']
|
|
@ -134,6 +134,39 @@ def test_migrate_config_sha_to_rev(tmpdir):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_migrate_config_language_python_venv(tmp_path):
|
||||||
|
src = '''\
|
||||||
|
repos:
|
||||||
|
- repo: local
|
||||||
|
hooks:
|
||||||
|
- id: example
|
||||||
|
name: example
|
||||||
|
entry: example
|
||||||
|
language: python_venv
|
||||||
|
- id: example
|
||||||
|
name: example
|
||||||
|
entry: example
|
||||||
|
language: system
|
||||||
|
'''
|
||||||
|
expected = '''\
|
||||||
|
repos:
|
||||||
|
- repo: local
|
||||||
|
hooks:
|
||||||
|
- id: example
|
||||||
|
name: example
|
||||||
|
entry: example
|
||||||
|
language: python
|
||||||
|
- id: example
|
||||||
|
name: example
|
||||||
|
entry: example
|
||||||
|
language: system
|
||||||
|
'''
|
||||||
|
cfg = tmp_path.joinpath('cfg.yaml')
|
||||||
|
cfg.write_text(src)
|
||||||
|
assert migrate_config(str(cfg)) == 0
|
||||||
|
assert cfg.read_text() == expected
|
||||||
|
|
||||||
|
|
||||||
def test_migrate_config_invalid_yaml(tmpdir):
|
def test_migrate_config_invalid_yaml(tmpdir):
|
||||||
contents = '['
|
contents = '['
|
||||||
cfg = tmpdir.join(C.CONFIG_FILE)
|
cfg = tmpdir.join(C.CONFIG_FILE)
|
||||||
|
|
|
@ -8,8 +8,8 @@ from unittest import mock
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
import pre_commit.constants as C
|
import pre_commit.constants as C
|
||||||
|
from pre_commit import lang_base
|
||||||
from pre_commit import parse_shebang
|
from pre_commit import parse_shebang
|
||||||
from pre_commit.languages import helpers
|
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
from pre_commit.util import CalledProcessError
|
from pre_commit.util import CalledProcessError
|
||||||
|
|
||||||
|
@ -32,42 +32,42 @@ def homedir_mck():
|
||||||
|
|
||||||
def test_exe_exists_does_not_exist(find_exe_mck, homedir_mck):
|
def test_exe_exists_does_not_exist(find_exe_mck, homedir_mck):
|
||||||
find_exe_mck.return_value = None
|
find_exe_mck.return_value = None
|
||||||
assert helpers.exe_exists('ruby') is False
|
assert lang_base.exe_exists('ruby') is False
|
||||||
|
|
||||||
|
|
||||||
def test_exe_exists_exists(find_exe_mck, homedir_mck):
|
def test_exe_exists_exists(find_exe_mck, homedir_mck):
|
||||||
find_exe_mck.return_value = os.path.normpath('/usr/bin/ruby')
|
find_exe_mck.return_value = os.path.normpath('/usr/bin/ruby')
|
||||||
assert helpers.exe_exists('ruby') is True
|
assert lang_base.exe_exists('ruby') is True
|
||||||
|
|
||||||
|
|
||||||
def test_exe_exists_false_if_shim(find_exe_mck, homedir_mck):
|
def test_exe_exists_false_if_shim(find_exe_mck, homedir_mck):
|
||||||
find_exe_mck.return_value = os.path.normpath('/foo/shims/ruby')
|
find_exe_mck.return_value = os.path.normpath('/foo/shims/ruby')
|
||||||
assert helpers.exe_exists('ruby') is False
|
assert lang_base.exe_exists('ruby') is False
|
||||||
|
|
||||||
|
|
||||||
def test_exe_exists_false_if_homedir(find_exe_mck, homedir_mck):
|
def test_exe_exists_false_if_homedir(find_exe_mck, homedir_mck):
|
||||||
find_exe_mck.return_value = os.path.normpath('/home/me/somedir/ruby')
|
find_exe_mck.return_value = os.path.normpath('/home/me/somedir/ruby')
|
||||||
assert helpers.exe_exists('ruby') is False
|
assert lang_base.exe_exists('ruby') is False
|
||||||
|
|
||||||
|
|
||||||
def test_exe_exists_commonpath_raises_ValueError(find_exe_mck, homedir_mck):
|
def test_exe_exists_commonpath_raises_ValueError(find_exe_mck, homedir_mck):
|
||||||
find_exe_mck.return_value = os.path.normpath('/usr/bin/ruby')
|
find_exe_mck.return_value = os.path.normpath('/usr/bin/ruby')
|
||||||
with mock.patch.object(os.path, 'commonpath', side_effect=ValueError):
|
with mock.patch.object(os.path, 'commonpath', side_effect=ValueError):
|
||||||
assert helpers.exe_exists('ruby') is True
|
assert lang_base.exe_exists('ruby') is True
|
||||||
|
|
||||||
|
|
||||||
def test_exe_exists_true_when_homedir_is_slash(find_exe_mck):
|
def test_exe_exists_true_when_homedir_is_slash(find_exe_mck):
|
||||||
find_exe_mck.return_value = os.path.normpath('/usr/bin/ruby')
|
find_exe_mck.return_value = os.path.normpath('/usr/bin/ruby')
|
||||||
with mock.patch.object(os.path, 'expanduser', return_value=os.sep):
|
with mock.patch.object(os.path, 'expanduser', return_value=os.sep):
|
||||||
assert helpers.exe_exists('ruby') is True
|
assert lang_base.exe_exists('ruby') is True
|
||||||
|
|
||||||
|
|
||||||
def test_basic_get_default_version():
|
def test_basic_get_default_version():
|
||||||
assert helpers.basic_get_default_version() == C.DEFAULT
|
assert lang_base.basic_get_default_version() == C.DEFAULT
|
||||||
|
|
||||||
|
|
||||||
def test_basic_health_check():
|
def test_basic_health_check():
|
||||||
assert helpers.basic_health_check(Prefix('.'), 'default') is None
|
assert lang_base.basic_health_check(Prefix('.'), 'default') is None
|
||||||
|
|
||||||
|
|
||||||
def test_failed_setup_command_does_not_unicode_error():
|
def test_failed_setup_command_does_not_unicode_error():
|
||||||
|
@ -79,12 +79,27 @@ def test_failed_setup_command_does_not_unicode_error():
|
||||||
|
|
||||||
# an assertion that this does not raise `UnicodeError`
|
# an assertion that this does not raise `UnicodeError`
|
||||||
with pytest.raises(CalledProcessError):
|
with pytest.raises(CalledProcessError):
|
||||||
helpers.run_setup_cmd(Prefix('.'), (sys.executable, '-c', script))
|
lang_base.setup_cmd(Prefix('.'), (sys.executable, '-c', script))
|
||||||
|
|
||||||
|
|
||||||
|
def test_environment_dir(tmp_path):
|
||||||
|
ret = lang_base.environment_dir(Prefix(tmp_path), 'langenv', 'default')
|
||||||
|
assert ret == f'{tmp_path}{os.sep}langenv-default'
|
||||||
|
|
||||||
|
|
||||||
|
def test_assert_version_default():
|
||||||
|
with pytest.raises(AssertionError) as excinfo:
|
||||||
|
lang_base.assert_version_default('lang', '1.2.3')
|
||||||
|
msg, = excinfo.value.args
|
||||||
|
assert msg == (
|
||||||
|
'for now, pre-commit requires system-installed lang -- '
|
||||||
|
'you selected `language_version: 1.2.3`'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_assert_no_additional_deps():
|
def test_assert_no_additional_deps():
|
||||||
with pytest.raises(AssertionError) as excinfo:
|
with pytest.raises(AssertionError) as excinfo:
|
||||||
helpers.assert_no_additional_deps('lang', ['hmmm'])
|
lang_base.assert_no_additional_deps('lang', ['hmmm'])
|
||||||
msg, = excinfo.value.args
|
msg, = excinfo.value.args
|
||||||
assert msg == (
|
assert msg == (
|
||||||
'for now, pre-commit does not support additional_dependencies for '
|
'for now, pre-commit does not support additional_dependencies for '
|
||||||
|
@ -93,22 +108,30 @@ def test_assert_no_additional_deps():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_env_noop(tmp_path):
|
||||||
|
before = os.environ.copy()
|
||||||
|
with lang_base.no_env(Prefix(tmp_path), '1.2.3'):
|
||||||
|
inside = os.environ.copy()
|
||||||
|
after = os.environ.copy()
|
||||||
|
assert before == inside == after
|
||||||
|
|
||||||
|
|
||||||
def test_target_concurrency_normal():
|
def test_target_concurrency_normal():
|
||||||
with mock.patch.object(multiprocessing, 'cpu_count', return_value=123):
|
with mock.patch.object(multiprocessing, 'cpu_count', return_value=123):
|
||||||
with mock.patch.dict(os.environ, {}, clear=True):
|
with mock.patch.dict(os.environ, {}, clear=True):
|
||||||
assert helpers.target_concurrency() == 123
|
assert lang_base.target_concurrency() == 123
|
||||||
|
|
||||||
|
|
||||||
def test_target_concurrency_testing_env_var():
|
def test_target_concurrency_testing_env_var():
|
||||||
with mock.patch.dict(
|
with mock.patch.dict(
|
||||||
os.environ, {'PRE_COMMIT_NO_CONCURRENCY': '1'}, clear=True,
|
os.environ, {'PRE_COMMIT_NO_CONCURRENCY': '1'}, clear=True,
|
||||||
):
|
):
|
||||||
assert helpers.target_concurrency() == 1
|
assert lang_base.target_concurrency() == 1
|
||||||
|
|
||||||
|
|
||||||
def test_target_concurrency_on_travis():
|
def test_target_concurrency_on_travis():
|
||||||
with mock.patch.dict(os.environ, {'TRAVIS': '1'}, clear=True):
|
with mock.patch.dict(os.environ, {'TRAVIS': '1'}, clear=True):
|
||||||
assert helpers.target_concurrency() == 2
|
assert lang_base.target_concurrency() == 2
|
||||||
|
|
||||||
|
|
||||||
def test_target_concurrency_cpu_count_not_implemented():
|
def test_target_concurrency_cpu_count_not_implemented():
|
||||||
|
@ -116,20 +139,35 @@ def test_target_concurrency_cpu_count_not_implemented():
|
||||||
multiprocessing, 'cpu_count', side_effect=NotImplementedError,
|
multiprocessing, 'cpu_count', side_effect=NotImplementedError,
|
||||||
):
|
):
|
||||||
with mock.patch.dict(os.environ, {}, clear=True):
|
with mock.patch.dict(os.environ, {}, clear=True):
|
||||||
assert helpers.target_concurrency() == 1
|
assert lang_base.target_concurrency() == 1
|
||||||
|
|
||||||
|
|
||||||
def test_shuffled_is_deterministic():
|
def test_shuffled_is_deterministic():
|
||||||
seq = [str(i) for i in range(10)]
|
seq = [str(i) for i in range(10)]
|
||||||
expected = ['4', '0', '5', '1', '8', '6', '2', '3', '7', '9']
|
expected = ['4', '0', '5', '1', '8', '6', '2', '3', '7', '9']
|
||||||
assert helpers._shuffled(seq) == expected
|
assert lang_base._shuffled(seq) == expected
|
||||||
|
|
||||||
|
|
||||||
def test_xargs_require_serial_is_not_shuffled():
|
def test_xargs_require_serial_is_not_shuffled():
|
||||||
ret, out = helpers.run_xargs(
|
ret, out = lang_base.run_xargs(
|
||||||
('echo',), [str(i) for i in range(10)],
|
('echo',), [str(i) for i in range(10)],
|
||||||
require_serial=True,
|
require_serial=True,
|
||||||
color=False,
|
color=False,
|
||||||
)
|
)
|
||||||
assert ret == 0
|
assert ret == 0
|
||||||
assert out.strip() == b'0 1 2 3 4 5 6 7 8 9'
|
assert out.strip() == b'0 1 2 3 4 5 6 7 8 9'
|
||||||
|
|
||||||
|
|
||||||
|
def test_basic_run_hook(tmp_path):
|
||||||
|
ret, out = lang_base.basic_run_hook(
|
||||||
|
Prefix(tmp_path),
|
||||||
|
'echo hi',
|
||||||
|
['hello'],
|
||||||
|
['file', 'file', 'file'],
|
||||||
|
is_local=False,
|
||||||
|
require_serial=False,
|
||||||
|
color=False,
|
||||||
|
)
|
||||||
|
assert ret == 0
|
||||||
|
out = out.replace(b'\r\n', b'\n')
|
||||||
|
assert out == b'hi hello file file file\n'
|
27
tests/languages/docker_image_test.py
Normal file
27
tests/languages/docker_image_test.py
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pre_commit.languages import docker_image
|
||||||
|
from testing.language_helpers import run_language
|
||||||
|
from testing.util import xfailif_windows
|
||||||
|
|
||||||
|
|
||||||
|
@xfailif_windows # pragma: win32 no cover
|
||||||
|
def test_docker_image_hook_via_entrypoint(tmp_path):
|
||||||
|
ret = run_language(
|
||||||
|
tmp_path,
|
||||||
|
docker_image,
|
||||||
|
'--entrypoint echo ubuntu:22.04',
|
||||||
|
args=('hello hello world',),
|
||||||
|
)
|
||||||
|
assert ret == (0, b'hello hello world\n')
|
||||||
|
|
||||||
|
|
||||||
|
@xfailif_windows # pragma: win32 no cover
|
||||||
|
def test_docker_image_hook_via_args(tmp_path):
|
||||||
|
ret = run_language(
|
||||||
|
tmp_path,
|
||||||
|
docker_image,
|
||||||
|
'ubuntu:22.04 echo',
|
||||||
|
args=('hello hello world',),
|
||||||
|
)
|
||||||
|
assert ret == (0, b'hello hello world\n')
|
|
@ -11,6 +11,8 @@ import pytest
|
||||||
|
|
||||||
from pre_commit.languages import docker
|
from pre_commit.languages import docker
|
||||||
from pre_commit.util import CalledProcessError
|
from pre_commit.util import CalledProcessError
|
||||||
|
from testing.language_helpers import run_language
|
||||||
|
from testing.util import xfailif_windows
|
||||||
|
|
||||||
DOCKER_CGROUP_EXAMPLE = b'''\
|
DOCKER_CGROUP_EXAMPLE = b'''\
|
||||||
12:hugetlb:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
12:hugetlb:/docker/c33988ec7651ebc867cb24755eaf637a6734088bc7eef59d5799293a9e5450f7
|
||||||
|
@ -181,3 +183,15 @@ def test_get_docker_path_in_docker_docker_in_docker(in_docker):
|
||||||
err = CalledProcessError(1, (), b'', b'')
|
err = CalledProcessError(1, (), b'', b'')
|
||||||
with mock.patch.object(docker, 'cmd_output_b', side_effect=err):
|
with mock.patch.object(docker, 'cmd_output_b', side_effect=err):
|
||||||
assert docker._get_docker_path('/project') == '/project'
|
assert docker._get_docker_path('/project') == '/project'
|
||||||
|
|
||||||
|
|
||||||
|
@xfailif_windows # pragma: win32 no cover
|
||||||
|
def test_docker_hook(tmp_path):
|
||||||
|
dockerfile = '''\
|
||||||
|
FROM ubuntu:22.04
|
||||||
|
CMD ["echo", "This is overwritten by the entry"']
|
||||||
|
'''
|
||||||
|
tmp_path.joinpath('Dockerfile').write_text(dockerfile)
|
||||||
|
|
||||||
|
ret = run_language(tmp_path, docker, 'echo hello hello world')
|
||||||
|
assert ret == (0, b'hello hello world\n')
|
||||||
|
|
|
@ -0,0 +1,154 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pre_commit.languages import dotnet
|
||||||
|
from testing.language_helpers import run_language
|
||||||
|
|
||||||
|
|
||||||
|
def _write_program_cs(tmp_path):
|
||||||
|
program_cs = '''\
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace dotnet_tests
|
||||||
|
{
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
static void Main(string[] args)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Hello from dotnet!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
tmp_path.joinpath('Program.cs').write_text(program_cs)
|
||||||
|
|
||||||
|
|
||||||
|
def _csproj(tool_name):
|
||||||
|
return f'''\
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net6</TargetFramework>
|
||||||
|
<PackAsTool>true</PackAsTool>
|
||||||
|
<ToolCommandName>{tool_name}</ToolCommandName>
|
||||||
|
<PackageOutputPath>./nupkg</PackageOutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
def test_dotnet_csproj(tmp_path):
|
||||||
|
csproj = _csproj('testeroni')
|
||||||
|
_write_program_cs(tmp_path)
|
||||||
|
tmp_path.joinpath('dotnet_csproj.csproj').write_text(csproj)
|
||||||
|
ret = run_language(tmp_path, dotnet, 'testeroni')
|
||||||
|
assert ret == (0, b'Hello from dotnet!\n')
|
||||||
|
|
||||||
|
|
||||||
|
def test_dotnet_csproj_prefix(tmp_path):
|
||||||
|
csproj = _csproj('testeroni.tool')
|
||||||
|
_write_program_cs(tmp_path)
|
||||||
|
tmp_path.joinpath('dotnet_hooks_csproj_prefix.csproj').write_text(csproj)
|
||||||
|
ret = run_language(tmp_path, dotnet, 'testeroni.tool')
|
||||||
|
assert ret == (0, b'Hello from dotnet!\n')
|
||||||
|
|
||||||
|
|
||||||
|
def test_dotnet_sln(tmp_path):
|
||||||
|
csproj = _csproj('testeroni')
|
||||||
|
sln = '''\
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 15
|
||||||
|
VisualStudioVersion = 15.0.26124.0
|
||||||
|
MinimumVisualStudioVersion = 15.0.26124.0
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet_hooks_sln_repo", "dotnet_hooks_sln_repo.csproj", "{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{6568CFDB-6F6F-45A9-932C-8C7DAABC8E56}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
|
''' # noqa: E501
|
||||||
|
_write_program_cs(tmp_path)
|
||||||
|
tmp_path.joinpath('dotnet_hooks_sln_repo.csproj').write_text(csproj)
|
||||||
|
tmp_path.joinpath('dotnet_hooks_sln_repo.sln').write_text(sln)
|
||||||
|
|
||||||
|
ret = run_language(tmp_path, dotnet, 'testeroni')
|
||||||
|
assert ret == (0, b'Hello from dotnet!\n')
|
||||||
|
|
||||||
|
|
||||||
|
def _setup_dotnet_combo(tmp_path):
|
||||||
|
sln = '''\
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 16
|
||||||
|
VisualStudioVersion = 16.0.30114.105
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "proj1", "proj1\\proj1.csproj", "{38A939C3-DEA4-47D7-9B75-0418C4249662}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "proj2", "proj2\\proj2.csproj", "{4C9916CB-165C-4EF5-8A57-4CB6794C1EBF}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{38A939C3-DEA4-47D7-9B75-0418C4249662}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{38A939C3-DEA4-47D7-9B75-0418C4249662}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{38A939C3-DEA4-47D7-9B75-0418C4249662}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{38A939C3-DEA4-47D7-9B75-0418C4249662}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{4C9916CB-165C-4EF5-8A57-4CB6794C1EBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{4C9916CB-165C-4EF5-8A57-4CB6794C1EBF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{4C9916CB-165C-4EF5-8A57-4CB6794C1EBF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{4C9916CB-165C-4EF5-8A57-4CB6794C1EBF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
|
''' # noqa: E501
|
||||||
|
tmp_path.joinpath('dotnet_hooks_combo_repo.sln').write_text(sln)
|
||||||
|
|
||||||
|
csproj1 = _csproj('proj1')
|
||||||
|
proj1 = tmp_path.joinpath('proj1')
|
||||||
|
proj1.mkdir()
|
||||||
|
proj1.joinpath('proj1.csproj').write_text(csproj1)
|
||||||
|
_write_program_cs(proj1)
|
||||||
|
|
||||||
|
csproj2 = _csproj('proj2')
|
||||||
|
proj2 = tmp_path.joinpath('proj2')
|
||||||
|
proj2.mkdir()
|
||||||
|
proj2.joinpath('proj2.csproj').write_text(csproj2)
|
||||||
|
_write_program_cs(proj2)
|
||||||
|
|
||||||
|
|
||||||
|
def test_dotnet_combo_proj1(tmp_path):
|
||||||
|
_setup_dotnet_combo(tmp_path)
|
||||||
|
ret = run_language(tmp_path, dotnet, 'proj1')
|
||||||
|
assert ret == (0, b'Hello from dotnet!\n')
|
||||||
|
|
||||||
|
|
||||||
|
def test_dotnet_combo_proj2(tmp_path):
|
||||||
|
_setup_dotnet_combo(tmp_path)
|
||||||
|
ret = run_language(tmp_path, dotnet, 'proj2')
|
||||||
|
assert ret == (0, b'Hello from dotnet!\n')
|
14
tests/languages/fail_test.py
Normal file
14
tests/languages/fail_test.py
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pre_commit.languages import fail
|
||||||
|
from testing.language_helpers import run_language
|
||||||
|
|
||||||
|
|
||||||
|
def test_fail_hooks(tmp_path):
|
||||||
|
ret = run_language(
|
||||||
|
tmp_path,
|
||||||
|
fail,
|
||||||
|
'watch out for',
|
||||||
|
file_args=('bunnies',),
|
||||||
|
)
|
||||||
|
assert ret == (1, b'watch out for\n\nbunnies\n')
|
|
@ -6,8 +6,11 @@ import pytest
|
||||||
import re_assert
|
import re_assert
|
||||||
|
|
||||||
import pre_commit.constants as C
|
import pre_commit.constants as C
|
||||||
|
from pre_commit import lang_base
|
||||||
|
from pre_commit.envcontext import envcontext
|
||||||
from pre_commit.languages import golang
|
from pre_commit.languages import golang
|
||||||
from pre_commit.languages import helpers
|
from pre_commit.store import _make_local_repo
|
||||||
|
from testing.language_helpers import run_language
|
||||||
|
|
||||||
|
|
||||||
ACTUAL_GET_DEFAULT_VERSION = golang.get_default_version.__wrapped__
|
ACTUAL_GET_DEFAULT_VERSION = golang.get_default_version.__wrapped__
|
||||||
|
@ -15,7 +18,7 @@ ACTUAL_GET_DEFAULT_VERSION = golang.get_default_version.__wrapped__
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def exe_exists_mck():
|
def exe_exists_mck():
|
||||||
with mock.patch.object(helpers, 'exe_exists') as mck:
|
with mock.patch.object(lang_base, 'exe_exists') as mck:
|
||||||
yield mck
|
yield mck
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,3 +44,93 @@ def test_golang_infer_go_version_default():
|
||||||
|
|
||||||
assert version != C.DEFAULT
|
assert version != C.DEFAULT
|
||||||
re_assert.Matches(r'^\d+\.\d+(?:\.\d+)?$').assert_matches(version)
|
re_assert.Matches(r'^\d+\.\d+(?:\.\d+)?$').assert_matches(version)
|
||||||
|
|
||||||
|
|
||||||
|
def _make_hello_world(tmp_path):
|
||||||
|
go_mod = '''\
|
||||||
|
module golang-hello-world
|
||||||
|
|
||||||
|
go 1.18
|
||||||
|
|
||||||
|
require github.com/BurntSushi/toml v1.1.0
|
||||||
|
'''
|
||||||
|
go_sum = '''\
|
||||||
|
github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
|
||||||
|
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||||
|
''' # noqa: E501
|
||||||
|
hello_world_go = '''\
|
||||||
|
package main
|
||||||
|
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/BurntSushi/toml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
What string
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var conf Config
|
||||||
|
toml.Decode("What = 'world'\\n", &conf)
|
||||||
|
fmt.Printf("hello %v\\n", conf.What)
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
tmp_path.joinpath('go.mod').write_text(go_mod)
|
||||||
|
tmp_path.joinpath('go.sum').write_text(go_sum)
|
||||||
|
mod_dir = tmp_path.joinpath('golang-hello-world')
|
||||||
|
mod_dir.mkdir()
|
||||||
|
main_file = mod_dir.joinpath('main.go')
|
||||||
|
main_file.write_text(hello_world_go)
|
||||||
|
|
||||||
|
|
||||||
|
def test_golang_system(tmp_path):
|
||||||
|
_make_hello_world(tmp_path)
|
||||||
|
|
||||||
|
ret = run_language(tmp_path, golang, 'golang-hello-world')
|
||||||
|
assert ret == (0, b'hello world\n')
|
||||||
|
|
||||||
|
|
||||||
|
def test_golang_default_version(tmp_path):
|
||||||
|
_make_hello_world(tmp_path)
|
||||||
|
|
||||||
|
ret = run_language(
|
||||||
|
tmp_path,
|
||||||
|
golang,
|
||||||
|
'golang-hello-world',
|
||||||
|
version=C.DEFAULT,
|
||||||
|
)
|
||||||
|
assert ret == (0, b'hello world\n')
|
||||||
|
|
||||||
|
|
||||||
|
def test_golang_versioned(tmp_path):
|
||||||
|
_make_local_repo(str(tmp_path))
|
||||||
|
|
||||||
|
ret, out = run_language(
|
||||||
|
tmp_path,
|
||||||
|
golang,
|
||||||
|
'go version',
|
||||||
|
version='1.18.4',
|
||||||
|
)
|
||||||
|
|
||||||
|
assert ret == 0
|
||||||
|
assert out.startswith(b'go version go1.18.4')
|
||||||
|
|
||||||
|
|
||||||
|
def test_local_golang_additional_deps(tmp_path):
|
||||||
|
_make_local_repo(str(tmp_path))
|
||||||
|
|
||||||
|
ret = run_language(
|
||||||
|
tmp_path,
|
||||||
|
golang,
|
||||||
|
'hello',
|
||||||
|
deps=('golang.org/x/example/hello@latest',),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert ret == (0, b'Hello, Go examples!\n')
|
||||||
|
|
||||||
|
|
||||||
|
def test_golang_hook_still_works_when_gobin_is_set(tmp_path):
|
||||||
|
with envcontext((('GOBIN', str(tmp_path.joinpath('gobin'))),)):
|
||||||
|
test_golang_system(tmp_path)
|
||||||
|
|
|
@ -3,6 +3,7 @@ from __future__ import annotations
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from pre_commit.languages import pygrep
|
from pre_commit.languages import pygrep
|
||||||
|
from testing.language_helpers import run_language
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
@ -13,6 +14,9 @@ def some_files(tmpdir):
|
||||||
tmpdir.join('f4').write_binary(b'foo\npattern\nbar\n')
|
tmpdir.join('f4').write_binary(b'foo\npattern\nbar\n')
|
||||||
tmpdir.join('f5').write_binary(b'[INFO] hi\npattern\nbar')
|
tmpdir.join('f5').write_binary(b'[INFO] hi\npattern\nbar')
|
||||||
tmpdir.join('f6').write_binary(b"pattern\nbarwith'foo\n")
|
tmpdir.join('f6').write_binary(b"pattern\nbarwith'foo\n")
|
||||||
|
tmpdir.join('f7').write_binary(b"hello'hi\nworld\n")
|
||||||
|
tmpdir.join('f8').write_binary(b'foo\nbar\nbaz\n')
|
||||||
|
tmpdir.join('f9').write_binary(b'[WARN] hi\n')
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
@ -125,3 +129,16 @@ def test_multiline_multiline_flag_is_enabled(cap_out):
|
||||||
out = cap_out.get()
|
out = cap_out.get()
|
||||||
assert ret == 1
|
assert ret == 1
|
||||||
assert out == 'f1:1:foo\nbar\n'
|
assert out == 'f1:1:foo\nbar\n'
|
||||||
|
|
||||||
|
|
||||||
|
def test_grep_hook_matching(some_files, tmp_path):
|
||||||
|
ret = run_language(
|
||||||
|
tmp_path, pygrep, 'ello', file_args=('f7', 'f8', 'f9'),
|
||||||
|
)
|
||||||
|
assert ret == (1, b"f7:1:hello'hi\n")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('regex', ('nope', "foo'bar", r'^\[INFO\]'))
|
||||||
|
def test_grep_hook_not_matching(regex, some_files, tmp_path):
|
||||||
|
ret = run_language(tmp_path, pygrep, regex, file_args=('f7', 'f8', 'f9'))
|
||||||
|
assert ret == (0, b'')
|
||||||
|
|
|
@ -12,6 +12,7 @@ from pre_commit.languages import python
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
from pre_commit.util import make_executable
|
from pre_commit.util import make_executable
|
||||||
from pre_commit.util import win_exe
|
from pre_commit.util import win_exe
|
||||||
|
from testing.language_helpers import run_language
|
||||||
|
|
||||||
|
|
||||||
def test_read_pyvenv_cfg(tmpdir):
|
def test_read_pyvenv_cfg(tmpdir):
|
||||||
|
@ -210,3 +211,25 @@ def test_unhealthy_then_replaced(python_dir):
|
||||||
os.replace(f'{py_exe}.tmp', py_exe)
|
os.replace(f'{py_exe}.tmp', py_exe)
|
||||||
|
|
||||||
assert python.health_check(prefix, C.DEFAULT) is None
|
assert python.health_check(prefix, C.DEFAULT) is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_language_versioned_python_hook(tmp_path):
|
||||||
|
setup_py = '''\
|
||||||
|
from setuptools import setup
|
||||||
|
setup(
|
||||||
|
name='example',
|
||||||
|
py_modules=['mod'],
|
||||||
|
entry_points={'console_scripts': ['myexe=mod:main']},
|
||||||
|
)
|
||||||
|
'''
|
||||||
|
tmp_path.joinpath('setup.py').write_text(setup_py)
|
||||||
|
tmp_path.joinpath('mod.py').write_text('def main(): print("ohai")')
|
||||||
|
|
||||||
|
# we patch this to force virtualenv executing with `-p` since we can't
|
||||||
|
# reliably have multiple pythons available in CI
|
||||||
|
with mock.patch.object(
|
||||||
|
python,
|
||||||
|
'_sys_executable_matches',
|
||||||
|
return_value=False,
|
||||||
|
):
|
||||||
|
assert run_language(tmp_path, python, 'myexe') == (0, b'ohai\n')
|
||||||
|
|
|
@ -9,8 +9,8 @@ import pre_commit.constants as C
|
||||||
from pre_commit import parse_shebang
|
from pre_commit import parse_shebang
|
||||||
from pre_commit.envcontext import envcontext
|
from pre_commit.envcontext import envcontext
|
||||||
from pre_commit.languages import ruby
|
from pre_commit.languages import ruby
|
||||||
|
from pre_commit.languages.ruby import _resource_bytesio
|
||||||
from pre_commit.store import _make_local_repo
|
from pre_commit.store import _make_local_repo
|
||||||
from pre_commit.util import resource_bytesio
|
|
||||||
from testing.language_helpers import run_language
|
from testing.language_helpers import run_language
|
||||||
from testing.util import cwd
|
from testing.util import cwd
|
||||||
from testing.util import xfailif_windows
|
from testing.util import xfailif_windows
|
||||||
|
@ -40,7 +40,7 @@ def test_uses_system_if_both_gem_and_ruby_are_available(find_exe_mck):
|
||||||
('rbenv.tar.gz', 'ruby-build.tar.gz', 'ruby-download.tar.gz'),
|
('rbenv.tar.gz', 'ruby-build.tar.gz', 'ruby-download.tar.gz'),
|
||||||
)
|
)
|
||||||
def test_archive_root_stat(filename):
|
def test_archive_root_stat(filename):
|
||||||
with resource_bytesio(filename) as f:
|
with _resource_bytesio(filename) as f:
|
||||||
with tarfile.open(fileobj=f) as tarf:
|
with tarfile.open(fileobj=f) as tarf:
|
||||||
root, _, _ = filename.partition('.')
|
root, _, _ = filename.partition('.')
|
||||||
assert oct(tarf.getmember(root).mode) == '0o755'
|
assert oct(tarf.getmember(root).mode) == '0o755'
|
||||||
|
|
14
tests/languages/script_test.py
Normal file
14
tests/languages/script_test.py
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pre_commit.languages import script
|
||||||
|
from pre_commit.util import make_executable
|
||||||
|
from testing.language_helpers import run_language
|
||||||
|
|
||||||
|
|
||||||
|
def test_script_language(tmp_path):
|
||||||
|
exe = tmp_path.joinpath('main')
|
||||||
|
exe.write_text('#!/usr/bin/env bash\necho hello hello world\n')
|
||||||
|
make_executable(exe)
|
||||||
|
|
||||||
|
expected = (0, b'hello hello world\n')
|
||||||
|
assert run_language(tmp_path, script, 'main') == expected
|
9
tests/languages/system_test.py
Normal file
9
tests/languages/system_test.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pre_commit.languages import system
|
||||||
|
from testing.language_helpers import run_language
|
||||||
|
|
||||||
|
|
||||||
|
def test_system_language(tmp_path):
|
||||||
|
expected = (0, b'hello hello world\n')
|
||||||
|
assert run_language(tmp_path, system, 'echo hello hello world') == expected
|
|
@ -10,15 +10,12 @@ import pytest
|
||||||
import re_assert
|
import re_assert
|
||||||
|
|
||||||
import pre_commit.constants as C
|
import pre_commit.constants as C
|
||||||
from pre_commit import git
|
from pre_commit import lang_base
|
||||||
|
from pre_commit.all_languages import languages
|
||||||
from pre_commit.clientlib import CONFIG_SCHEMA
|
from pre_commit.clientlib import CONFIG_SCHEMA
|
||||||
from pre_commit.clientlib import load_manifest
|
from pre_commit.clientlib import load_manifest
|
||||||
from pre_commit.envcontext import envcontext
|
|
||||||
from pre_commit.hook import Hook
|
from pre_commit.hook import Hook
|
||||||
from pre_commit.languages import golang
|
|
||||||
from pre_commit.languages import helpers
|
|
||||||
from pre_commit.languages import python
|
from pre_commit.languages import python
|
||||||
from pre_commit.languages.all import languages
|
|
||||||
from pre_commit.prefix import Prefix
|
from pre_commit.prefix import Prefix
|
||||||
from pre_commit.repository import _hook_installed
|
from pre_commit.repository import _hook_installed
|
||||||
from pre_commit.repository import all_hooks
|
from pre_commit.repository import all_hooks
|
||||||
|
@ -28,26 +25,24 @@ from pre_commit.util import cmd_output_b
|
||||||
from testing.fixtures import make_config_from_repo
|
from testing.fixtures import make_config_from_repo
|
||||||
from testing.fixtures import make_repo
|
from testing.fixtures import make_repo
|
||||||
from testing.fixtures import modify_manifest
|
from testing.fixtures import modify_manifest
|
||||||
|
from testing.language_helpers import run_language
|
||||||
from testing.util import cwd
|
from testing.util import cwd
|
||||||
from testing.util import get_resource_path
|
from testing.util import get_resource_path
|
||||||
from testing.util import skipif_cant_run_docker
|
|
||||||
|
|
||||||
|
|
||||||
def _norm_out(b):
|
|
||||||
return b.replace(b'\r\n', b'\n')
|
|
||||||
|
|
||||||
|
|
||||||
def _hook_run(hook, filenames, color):
|
def _hook_run(hook, filenames, color):
|
||||||
with languages[hook.language].in_env(hook.prefix, hook.language_version):
|
return run_language(
|
||||||
return languages[hook.language].run_hook(
|
path=hook.prefix.prefix_dir,
|
||||||
hook.prefix,
|
language=languages[hook.language],
|
||||||
hook.entry,
|
exe=hook.entry,
|
||||||
hook.args,
|
args=hook.args,
|
||||||
filenames,
|
file_args=filenames,
|
||||||
is_local=hook.src == 'local',
|
version=hook.language_version,
|
||||||
require_serial=hook.require_serial,
|
deps=hook.additional_dependencies,
|
||||||
color=color,
|
is_local=hook.src == 'local',
|
||||||
)
|
require_serial=hook.require_serial,
|
||||||
|
color=color,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _get_hook_no_install(repo_config, store, hook_id):
|
def _get_hook_no_install(repo_config, store, hook_id):
|
||||||
|
@ -81,7 +76,7 @@ def _test_hook_repo(
|
||||||
hook = _get_hook(config, store, hook_id)
|
hook = _get_hook(config, store, hook_id)
|
||||||
ret, out = _hook_run(hook, args, color=color)
|
ret, out = _hook_run(hook, args, color=color)
|
||||||
assert ret == expected_return_code
|
assert ret == expected_return_code
|
||||||
assert _norm_out(out) == expected
|
assert out == expected
|
||||||
|
|
||||||
|
|
||||||
def test_python_hook(tempdir_factory, store):
|
def test_python_hook(tempdir_factory, store):
|
||||||
|
@ -129,66 +124,21 @@ def test_python_hook_weird_setup_cfg(in_git_dir, tempdir_factory, store):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_python_venv(tempdir_factory, store):
|
def test_python_venv_deprecation(store, caplog):
|
||||||
_test_hook_repo(
|
config = {
|
||||||
tempdir_factory, store, 'python_venv_hooks_repo',
|
'repo': 'local',
|
||||||
'foo', [os.devnull],
|
'hooks': [{
|
||||||
f'[{os.devnull!r}]\nHello World\n'.encode(),
|
'id': 'example',
|
||||||
)
|
'name': 'example',
|
||||||
|
'language': 'python_venv',
|
||||||
|
'entry': 'echo hi',
|
||||||
def test_language_versioned_python_hook(tempdir_factory, store):
|
}],
|
||||||
# we patch this force virtualenv executing with `-p` since we can't
|
}
|
||||||
# reliably have multiple pythons available in CI
|
_get_hook(config, store, 'example')
|
||||||
with mock.patch.object(
|
assert caplog.messages[-1] == (
|
||||||
python,
|
'`repo: local` uses deprecated `language: python_venv`. '
|
||||||
'_sys_executable_matches',
|
'This is an alias for `language: python`. '
|
||||||
return_value=False,
|
'Often `pre-commit autoupdate --repo local` will fix this.'
|
||||||
):
|
|
||||||
_test_hook_repo(
|
|
||||||
tempdir_factory, store, 'python3_hooks_repo',
|
|
||||||
'python3-hook',
|
|
||||||
[os.devnull],
|
|
||||||
f'3\n[{os.devnull!r}]\nHello World\n'.encode(),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@skipif_cant_run_docker # pragma: win32 no cover
|
|
||||||
def test_run_a_docker_hook(tempdir_factory, store):
|
|
||||||
_test_hook_repo(
|
|
||||||
tempdir_factory, store, 'docker_hooks_repo',
|
|
||||||
'docker-hook',
|
|
||||||
['Hello World from docker'], b'Hello World from docker\n',
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@skipif_cant_run_docker # pragma: win32 no cover
|
|
||||||
def test_run_a_docker_hook_with_entry_args(tempdir_factory, store):
|
|
||||||
_test_hook_repo(
|
|
||||||
tempdir_factory, store, 'docker_hooks_repo',
|
|
||||||
'docker-hook-arg',
|
|
||||||
['Hello World from docker'], b'Hello World from docker',
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@skipif_cant_run_docker # pragma: win32 no cover
|
|
||||||
def test_run_a_failing_docker_hook(tempdir_factory, store):
|
|
||||||
_test_hook_repo(
|
|
||||||
tempdir_factory, store, 'docker_hooks_repo',
|
|
||||||
'docker-hook-failing',
|
|
||||||
['Hello World from docker'],
|
|
||||||
mock.ANY, # an error message about `bork` not existing
|
|
||||||
expected_return_code=127,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@skipif_cant_run_docker # pragma: win32 no cover
|
|
||||||
@pytest.mark.parametrize('hook_id', ('echo-entrypoint', 'echo-cmd'))
|
|
||||||
def test_run_a_docker_image_hook(tempdir_factory, store, hook_id):
|
|
||||||
_test_hook_repo(
|
|
||||||
tempdir_factory, store, 'docker_image_hooks_repo',
|
|
||||||
hook_id,
|
|
||||||
['Hello World from docker'], b'Hello World from docker\n',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -199,92 +149,6 @@ def test_system_hook_with_spaces(tempdir_factory, store):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_golang_system_hook(tempdir_factory, store):
|
|
||||||
_test_hook_repo(
|
|
||||||
tempdir_factory, store, 'golang_hooks_repo',
|
|
||||||
'golang-hook', ['system'], b'hello world from system\n',
|
|
||||||
config_kwargs={
|
|
||||||
'hooks': [{
|
|
||||||
'id': 'golang-hook',
|
|
||||||
'language_version': 'system',
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_golang_versioned_hook(tempdir_factory, store):
|
|
||||||
_test_hook_repo(
|
|
||||||
tempdir_factory, store, 'golang_hooks_repo',
|
|
||||||
'golang-hook', [], b'hello world from go1.18.4\n',
|
|
||||||
config_kwargs={
|
|
||||||
'hooks': [{
|
|
||||||
'id': 'golang-hook',
|
|
||||||
'language_version': '1.18.4',
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_golang_hook_still_works_when_gobin_is_set(tempdir_factory, store):
|
|
||||||
gobin_dir = tempdir_factory.get()
|
|
||||||
with envcontext((('GOBIN', gobin_dir),)):
|
|
||||||
test_golang_system_hook(tempdir_factory, store)
|
|
||||||
assert os.listdir(gobin_dir) == []
|
|
||||||
|
|
||||||
|
|
||||||
def test_golang_with_recursive_submodule(tmpdir, tempdir_factory, store):
|
|
||||||
sub_go = '''\
|
|
||||||
package sub
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
func Func() {
|
|
||||||
fmt.Println("hello hello world")
|
|
||||||
}
|
|
||||||
'''
|
|
||||||
sub = tmpdir.join('sub').ensure_dir()
|
|
||||||
sub.join('sub.go').write(sub_go)
|
|
||||||
cmd_output('git', '-C', str(sub), 'init', '.')
|
|
||||||
cmd_output('git', '-C', str(sub), 'add', '.')
|
|
||||||
git.commit(str(sub))
|
|
||||||
|
|
||||||
pre_commit_hooks = '''\
|
|
||||||
- id: example
|
|
||||||
name: example
|
|
||||||
entry: example
|
|
||||||
language: golang
|
|
||||||
verbose: true
|
|
||||||
'''
|
|
||||||
go_mod = '''\
|
|
||||||
module github.com/asottile/example
|
|
||||||
|
|
||||||
go 1.14
|
|
||||||
'''
|
|
||||||
main_go = '''\
|
|
||||||
package main
|
|
||||||
|
|
||||||
import "github.com/asottile/example/sub"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
sub.Func()
|
|
||||||
}
|
|
||||||
'''
|
|
||||||
repo = tmpdir.join('repo').ensure_dir()
|
|
||||||
repo.join('.pre-commit-hooks.yaml').write(pre_commit_hooks)
|
|
||||||
repo.join('go.mod').write(go_mod)
|
|
||||||
repo.join('main.go').write(main_go)
|
|
||||||
cmd_output('git', '-C', str(repo), 'init', '.')
|
|
||||||
cmd_output('git', '-C', str(repo), 'add', '.')
|
|
||||||
cmd_output('git', '-C', str(repo), 'submodule', 'add', str(sub), 'sub')
|
|
||||||
git.commit(str(repo))
|
|
||||||
|
|
||||||
config = make_config_from_repo(str(repo))
|
|
||||||
hook = _get_hook(config, store, 'example')
|
|
||||||
ret, out = _hook_run(hook, (), color=False)
|
|
||||||
assert ret == 0
|
|
||||||
assert _norm_out(out) == b'hello hello world\n'
|
|
||||||
|
|
||||||
|
|
||||||
def test_missing_executable(tempdir_factory, store):
|
def test_missing_executable(tempdir_factory, store):
|
||||||
_test_hook_repo(
|
_test_hook_repo(
|
||||||
tempdir_factory, store, 'not_found_exe',
|
tempdir_factory, store, 'not_found_exe',
|
||||||
|
@ -345,52 +209,6 @@ def test_output_isatty(tempdir_factory, store):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _make_grep_repo(entry, store, args=()):
|
|
||||||
config = {
|
|
||||||
'repo': 'local',
|
|
||||||
'hooks': [{
|
|
||||||
'id': 'grep-hook',
|
|
||||||
'name': 'grep-hook',
|
|
||||||
'language': 'pygrep',
|
|
||||||
'entry': entry,
|
|
||||||
'args': args,
|
|
||||||
'types': ['text'],
|
|
||||||
}],
|
|
||||||
}
|
|
||||||
return _get_hook(config, store, 'grep-hook')
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def greppable_files(tmpdir):
|
|
||||||
with tmpdir.as_cwd():
|
|
||||||
cmd_output_b('git', 'init', '.')
|
|
||||||
tmpdir.join('f1').write_binary(b"hello'hi\nworld\n")
|
|
||||||
tmpdir.join('f2').write_binary(b'foo\nbar\nbaz\n')
|
|
||||||
tmpdir.join('f3').write_binary(b'[WARN] hi\n')
|
|
||||||
yield tmpdir
|
|
||||||
|
|
||||||
|
|
||||||
def test_grep_hook_matching(greppable_files, store):
|
|
||||||
hook = _make_grep_repo('ello', store)
|
|
||||||
ret, out = _hook_run(hook, ('f1', 'f2', 'f3'), color=False)
|
|
||||||
assert ret == 1
|
|
||||||
assert _norm_out(out) == b"f1:1:hello'hi\n"
|
|
||||||
|
|
||||||
|
|
||||||
def test_grep_hook_case_insensitive(greppable_files, store):
|
|
||||||
hook = _make_grep_repo('ELLO', store, args=['-i'])
|
|
||||||
ret, out = _hook_run(hook, ('f1', 'f2', 'f3'), color=False)
|
|
||||||
assert ret == 1
|
|
||||||
assert _norm_out(out) == b"f1:1:hello'hi\n"
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('regex', ('nope', "foo'bar", r'^\[INFO\]'))
|
|
||||||
def test_grep_hook_not_matching(regex, greppable_files, store):
|
|
||||||
hook = _make_grep_repo(regex, store)
|
|
||||||
ret, out = _hook_run(hook, ('f1', 'f2', 'f3'), color=False)
|
|
||||||
assert (ret, out) == (0, b'')
|
|
||||||
|
|
||||||
|
|
||||||
def _norm_pwd(path):
|
def _norm_pwd(path):
|
||||||
# Under windows bash's temp and windows temp is different.
|
# Under windows bash's temp and windows temp is different.
|
||||||
# This normalizes to the bash /tmp
|
# This normalizes to the bash /tmp
|
||||||
|
@ -440,7 +258,7 @@ def test_repository_state_compatibility(tempdir_factory, store, v):
|
||||||
|
|
||||||
config = make_config_from_repo(path)
|
config = make_config_from_repo(path)
|
||||||
hook = _get_hook(config, store, 'foo')
|
hook = _get_hook(config, store, 'foo')
|
||||||
envdir = helpers.environment_dir(
|
envdir = lang_base.environment_dir(
|
||||||
hook.prefix,
|
hook.prefix,
|
||||||
python.ENVIRONMENT_DIR,
|
python.ENVIRONMENT_DIR,
|
||||||
hook.language_version,
|
hook.language_version,
|
||||||
|
@ -449,67 +267,6 @@ def test_repository_state_compatibility(tempdir_factory, store, v):
|
||||||
assert _hook_installed(hook) is True
|
assert _hook_installed(hook) is True
|
||||||
|
|
||||||
|
|
||||||
def test_additional_golang_dependencies_installed(
|
|
||||||
tempdir_factory, store,
|
|
||||||
):
|
|
||||||
path = make_repo(tempdir_factory, 'golang_hooks_repo')
|
|
||||||
config = make_config_from_repo(path)
|
|
||||||
# A small go package
|
|
||||||
deps = ['golang.org/x/example/hello@latest']
|
|
||||||
config['hooks'][0]['additional_dependencies'] = deps
|
|
||||||
hook = _get_hook(config, store, 'golang-hook')
|
|
||||||
envdir = helpers.environment_dir(
|
|
||||||
hook.prefix,
|
|
||||||
golang.ENVIRONMENT_DIR,
|
|
||||||
golang.get_default_version(),
|
|
||||||
)
|
|
||||||
binaries = os.listdir(os.path.join(envdir, 'bin'))
|
|
||||||
# normalize for windows
|
|
||||||
binaries = [os.path.splitext(binary)[0] for binary in binaries]
|
|
||||||
assert 'hello' in binaries
|
|
||||||
|
|
||||||
|
|
||||||
def test_local_golang_additional_dependencies(store):
|
|
||||||
config = {
|
|
||||||
'repo': 'local',
|
|
||||||
'hooks': [{
|
|
||||||
'id': 'hello',
|
|
||||||
'name': 'hello',
|
|
||||||
'entry': 'hello',
|
|
||||||
'language': 'golang',
|
|
||||||
'additional_dependencies': ['golang.org/x/example/hello@latest'],
|
|
||||||
}],
|
|
||||||
}
|
|
||||||
hook = _get_hook(config, store, 'hello')
|
|
||||||
ret, out = _hook_run(hook, (), color=False)
|
|
||||||
assert ret == 0
|
|
||||||
assert _norm_out(out) == b'Hello, Go examples!\n'
|
|
||||||
|
|
||||||
|
|
||||||
def test_fail_hooks(store):
|
|
||||||
config = {
|
|
||||||
'repo': 'local',
|
|
||||||
'hooks': [{
|
|
||||||
'id': 'fail',
|
|
||||||
'name': 'fail',
|
|
||||||
'language': 'fail',
|
|
||||||
'entry': 'make sure to name changelogs as .rst!',
|
|
||||||
'files': r'changelog/.*(?<!\.rst)$',
|
|
||||||
}],
|
|
||||||
}
|
|
||||||
hook = _get_hook(config, store, 'fail')
|
|
||||||
ret, out = _hook_run(
|
|
||||||
hook, ('changelog/123.bugfix', 'changelog/wat'), color=False,
|
|
||||||
)
|
|
||||||
assert ret == 1
|
|
||||||
assert out == (
|
|
||||||
b'make sure to name changelogs as .rst!\n'
|
|
||||||
b'\n'
|
|
||||||
b'changelog/123.bugfix\n'
|
|
||||||
b'changelog/wat\n'
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_unknown_keys(store, caplog):
|
def test_unknown_keys(store, caplog):
|
||||||
config = {
|
config = {
|
||||||
'repo': 'local',
|
'repo': 'local',
|
||||||
|
@ -553,7 +310,7 @@ def test_control_c_control_c_on_install(tempdir_factory, store):
|
||||||
# raise as well.
|
# raise as well.
|
||||||
with pytest.raises(MyKeyboardInterrupt):
|
with pytest.raises(MyKeyboardInterrupt):
|
||||||
with mock.patch.object(
|
with mock.patch.object(
|
||||||
helpers, 'run_setup_cmd', side_effect=MyKeyboardInterrupt,
|
lang_base, 'setup_cmd', side_effect=MyKeyboardInterrupt,
|
||||||
):
|
):
|
||||||
with mock.patch.object(
|
with mock.patch.object(
|
||||||
shutil, 'rmtree', side_effect=MyKeyboardInterrupt,
|
shutil, 'rmtree', side_effect=MyKeyboardInterrupt,
|
||||||
|
@ -562,7 +319,7 @@ def test_control_c_control_c_on_install(tempdir_factory, store):
|
||||||
|
|
||||||
# Should have made an environment, however this environment is broken!
|
# Should have made an environment, however this environment is broken!
|
||||||
hook, = hooks
|
hook, = hooks
|
||||||
envdir = helpers.environment_dir(
|
envdir = lang_base.environment_dir(
|
||||||
hook.prefix,
|
hook.prefix,
|
||||||
python.ENVIRONMENT_DIR,
|
python.ENVIRONMENT_DIR,
|
||||||
hook.language_version,
|
hook.language_version,
|
||||||
|
@ -585,7 +342,7 @@ def test_invalidated_virtualenv(tempdir_factory, store):
|
||||||
hook = _get_hook(config, store, 'foo')
|
hook = _get_hook(config, store, 'foo')
|
||||||
|
|
||||||
# Simulate breaking of the virtualenv
|
# Simulate breaking of the virtualenv
|
||||||
envdir = helpers.environment_dir(
|
envdir = lang_base.environment_dir(
|
||||||
hook.prefix,
|
hook.prefix,
|
||||||
python.ENVIRONMENT_DIR,
|
python.ENVIRONMENT_DIR,
|
||||||
hook.language_version,
|
hook.language_version,
|
||||||
|
@ -667,7 +424,7 @@ def test_local_python_repo(store, local_python_config):
|
||||||
assert hook.language_version != C.DEFAULT
|
assert hook.language_version != C.DEFAULT
|
||||||
ret, out = _hook_run(hook, ('filename',), color=False)
|
ret, out = _hook_run(hook, ('filename',), color=False)
|
||||||
assert ret == 0
|
assert ret == 0
|
||||||
assert _norm_out(out) == b"['filename']\nHello World\n"
|
assert out == b"['filename']\nHello World\n"
|
||||||
|
|
||||||
|
|
||||||
def test_default_language_version(store, local_python_config):
|
def test_default_language_version(store, local_python_config):
|
||||||
|
@ -781,22 +538,6 @@ def test_manifest_hooks(tempdir_factory, store):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
'repo',
|
|
||||||
(
|
|
||||||
'dotnet_hooks_csproj_repo',
|
|
||||||
'dotnet_hooks_sln_repo',
|
|
||||||
'dotnet_hooks_combo_repo',
|
|
||||||
'dotnet_hooks_csproj_prefix_repo',
|
|
||||||
),
|
|
||||||
)
|
|
||||||
def test_dotnet_hook(tempdir_factory, store, repo):
|
|
||||||
_test_hook_repo(
|
|
||||||
tempdir_factory, store, repo,
|
|
||||||
'dotnet-example-hook', [], b'Hello from dotnet!\n',
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_non_installable_hook_error_for_language_version(store, caplog):
|
def test_non_installable_hook_error_for_language_version(store, caplog):
|
||||||
config = {
|
config = {
|
||||||
'repo': 'local',
|
'repo': 'local',
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import contextlib
|
||||||
import itertools
|
import itertools
|
||||||
import os.path
|
import os.path
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
import re_assert
|
||||||
|
|
||||||
from pre_commit import git
|
from pre_commit import git
|
||||||
|
from pre_commit.errors import FatalError
|
||||||
from pre_commit.staged_files_only import staged_files_only
|
from pre_commit.staged_files_only import staged_files_only
|
||||||
from pre_commit.util import cmd_output
|
from pre_commit.util import cmd_output
|
||||||
from testing.auto_namedtuple import auto_namedtuple
|
from testing.auto_namedtuple import auto_namedtuple
|
||||||
|
@ -14,6 +17,7 @@ from testing.fixtures import git_dir
|
||||||
from testing.util import cwd
|
from testing.util import cwd
|
||||||
from testing.util import get_resource_path
|
from testing.util import get_resource_path
|
||||||
from testing.util import git_commit
|
from testing.util import git_commit
|
||||||
|
from testing.util import xfailif_windows
|
||||||
|
|
||||||
|
|
||||||
FOO_CONTENTS = '\n'.join(('1', '2', '3', '4', '5', '6', '7', '8', ''))
|
FOO_CONTENTS = '\n'.join(('1', '2', '3', '4', '5', '6', '7', '8', ''))
|
||||||
|
@ -382,3 +386,49 @@ def test_intent_to_add(in_git_dir, patch_dir):
|
||||||
with staged_files_only(patch_dir):
|
with staged_files_only(patch_dir):
|
||||||
assert_no_diff()
|
assert_no_diff()
|
||||||
assert git.intent_to_add_files() == ['foo']
|
assert git.intent_to_add_files() == ['foo']
|
||||||
|
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def _unreadable(f):
|
||||||
|
orig = os.stat(f).st_mode
|
||||||
|
os.chmod(f, 0o000)
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
os.chmod(f, orig)
|
||||||
|
|
||||||
|
|
||||||
|
@xfailif_windows # pragma: win32 no cover
|
||||||
|
def test_failed_diff_does_not_discard_changes(in_git_dir, patch_dir):
|
||||||
|
# stage 3 files
|
||||||
|
for i in range(3):
|
||||||
|
with open(str(i), 'w') as f:
|
||||||
|
f.write(str(i))
|
||||||
|
cmd_output('git', 'add', '0', '1', '2')
|
||||||
|
|
||||||
|
# modify all of their contents
|
||||||
|
for i in range(3):
|
||||||
|
with open(str(i), 'w') as f:
|
||||||
|
f.write('new contents')
|
||||||
|
|
||||||
|
with _unreadable('1'):
|
||||||
|
with pytest.raises(FatalError) as excinfo:
|
||||||
|
with staged_files_only(patch_dir):
|
||||||
|
raise AssertionError('should have errored on enter')
|
||||||
|
|
||||||
|
# the diff command failed to produce a diff of `1`
|
||||||
|
msg, = excinfo.value.args
|
||||||
|
re_assert.Matches(
|
||||||
|
r'^pre-commit failed to diff -- perhaps due to permissions\?\n\n'
|
||||||
|
r'command: .*\n'
|
||||||
|
r'return code: 128\n'
|
||||||
|
r'stdout: \(none\)\n'
|
||||||
|
r'stderr:\n'
|
||||||
|
r' error: open\("1"\): Permission denied\n'
|
||||||
|
r' fatal: cannot hash 1$',
|
||||||
|
).assert_matches(msg)
|
||||||
|
|
||||||
|
# even though it errored, the unstaged changes should still be present
|
||||||
|
for i in range(3):
|
||||||
|
with open(str(i)) as f:
|
||||||
|
assert f.read() == 'new contents'
|
||||||
|
|
|
@ -180,7 +180,7 @@ def test_create_when_store_already_exists(store):
|
||||||
|
|
||||||
def test_db_repo_name(store):
|
def test_db_repo_name(store):
|
||||||
assert store.db_repo_name('repo', ()) == 'repo'
|
assert store.db_repo_name('repo', ()) == 'repo'
|
||||||
assert store.db_repo_name('repo', ('b', 'a', 'c')) == 'repo:a,b,c'
|
assert store.db_repo_name('repo', ('b', 'a', 'c')) == 'repo:b,a,c'
|
||||||
|
|
||||||
|
|
||||||
def test_local_resources_reflects_reality():
|
def test_local_resources_reflects_reality():
|
||||||
|
@ -246,3 +246,27 @@ def test_mark_config_as_used_readonly(tmpdir):
|
||||||
# should be skipped due to readonly
|
# should be skipped due to readonly
|
||||||
store.mark_config_used(str(cfg))
|
store.mark_config_used(str(cfg))
|
||||||
assert store.select_all_configs() == []
|
assert store.select_all_configs() == []
|
||||||
|
|
||||||
|
|
||||||
|
def test_clone_with_recursive_submodules(store, tmp_path):
|
||||||
|
sub = tmp_path.joinpath('sub')
|
||||||
|
sub.mkdir()
|
||||||
|
sub.joinpath('submodule').write_text('i am a submodule')
|
||||||
|
cmd_output('git', '-C', str(sub), 'init', '.')
|
||||||
|
cmd_output('git', '-C', str(sub), 'add', '.')
|
||||||
|
git.commit(str(sub))
|
||||||
|
|
||||||
|
repo = tmp_path.joinpath('repo')
|
||||||
|
repo.mkdir()
|
||||||
|
repo.joinpath('repository').write_text('i am a repo')
|
||||||
|
cmd_output('git', '-C', str(repo), 'init', '.')
|
||||||
|
cmd_output('git', '-C', str(repo), 'add', '.')
|
||||||
|
cmd_output('git', '-C', str(repo), 'submodule', 'add', str(sub), 'sub')
|
||||||
|
git.commit(str(repo))
|
||||||
|
|
||||||
|
rev = git.head_rev(str(repo))
|
||||||
|
ret = store.clone(str(repo), rev)
|
||||||
|
|
||||||
|
assert os.path.exists(ret)
|
||||||
|
assert os.path.exists(os.path.join(ret, str(repo), 'repository'))
|
||||||
|
assert os.path.exists(os.path.join(ret, str(sub), 'submodule'))
|
||||||
|
|
|
@ -16,7 +16,7 @@ from pre_commit.util import rmtree
|
||||||
|
|
||||||
|
|
||||||
def test_CalledProcessError_str():
|
def test_CalledProcessError_str():
|
||||||
error = CalledProcessError(1, ('exe',), b'output', b'errors')
|
error = CalledProcessError(1, ('exe',), b'output\n', b'errors\n')
|
||||||
assert str(error) == (
|
assert str(error) == (
|
||||||
"command: ('exe',)\n"
|
"command: ('exe',)\n"
|
||||||
'return code: 1\n'
|
'return code: 1\n'
|
||||||
|
|
4
tox.ini
4
tox.ini
|
@ -6,8 +6,8 @@ deps = -rrequirements-dev.txt
|
||||||
passenv = *
|
passenv = *
|
||||||
commands =
|
commands =
|
||||||
coverage erase
|
coverage erase
|
||||||
coverage run -m pytest {posargs:tests}
|
coverage run -m pytest {posargs:tests} --ignore=tests/languages
|
||||||
coverage report
|
coverage report --omit=pre_commit/languages/*,tests/languages/*
|
||||||
|
|
||||||
[testenv:pre-commit]
|
[testenv:pre-commit]
|
||||||
skip_install = true
|
skip_install = true
|
||||||
|
|
Loading…
Add table
Reference in a new issue