feat: add options for disabling venv in python

This commit is contained in:
alec.tu 2024-03-28 15:41:28 +08:00
parent 7b4667e9e6
commit 9cbd9f69ff
3 changed files with 45 additions and 24 deletions

View file

@ -132,6 +132,7 @@ MANIFEST_HOOK_DICT = cfgv.Map(
cfgv.Optional('language_version', cfgv.check_string, C.DEFAULT), cfgv.Optional('language_version', cfgv.check_string, C.DEFAULT),
cfgv.Optional('log_file', cfgv.check_string, ''), cfgv.Optional('log_file', cfgv.check_string, ''),
cfgv.Optional('require_serial', cfgv.check_bool, False), cfgv.Optional('require_serial', cfgv.check_bool, False),
cfgv.Optional('require_venv', cfgv.check_bool, True),
StagesMigration('stages', []), StagesMigration('stages', []),
cfgv.Optional('verbose', cfgv.check_bool, False), cfgv.Optional('verbose', cfgv.check_bool, False),
) )

View file

@ -33,6 +33,7 @@ class Hook(NamedTuple):
log_file: str log_file: str
minimum_pre_commit_version: str minimum_pre_commit_version: str
require_serial: bool require_serial: bool
require_venv: bool
stages: Sequence[str] stages: Sequence[str]
verbose: bool verbose: bool

View file

@ -1,5 +1,6 @@
from __future__ import annotations from __future__ import annotations
import sys
import json import json
import logging import logging
import os import os
@ -84,35 +85,52 @@ def _hook_install(hook: Hook) -> None:
lang.ENVIRONMENT_DIR, lang.ENVIRONMENT_DIR,
hook.language_version, hook.language_version,
) )
if hook.language == 'python' and not hook.require_venv:
logger.info(f'Disabling creation of virtual environment for hook {hook.src}')
# Path to the Python executable inside the virtual environment
python_executable = sys.executable
# There's potentially incomplete cleanup from previous runs # Get the directory containing the Python executable
# Clean it up! executable_dir = os.path.dirname(python_executable)
if os.path.exists(venv): # Virtual environment's base directory is one level up from the executable directory
rmtree(venv) venv_dir = os.path.dirname(executable_dir)
# Remove existing directory or link if necessary
if os.path.islink(venv):
os.remove(venv)
if os.path.exists(venv):
rmtree(venv)
# Create a symbolic link pointing venv_dir to envdir
os.symlink(venv_dir, venv)
else:
# There's potentially incomplete cleanup from previous runs
# Clean it up!
if os.path.exists(venv):
rmtree(venv)
with clean_path_on_failure(venv): with clean_path_on_failure(venv):
lang.install_environment( lang.install_environment(
hook.prefix, hook.language_version, hook.additional_dependencies, hook.prefix, hook.language_version, hook.additional_dependencies,
)
health_error = lang.health_check(hook.prefix, hook.language_version)
if health_error:
raise AssertionError(
f'BUG: expected environment for {hook.language} to be healthy '
f'immediately after install, please open an issue describing '
f'your environment\n\n'
f'more info:\n\n{health_error}',
) )
health_error = lang.health_check(hook.prefix, hook.language_version)
if health_error:
raise AssertionError(
f'BUG: expected environment for {hook.language} to be healthy '
f'immediately after install, please open an issue describing '
f'your environment\n\n'
f'more info:\n\n{health_error}',
)
# TODO: remove v1 state writing, no longer needed after pre-commit 3.0 # TODO: remove v1 state writing, no longer needed after pre-commit 3.0
# Write our state to indicate we're installed # Write our state to indicate we're installed
state_filename = _state_filename_v1(venv) state_filename = _state_filename_v1(venv)
staging = f'{state_filename}staging' staging = f'{state_filename}staging'
with open(staging, 'w') as state_file: with open(staging, 'w') as state_file:
state_file.write(json.dumps(_state(hook.additional_dependencies))) state_file.write(json.dumps(_state(hook.additional_dependencies)))
# Move the file into place atomically to indicate we've installed # Move the file into place atomically to indicate we've installed
os.replace(staging, state_filename) os.replace(staging, state_filename)
open(_state_filename_v2(venv), 'a+').close() open(_state_filename_v2(venv), 'a+').close()
def _hook( def _hook(
@ -225,6 +243,7 @@ def install_hook_envs(hooks: Sequence[Hook], store: Store) -> None:
seen: set[tuple[Prefix, str, str, tuple[str, ...]]] = set() seen: set[tuple[Prefix, str, str, tuple[str, ...]]] = set()
ret = [] ret = []
for hook in hooks: for hook in hooks:
# print(f'hook={hook.src}, install_key={hook.install_key}')
if hook.install_key not in seen and not _hook_installed(hook): if hook.install_key not in seen and not _hook_installed(hook):
ret.append(hook) ret.append(hook)
seen.add(hook.install_key) seen.add(hook.install_key)