feat: option to disable pnpmfile (#979)

* feat: option to disable pnpm hooks

* fix: as for review; doesn't work until @pnpm/types is upgraded

* fix: use opts.ignorePnpmfile in the caller

* chore: update shrinkwrap.yaml

* test: --ignore-pnpmfile flag
This commit is contained in:
Emanuele Tamponi 2017-12-30 23:15:42 +01:00 committed by Zoltan Kochan
parent ce12413bbf
commit 49165f5527
11 changed files with 134 additions and 18 deletions

3
.gitignore vendored
View File

@ -19,6 +19,9 @@ lib
# Visual Studio Code configs
.vscode/
# JetBrains IDEs
.idea/
# pnpm uses npm for publishing a new version with
# dependencies bundled but the npm lockfile is not needed
# because pnpm use pnpm for installation

View File

@ -190,6 +190,14 @@ Can be passed in via a CLI option. `--no-lock` to set it to false. E.g.: `pnpm i
> If you experience issues similar to the ones described in [#594](https://github.com/pnpm/pnpm/issues/594), use this option to disable locking.
> In the meanwhile, we'll try to find a solution that will make locking work for everyone.
#### ignore-pnpmfile
* Default: **false**
* Type: **Boolean**
`pnpmfile.js` will be ignored. Useful together with `--ignore-scripts` when you want to make sure that
no script gets executed during install.
#### independent-leaves
* Default: **false**

View File

@ -27,7 +27,7 @@
"@pnpm/logger": "^1.0.0",
"@pnpm/outdated": "^0.2.2",
"@pnpm/server": "^0.4.0",
"@pnpm/types": "^1.3.0",
"@pnpm/types": "^1.5.0",
"@types/get-port": "^3.2.0",
"@types/write-json-file": "^2.2.1",
"@zkochan/libnpx": "^9.6.1",

View File

@ -4,7 +4,7 @@ dependencies:
'@pnpm/logger': 1.0.0
'@pnpm/outdated': 0.2.2
'@pnpm/server': 0.4.0
'@pnpm/types': 1.4.0
'@pnpm/types': 1.5.0
'@types/get-port': 3.2.0
'@types/write-json-file': 2.2.1
'@zkochan/libnpx': 9.6.1
@ -28,7 +28,7 @@ dependencies:
package-store: 0.12.0
path-name: 1.0.0
pkgs-graph: 2.0.0-0
pnpm-default-reporter: 0.11.0
pnpm-default-reporter: 0.11.1
pnpm-file-reporter: 0.0.1
pnpm-list: 2.0.0
ramda: 0.25.0
@ -307,7 +307,7 @@ packages:
dependencies:
'@pnpm/git-fetcher': 0.2.0
'@pnpm/tarball-fetcher': 0.3.1
'@pnpm/types': 1.4.0
'@pnpm/types': 1.5.0
dev: false
engines:
node: '>=4'
@ -319,7 +319,7 @@ packages:
'@pnpm/local-resolver': 0.1.0
'@pnpm/npm-resolver': 0.3.5
'@pnpm/tarball-resolver': 0.1.0
'@pnpm/types': 1.4.0
'@pnpm/types': 1.5.0
dev: false
engines:
node: '>=4'
@ -374,7 +374,7 @@ packages:
integrity: sha512-HBt5ySfGqXOKLk+mn9JVDJOmhc2sv9wZiOwgnX494Y0aYwf27lDjjJm5wbscsglMBnKpnybveWnc+6a/B08E+w==
/@pnpm/local-resolver/0.1.0:
dependencies:
'@pnpm/types': 1.4.0
'@pnpm/types': 1.5.0
'@types/node': 8.5.2
normalize-path: 2.1.1
osenv: 0.1.4
@ -397,7 +397,7 @@ packages:
integrity: sha512-VRqE5/SiuR7ZrwBmS+Af89BTXli5xBbiqu7WPq56gEtWT8dKf9rFLoimmmMBVeRq5LmVZIXlOxs29F9I+vgSvQ==
/@pnpm/npm-resolver/0.3.5:
dependencies:
'@pnpm/types': 1.4.0
'@pnpm/types': 1.5.0
'@types/load-json-file': 2.0.7
'@types/mem': 1.1.2
'@types/node': 8.5.2
@ -436,7 +436,7 @@ packages:
dependencies:
'@pnpm/check-package': 1.0.0
'@pnpm/pkgid-to-filename': 1.0.0
'@pnpm/types': 1.4.0
'@pnpm/types': 1.5.0
'@types/load-json-file': 2.0.7
'@types/mz': 0.0.32
'@types/p-queue': 1.1.0
@ -516,10 +516,10 @@ packages:
node: '>=4'
resolution:
integrity: sha512-Ieeu9Gg5qZkUdgnsHkjFlqr1Gp2z0LegDnCKe7l4l2klnH5Yp2fjqegfkebpM7Qut9YYe+aFsXFWxSCUk13Z8g==
/@pnpm/types/1.4.0:
/@pnpm/types/1.5.0:
dev: false
resolution:
integrity: sha512-VghLLKj5eoPnxl2H0g4uDrDzvVyDc1iqwk4JJN7iQJ6XuVdJvJsU0ecyywAT/XZKI8YZQNYm+zLlwuD4u4jpqQ==
integrity: sha512-TSVIseQbSxXF60P9YauEzGfV6T1LdWMG+XACWKh6zxUI1aUDxQBb3w2LryR6+nGBEvudUrnQ5sRFPFzdxsIj3A==
/@sindresorhus/is/0.6.0:
engines:
node: '>=4'
@ -4325,7 +4325,7 @@ packages:
dependencies:
'@pnpm/fs-locker': 1.0.0
'@pnpm/package-requester': 0.5.1
'@pnpm/types': 1.4.0
'@pnpm/types': 1.5.0
'@types/load-json-file': 2.0.7
'@types/node': 8.5.2
'@types/ramda': 0.25.12
@ -4561,7 +4561,7 @@ packages:
node: '>=4'
resolution:
integrity: sha512-DDjRXcmxXjaR/VAqI5dkNBoj7nh4Te4EvYDIm7L6gOk9cWzCOfcbSbbu+OsPt0mrOiShbXSTWhwbeKFGZ1Ma7g==
/pnpm-default-reporter/0.11.0:
/pnpm-default-reporter/0.11.1:
dependencies:
'@types/common-tags': 1.4.0
'@types/node': 8.5.2
@ -4584,7 +4584,7 @@ packages:
peerDependencies:
supi: ^0.8.0
resolution:
integrity: sha512-32TuzzPTuwjDO4Up73uJeaBBQ+7jncHulOLCW9Y1yjHy8O9YfNqIQTv4ux33XYyDMwiYKDNuw1UgyY7G2G4XLQ==
integrity: sha512-scwFaG7skjWIUxPyXwLLadCfbUn7E5Ni1wyJJ5RIs6693oJXg6EqQQkvNSttU5E7eoBGC427nCikzv8CMrxPUw==
/pnpm-file-reporter/0.0.1:
dependencies:
'@types/chalk': 0.4.31
@ -5666,7 +5666,7 @@ packages:
'@pnpm/fs-locker': 1.0.0
'@pnpm/package-requester': 0.5.1
'@pnpm/pkgid-to-filename': 1.0.0
'@pnpm/types': 1.4.0
'@pnpm/types': 1.5.0
'@types/byline': 4.2.31
'@types/common-tags': 1.4.0
'@types/load-json-file': 2.0.7
@ -6487,7 +6487,7 @@ specifiers:
'@pnpm/logger': ^1.0.0
'@pnpm/outdated': ^0.2.2
'@pnpm/server': ^0.4.0
'@pnpm/types': ^1.3.0
'@pnpm/types': ^1.5.0
'@types/byline': ^4.2.31
'@types/common-tags': ^1.2.5
'@types/delay': ^2.0.1

View File

@ -114,6 +114,7 @@ async function run (argv: string[]) {
'child-concurrency': Number,
'fetching-concurrency': Number,
'global-path': path,
'ignore-pnpmfile': Boolean,
'independent-leaves': Boolean,
'lock': Boolean,
'lock-stale-duration': Number,

View File

@ -34,6 +34,7 @@ function getHelpText (command: string) {
--offline trigger an error if any required dependencies are not available in local store
--network-concurrency <number> maximum number of concurrent network requests
--child-concurrency <number> controls the number of child processes run parallelly to build node modules
--ignore-pnpmfile disable pnpm hooks defined in pnpmfile.js
--independent-leaves symlinks leaf dependencies directly from the global store
--[no-]verify-store-integrity if false, doesn't check whether packages in the store were mutated
--production, --only prod[uction] packages in \`devDependencies\` won't be installed

View File

@ -12,7 +12,9 @@ export default async function installCmd (input: string[], opts: PnpmOptions) {
input = input.filter(Boolean)
const prefix = opts.prefix || process.cwd()
opts.hooks = requireHooks(prefix)
if (!opts.ignorePnpmfile) {
opts.hooks = requireHooks(prefix)
}
opts['storeController'] = (await createStoreController(opts)).ctrl // tslint:disable-line

View File

@ -64,7 +64,7 @@ export default async (input: string[], opts: PnpmOptions) => {
for (const chunk of chunks) {
await chunk.map((prefix: string) =>
limitInstallation(() => {
const hooks = requireHooks(prefix)
const hooks = opts.ignorePnpmfile ? {} : requireHooks(prefix)
return install({...opts, hooks, storeController, prefix})
}),
)

View File

@ -6,7 +6,9 @@ export default async function (input: string[], opts: PnpmOptions) {
opts = Object.assign({update: true}, opts)
const prefix = opts.prefix || process.cwd()
opts.hooks = requireHooks(prefix)
if (!opts.ignorePnpmfile) {
opts.hooks = requireHooks(prefix)
}
opts['storeController'] = (await createStoreController(opts)).ctrl // tslint:disable-line
if (!input || !input.length) {

View File

@ -74,3 +74,55 @@ test('prints meaningful error when there is syntax error in pnpmfile.js', async
t.ok(proc.stderr.toString().indexOf('SyntaxError: Invalid regular expression: missing /') !== -1)
t.equal(proc.status, 1)
})
test('ignore pnpmfile.js when --ignore-pnpmfile is used', async (t: tape.Test) => {
const project = prepare(t)
await fs.writeFile('pnpmfile.js', `
'use strict'
module.exports = {
hooks: {
readPackage (pkg) {
if (pkg.name === 'pkg-with-1-dep') {
pkg.dependencies['dep-of-pkg-with-1-dep'] = '100.0.0'
}
return pkg
}
}
}
`, 'utf8')
await addDistTag('dep-of-pkg-with-1-dep', '100.1.0', 'latest')
await execPnpm('install', 'pkg-with-1-dep', '--ignore-pnpmfile')
await project.storeHas('dep-of-pkg-with-1-dep', '100.1.0')
})
test('ignore pnpmfile.js during update when --ignore-pnpmfile is used', async (t: tape.Test) => {
const project = prepare(t, {
dependencies: {
'pkg-with-1-dep': '*',
},
})
await fs.writeFile('pnpmfile.js', `
'use strict'
module.exports = {
hooks: {
readPackage (pkg) {
if (pkg.name === 'pkg-with-1-dep') {
pkg.dependencies['dep-of-pkg-with-1-dep'] = '100.0.0'
}
return pkg
}
}
}
`, 'utf8')
await addDistTag('dep-of-pkg-with-1-dep', '100.1.0', 'latest')
await execPnpm('update', '--ignore-pnpmfile')
await project.storeHas('dep-of-pkg-with-1-dep', '100.1.0')
})

View File

@ -119,3 +119,50 @@ test('recursive installation of packages with hooks', async t => {
t.end()
})
test('ignores pnpmfile.js during recursive installation when --ignore-pnpmfile is used', async t => {
// This test hangs on Appveyor for some reason
if (isCI && isWindows()) return
const projects = prepare(t, [
{
name: 'project-1',
version: '1.0.0',
dependencies: {
'is-positive': '1.0.0',
},
},
{
name: 'project-2',
version: '1.0.0',
dependencies: {
'is-negative': '1.0.0',
},
},
])
process.chdir('project-1')
const pnpmfile = `
module.exports = { hooks: { readPackage } }
function readPackage (pkg) {
pkg.dependencies = pkg.dependencies || {}
pkg.dependencies['dep-of-pkg-with-1-dep'] = '100.1.0'
return pkg
}
`
await fs.writeFile('pnpmfile.js', pnpmfile, 'utf8')
process.chdir('../project-2')
await fs.writeFile('pnpmfile.js', pnpmfile, 'utf8')
process.chdir('..')
await execPnpm('recursive', 'install', '--ignore-pnpmfile')
const shr1 = await projects['project-1'].loadShrinkwrap()
t.notOk(shr1.packages['/dep-of-pkg-with-1-dep/100.1.0'])
const shr2 = await projects['project-2'].loadShrinkwrap()
t.notOk(shr2.packages['/dep-of-pkg-with-1-dep/100.1.0'])
t.end()
})