From 8287aac6693c710db76e4f717cb430689d12fd11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=84=9D=EC=A7=80=EC=98=81/=EC=B1=85=EC=9E=84=EC=97=B0?= =?UTF-8?q?=EA=B5=AC=EC=9B=90/SW=EA=B3=B5=ED=95=99=28=EC=97=B0=29Open=20So?= =?UTF-8?q?urce=20TP?= Date: Fri, 29 May 2026 18:36:53 +0900 Subject: [PATCH 1/2] fix(yarn): improve PnP mode detection and Berry-compatible install options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 석지영/책임연구원/SW공학(연)Open Source TP --- .../package_manager/Yarn.py | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/fosslight_dependency/package_manager/Yarn.py b/src/fosslight_dependency/package_manager/Yarn.py index c012d104..50762cc8 100644 --- a/src/fosslight_dependency/package_manager/Yarn.py +++ b/src/fosslight_dependency/package_manager/Yarn.py @@ -4,6 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 import os +import re import logging import subprocess import json @@ -56,26 +57,38 @@ def start_license_checker(self): self.detect_yarn_version() - # For Yarn Berry (2+), check if using PnP mode + # For Yarn Berry (2+), PnP is the default mode. + # Only treat as non-PnP if .yarnrc.yml explicitly sets nodeLinker to node-modules or pnpm. is_pnp_mode = False if self.yarn_version and self.yarn_version >= 2: - # Check if .pnp.cjs exists (PnP mode indicator) - if os.path.exists('.pnp.cjs') or os.path.exists('.pnp.js'): - is_pnp_mode = True + is_pnp_mode = True + yarnrc_path = '.yarnrc.yml' + if os.path.exists(yarnrc_path): + with open(yarnrc_path, 'r', encoding='utf-8') as f: + yarnrc_content = f.read() + match = re.search(r'^\s*nodeLinker\s*:\s*(\S+)', yarnrc_content, re.MULTILINE) + if match: + node_linker = match.group(1).strip('"\'') + if node_linker in ('node-modules', 'pnpm'): + is_pnp_mode = False + logger.info(f"Detected Yarn Berry with nodeLinker: {node_linker} (non-PnP mode)") + if is_pnp_mode: logger.info("Detected Yarn Berry with PnP mode") if not os.path.isdir(node_modules): logger.info("node_modules directory does not exist.") self.flag_tmp_node_modules = True - # For PnP mode, try to force node_modules creation - if is_pnp_mode: - logger.info("Attempting to create node_modules for PnP project...") - yarn_install_cmd = 'YARN_NODE_LINKER=node-modules yarn install --production --ignore-scripts' - logger.info(f"Executing: {yarn_install_cmd}") + if self.yarn_version and self.yarn_version >= 2: + if is_pnp_mode: + # Force node-modules linker via env var (Yarn Berry supports YARN_ env vars) + logger.info("Attempting to create node_modules for PnP project using YARN_NODE_LINKER=node-modules...") + yarn_install_cmd = 'YARN_NODE_LINKER=node-modules yarn install --mode=skip-build' + else: + yarn_install_cmd = 'yarn install --mode=skip-build' else: yarn_install_cmd = 'yarn install --production --ignore-scripts' - logger.info(f"Executing: {yarn_install_cmd}") + logger.info(f"Executing: {yarn_install_cmd}") result = subprocess.run(yarn_install_cmd, shell=True, capture_output=True, text=True) if result.returncode != 0: From 4a03be0e1357ee2cf31e40cac613b347685cbf68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=84=9D=EC=A7=80=EC=98=81/=EC=B1=85=EC=9E=84=EC=97=B0?= =?UTF-8?q?=EA=B5=AC=EC=9B=90/SW=EA=B3=B5=ED=95=99=28=EC=97=B0=29Open=20So?= =?UTF-8?q?urce=20TP?= Date: Mon, 1 Jun 2026 11:07:52 +0900 Subject: [PATCH 2/2] fix(yarn): modify env cmd for cross-platform support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 석지영/책임연구원/SW공학(연)Open Source TP --- src/fosslight_dependency/package_manager/Yarn.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/fosslight_dependency/package_manager/Yarn.py b/src/fosslight_dependency/package_manager/Yarn.py index 50762cc8..07384d9a 100644 --- a/src/fosslight_dependency/package_manager/Yarn.py +++ b/src/fosslight_dependency/package_manager/Yarn.py @@ -79,18 +79,19 @@ def start_license_checker(self): logger.info("node_modules directory does not exist.") self.flag_tmp_node_modules = True + yarn_install_env = None if self.yarn_version and self.yarn_version >= 2: if is_pnp_mode: - # Force node-modules linker via env var (Yarn Berry supports YARN_ env vars) + # Force node-modules linker via env (cross-platform; avoids POSIX shell VAR=val syntax) logger.info("Attempting to create node_modules for PnP project using YARN_NODE_LINKER=node-modules...") - yarn_install_cmd = 'YARN_NODE_LINKER=node-modules yarn install --mode=skip-build' - else: - yarn_install_cmd = 'yarn install --mode=skip-build' + yarn_install_env = os.environ.copy() + yarn_install_env['YARN_NODE_LINKER'] = 'node-modules' + yarn_install_cmd = 'yarn install --mode=skip-build' else: yarn_install_cmd = 'yarn install --production --ignore-scripts' logger.info(f"Executing: {yarn_install_cmd}") - result = subprocess.run(yarn_install_cmd, shell=True, capture_output=True, text=True) + result = subprocess.run(yarn_install_cmd, shell=True, capture_output=True, text=True, env=yarn_install_env) if result.returncode != 0: logger.error(f"{yarn_install_cmd} failed") if is_pnp_mode: