diff --git a/npm_install.py b/npm_install.py index 9988575..b3fc20a 100644 --- a/npm_install.py +++ b/npm_install.py @@ -2232,35 +2232,54 @@ def _build_frontend(src_frontend: Path, dest_frontend: Path): if DEBUG: print(f" ⚠ 'yarn set version' failed: {e}") - # METHOD 3: npm install yarn@berry + # METHOD 3: npm install @yarnpkg/cli (yarn 4.x) try: - run(["npm", "install", "-g", "yarn@berry"], check=False) + run(["npm", "install", "-g", "@yarnpkg/cli"], check=False) if shutil.which("yarn"): major = _get_yarn_major_version(["yarn"]) if major and major >= 4: if DEBUG: - print(f" ✓ Yarn {major}.x installed via npm") + print(f" ✓ Yarn {major}.x installed via @yarnpkg/cli") return True except Exception as e: if DEBUG: - print(f" ⚠ npm install yarn@berry failed: {e}") + print(f" ⚠ npm install @yarnpkg/cli failed: {e}") - # METHOD 4: Force install latest yarn - try: - run(["npm", "install", "-g", "yarn@latest", "--force"], check=False) - - if shutil.which("yarn"): - major = _get_yarn_major_version(["yarn"]) + # METHOD 4: yarn set version stable (requires yarn 1.x) + # First install yarn 1.x if not present + if not shutil.which("yarn"): + try: + run(["npm", "install", "-g", "yarn@1"], check=False) + except Exception: + pass + + if shutil.which("yarn"): + try: + # Uninstall any global yarn 4.x first + run(["npm", "uninstall", "-g", "@yarnpkg/cli"], check=False, + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - if major and major >= 4: - if DEBUG: - print(f" ✓ Yarn {major}.x installed via npm --force") - return True - except Exception as e: - if DEBUG: - print(f" ⚠ npm install --force failed: {e}") + # yarn 1.x can upgrade itself to 4.x + result = subprocess.run( + ["yarn", "set", "version", "stable"], + capture_output=True, + timeout=120, + text=True, + check=False, + ) + + if result.returncode == 0: + major = _get_yarn_major_version(["yarn"]) + + if major and major >= 4: + if DEBUG: + print(f" ✓ Yarn {major}.x installed via 'yarn set version'") + return True + except Exception as e: + if DEBUG: + print(f" ⚠ 'yarn set version' failed: {e}") return False