mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-04-16 02:21:46 +04:00
Remove nodeenv dependency
This commit is contained in:
parent
d6ec6cf719
commit
c85f08bcb5
3 changed files with 113 additions and 10 deletions
|
|
@ -13,6 +13,7 @@ from pre_commit.envcontext import UNSET
|
||||||
from pre_commit.envcontext import Var
|
from pre_commit.envcontext import Var
|
||||||
from pre_commit.hook import Hook
|
from pre_commit.hook import Hook
|
||||||
from pre_commit.languages import helpers
|
from pre_commit.languages import helpers
|
||||||
|
from pre_commit.languages.node_env import install_node
|
||||||
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 clean_path_on_failure
|
from pre_commit.util import clean_path_on_failure
|
||||||
|
|
@ -89,27 +90,22 @@ def install_environment(
|
||||||
if sys.platform == 'win32': # pragma: no cover
|
if sys.platform == 'win32': # pragma: no cover
|
||||||
envdir = fr'\\?\{os.path.normpath(envdir)}'
|
envdir = fr'\\?\{os.path.normpath(envdir)}'
|
||||||
with clean_path_on_failure(envdir):
|
with clean_path_on_failure(envdir):
|
||||||
cmd = [
|
npm = install_node(envdir, version)
|
||||||
sys.executable, '-mnodeenv', '--prebuilt', '--clean-src', envdir,
|
|
||||||
]
|
|
||||||
if version != C.DEFAULT:
|
|
||||||
cmd.extend(['-n', version])
|
|
||||||
cmd_output_b(*cmd)
|
|
||||||
|
|
||||||
with in_env(prefix, version):
|
with in_env(prefix, version):
|
||||||
# https://npm.community/t/npm-install-g-git-vs-git-clone-cd-npm-install-g/5449
|
# https://npm.community/t/npm-install-g-git-vs-git-clone-cd-npm-install-g/5449
|
||||||
# install as if we installed from git
|
# install as if we installed from git
|
||||||
|
|
||||||
local_install_cmd = (
|
local_install_cmd = (
|
||||||
'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)
|
helpers.run_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)
|
helpers.run_setup_cmd(prefix, install)
|
||||||
|
|
||||||
# clean these up after installation
|
# clean these up after installation
|
||||||
|
|
|
||||||
108
pre_commit/languages/node_env.py
Normal file
108
pre_commit/languages/node_env.py
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
import io
|
||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import sysconfig
|
||||||
|
from tarfile import TarFile
|
||||||
|
from tarfile import TarInfo
|
||||||
|
from typing import Generator
|
||||||
|
from urllib.parse import urljoin
|
||||||
|
from urllib.request import urlopen
|
||||||
|
from zipfile import ZipFile
|
||||||
|
|
||||||
|
import pre_commit.constants as C
|
||||||
|
|
||||||
|
ARCHITECTURES = {
|
||||||
|
'x86': 'x86', # Windows Vista 32
|
||||||
|
'i686': 'x86',
|
||||||
|
'x86_64': 'x64', # Linux Ubuntu 64
|
||||||
|
'amd64': 'x64', # FreeBSD 64bits
|
||||||
|
'AMD64': 'x64', # Windows Server 2012 R2 (x64)
|
||||||
|
'armv6l': 'armv6l', # arm
|
||||||
|
'armv7l': 'armv7l',
|
||||||
|
'armv8l': 'armv7l',
|
||||||
|
'aarch64': 'arm64',
|
||||||
|
'arm64': 'arm64',
|
||||||
|
'arm64/v8': 'arm64',
|
||||||
|
'armv8': 'arm64',
|
||||||
|
'armv8.4': 'arm64',
|
||||||
|
'ppc64le': 'ppc64le', # Power PC
|
||||||
|
's390x': 's390x', # IBM S390x
|
||||||
|
}
|
||||||
|
|
||||||
|
NIX_NODE_SUBDIRS = re.compile(r'node[^/]+/(bin|lib|include|share)')
|
||||||
|
WINDOWS_NODE_SUBDIRS = re.compile(r'node[^/]+(np|node)')
|
||||||
|
|
||||||
|
|
||||||
|
def install_node(envdir: str, language_version: str) -> str:
|
||||||
|
windows = sys.platform in ('cygwin', 'win32')
|
||||||
|
|
||||||
|
if sysconfig.get_config_var('HOST_GNU_TYPE') == 'x86_64-pc-linux-musl':
|
||||||
|
domain = 'https://unofficial-builds.nodejs.org'
|
||||||
|
suffix = 'linux-x64-musl.tar.gz'
|
||||||
|
else:
|
||||||
|
domain = 'https://nodejs.org'
|
||||||
|
|
||||||
|
arch = ARCHITECTURES[platform.machine()]
|
||||||
|
if windows:
|
||||||
|
suffix = f'win-{arch}.zip'
|
||||||
|
else:
|
||||||
|
suffix = f'{platform.system().lower()}-{arch}.tar.gz'
|
||||||
|
|
||||||
|
version = _node_version(domain, language_version)
|
||||||
|
|
||||||
|
archive_name = f'node-{version}-{suffix}'
|
||||||
|
with urlopen(
|
||||||
|
urljoin(domain, f'download/release/{version}/{archive_name}'),
|
||||||
|
) as release:
|
||||||
|
compressed = io.BytesIO(release.read())
|
||||||
|
|
||||||
|
# TODO should i just extractall + rm the extra bits instead of partially
|
||||||
|
# extracting & renaming?
|
||||||
|
|
||||||
|
if windows:
|
||||||
|
# TODO this doesn't quite work
|
||||||
|
def renamed_members(z: ZipFile) -> Generator[str, None, None]:
|
||||||
|
prefix_len = len(f'{archive_name}/')
|
||||||
|
for m in z.filelist:
|
||||||
|
if WINDOWS_NODE_SUBDIRS.match(m.filename):
|
||||||
|
m.filename = m.filename[prefix_len:]
|
||||||
|
yield m.filename
|
||||||
|
|
||||||
|
with ZipFile(compressed) as z:
|
||||||
|
z.extractall(envdir, renamed_members(z))
|
||||||
|
|
||||||
|
raise NotImplementedError('TODO')
|
||||||
|
|
||||||
|
else:
|
||||||
|
def rename_members_tf(tf: TarFile) -> Generator[TarInfo, None, None]:
|
||||||
|
prefix_len = len(f'{archive_name}/')
|
||||||
|
for m in tf.getmembers():
|
||||||
|
if NIX_NODE_SUBDIRS.match(m.name):
|
||||||
|
m.path = m.path[prefix_len:]
|
||||||
|
yield m
|
||||||
|
|
||||||
|
with TarFile.open(fileobj=compressed) as tf:
|
||||||
|
tf.extractall(envdir, rename_members_tf(tf)) # type: ignore
|
||||||
|
|
||||||
|
for file in ('npm', 'npx', 'node'):
|
||||||
|
path = os.path.join(envdir, 'bin', file)
|
||||||
|
os.chmod(path, os.stat(path).st_mode | 0o111)
|
||||||
|
os.symlink('node', os.path.join(envdir, 'bin', 'nodejs'))
|
||||||
|
|
||||||
|
return os.path.join(envdir, 'bin', 'npm')
|
||||||
|
|
||||||
|
|
||||||
|
def _node_version(domain: str, language_version: str) -> str:
|
||||||
|
"""Looks up the node.js version based on the configured
|
||||||
|
version (uses the latest by default)"""
|
||||||
|
if language_version == C.DEFAULT:
|
||||||
|
# grab latest
|
||||||
|
with urlopen(urljoin(domain, 'download/release/index.tab')) as index:
|
||||||
|
_ = next(index) # header
|
||||||
|
version = next(index).split()[0].decode()
|
||||||
|
else:
|
||||||
|
version = f'v{language_version.replace("v", "")}'
|
||||||
|
|
||||||
|
return version
|
||||||
|
|
@ -25,7 +25,6 @@ packages = find:
|
||||||
install_requires =
|
install_requires =
|
||||||
cfgv>=2.0.0
|
cfgv>=2.0.0
|
||||||
identify>=1.0.0
|
identify>=1.0.0
|
||||||
nodeenv>=0.11.1
|
|
||||||
pyyaml>=5.1
|
pyyaml>=5.1
|
||||||
toml
|
toml
|
||||||
virtualenv>=20.0.8
|
virtualenv>=20.0.8
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue