From 0d50ffc2b75c0129540bff4fe1d83b2c3a682e64 Mon Sep 17 00:00:00 2001 From: "Rodney, Tiara" Date: Tue, 15 Apr 2025 15:12:07 +0200 Subject: [PATCH] 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 --- pre_commit/languages/node.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/pre_commit/languages/node.py b/pre_commit/languages/node.py index af7dc6f8..5953bdd6 100644 --- a/pre_commit/languages/node.py +++ b/pre_commit/languages/node.py @@ -4,6 +4,7 @@ import contextlib import functools import os import sys +import sysconfig from collections.abc import Generator from collections.abc import Sequence @@ -37,16 +38,18 @@ def get_default_version() -> str: 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) - lib_dir = 'Scripts' - else: # pragma: win32 no cover + + install_prefix = bin_dir(venv) + 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 - lib_dir = 'lib' + + if install_prefix.name != 'bin': + lib_dir = install_prefix.name + return ( ('NODE_VIRTUAL_ENV', venv), ('NPM_CONFIG_PREFIX', install_prefix), @@ -54,7 +57,7 @@ def get_env_patch(venv: str) -> PatchesT: ('NPM_CONFIG_USERCONFIG', UNSET), ('npm_config_userconfig', UNSET), ('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'))), )