Skip to content

fix(ci): rm workspace node_modules #7490

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions lib/arborist-cmd.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ class ArboristCmd extends BaseCommand {
}

static params = [
'workspace',
'workspaces',
'include-workspace-root',
'install-links',
]

Expand Down Expand Up @@ -44,7 +41,6 @@ class ArboristCmd extends BaseCommand {
}

async execWorkspaces (args) {
await this.setWorkspaces()
return this.exec(args)
}
}
Expand Down
20 changes: 20 additions & 0 deletions lib/arborist-ws-cmd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const ArboristCmd = require('./arborist-cmd.js')

// This is the base for all commands whose execWorkspaces just gets
// a list of workspace names and passes it on to new Arborist() to
// be able to run a filtered Arborist.reify() at some point.
class ArboristWsCmd extends ArboristCmd {
static params = [
'workspace',
'workspaces',
'include-workspace-root',
...super.params,
]

async execWorkspaces (args) {
await this.setWorkspaces()
return this.exec(args)
}
}

module.exports = ArboristWsCmd
2 changes: 1 addition & 1 deletion lib/commands/audit.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const npmAuditReport = require('npm-audit-report')
const ArboristWorkspaceCmd = require('../arborist-cmd.js')
const ArboristWorkspaceCmd = require('../arborist-ws-cmd.js')
const auditError = require('../utils/audit-error.js')
const { log, output } = require('proc-log')
const reifyFinish = require('../utils/reify-finish.js')
Expand Down
28 changes: 20 additions & 8 deletions lib/commands/ci.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ const runScript = require('@npmcli/run-script')
const fs = require('fs/promises')
const { log, time } = require('proc-log')
const validateLockfile = require('../utils/validate-lockfile.js')
const ArboristWorkspaceCmd = require('../arborist-cmd.js')
const ArboristCmd = require('../arborist-cmd.js')
const getWorkspaces = require('../utils/get-workspaces.js')

