From 2abe05ac345881a771a28cb4557f56afada15551 Mon Sep 17 00:00:00 2001 From: kchindam-infy Date: Mon, 11 Nov 2024 05:53:21 -0800 Subject: [PATCH] fix-npm --workspaces does not update the dependencies --- lib/commands/version.js | 2 +- lib/utils/update-workspaces.js | 68 +++++++++++++++++++++++++--------- 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/lib/commands/version.js b/lib/commands/version.js index d6c2dd4caed75..ecd1e54304a20 100644 --- a/lib/commands/version.js +++ b/lib/commands/version.js @@ -97,7 +97,7 @@ class Version extends BaseCommand { 'git-tag-version': false, path, }) - updatedWorkspaces.push(name) + updatedWorkspaces.push([name, path]) // Modified to include the path output.standard(`${prefix}${version}`) } return updateWorkspaces({ diff --git a/lib/utils/update-workspaces.js b/lib/utils/update-workspaces.js index 892f366e9980a..e68bd02813cab 100644 --- a/lib/utils/update-workspaces.js +++ b/lib/utils/update-workspaces.js @@ -1,40 +1,74 @@ 'use strict' -const reifyFinish = require('../utils/reify-finish.js') +const fs = require('fs') +const path = require('path') +const Arborist = require('@npmcli/arborist') async function updateWorkspaces ({ - config, flatOptions, localPrefix, - npm, workspaces, }) { if (!flatOptions.workspacesUpdate || !workspaces.length) { return } - // default behavior is to not save by default in order to avoid - // race condition problems when publishing multiple workspaces - // that have dependencies on one another, it might still be useful - // in some cases, which then need to set --save - const save = config.isDefault('save') - ? false - : config.get('save') + // collect updated workspace package versions + const workspacePackages = new Map() - // runs a minimalistic reify update, targeting only the workspaces - // that had version updates and skipping fund/audit/save + // get the updated versions of workspace packages + for (const [, workspacePath] of workspaces) { + const pkgPath = path.join(workspacePath, 'package.json') + const pkgData = await fs.promises.readFile(pkgPath, 'utf8') + const pkg = JSON.parse(pkgData) + workspacePackages.set(pkg.name, pkg.version) + } + + // update dependencies in all workspace packages + for (const [, workspacePath] of workspaces) { + const pkgPath = path.join(workspacePath, 'package.json') + const pkgData = await fs.promises.readFile(pkgPath, 'utf8') + const pkg = JSON.parse(pkgData) + + // list of dependency fields to update + const depFields = [ + 'dependencies', + 'devDependencies', + 'peerDependencies', + 'optionalDependencies', + ] + + let updated = false + + for (const field of depFields) { + if (pkg[field]) { + for (const depName of Object.keys(pkg[field])) { + if (workspacePackages.has(depName)) { + // update the version spec to match the new version + pkg[field][depName] = workspacePackages.get(depName) + updated = true + } + } + } + } + + if (updated) { + // write the updated package.json back to disk + const updatedPkgData = JSON.stringify(pkg, null, 2) + '\n' + await fs.promises.writeFile(pkgPath, updatedPkgData, 'utf8') + } + } + + // after done with updating package.json files, use arborist.reify() to update node_modules const opts = { ...flatOptions, audit: false, fund: false, path: localPrefix, - save, + save: false, // since the package.json is already updated, so no need to save changes again } - const Arborist = require('@npmcli/arborist') const arb = new Arborist(opts) - - await arb.reify({ ...opts, update: workspaces }) - await reifyFinish(npm, arb) + await arb.reify() } module.exports = updateWorkspaces