diff --git a/package.json b/package.json index 926bc24598..1dae9ae856 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "pnpm-logger": "^0.6.2", "ramda": "^0.25.0", "strip-color": "^0.1.0", - "supi": "^0.2.37", + "supi": "^0.5.0", "text-table": "^0.2.0", "update-notifier": "^2.1.0" }, diff --git a/shrinkwrap.yaml b/shrinkwrap.yaml index 6ac8d48134..a9f875acb6 100644 --- a/shrinkwrap.yaml +++ b/shrinkwrap.yaml @@ -19,7 +19,7 @@ dependencies: pnpm-logger: 0.6.2 ramda: 0.25.0 strip-color: 0.1.0 - supi: 0.2.37 + supi: 0.5.0 text-table: 0.2.0 update-notifier: 2.3.0 devDependencies: @@ -132,7 +132,7 @@ packages: integrity: sha512-v+dxizsFVyXgD3EpFuqT9YjdEjbJmPxNf1QIX9ohZOhxh1ZF2yhqv3vYaeum9lg3VghhxS5S0a6yldN9J9lPEQ== /@types/byline/4.2.31: dependencies: - '@types/node': 8.0.34 + '@types/node': 8.0.47 resolution: integrity: sha1-DmH8ucA+BH0hxEllVMcRYperYM0= /@types/chalk/0.4.31: @@ -142,8 +142,12 @@ packages: resolution: integrity: sha512-HI1tSO87vmd1sPS3DOVSK4gvVKROvCBFvAnXlLiQtAus/+1xXMQcNyu9TX2ChwRXFeQZeB9+f+nMo99xLd5DdA== /@types/load-json-file/2.0.6: + dev: true resolution: integrity: sha512-nMEwdmNE0w4JTXfwiCABJ57ZLk4DnHgWxIRfiyZ32UPPkmjsoCTChroYeTUbWG7NMbdgrvKSyS744Hg3A/9tAw== + /@types/load-json-file/2.0.7: + resolution: + integrity: sha512-NrH6jPlV77QCVPhAHofWeiOr77TgpKt82c2RVxSBChWBJqyY/u4ngl3CA4mcsAg/w7rNLrkR7dkObMV0ihLLXw== /@types/mkdirp/0.5.1: dependencies: '@types/node': 8.0.34 @@ -152,26 +156,32 @@ packages: integrity: sha512-XA4vNO6GCBz8Smq0hqSRo4yRWMqr4FPQrWjhJt6nKskzly4/p87SfuJMFYGRyYb6jo2WNIQU2FDBsY5r1BibUA== /@types/mz/0.0.31: dependencies: - '@types/node': 8.0.34 + '@types/node': 8.0.47 resolution: integrity: sha1-pNgMCC/v5x5Ap8DwfR5lVbu8e1I= /@types/mz/0.0.32: dependencies: - '@types/node': 8.0.34 + '@types/node': 8.0.47 resolution: integrity: sha512-cy3yebKhrHuOcrJGkfwNHhpTXQLgmXSv1BX+4p32j+VUQ6aP2eJ5cL7OvGcAQx75fCTFaAIIAKewvqL+iwSd4g== /@types/node/7.0.43: resolution: integrity: sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ== + /@types/node/7.0.46: + resolution: + integrity: sha512-u+JAi1KtmaUoU/EHJkxoiuvzyo91FCE41Z9TZWWcOUU3P8oUdlDLdrGzCGWySPgbRMD17B0B+1aaJLYI9egQ6A== /@types/node/8.0.34: resolution: integrity: sha512-Jnmm57+nHqvJUPwUzt1CLoLzFtF2B2vgG7cWFut+a4nqTp9/L6pL0N+o0Jt3V7AQnCKMsPEqQpLFZYleBCdq3w== + /@types/node/8.0.47: + resolution: + integrity: sha512-kOwL746WVvt/9Phf6/JgX/bsGQvbrK5iUgzyfwZNcKVFcjAUVSpF9HxevLTld2SG9aywYHOILj38arDdY1r/iQ== /@types/nopt/3.0.29: resolution: integrity: sha1-8Z3z20yX7hRZonQAKDIKcdcJZM4= /@types/npm/2.0.29: dependencies: - '@types/node': 8.0.34 + '@types/node': 8.0.47 resolution: integrity: sha512-McqGDdeT1tSMu8sPaL0ya7xBwojQYKGVwCrlPNBcaF+o+H4wLNH03nYRTfycU11Xdu8eziEb4cgdGmu4VF/NWA== /@types/p-series/1.0.0: @@ -183,12 +193,15 @@ packages: /@types/ramda/0.24.17: resolution: integrity: sha512-1zj7HQqHEdzjueCIRMiTSZteGavafmc12SWV3hp4yseKbXdebCsWGGoc+a9ywrJ4c7hQCLOBsoGQjc6wRXJyVA== + /@types/ramda/0.24.18: + resolution: + integrity: sha512-37umDB+zS6tK+3j0YJxsl7O8T4aYHYO6s1UpADJ/nxMHFjmuSd5XRQryC4IXX3HQ4XzstqAqhk/D+cdxwvqtEQ== /@types/rc/0.0.1: resolution: integrity: sha1-H1uKGzsaxtH+4TfFP6xfoPKK4Nc= - /@types/retry/0.10.1: + /@types/retry/0.10.2: resolution: - integrity: sha512-iV8ZXtRV3FxfTJNEWN/3ZbexH52w//uMB+8sPYCKBIA/a2bEQWYrNwGuftGI5Xt1wMROTHrGoJPSvwrM4njx7g== + integrity: sha512-LqJkY4VQ7S09XhI7kA3ON71AxauROhSv74639VsNXC9ish4IWHnIi98if+nP1MxQV3RMPqXSCYgpPsDHjlg9UQ== /@types/semver/5.4.0: resolution: integrity: sha512-PBHCvO98hNec9A491vBbh0ZNDOVxccwKL1u2pm6fs9oDgm7SEnw0lEHqHfjsYryDxnE3zaf7LvERWEXjOp1hig== @@ -273,14 +286,14 @@ packages: json-stable-stringify: 1.0.1 resolution: integrity: sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY= - /ajv/5.2.3: + /ajv/5.3.0: dependencies: co: 4.6.0 fast-deep-equal: 1.0.0 + fast-json-stable-stringify: 2.0.0 json-schema-traverse: 0.3.1 - json-stable-stringify: 1.0.1 resolution: - integrity: sha1-wG9Zh3jETGsWGrr+NGa4GtGBTtI= + integrity: sha1-RBT/dKUIecII7l/cgm4ywwNUnto= /ansi-align/2.0.0: dependencies: string-width: 2.1.1 @@ -999,10 +1012,10 @@ packages: engines: node: '>=4' optionalDependencies: - drivelist: 5.2.4 + drivelist: 5.2.6 resolution: integrity: sha512-FSY6axBYIVfYz9Rj6c6ECzcSxoNgqZRfAQP0kDiCVa38gPDzVyPWcEvxfDnJ96xW4oXLZLpiOloxRnC1sUKksA== - /drivelist/5.2.4: + /drivelist/5.2.6: dependencies: bindings: 1.3.0 debug: 3.1.0 @@ -1014,7 +1027,7 @@ packages: node: '>=4' optional: true resolution: - integrity: sha1-LDzZKd1x+gVjYQQ6BWPd/j1JvH8= + integrity: sha512-KfjqFdx5JrHWPIedkfQI0EB20ma/knHJjTUSyWC5Zx0a6TdtZOWULI3D3ef7tGbBk7MtRNVSmnTxvLCfYz6Fng== /duplexer3/0.1.4: resolution: integrity: sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= @@ -1154,6 +1167,9 @@ packages: /fast-deep-equal/1.0.0: resolution: integrity: sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8= + /fast-json-stable-stringify/2.0.0: + resolution: + integrity: sha1-1RQsDK7msRifh9OnYREGT4bIu/I= /fast-safe-stringify/1.1.13: resolution: integrity: sha1-oB6c2cnkkXFcmKdaQtXwu9EH/3Y= @@ -1383,7 +1399,7 @@ packages: integrity: sha1-M0gdDxu/9gDdID11gSpqX7oALio= /har-validator/5.0.3: dependencies: - ajv: 5.2.3 + ajv: 5.3.0 har-schema: 2.0.0 engines: node: '>=4' @@ -1426,7 +1442,7 @@ packages: boom: 4.3.1 cryptiles: 3.1.2 hoek: 4.2.0 - sntp: 2.0.2 + sntp: 2.1.0 engines: node: '>=4.5.0' resolution: @@ -1975,6 +1991,13 @@ packages: node: '>=4' resolution: integrity: sha1-l6ARdR6R3YfPre9Ygy67BJNt6Xg= + /make-dir/1.1.0: + dependencies: + pify: 3.0.0 + engines: + node: '>=4' + resolution: + integrity: sha512-0Pkui4wLJ7rxvmfUvs87skoEaxmu0hCUApF8nonzpl7q//FWp9zu8W61Scz4sd/kUiqDxvUhtoam2efDyiBzcA== /make-fetch-happen/2.5.0: dependencies: agentkeepalive: 3.3.0 @@ -2553,10 +2576,10 @@ packages: integrity: sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0= /package-store/0.4.2: dependencies: - '@types/load-json-file': 2.0.6 - '@types/node': 7.0.43 - '@types/ramda': 0.24.17 - '@types/retry': 0.10.1 + '@types/load-json-file': 2.0.7 + '@types/node': 7.0.46 + '@types/ramda': 0.24.18 + '@types/retry': 0.10.2 '@types/semver': 5.4.0 credentials-by-uri: 1.0.0 dint: 1.0.0 @@ -2644,7 +2667,7 @@ packages: integrity: sha1-+m9HsY4jgm6tMvJj50TQ4ehH+xM= /parse-npm-tarball-url/1.0.1: dependencies: - '@types/node': 7.0.43 + '@types/node': 7.0.46 semver-regex: 1.0.0 resolution: integrity: sha1-TfHPBF05fvLZw59RMImKiqjgYuQ= @@ -2809,7 +2832,7 @@ packages: integrity: sha512-VLlRExib18bl5lSFp74vFHeZV0iWuxTkdOvI7BIhfWpiP9EdrkAq/GnjE5pxjXmsvXyZlaBDwoEQygU8kbVr8g== /pnpm-shrinkwrap/3.4.0: dependencies: - '@types/node': 7.0.43 + '@types/node': 7.0.46 '@types/ramda': 0.0.11 dependency-path: 1.2.0 js-yaml: 3.10.0 @@ -3338,13 +3361,13 @@ packages: node: '>=0.8.0' resolution: integrity: sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg= - /sntp/2.0.2: + /sntp/2.1.0: dependencies: hoek: 4.2.0 engines: node: '>=4.0.0' resolution: - integrity: sha1-UGQRDwr4X3z9t9a2ekACjOUrSys= + integrity: sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg== /socks-proxy-agent/3.0.1: dependencies: agent-base: 4.1.1 @@ -3525,17 +3548,17 @@ packages: node: '>=0.10.0' resolution: integrity: sha1-PFMZQukIwml8DsNEhYwobHygpgo= - /supi/0.2.37: + /supi/0.5.0: dependencies: '@types/byline': 4.2.31 '@types/common-tags': 1.4.0 - '@types/load-json-file': 2.0.6 + '@types/load-json-file': 2.0.7 '@types/mz': 0.0.32 - '@types/node': 8.0.34 + '@types/node': 8.0.47 '@types/nopt': 3.0.29 '@types/npm': 2.0.29 '@types/p-series': 1.0.0 - '@types/ramda': 0.24.17 + '@types/ramda': 0.24.18 '@types/rc': 0.0.1 '@types/semver': 5.4.0 '@types/update-notifier': 1.0.2 @@ -3590,7 +3613,7 @@ packages: peerDependencies: pnpm-logger: ^0.6.2 resolution: - integrity: sha1-WvkTMEaw0X0popGDeHQ8V3STnEs= + integrity: sha512-5e5k5dA6rq0Y234eDCJWyZQgs5WO50Bmsa7J03RVCIAGXtRQ5zptJeZupUxzcgOsOWsFc0GDHa9n6b4va4u2BA== /supports-color/2.0.0: engines: node: '>=0.8.0' @@ -3618,7 +3641,7 @@ packages: /symlink-dir/1.1.0: dependencies: '@types/mz': 0.0.31 - '@types/node': 8.0.34 + '@types/node': 8.0.47 graceful-fs: 4.1.11 is-windows: 1.0.1 mkdirp-promise: 5.0.1 @@ -3819,7 +3842,7 @@ packages: integrity: sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= /unpack-stream/2.1.1: dependencies: - '@types/node': 8.0.34 + '@types/node': 8.0.47 decompress-maybe: 1.0.0 ssri: 4.1.6 tar-fs: 1.16.0 @@ -4011,7 +4034,7 @@ packages: dependencies: detect-indent: 5.0.0 graceful-fs: 4.1.11 - make-dir: 1.0.0 + make-dir: 1.1.0 pify: 3.0.0 sort-keys: 2.0.0 write-file-atomic: 2.3.0 @@ -4083,7 +4106,6 @@ packages: resolution: integrity: sha1-YpmpBVsc78lp/355wdkY3Osiw2A= registry: 'https://registry.npmjs.org/' -shrinkwrapMinorVersion: 1 shrinkwrapVersion: 3 specifiers: '@commitlint/cli': ^4.0.0 @@ -4121,7 +4143,7 @@ specifiers: ramda: ^0.25.0 rimraf: ^2.5.4 strip-color: ^0.1.0 - supi: ^0.2.37 + supi: ^0.5.0 text-table: ^0.2.0 tslint: ^5.4.2 typescript: ^2.4.1 diff --git a/src/bin/pnpm.ts b/src/bin/pnpm.ts index f0ec995cdd..d9161c099f 100755 --- a/src/bin/pnpm.ts +++ b/src/bin/pnpm.ts @@ -172,6 +172,20 @@ async function run (argv: string[]) { opts.packageManager = pkg opts.force = force + if (opts.only === 'prod' || opts.only === 'production' || !opts.only && opts.production) { + opts.production = true + opts.development = false + opts.optional = true + } else if (opts.only === 'dev' || opts.only === 'development') { + opts.production = false + opts.development = true + opts.optional = false + } else { + opts.production = true + opts.development = true + opts.optional = true + } + initReporter(silent ? 'silent' : (opts.reporter || 'default')) // tslint:disable-line // `pnpm install ""` is going to be just `pnpm install` diff --git a/src/cmd/help.ts b/src/cmd/help.ts index 7633d4bccb..feb457a4dd 100644 --- a/src/cmd/help.ts +++ b/src/cmd/help.ts @@ -25,18 +25,19 @@ function getHelpText(command: string) { Options: - -P, --save-prod save package to your \`dependencies\` - -D, --save-dev save package to your \`devDependencies\` - -O, --save-optional save package to your \`optionalDependencies\` - -E, --save-exact install exact version - -g, --global install as a global package - --store the location where all the packages are saved on the disk. - --offline trigger an error if any required dependencies are not available in local store - --network-concurrency maximum number of concurrent network requests - --child-concurrency controls the number of child processes run parallelly to build node modules - --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 packages in \`devDependencies\` won't be installed + -P, --save-prod save package to your \`dependencies\` + -D, --save-dev save package to your \`devDependencies\` + -O, --save-optional save package to your \`optionalDependencies\` + -E, --save-exact install exact version + -g, --global install as a global package + --store the location where all the packages are saved on the disk. + --offline trigger an error if any required dependencies are not available in local store + --network-concurrency maximum number of concurrent network requests + --child-concurrency controls the number of child processes run parallelly to build node modules + --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 + --only dev[elopment] only \`devDependencies\` are installed regardless of the \`NODE_ENV\`. --[no-]lock ` diff --git a/test/install/index.ts b/test/install/index.ts index 9c55732fdd..0e594956c7 100644 --- a/test/install/index.ts +++ b/test/install/index.ts @@ -1,3 +1,4 @@ import './misc' +import './only' import './lifecycleScripts' import './hooks' diff --git a/test/install/only.ts b/test/install/only.ts new file mode 100644 index 0000000000..4cb1c15b07 --- /dev/null +++ b/test/install/only.ts @@ -0,0 +1,77 @@ +import path = require('path') +import fs = require('mz/fs') +import tape = require('tape') +import loadJsonFile = require('load-json-file') +import promisifyTape from 'tape-promise' +import { + prepare, + testDefaults, + execPnpm, +} from '../utils' + +const basicPackageJson = loadJsonFile.sync(path.join(__dirname, '../utils/simple-package.json')) +const test = promisifyTape(tape) + +test('production install (with --production flag)', async (t: tape.Test) => { + const project = prepare(t, basicPackageJson) + + await execPnpm('install', '--production') + + const rimrafDir = fs.statSync(path.resolve('node_modules', 'rimraf')) + + let tapStatErrCode: number = 0 + try { + fs.statSync(path.resolve('node_modules', '@rstacruz')) + } catch (err) { + tapStatErrCode = err.code + } + + t.ok(rimrafDir.isSymbolicLink, 'rimraf exists') + t.is(tapStatErrCode, 'ENOENT', 'tap-spec does not exist') +}) + +test('production install (with production NODE_ENV)', async (t: tape.Test) => { + const originalNodeEnv = process.env.NODE_ENV + process.env.NODE_ENV = 'production' + const project = prepare(t, basicPackageJson) + + await execPnpm('install') + + // reset NODE_ENV + process.env.NODE_ENV = originalNodeEnv + + const rimrafDir = fs.statSync(path.resolve('node_modules', 'rimraf')) + + let tapStatErrCode: number = 0 + try { + fs.statSync(path.resolve('node_modules', '@rstacruz')) + } catch (err) { tapStatErrCode = err.code } + + t.ok(rimrafDir.isSymbolicLink, 'rimraf exists') + t.is(tapStatErrCode, 'ENOENT', 'tap-spec does not exist') +}) + +test('install dev dependencies only', async (t: tape.Test) => { + const project = prepare(t, { + dependencies: { + 'is-positive': "^1.0.0", + }, + devDependencies: { + 'is-negative': "^1.0.0", + }, + }) + + // NODE_ENV should be ignored if --only is used + const originalNodeEnv = process.env.NODE_ENV + process.env.NODE_ENV = 'production' + + await execPnpm('install', '--only', 'dev') + + // reset NODE_ENV + process.env.NODE_ENV = originalNodeEnv + + const isNegative = project.requireModule('is-negative') + t.equal(typeof isNegative, 'function', 'dev dependency is available') + + await project.hasNot('is-positive') +})