Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
feat: set --no-audit when installing outside of a project (like --glo…
…bal)
  • Loading branch information
fritzy authored and wraithgar committed Nov 1, 2022
1 parent 6df246f commit 706b3d3
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 3 deletions.
14 changes: 14 additions & 0 deletions lib/arborist-cmd.js
@@ -1,3 +1,5 @@
const log = require('./utils/log-shim.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.
Expand All @@ -17,6 +19,18 @@ class ArboristCmd extends BaseCommand {

static ignoreImplicitWorkspace = false

constructor (npm) {
super(npm)
if (this.npm.config.isDefault('audit')
&& (this.npm.global || this.npm.config.get('location') !== 'project')
) {
this.npm.config.set('audit', false)
} else if (this.npm.global && this.npm.config.get('audit')) {
log.warn('config',
'includes both --global and --audit, which is currently unsupported.')
}
}

async execWorkspaces (args, filters) {
await this.setWorkspaces(filters)
return this.exec(args)
Expand Down
15 changes: 15 additions & 0 deletions lib/npm.js
Expand Up @@ -88,6 +88,21 @@ class Npm extends EventEmitter {
// would be needed to change this
async cmd (cmd) {
await this.load()

// when location isn't set and global isn't true
// check for a package.json at the localPrefix
// and set the location to project if found
// TODO: this logic can move to the config module loadLocalPrefix to
// avoid double stat calls and consolidate logic
if (this.config.isDefault('location') && !this.config.get('global')) {
const hasPackageJson = await fs.stat(resolve(this.config.localPrefix, 'package.json'))
.then((st) => st.isFile())
.catch(() => false)
if (hasPackageJson) {
this.config.set('location', 'project')
}
}

const command = this.deref(cmd)
if (!command) {
throw Object.assign(new Error(`Unknown command ${cmd}`), {
Expand Down
1 change: 1 addition & 0 deletions tap-snapshots/test/lib/commands/config.js.test.cjs
Expand Up @@ -354,6 +354,7 @@ exports[`test/lib/commands/config.js TAP config list with publishConfig > output
; "cli" config from command line options
cache = "{NPMDIR}/test/lib/commands/tap-testdir-config-config-list-with-publishConfig-sandbox/cache"
location = "project"
prefix = "{LOCALPREFIX}"
userconfig = "{HOME}/.npmrc"
Expand Down
12 changes: 11 additions & 1 deletion test/index.js
Expand Up @@ -11,7 +11,17 @@ t.test('loading as main module will load the cli', t => {
const cwd = t.testdir()
const { spawn } = require('child_process')
const LS = require('../lib/commands/ls.js')
const ls = new LS({ config: { validate: () => {} } })
const ls = new LS({
config: {
validate: () => {},
get: (key) => {
if (key === 'location') {
return 'project'
}
},
isDefault: () => {},
},
})
const p = spawn(process.execPath, [index, 'ls', '-h', '--cache', cwd])
const out = []
p.stdout.on('data', c => out.push(c))
Expand Down
14 changes: 12 additions & 2 deletions test/lib/arborist-cmd.js
Expand Up @@ -2,6 +2,16 @@ const { resolve } = require('path')
const t = require('tap')
const ArboristCmd = require('../../lib/arborist-cmd.js')

const configMock = {
validate: () => {},
get: (key) => {
if (key === 'location') {
return 'project'
}
},
isDefault: () => {},
}

t.test('arborist-cmd', async t => {
const path = t.testdir({
'package.json': JSON.stringify({
Expand Down Expand Up @@ -44,7 +54,7 @@ t.test('arborist-cmd', async t => {

class TestCmd extends ArboristCmd {}

const cmd = new TestCmd({ localPrefix: path, config: { validate: () => {} } })
const cmd = new TestCmd({ localPrefix: path, config: configMock })

// check filtering for a single workspace name
cmd.exec = async function (args) {
Expand Down Expand Up @@ -96,7 +106,7 @@ t.test('handle getWorkspaces raising an error', async t => {
},
})
class TestCmd extends ArboristCmd {}
const cmd = new TestCmd({ localPrefix: t.testdir(), config: { validate: () => {} } })
const cmd = new TestCmd({ localPrefix: t.testdir(), config: configMock })

await t.rejects(
cmd.execWorkspaces(['foo'], ['a']),
Expand Down
6 changes: 6 additions & 0 deletions test/lib/commands/explain.js
Expand Up @@ -8,6 +8,12 @@ const npm = {
},
config: {
validate: () => {},
get: (key) => {
if (key === 'location') {
return 'project'
}
},
isDefault: () => {},
},
}
const { resolve } = require('path')
Expand Down
6 changes: 6 additions & 0 deletions test/lib/commands/install-ci-test.js
Expand Up @@ -25,6 +25,12 @@ const installCITest = new InstallCITest({
},
config: {
validate: () => {},
get: (key) => {
if (key === 'location') {
return 'project'
}
},
isDefault: () => {},
},
})

Expand Down
6 changes: 6 additions & 0 deletions test/lib/commands/install-test.js
Expand Up @@ -25,6 +25,12 @@ const installTest = new InstallTest({
},
config: {
validate: () => {},
get: (key) => {
if (key === 'location') {
return 'project'
}
},
isDefault: () => {},
},
})

Expand Down
75 changes: 75 additions & 0 deletions test/lib/commands/install.js
Expand Up @@ -130,6 +130,7 @@ t.test('exec commands', async t => {
)
t.equal(REIFY_CALLED, true, 'called reify')
t.strictSame(SCRIPTS, [], 'no scripts when installing globally')
t.equal(npm.config.get('audit', 'cli'), false)
})

await t.test('should not install invalid global package name', async t => {
Expand Down Expand Up @@ -327,3 +328,77 @@ t.test('completion', async t => {
t.strictSame(res, [])
})
})

t.test('location detection and audit', async () => {
t.test('audit false without package.json', async t => {
const { npm } = await _loadMockNpm(t, {
prefixDir: {
// no package.json
'readme.txt': 'just a file',
other: {},
},
})
const install = await npm.cmd('install')
t.equal(install.npm.config.get('location'), 'user')
t.equal(install.npm.config.get('audit'), false)
})
t.test('audit true with package.json', async t => {
const { npm } = await _loadMockNpm(t, {
prefixDir: {
'package.json': '{ "name": "testpkg", "version": "1.0.0" }',
'readme.txt': 'just a file',
},
})
const install = await npm.cmd('install')
t.equal(install.npm.config.get('location'), 'project')
t.equal(install.npm.config.get('audit'), true)
})
t.test('audit true without package.json when set', async t => {
const { npm } = await _loadMockNpm(t, {
prefixDir: {
// no package.json
'readme.txt': 'just a file',
other: {},
},
config: {
audit: { value: true, where: 'cli' },
},
})
const install = await npm.cmd('install')
t.equal(install.npm.config.get('location'), 'user')
t.equal(install.npm.config.get('audit'), true)
})
t.test('audit true in root config without package.json', async t => {
const { npm } = await _loadMockNpm(t, {
prefixDir: {
// no package.json
'readme.txt': 'just a file',
other: {},
},
config: {
audit: { value: true, where: 'builtin' },
},
})
const install = await npm.cmd('install')
t.equal(install.npm.config.get('location'), 'user')
t.equal(install.npm.config.get('audit'), true)
})
t.test('test for warning when --global & --audit', async t => {
const { npm, logs } = await _loadMockNpm(t, {
prefixDir: {
// no package.json
'readme.txt': 'just a file',
other: {},
},
config: {
audit: { value: true, where: 'cli' },
global: { value: true, where: 'cli' },
},
})
const install = await npm.cmd('install')
t.equal(install.npm.config.get('location'), 'user')
t.equal(install.npm.config.get('audit'), true)
t.equal(logs.warn[0][0], 'config')
t.equal(logs.warn[0][1], 'includes both --global and --audit, which is currently unsupported.')
})
})
1 change: 1 addition & 0 deletions test/lib/commands/ls.js
Expand Up @@ -103,6 +103,7 @@ const config = {
global: false,
json: false,
link: false,
location: 'project',
omit: [],
parseable: false,
'package-lock-only': false,
Expand Down
1 change: 1 addition & 0 deletions test/lib/commands/set.js
Expand Up @@ -42,6 +42,7 @@ const npm = {
},
config: {
validate: () => {},
isDefault: () => {},
},
}

Expand Down

0 comments on commit 706b3d3

Please sign in to comment.