pre-commit-ex 4.5.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pre_commit/__init__.py +0 -0
- pre_commit/__main__.py +7 -0
- pre_commit/all_languages.py +50 -0
- pre_commit/clientlib.py +551 -0
- pre_commit/color.py +109 -0
- pre_commit/commands/__init__.py +0 -0
- pre_commit/commands/autoupdate.py +215 -0
- pre_commit/commands/clean.py +16 -0
- pre_commit/commands/gc.py +98 -0
- pre_commit/commands/hazmat.py +95 -0
- pre_commit/commands/hook_impl.py +272 -0
- pre_commit/commands/init_templatedir.py +39 -0
- pre_commit/commands/install_uninstall.py +167 -0
- pre_commit/commands/migrate_config.py +135 -0
- pre_commit/commands/run.py +474 -0
- pre_commit/commands/sample_config.py +18 -0
- pre_commit/commands/try_repo.py +77 -0
- pre_commit/commands/validate_config.py +18 -0
- pre_commit/commands/validate_manifest.py +18 -0
- pre_commit/constants.py +13 -0
- pre_commit/envcontext.py +62 -0
- pre_commit/error_handler.py +81 -0
- pre_commit/errors.py +5 -0
- pre_commit/file_lock.py +75 -0
- pre_commit/git.py +245 -0
- pre_commit/hook.py +60 -0
- pre_commit/lang_base.py +196 -0
- pre_commit/languages/__init__.py +0 -0
- pre_commit/languages/conda.py +77 -0
- pre_commit/languages/coursier.py +76 -0
- pre_commit/languages/dart.py +97 -0
- pre_commit/languages/docker.py +181 -0
- pre_commit/languages/docker_image.py +32 -0
- pre_commit/languages/dotnet.py +111 -0
- pre_commit/languages/fail.py +27 -0
- pre_commit/languages/golang.py +161 -0
- pre_commit/languages/haskell.py +56 -0
- pre_commit/languages/julia.py +133 -0
- pre_commit/languages/lua.py +75 -0
- pre_commit/languages/node.py +110 -0
- pre_commit/languages/perl.py +50 -0
- pre_commit/languages/pygrep.py +133 -0
- pre_commit/languages/python.py +228 -0
- pre_commit/languages/r.py +278 -0
- pre_commit/languages/ruby.py +145 -0
- pre_commit/languages/rust.py +160 -0
- pre_commit/languages/swift.py +50 -0
- pre_commit/languages/unsupported.py +10 -0
- pre_commit/languages/unsupported_script.py +32 -0
- pre_commit/logging_handler.py +42 -0
- pre_commit/main.py +472 -0
- pre_commit/meta_hooks/__init__.py +0 -0
- pre_commit/meta_hooks/check_hooks_apply.py +43 -0
- pre_commit/meta_hooks/check_useless_excludes.py +83 -0
- pre_commit/meta_hooks/identity.py +17 -0
- pre_commit/output.py +33 -0
- pre_commit/parse_shebang.py +85 -0
- pre_commit/prefix.py +18 -0
- pre_commit/repository.py +237 -0
- pre_commit/resources/__init__.py +0 -0
- pre_commit/resources/empty_template_.npmignore +1 -0
- pre_commit/resources/empty_template_Cargo.toml +7 -0
- pre_commit/resources/empty_template_LICENSE.renv +7 -0
- pre_commit/resources/empty_template_Makefile.PL +6 -0
- pre_commit/resources/empty_template_activate.R +440 -0
- pre_commit/resources/empty_template_environment.yml +9 -0
- pre_commit/resources/empty_template_go.mod +1 -0
- pre_commit/resources/empty_template_main.go +3 -0
- pre_commit/resources/empty_template_main.rs +1 -0
- pre_commit/resources/empty_template_package.json +4 -0
- pre_commit/resources/empty_template_pre-commit-package-dev-1.rockspec +12 -0
- pre_commit/resources/empty_template_pre_commit_placeholder_package.gemspec +6 -0
- pre_commit/resources/empty_template_pubspec.yaml +4 -0
- pre_commit/resources/empty_template_renv.lock +20 -0
- pre_commit/resources/empty_template_setup.py +4 -0
- pre_commit/resources/hook-tmpl +20 -0
- pre_commit/resources/rbenv.tar.gz +0 -0
- pre_commit/resources/ruby-build.tar.gz +0 -0
- pre_commit/resources/ruby-download.tar.gz +0 -0
- pre_commit/staged_files_only.py +113 -0
- pre_commit/store.py +235 -0
- pre_commit/util.py +239 -0
- pre_commit/xargs.py +184 -0
- pre_commit/yaml.py +19 -0
- pre_commit/yaml_rewrite.py +52 -0
- pre_commit_ex-4.5.1.dist-info/METADATA +63 -0
- pre_commit_ex-4.5.1.dist-info/RECORD +91 -0
- pre_commit_ex-4.5.1.dist-info/WHEEL +6 -0
- pre_commit_ex-4.5.1.dist-info/entry_points.txt +2 -0
- pre_commit_ex-4.5.1.dist-info/licenses/LICENSE +19 -0
- pre_commit_ex-4.5.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import contextlib
|
|
4
|
+
import functools
|
|
5
|
+
import json
|
|
6
|
+
import os.path
|
|
7
|
+
import platform
|
|
8
|
+
import shutil
|
|
9
|
+
import sys
|
|
10
|
+
import tarfile
|
|
11
|
+
import tempfile
|
|
12
|
+
import urllib.error
|
|
13
|
+
import urllib.request
|
|
14
|
+
import zipfile
|
|
15
|
+
from collections.abc import Generator
|
|
16
|
+
from collections.abc import Sequence
|
|
17
|
+
from typing import ContextManager
|
|
18
|
+
from typing import IO
|
|
19
|
+
from typing import Protocol
|
|
20
|
+
|
|
21
|
+
import pre_commit.constants as C
|
|
22
|
+
from pre_commit import lang_base
|
|
23
|
+
from pre_commit.envcontext import envcontext
|
|
24
|
+
from pre_commit.envcontext import PatchesT
|
|
25
|
+
from pre_commit.envcontext import Var
|
|
26
|
+
from pre_commit.git import no_git_env
|
|
27
|
+
from pre_commit.prefix import Prefix
|
|
28
|
+
from pre_commit.util import cmd_output
|
|
29
|
+
from pre_commit.util import rmtree
|
|
30
|
+
|
|
31
|
+
ENVIRONMENT_DIR = 'golangenv'
|
|
32
|
+
health_check = lang_base.basic_health_check
|
|
33
|
+
run_hook = lang_base.basic_run_hook
|
|
34
|
+
|
|
35
|
+
_ARCH_ALIASES = {
|
|
36
|
+
'x86_64': 'amd64',
|
|
37
|
+
'i386': '386',
|
|
38
|
+
'aarch64': 'arm64',
|
|
39
|
+
'armv8': 'arm64',
|
|
40
|
+
'armv7l': 'armv6l',
|
|
41
|
+
}
|
|
42
|
+
_ARCH = platform.machine().lower()
|
|
43
|
+
_ARCH = _ARCH_ALIASES.get(_ARCH, _ARCH)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class ExtractAll(Protocol):
|
|
47
|
+
def extractall(self, path: str) -> None: ...
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
if sys.platform == 'win32': # pragma: win32 cover
|
|
51
|
+
_EXT = 'zip'
|
|
52
|
+
|
|
53
|
+
def _open_archive(bio: IO[bytes]) -> ContextManager[ExtractAll]:
|
|
54
|
+
return zipfile.ZipFile(bio)
|
|
55
|
+
else: # pragma: win32 no cover
|
|
56
|
+
_EXT = 'tar.gz'
|
|
57
|
+
|
|
58
|
+
def _open_archive(bio: IO[bytes]) -> ContextManager[ExtractAll]:
|
|
59
|
+
return tarfile.open(fileobj=bio)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@functools.lru_cache(maxsize=1)
|
|
63
|
+
def get_default_version() -> str:
|
|
64
|
+
if lang_base.exe_exists('go'):
|
|
65
|
+
return 'system'
|
|
66
|
+
else:
|
|
67
|
+
return C.DEFAULT
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def get_env_patch(venv: str, version: str) -> PatchesT:
|
|
71
|
+
if version == 'system':
|
|
72
|
+
return (
|
|
73
|
+
('PATH', (os.path.join(venv, 'bin'), os.pathsep, Var('PATH'))),
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
('GOROOT', os.path.join(venv, '.go')),
|
|
78
|
+
('GOTOOLCHAIN', 'local'),
|
|
79
|
+
(
|
|
80
|
+
'PATH', (
|
|
81
|
+
os.path.join(venv, 'bin'), os.pathsep,
|
|
82
|
+
os.path.join(venv, '.go', 'bin'), os.pathsep, Var('PATH'),
|
|
83
|
+
),
|
|
84
|
+
),
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@functools.lru_cache
|
|
89
|
+
def _infer_go_version(version: str) -> str:
|
|
90
|
+
if version != C.DEFAULT:
|
|
91
|
+
return version
|
|
92
|
+
resp = urllib.request.urlopen('https://go.dev/dl/?mode=json')
|
|
93
|
+
return json.load(resp)[0]['version'].removeprefix('go')
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _get_url(version: str) -> str:
|
|
97
|
+
os_name = platform.system().lower()
|
|
98
|
+
version = _infer_go_version(version)
|
|
99
|
+
return f'https://dl.google.com/go/go{version}.{os_name}-{_ARCH}.{_EXT}'
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _install_go(version: str, dest: str) -> None:
|
|
103
|
+
try:
|
|
104
|
+
resp = urllib.request.urlopen(_get_url(version))
|
|
105
|
+
except urllib.error.HTTPError as e: # pragma: no cover
|
|
106
|
+
if e.code == 404:
|
|
107
|
+
raise ValueError(
|
|
108
|
+
f'Could not find a version matching your system requirements '
|
|
109
|
+
f'(os={platform.system().lower()}; arch={_ARCH})',
|
|
110
|
+
) from e
|
|
111
|
+
else:
|
|
112
|
+
raise
|
|
113
|
+
else:
|
|
114
|
+
with tempfile.TemporaryFile() as f:
|
|
115
|
+
shutil.copyfileobj(resp, f)
|
|
116
|
+
f.seek(0)
|
|
117
|
+
|
|
118
|
+
with _open_archive(f) as archive:
|
|
119
|
+
archive.extractall(dest)
|
|
120
|
+
shutil.move(os.path.join(dest, 'go'), os.path.join(dest, '.go'))
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@contextlib.contextmanager
|
|
124
|
+
def in_env(prefix: Prefix, version: str) -> Generator[None]:
|
|
125
|
+
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
|
126
|
+
with envcontext(get_env_patch(envdir, version)):
|
|
127
|
+
yield
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def install_environment(
|
|
131
|
+
prefix: Prefix,
|
|
132
|
+
version: str,
|
|
133
|
+
additional_dependencies: Sequence[str],
|
|
134
|
+
) -> None:
|
|
135
|
+
env_dir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
|
136
|
+
|
|
137
|
+
if version != 'system':
|
|
138
|
+
_install_go(version, env_dir)
|
|
139
|
+
|
|
140
|
+
if sys.platform == 'cygwin': # pragma: no cover
|
|
141
|
+
gopath = cmd_output('cygpath', '-w', env_dir)[1].strip()
|
|
142
|
+
else:
|
|
143
|
+
gopath = env_dir
|
|
144
|
+
|
|
145
|
+
env = no_git_env(dict(os.environ, GOPATH=gopath))
|
|
146
|
+
env.pop('GOBIN', None)
|
|
147
|
+
if version != 'system':
|
|
148
|
+
env['GOTOOLCHAIN'] = 'local'
|
|
149
|
+
env['GOROOT'] = os.path.join(env_dir, '.go')
|
|
150
|
+
env['PATH'] = os.pathsep.join((
|
|
151
|
+
os.path.join(env_dir, '.go', 'bin'), os.environ['PATH'],
|
|
152
|
+
))
|
|
153
|
+
|
|
154
|
+
lang_base.setup_cmd(prefix, ('go', 'install', './...'), env=env)
|
|
155
|
+
for dependency in additional_dependencies:
|
|
156
|
+
lang_base.setup_cmd(prefix, ('go', 'install', dependency), env=env)
|
|
157
|
+
|
|
158
|
+
# save some disk space -- we don't need this after installation
|
|
159
|
+
pkgdir = os.path.join(env_dir, 'pkg')
|
|
160
|
+
if os.path.exists(pkgdir): # pragma: no branch (always true on windows?)
|
|
161
|
+
rmtree(pkgdir)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import contextlib
|
|
4
|
+
import os.path
|
|
5
|
+
from collections.abc import Generator
|
|
6
|
+
from collections.abc import Sequence
|
|
7
|
+
|
|
8
|
+
from pre_commit import lang_base
|
|
9
|
+
from pre_commit.envcontext import envcontext
|
|
10
|
+
from pre_commit.envcontext import PatchesT
|
|
11
|
+
from pre_commit.envcontext import Var
|
|
12
|
+
from pre_commit.errors import FatalError
|
|
13
|
+
from pre_commit.prefix import Prefix
|
|
14
|
+
|
|
15
|
+
ENVIRONMENT_DIR = 'hs_env'
|
|
16
|
+
get_default_version = lang_base.basic_get_default_version
|
|
17
|
+
health_check = lang_base.basic_health_check
|
|
18
|
+
run_hook = lang_base.basic_run_hook
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_env_patch(target_dir: str) -> PatchesT:
|
|
22
|
+
bin_path = os.path.join(target_dir, 'bin')
|
|
23
|
+
return (('PATH', (bin_path, os.pathsep, Var('PATH'))),)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@contextlib.contextmanager
|
|
27
|
+
def in_env(prefix: Prefix, version: str) -> Generator[None]:
|
|
28
|
+
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
|
29
|
+
with envcontext(get_env_patch(envdir)):
|
|
30
|
+
yield
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def install_environment(
|
|
34
|
+
prefix: Prefix,
|
|
35
|
+
version: str,
|
|
36
|
+
additional_dependencies: Sequence[str],
|
|
37
|
+
) -> None:
|
|
38
|
+
lang_base.assert_version_default('haskell', version)
|
|
39
|
+
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
|
40
|
+
|
|
41
|
+
pkgs = [*prefix.star('.cabal'), *additional_dependencies]
|
|
42
|
+
if not pkgs:
|
|
43
|
+
raise FatalError('Expected .cabal files or additional_dependencies')
|
|
44
|
+
|
|
45
|
+
bindir = os.path.join(envdir, 'bin')
|
|
46
|
+
os.makedirs(bindir, exist_ok=True)
|
|
47
|
+
lang_base.setup_cmd(prefix, ('cabal', 'update'))
|
|
48
|
+
lang_base.setup_cmd(
|
|
49
|
+
prefix,
|
|
50
|
+
(
|
|
51
|
+
'cabal', 'install',
|
|
52
|
+
'--install-method', 'copy',
|
|
53
|
+
'--installdir', bindir,
|
|
54
|
+
*pkgs,
|
|
55
|
+
),
|
|
56
|
+
)
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import contextlib
|
|
4
|
+
import os
|
|
5
|
+
import shutil
|
|
6
|
+
from collections.abc import Generator
|
|
7
|
+
from collections.abc import Sequence
|
|
8
|
+
|
|
9
|
+
from pre_commit import lang_base
|
|
10
|
+
from pre_commit.envcontext import envcontext
|
|
11
|
+
from pre_commit.envcontext import PatchesT
|
|
12
|
+
from pre_commit.envcontext import UNSET
|
|
13
|
+
from pre_commit.prefix import Prefix
|
|
14
|
+
from pre_commit.util import cmd_output_b
|
|
15
|
+
|
|
16
|
+
ENVIRONMENT_DIR = 'juliaenv'
|
|
17
|
+
health_check = lang_base.basic_health_check
|
|
18
|
+
get_default_version = lang_base.basic_get_default_version
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def run_hook(
|
|
22
|
+
prefix: Prefix,
|
|
23
|
+
entry: str,
|
|
24
|
+
args: Sequence[str],
|
|
25
|
+
file_args: Sequence[str],
|
|
26
|
+
*,
|
|
27
|
+
is_local: bool,
|
|
28
|
+
require_serial: bool,
|
|
29
|
+
color: bool,
|
|
30
|
+
) -> tuple[int, bytes]:
|
|
31
|
+
# `entry` is a (hook-repo relative) file followed by (optional) args, e.g.
|
|
32
|
+
# `bin/id.jl` or `bin/hook.jl --arg1 --arg2` so we
|
|
33
|
+
# 1) shell parse it and join with args with hook_cmd
|
|
34
|
+
# 2) prepend the hooks prefix path to the first argument (the file), unless
|
|
35
|
+
# it is a local script
|
|
36
|
+
# 3) prepend `julia` as the interpreter
|
|
37
|
+
|
|
38
|
+
cmd = lang_base.hook_cmd(entry, args)
|
|
39
|
+
script = cmd[0] if is_local else prefix.path(cmd[0])
|
|
40
|
+
cmd = ('julia', '--startup-file=no', script, *cmd[1:])
|
|
41
|
+
return lang_base.run_xargs(
|
|
42
|
+
cmd,
|
|
43
|
+
file_args,
|
|
44
|
+
require_serial=require_serial,
|
|
45
|
+
color=color,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def get_env_patch(target_dir: str, version: str) -> PatchesT:
|
|
50
|
+
return (
|
|
51
|
+
('JULIA_LOAD_PATH', target_dir),
|
|
52
|
+
# May be set, remove it to not interfer with LOAD_PATH
|
|
53
|
+
('JULIA_PROJECT', UNSET),
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@contextlib.contextmanager
|
|
58
|
+
def in_env(prefix: Prefix, version: str) -> Generator[None]:
|
|
59
|
+
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
|
60
|
+
with envcontext(get_env_patch(envdir, version)):
|
|
61
|
+
yield
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def install_environment(
|
|
65
|
+
prefix: Prefix,
|
|
66
|
+
version: str,
|
|
67
|
+
additional_dependencies: Sequence[str],
|
|
68
|
+
) -> None:
|
|
69
|
+
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
|
70
|
+
with in_env(prefix, version):
|
|
71
|
+
# TODO: Support language_version with juliaup similar to rust via
|
|
72
|
+
# rustup
|
|
73
|
+
# if version != 'system':
|
|
74
|
+
# ...
|
|
75
|
+
|
|
76
|
+
# Copy Project.toml to hook env if it exist
|
|
77
|
+
os.makedirs(envdir, exist_ok=True)
|
|
78
|
+
project_names = ('JuliaProject.toml', 'Project.toml')
|
|
79
|
+
project_found = False
|
|
80
|
+
for project_name in project_names:
|
|
81
|
+
project_file = prefix.path(project_name)
|
|
82
|
+
if not os.path.isfile(project_file):
|
|
83
|
+
continue
|
|
84
|
+
shutil.copy(project_file, envdir)
|
|
85
|
+
project_found = True
|
|
86
|
+
break
|
|
87
|
+
|
|
88
|
+
# If no project file was found we create an empty one so that the
|
|
89
|
+
# package manager doesn't error
|
|
90
|
+
if not project_found:
|
|
91
|
+
open(os.path.join(envdir, 'Project.toml'), 'a').close()
|
|
92
|
+
|
|
93
|
+
# Copy Manifest.toml to hook env if it exists
|
|
94
|
+
manifest_names = ('JuliaManifest.toml', 'Manifest.toml')
|
|
95
|
+
for manifest_name in manifest_names:
|
|
96
|
+
manifest_file = prefix.path(manifest_name)
|
|
97
|
+
if not os.path.isfile(manifest_file):
|
|
98
|
+
continue
|
|
99
|
+
shutil.copy(manifest_file, envdir)
|
|
100
|
+
break
|
|
101
|
+
|
|
102
|
+
# Julia code to instantiate the hook environment
|
|
103
|
+
julia_code = """
|
|
104
|
+
@assert length(ARGS) > 0
|
|
105
|
+
hook_env = ARGS[1]
|
|
106
|
+
deps = join(ARGS[2:end], " ")
|
|
107
|
+
|
|
108
|
+
# We prepend @stdlib here so that we can load the package manager even
|
|
109
|
+
# though `get_env_patch` limits `JULIA_LOAD_PATH` to just the hook env.
|
|
110
|
+
pushfirst!(LOAD_PATH, "@stdlib")
|
|
111
|
+
using Pkg
|
|
112
|
+
popfirst!(LOAD_PATH)
|
|
113
|
+
|
|
114
|
+
# Instantiate the environment shipped with the hook repo. If we have
|
|
115
|
+
# additional dependencies we disable precompilation in this step to
|
|
116
|
+
# avoid double work.
|
|
117
|
+
precompile = isempty(deps) ? "1" : "0"
|
|
118
|
+
withenv("JULIA_PKG_PRECOMPILE_AUTO" => precompile) do
|
|
119
|
+
Pkg.instantiate()
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Add additional dependencies (with precompilation)
|
|
123
|
+
if !isempty(deps)
|
|
124
|
+
withenv("JULIA_PKG_PRECOMPILE_AUTO" => "1") do
|
|
125
|
+
Pkg.REPLMode.pkgstr("add " * deps)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
"""
|
|
129
|
+
cmd_output_b(
|
|
130
|
+
'julia', '--startup-file=no', '-e', julia_code, '--', envdir,
|
|
131
|
+
*additional_dependencies,
|
|
132
|
+
cwd=prefix.prefix_dir,
|
|
133
|
+
)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import contextlib
|
|
4
|
+
import os
|
|
5
|
+
import sys
|
|
6
|
+
from collections.abc import Generator
|
|
7
|
+
from collections.abc import Sequence
|
|
8
|
+
|
|
9
|
+
from pre_commit import lang_base
|
|
10
|
+
from pre_commit.envcontext import envcontext
|
|
11
|
+
from pre_commit.envcontext import PatchesT
|
|
12
|
+
from pre_commit.envcontext import Var
|
|
13
|
+
from pre_commit.prefix import Prefix
|
|
14
|
+
from pre_commit.util import cmd_output
|
|
15
|
+
|
|
16
|
+
ENVIRONMENT_DIR = 'lua_env'
|
|
17
|
+
get_default_version = lang_base.basic_get_default_version
|
|
18
|
+
health_check = lang_base.basic_health_check
|
|
19
|
+
run_hook = lang_base.basic_run_hook
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _get_lua_version() -> str: # pragma: win32 no cover
|
|
23
|
+
"""Get the Lua version used in file paths."""
|
|
24
|
+
_, stdout, _ = cmd_output('luarocks', 'config', '--lua-ver')
|
|
25
|
+
return stdout.strip()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_env_patch(d: str) -> PatchesT: # pragma: win32 no cover
|
|
29
|
+
version = _get_lua_version()
|
|
30
|
+
so_ext = 'dll' if sys.platform == 'win32' else 'so'
|
|
31
|
+
return (
|
|
32
|
+
('PATH', (os.path.join(d, 'bin'), os.pathsep, Var('PATH'))),
|
|
33
|
+
(
|
|
34
|
+
'LUA_PATH', (
|
|
35
|
+
os.path.join(d, 'share', 'lua', version, '?.lua;'),
|
|
36
|
+
os.path.join(d, 'share', 'lua', version, '?', 'init.lua;;'),
|
|
37
|
+
),
|
|
38
|
+
),
|
|
39
|
+
(
|
|
40
|
+
'LUA_CPATH',
|
|
41
|
+
(os.path.join(d, 'lib', 'lua', version, f'?.{so_ext};;'),),
|
|
42
|
+
),
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@contextlib.contextmanager # pragma: win32 no cover
|
|
47
|
+
def in_env(prefix: Prefix, version: str) -> Generator[None]:
|
|
48
|
+
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
|
49
|
+
with envcontext(get_env_patch(envdir)):
|
|
50
|
+
yield
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def install_environment(
|
|
54
|
+
prefix: Prefix,
|
|
55
|
+
version: str,
|
|
56
|
+
additional_dependencies: Sequence[str],
|
|
57
|
+
) -> None: # pragma: win32 no cover
|
|
58
|
+
lang_base.assert_version_default('lua', version)
|
|
59
|
+
|
|
60
|
+
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
|
61
|
+
with in_env(prefix, version):
|
|
62
|
+
# luarocks doesn't bootstrap a tree prior to installing
|
|
63
|
+
# so ensure the directory exists.
|
|
64
|
+
os.makedirs(envdir, exist_ok=True)
|
|
65
|
+
|
|
66
|
+
# Older luarocks (e.g., 2.4.2) expect the rockspec as an arg
|
|
67
|
+
for rockspec in prefix.star('.rockspec'):
|
|
68
|
+
make_cmd = ('luarocks', '--tree', envdir, 'make', rockspec)
|
|
69
|
+
lang_base.setup_cmd(prefix, make_cmd)
|
|
70
|
+
|
|
71
|
+
# luarocks can't install multiple packages at once
|
|
72
|
+
# so install them individually.
|
|
73
|
+
for dependency in additional_dependencies:
|
|
74
|
+
cmd = ('luarocks', '--tree', envdir, 'install', dependency)
|
|
75
|
+
lang_base.setup_cmd(prefix, cmd)
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import contextlib
|
|
4
|
+
import functools
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
from collections.abc import Generator
|
|
8
|
+
from collections.abc import Sequence
|
|
9
|
+
|
|
10
|
+
import pre_commit.constants as C
|
|
11
|
+
from pre_commit import lang_base
|
|
12
|
+
from pre_commit.envcontext import envcontext
|
|
13
|
+
from pre_commit.envcontext import PatchesT
|
|
14
|
+
from pre_commit.envcontext import UNSET
|
|
15
|
+
from pre_commit.envcontext import Var
|
|
16
|
+
from pre_commit.languages.python import bin_dir
|
|
17
|
+
from pre_commit.prefix import Prefix
|
|
18
|
+
from pre_commit.util import cmd_output
|
|
19
|
+
from pre_commit.util import cmd_output_b
|
|
20
|
+
from pre_commit.util import rmtree
|
|
21
|
+
|
|
22
|
+
ENVIRONMENT_DIR = 'node_env'
|
|
23
|
+
run_hook = lang_base.basic_run_hook
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@functools.lru_cache(maxsize=1)
|
|
27
|
+
def get_default_version() -> str:
|
|
28
|
+
# nodeenv does not yet support `-n system` on windows
|
|
29
|
+
if sys.platform == 'win32':
|
|
30
|
+
return C.DEFAULT
|
|
31
|
+
# if node is already installed, we can save a bunch of setup time by
|
|
32
|
+
# using the installed version
|
|
33
|
+
elif all(lang_base.exe_exists(exe) for exe in ('node', 'npm')):
|
|
34
|
+
return 'system'
|
|
35
|
+
else:
|
|
36
|
+
return C.DEFAULT
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_env_patch(venv: str) -> PatchesT:
|
|
40
|
+
if sys.platform == 'cygwin': # pragma: no cover
|
|
41
|
+
_, win_venv, _ = cmd_output('cygpath', '-w', venv)
|
|
42
|
+
install_prefix = fr'{win_venv.strip()}\bin'
|
|
43
|
+
lib_dir = 'lib'
|
|
44
|
+
elif sys.platform == 'win32': # pragma: no cover
|
|
45
|
+
install_prefix = bin_dir(venv)
|
|
46
|
+
lib_dir = 'Scripts'
|
|
47
|
+
else: # pragma: win32 no cover
|
|
48
|
+
install_prefix = venv
|
|
49
|
+
lib_dir = 'lib'
|
|
50
|
+
return (
|
|
51
|
+
('NODE_VIRTUAL_ENV', venv),
|
|
52
|
+
('NPM_CONFIG_PREFIX', install_prefix),
|
|
53
|
+
('npm_config_prefix', install_prefix),
|
|
54
|
+
('NPM_CONFIG_USERCONFIG', UNSET),
|
|
55
|
+
('npm_config_userconfig', UNSET),
|
|
56
|
+
('NODE_PATH', os.path.join(venv, lib_dir, 'node_modules')),
|
|
57
|
+
('PATH', (bin_dir(venv), os.pathsep, Var('PATH'))),
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@contextlib.contextmanager
|
|
62
|
+
def in_env(prefix: Prefix, version: str) -> Generator[None]:
|
|
63
|
+
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
|
64
|
+
with envcontext(get_env_patch(envdir)):
|
|
65
|
+
yield
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def health_check(prefix: Prefix, version: str) -> str | None:
|
|
69
|
+
with in_env(prefix, version):
|
|
70
|
+
retcode, _, _ = cmd_output_b('node', '--version', check=False)
|
|
71
|
+
if retcode != 0: # pragma: win32 no cover
|
|
72
|
+
return f'`node --version` returned {retcode}'
|
|
73
|
+
else:
|
|
74
|
+
return None
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def install_environment(
|
|
78
|
+
prefix: Prefix, version: str, additional_dependencies: Sequence[str],
|
|
79
|
+
) -> None:
|
|
80
|
+
assert prefix.exists('package.json')
|
|
81
|
+
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
|
82
|
+
|
|
83
|
+
# https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx?f=255&MSPPError=-2147217396#maxpath
|
|
84
|
+
if sys.platform == 'win32': # pragma: no cover
|
|
85
|
+
envdir = fr'\\?\{os.path.normpath(envdir)}'
|
|
86
|
+
cmd = [sys.executable, '-mnodeenv', '--prebuilt', '--clean-src', envdir]
|
|
87
|
+
if version != C.DEFAULT:
|
|
88
|
+
cmd.extend(['-n', version])
|
|
89
|
+
cmd_output_b(*cmd)
|
|
90
|
+
|
|
91
|
+
with in_env(prefix, version):
|
|
92
|
+
# https://npm.community/t/npm-install-g-git-vs-git-clone-cd-npm-install-g/5449
|
|
93
|
+
# install as if we installed from git
|
|
94
|
+
|
|
95
|
+
local_install_cmd = (
|
|
96
|
+
'npm', 'install', '--include=dev', '--include=prod',
|
|
97
|
+
'--ignore-prepublish', '--no-progress', '--no-save',
|
|
98
|
+
)
|
|
99
|
+
lang_base.setup_cmd(prefix, local_install_cmd)
|
|
100
|
+
|
|
101
|
+
_, pkg, _ = cmd_output('npm', 'pack', cwd=prefix.prefix_dir)
|
|
102
|
+
pkg = prefix.path(pkg.strip())
|
|
103
|
+
|
|
104
|
+
install = ('npm', 'install', '-g', pkg, *additional_dependencies)
|
|
105
|
+
lang_base.setup_cmd(prefix, install)
|
|
106
|
+
|
|
107
|
+
# clean these up after installation
|
|
108
|
+
if prefix.exists('node_modules'): # pragma: win32 no cover
|
|
109
|
+
rmtree(prefix.path('node_modules'))
|
|
110
|
+
os.remove(pkg)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import contextlib
|
|
4
|
+
import os
|
|
5
|
+
import shlex
|
|
6
|
+
from collections.abc import Generator
|
|
7
|
+
from collections.abc import Sequence
|
|
8
|
+
|
|
9
|
+
from pre_commit import lang_base
|
|
10
|
+
from pre_commit.envcontext import envcontext
|
|
11
|
+
from pre_commit.envcontext import PatchesT
|
|
12
|
+
from pre_commit.envcontext import Var
|
|
13
|
+
from pre_commit.prefix import Prefix
|
|
14
|
+
|
|
15
|
+
ENVIRONMENT_DIR = 'perl_env'
|
|
16
|
+
get_default_version = lang_base.basic_get_default_version
|
|
17
|
+
health_check = lang_base.basic_health_check
|
|
18
|
+
run_hook = lang_base.basic_run_hook
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_env_patch(venv: str) -> PatchesT:
|
|
22
|
+
return (
|
|
23
|
+
('PATH', (os.path.join(venv, 'bin'), os.pathsep, Var('PATH'))),
|
|
24
|
+
('PERL5LIB', os.path.join(venv, 'lib', 'perl5')),
|
|
25
|
+
('PERL_MB_OPT', f'--install_base {shlex.quote(venv)}'),
|
|
26
|
+
(
|
|
27
|
+
'PERL_MM_OPT', (
|
|
28
|
+
f'INSTALL_BASE={shlex.quote(venv)} '
|
|
29
|
+
f'INSTALLSITEMAN1DIR=none INSTALLSITEMAN3DIR=none'
|
|
30
|
+
),
|
|
31
|
+
),
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@contextlib.contextmanager
|
|
36
|
+
def in_env(prefix: Prefix, version: str) -> Generator[None]:
|
|
37
|
+
envdir = lang_base.environment_dir(prefix, ENVIRONMENT_DIR, version)
|
|
38
|
+
with envcontext(get_env_patch(envdir)):
|
|
39
|
+
yield
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def install_environment(
|
|
43
|
+
prefix: Prefix, version: str, additional_dependencies: Sequence[str],
|
|
44
|
+
) -> None:
|
|
45
|
+
lang_base.assert_version_default('perl', version)
|
|
46
|
+
|
|
47
|
+
with in_env(prefix, version):
|
|
48
|
+
lang_base.setup_cmd(
|
|
49
|
+
prefix, ('cpan', '-T', '.', *additional_dependencies),
|
|
50
|
+
)
|