Skip to content

Commit

Permalink
fix-npm --workspaces does not update the dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
kchindam-infy committed Nov 11, 2024
1 parent 780afc5 commit 2abe05a
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 18 deletions.
2 changes: 1 addition & 1 deletion lib/commands/version.js
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
68 changes: 51 additions & 17 deletions lib/utils/update-workspaces.js
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 2abe05a

Please sign in to comment.