refactor(languages/node): adapt scripts path resolution

Cygwin isn't the only edge-case for a differing bin/ path. In addition there
also is MSYS2, which behaves differently than Cygwin. CPython compiled against
Microsoft Visual C++ Runtime (MSVCRT) through MinGW, will correctly identify as
an 'nt' platform, yet will prefer a POSIX path scheme.

In order to avoid having to patch every edge-case, we can spy on the system
configurations install paths through the `sysconfig` module and get the basename
of the global scripts path, which will be returned in accordance with the
preferred install path scheme of the system/platform.

Fixes: https://github.com/pre-commit/pre-commit/issues/3448
This commit is contained in:
Rodney, Tiara 2025-04-15 15:12:07 +02:00
parent 7c4dfd7779
commit 0d50ffc2b7
No known key found for this signature in database
GPG key ID: 5CD8EC1D46106723

View file

@ -4,6 +4,7 @@ import contextlib
import functools import functools
import os import os
import sys import sys
import sysconfig
from collections.abc import Generator from collections.abc import Generator
from collections.abc import Sequence from collections.abc import Sequence
@ -37,16 +38,18 @@ def get_default_version() -> str:
def get_env_patch(venv: str) -> PatchesT: def get_env_patch(venv: str) -> PatchesT:
if sys.platform == 'cygwin': # pragma: no cover
_, win_venv, _ = cmd_output('cygpath', '-w', venv)
install_prefix = fr'{win_venv.strip()}\bin'
lib_dir = 'lib'
elif sys.platform == 'win32': # pragma: no cover
install_prefix = bin_dir(venv) install_prefix = bin_dir(venv)
lib_dir = 'Scripts'
else: # pragma: win32 no cover
install_prefix = venv
lib_dir = 'lib' lib_dir = 'lib'
# if not a Cygwin platform and not a win32 platform with a Windows path scheme
# catering to the previously defined edge-cases.
if sys.platform != 'cygwin' and (sys.platform == 'win32' and install_prefix.name != 'Scripts'):
install_prefix = venv
if install_prefix.name != 'bin':
lib_dir = install_prefix.name
return ( return (
('NODE_VIRTUAL_ENV', venv), ('NODE_VIRTUAL_ENV', venv),
('NPM_CONFIG_PREFIX', install_prefix), ('NPM_CONFIG_PREFIX', install_prefix),
@ -54,7 +57,7 @@ def get_env_patch(venv: str) -> PatchesT:
('NPM_CONFIG_USERCONFIG', UNSET), ('NPM_CONFIG_USERCONFIG', UNSET),
('npm_config_userconfig', UNSET), ('npm_config_userconfig', UNSET),
('NODE_PATH', os.path.join(venv, lib_dir, 'node_modules')), ('NODE_PATH', os.path.join(venv, lib_dir, 'node_modules')),
('PATH', (bin_dir(venv), os.pathsep, Var('PATH'))), ('PATH', (install_prefix, os.pathsep, Var('PATH'))),
) )