class CI extends ArboristWorkspaceCmd {
class CI extends ArboristCmd {
static description = 'Clean install a project'
static name = 'ci'

static workspaces = true
static ignoreImplicitWorkspace = true

// These are in the order they will show up in when running "-h"
static params = [
'install-strategy',
Expand All @@ -33,14 +37,19 @@ class CI extends ArboristWorkspaceCmd {
})
}

const workspacePaths = await getWorkspaces([], {
path: this.npm.localPrefix,
includeWorkspaceRoot: true,
})

const where = this.npm.prefix
const Arborist = require('@npmcli/arborist')
const opts = {
...this.npm.flatOptions,
packageLock: true, // npm ci should never skip lock files
path: where,
save: false, // npm ci should never modify the lockfile or package.json
workspaces: this.workspaceNames,
workspaces: [...workspacePaths.keys()],
}

const arb = new Arborist(opts)
Expand Down Expand Up @@ -79,11 +88,14 @@ class CI extends ArboristWorkspaceCmd {
// Only remove node_modules after we've successfully loaded the virtual
// tree and validated the lockfile
await time.start('npm-ci:rm', async () => {
const path = `${where}/node_modules`
// get the list of entries so we can skip the glob for performance
const entries = await fs.readdir(path, null).catch(() => [])
return Promise.all(entries.map(f => fs.rm(`${path}/${f}`,
{ force: true, recursive: true })))
return await Promise.all([...workspacePaths.values()].map(async modulePath => {
const path = `${modulePath}/node_modules`
// get the list of entries so we can skip the glob for performance
const entries = await fs.readdir(path, null).catch(() => [])
return Promise.all(entries.map(f => {
return fs.rm(`${path}/${f}`, { force: true, recursive: true })
}))
}))
})
}

Expand Down
2 changes: 1 addition & 1 deletion lib/commands/dedupe.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const reifyFinish = require('../utils/reify-finish.js')
const ArboristWorkspaceCmd = require('../arborist-cmd.js')
const ArboristWorkspaceCmd = require('../arborist-ws-cmd.js')

// dedupe duplicated packages, or find them in the tree
class Dedupe extends ArboristWorkspaceCmd {
Expand Down
2 changes: 1 addition & 1 deletion lib/commands/explain.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const semver = require('semver')
const { relative, resolve } = require('path')
const validName = require('validate-npm-package-name')
const { output } = require('proc-log')
const ArboristWorkspaceCmd = require('../arborist-cmd.js')
const ArboristWorkspaceCmd = require('../arborist-ws-cmd.js')

class Explain extends ArboristWorkspaceCmd {
static description = 'Explain installed packages'
Expand Down
2 changes: 1 addition & 1 deletion lib/commands/find-dupes.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const ArboristWorkspaceCmd = require('../arborist-cmd.js')
const ArboristWorkspaceCmd = require('../arborist-ws-cmd.js')

// dedupe duplicated packages, or find them in the tree
class FindDupes extends ArboristWorkspaceCmd {
Expand Down
2 changes: 1 addition & 1 deletion lib/commands/fund.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const npa = require('npm-package-arg')
const { depth } = require('treeverse')
const { readTree: getFundingInfo, normalizeFunding, isValidFunding } = require('libnpmfund')
const { openUrl } = require('../utils/open-url.js')
const ArboristWorkspaceCmd = require('../arborist-cmd.js')
const ArboristWorkspaceCmd = require('../arborist-ws-cmd.js')

const getPrintableName = ({ name, version }) => {
const printableVersion = version ? `@${version}` : ''
Expand Down
2 changes: 1 addition & 1 deletion lib/commands/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const runScript = require('@npmcli/run-script')
const pacote = require('pacote')
const checks = require('npm-install-checks')
const reifyFinish = require('../utils/reify-finish.js')
const ArboristWorkspaceCmd = require('../arborist-cmd.js')
const ArboristWorkspaceCmd = require('../arborist-ws-cmd.js')

class Install extends ArboristWorkspaceCmd {
static description = 'Install a package'
Expand Down
2 changes: 1 addition & 1 deletion lib/commands/link.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const npa = require('npm-package-arg')
const pkgJson = require('@npmcli/package-json')
const semver = require('semver')
const reifyFinish = require('../utils/reify-finish.js')
const ArboristWorkspaceCmd = require('../arborist-cmd.js')
const ArboristWorkspaceCmd = require('../arborist-ws-cmd.js')

class Link extends ArboristWorkspaceCmd {
static description = 'Symlink a package folder'
Expand Down
2 changes: 1 addition & 1 deletion lib/commands/ls.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const archy = require('archy')
const { breadth } = require('treeverse')
const npa = require('npm-package-arg')
const { output } = require('proc-log')
const ArboristWorkspaceCmd = require('../arborist-cmd.js')
const ArboristWorkspaceCmd = require('../arborist-ws-cmd.js')
const localeCompare = require('@isaacs/string-locale-compare')('en')

const relativePrefix = `.${sep}`
Expand Down
2 changes: 1 addition & 1 deletion lib/commands/outdated.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const npa = require('npm-package-arg')
const pickManifest = require('npm-pick-manifest')
const { output } = require('proc-log')
const localeCompare = require('@isaacs/string-locale-compare')('en')
const ArboristWorkspaceCmd = require('../arborist-cmd.js')
const ArboristWorkspaceCmd = require('../arborist-ws-cmd.js')

class Outdated extends ArboristWorkspaceCmd {
static description = 'Check for outdated packages'
Expand Down
2 changes: 1 addition & 1 deletion lib/commands/prune.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const reifyFinish = require('../utils/reify-finish.js')
const ArboristWorkspaceCmd = require('../arborist-cmd.js')
const ArboristWorkspaceCmd = require('../arborist-ws-cmd.js')

// prune extraneous packages
class Prune extends ArboristWorkspaceCmd {
Expand Down
2 changes: 1 addition & 1 deletion lib/commands/rebuild.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const { resolve } = require('path')
const { output } = require('proc-log')
const npa = require('npm-package-arg')
const semver = require('semver')
const ArboristWorkspaceCmd = require('../arborist-cmd.js')
const ArboristWorkspaceCmd = require('../arborist-ws-cmd.js')

class Rebuild extends ArboristWorkspaceCmd {
static description = 'Rebuild a package'
Expand Down
2 changes: 1 addition & 1 deletion lib/commands/uninstall.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const { resolve } = require('path')
const pkgJson = require('@npmcli/package-json')
const reifyFinish = require('../utils/reify-finish.js')
const completion = require('../utils/installed-shallow.js')
const ArboristWorkspaceCmd = require('../arborist-cmd.js')
const ArboristWorkspaceCmd = require('../arborist-ws-cmd.js')

class Uninstall extends ArboristWorkspaceCmd {
static description = 'Remove a package'
Expand Down
2 changes: 1 addition & 1 deletion lib/commands/update.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const path = require('path')
const { log } = require('proc-log')
const reifyFinish = require('../utils/reify-finish.js')
const ArboristWorkspaceCmd = require('../arborist-cmd.js')
const ArboristWorkspaceCmd = require('../arborist-ws-cmd.js')

class Update extends ArboristWorkspaceCmd {
static description = 'Update packages'
Expand Down
44 changes: 44 additions & 0 deletions mock-registry/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,50 @@ class MockRegistry {
...packument,
}
}

/**
* this is a simpler convience method for creating mockable registry with
* tarballs for specific versions
*/
async setup (packages) {
const format = Object.keys(packages).map(v => {
const [name, version] = v.split('@')
return { name, version }
}).reduce((acc, inc) => {
const exists = acc.find(pkg => pkg.name === inc.name)
if (exists) {
exists.tarballs = {
...exists.tarballs,
[inc.version]: packages[`${inc.name}@${inc.version}`],
}
} else {
acc.push({ name: inc.name,
tarballs: {
[inc.version]: packages[`${inc.name}@${inc.version}`],
},
})
}
return acc
}, [])
const registry = this
for (const pkg of format) {
const { name, tarballs } = pkg
const versions = Object.keys(tarballs)
const manifest = await registry.manifest({ name, versions })

for (const version of versions) {
const tarballPath = pkg.tarballs[version]
if (!tarballPath) {
throw new Error(`Tarball path not provided for version ${version}`)
}

await registry.tarball({
manifest: manifest.versions[version],
tarball: tarballPath,
})
}
}
}
}

module.exports = MockRegistry
4 changes: 1 addition & 3 deletions smoke-tests/tap-snapshots/test/index.js.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@ npm error [--install-strategy <hoisted|nested|shallow|linked>] [--legacy-bundlin
npm error [--global-style] [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]]
npm error [--include <prod|dev|optional|peer> [--include <prod|dev|optional|peer> ...]]
npm error [--strict-peer-deps] [--foreground-scripts] [--ignore-scripts] [--no-audit]
npm error [--no-bin-links] [--no-fund] [--dry-run]
npm error [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
npm error [-ws|--workspaces] [--include-workspace-root] [--install-links]
npm error [--no-bin-links] [--no-fund] [--dry-run] [--install-links]
npm error
npm error aliases: clean-install, ic, install-clean, isntall-clean
npm error
Expand Down
14 changes: 2 additions & 12 deletions tap-snapshots/test/lib/docs.js.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -2710,9 +2710,7 @@ Options:
[--global-style] [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]]
[--include <prod|dev|optional|peer> [--include <prod|dev|optional|peer> ...]]
[--strict-peer-deps] [--foreground-scripts] [--ignore-scripts] [--no-audit]
[--no-bin-links] [--no-fund] [--dry-run]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root] [--install-links]
[--no-bin-links] [--no-fund] [--dry-run] [--install-links]

aliases: clean-install, ic, install-clean, isntall-clean

Expand All @@ -2736,9 +2734,6 @@ aliases: clean-install, ic, install-clean, isntall-clean
#### \`bin-links\`
#### \`fund\`
#### \`dry-run\`
#### \`workspace\`
#### \`workspaces\`
#### \`include-workspace-root\`
#### \`install-links\`
`

Expand Down Expand Up @@ -3329,9 +3324,7 @@ Options:
[--global-style] [--omit <dev|optional|peer> [--omit <dev|optional|peer> ...]]
[--include <prod|dev|optional|peer> [--include <prod|dev|optional|peer> ...]]
[--strict-peer-deps] [--foreground-scripts] [--ignore-scripts] [--no-audit]
[--no-bin-links] [--no-fund] [--dry-run]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root] [--install-links]
[--no-bin-links] [--no-fund] [--dry-run] [--install-links]

aliases: cit, clean-install-test, sit

Expand All @@ -3355,9 +3348,6 @@ aliases: cit, clean-install-test, sit
#### \`bin-links\`
#### \`fund\`
#### \`dry-run\`
#### \`workspace\`
#### \`workspaces\`
#### \`include-workspace-root\`
#### \`install-links\`
`

Expand Down
Loading