From 125a174298a9c37e35bf2a7f766ef84f4cbb6f20 Mon Sep 17 00:00:00 2001 From: Alireza Date: Tue, 14 Jul 2026 19:10:49 -0400 Subject: [PATCH] fix(cli): link and unlink extensions/modes with pnpm instead of yarn (#6144) --- platform/cli/src/commands/linkPackage.js | 21 +++++++++---------- platform/cli/src/commands/unlinkPackage.js | 16 +++++++------- platform/cli/src/commands/utils/index.js | 4 ++-- .../{validateYarn.js => validatePnpm.js} | 6 +++--- 4 files changed, 24 insertions(+), 23 deletions(-) rename platform/cli/src/commands/utils/{validateYarn.js => validatePnpm.js} (55%) diff --git a/platform/cli/src/commands/linkPackage.js b/platform/cli/src/commands/linkPackage.js index 25aaec87f..bf0594e3e 100644 --- a/platform/cli/src/commands/linkPackage.js +++ b/platform/cli/src/commands/linkPackage.js @@ -2,7 +2,7 @@ import fs from 'fs'; import path from 'path'; import { execa } from 'execa'; import { keywords } from './enums/index.js'; -import { validateYarn, addExtensionToConfig, addModeToConfig } from './utils/index.js'; +import { validatePnpm, addExtensionToConfig, addModeToConfig } from './utils/index.js'; async function linkPackage(packageDir, options, addToConfig, keyword) { const { viewerDirectory } = options; @@ -22,19 +22,18 @@ async function linkPackage(packageDir, options, addToConfig, keyword) { const version = packageJSON.version; - // make sure yarn is installed - await validateYarn(); + // make sure pnpm is installed + await validatePnpm(); - // change directory to packageDir and execute yarn link - process.chdir(packageDir); + // resolve the package directory before changing the working directory + const resolvedPackageDir = path.resolve(packageDir); - let results; - results = await execa(`yarn`, ['link']); - - // change directory to OHIF Platform root and execute yarn link + // change directory to the OHIF Platform root and link the local package there. + // Linking mutates the lockfile, so disable the workspace's frozen-lockfile + // default for this call (pnpm link rejects --no-frozen-lockfile). process.chdir(`${viewerDirectory}/../..`); - results = await execa(`yarn`, ['link', packageName]); + let results = await execa('pnpm', ['link', resolvedPackageDir, '--config.frozen-lockfile=false']); console.log(results.stdout); // Add the node_modules of the linked package so that webpack @@ -63,7 +62,7 @@ async function linkPackage(packageDir, options, addToConfig, keyword) { }); // run prettier on the webpack config - results = await execa(`yarn`, ['prettier', '--write', webpackPwaPath]); + results = await execa('pnpm', ['exec', 'prettier', '--write', webpackPwaPath]); } function linkExtension(packageDir, options) { diff --git a/platform/cli/src/commands/unlinkPackage.js b/platform/cli/src/commands/unlinkPackage.js index 8aaa9f871..a0a6547d0 100644 --- a/platform/cli/src/commands/unlinkPackage.js +++ b/platform/cli/src/commands/unlinkPackage.js @@ -1,18 +1,20 @@ import { execa } from 'execa'; import fs from 'fs'; import path from 'path'; -import { validateYarn, removeExtensionFromConfig, removeModeFromConfig } from './utils/index.js'; +import { validatePnpm, removeExtensionFromConfig, removeModeFromConfig } from './utils/index.js'; const linkPackage = async (packageName, options, removeFromConfig) => { const { viewerDirectory } = options; - // make sure yarn is installed - await validateYarn(); + // make sure pnpm is installed + await validatePnpm(); - // change directory to OHIF Platform root and execute yarn link - process.chdir(viewerDirectory); + // change directory to the OHIF Platform root, where the package was linked. + // Unlinking mutates the lockfile, so disable the workspace's frozen-lockfile + // default for this call (pnpm unlink rejects --no-frozen-lockfile). + process.chdir(`${viewerDirectory}/../..`); - const results = await execa(`yarn`, ['unlink', packageName]); + const results = await execa('pnpm', ['unlink', packageName, '--config.frozen-lockfile=false']); console.log(results.stdout); const webpackPwaPath = path.join(viewerDirectory, '.webpack', 'webpack.pwa.js'); @@ -23,7 +25,7 @@ const linkPackage = async (packageName, options, removeFromConfig) => { removeFromConfig(packageName); // run prettier on the webpack config - await execa(`yarn`, ['prettier', '--write', webpackPwaPath]); + await execa('pnpm', ['exec', 'prettier', '--write', webpackPwaPath]); }; async function removePathFromWebpackConfig(webpackConfigPath, packageName) { diff --git a/platform/cli/src/commands/utils/index.js b/platform/cli/src/commands/utils/index.js index ee32c1efb..9163d5e1c 100644 --- a/platform/cli/src/commands/utils/index.js +++ b/platform/cli/src/commands/utils/index.js @@ -19,7 +19,7 @@ import editPackageJson from './editPackageJson.js'; import createLicense from './createLicense.js'; import createReadme from './createReadme.js'; import prettyPrint from './prettyPrint.js'; -import validateYarn from './validateYarn.js'; +import validatePnpm from './validatePnpm.js'; export { getYarnInfo, @@ -43,5 +43,5 @@ export { createLicense, createReadme, prettyPrint, - validateYarn, + validatePnpm, }; diff --git a/platform/cli/src/commands/utils/validateYarn.js b/platform/cli/src/commands/utils/validatePnpm.js similarity index 55% rename from platform/cli/src/commands/utils/validateYarn.js rename to platform/cli/src/commands/utils/validatePnpm.js index 8a74b83c0..f9abb671c 100644 --- a/platform/cli/src/commands/utils/validateYarn.js +++ b/platform/cli/src/commands/utils/validatePnpm.js @@ -1,12 +1,12 @@ import chalk from 'chalk'; import { execa } from 'execa'; -export default async function validateYarn() { +export default async function validatePnpm() { try { - await execa('yarn', ['--version']); + await execa('pnpm', ['--version']); } catch (err) { console.log( - '%s Yarn is not installed, please install it before linking your extension', + '%s pnpm is not installed, please install it before linking your extension', chalk.red.bold('ERROR') ); process.exit(1);