From d7652e8564db2dec800cded1611c01709bff6f2b Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Sun, 15 Apr 2018 13:47:26 +0300 Subject: [PATCH] feat(recursive): read local package configs close #1093 --- package.json | 3 +++ shrinkwrap.yaml | 22 +++++++++++++++++++--- src/cmd/recursive.ts | 18 ++++++++++++++++++ test/recursive.ts | 35 +++++++++++++++++++++++++++++++++++ typings/local.d.ts | 5 +++++ 5 files changed, 80 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 5199e03d25..88b9f8e88c 100644 --- a/package.json +++ b/package.json @@ -28,12 +28,14 @@ "@pnpm/server": "^0.9.0", "@pnpm/store-path": "^1.0.3", "@pnpm/types": "^1.5.0", + "@types/camelcase-keys": "^4.0.0", "@types/get-port": "^3.2.0", "@types/retry": "^0.10.2", "@types/write-json-file": "^2.2.1", "@zkochan/libnpx": "^9.6.1", "byline": "^5.0.0", "camelcase": "^4.1.0", + "camelcase-keys": "^4.2.0", "chalk": "^2.2.0", "common-tags": "^1.4.0", "cross-spawn": "^6.0.3", @@ -60,6 +62,7 @@ "pnpm-list": "^2.0.0", "process-exists": "^3.0.0", "ramda": "^0.25.0", + "read-ini-file": "^1.0.0", "retry": "^0.12.0", "signal-exit": "^3.0.2", "strip-color": "^0.1.0", diff --git a/shrinkwrap.yaml b/shrinkwrap.yaml index 26811fe93a..7252c3c085 100644 --- a/shrinkwrap.yaml +++ b/shrinkwrap.yaml @@ -7,12 +7,14 @@ dependencies: '@pnpm/server': 0.9.0 '@pnpm/store-path': 1.0.3 '@pnpm/types': 1.7.0 + '@types/camelcase-keys': 4.0.0 '@types/get-port': 3.2.0 '@types/retry': 0.10.2 '@types/write-json-file': 2.2.1 '@zkochan/libnpx': 9.6.1 byline: 5.0.0 camelcase: 4.1.0 + camelcase-keys: 4.2.0 chalk: 2.4.0 common-tags: 1.7.2 cross-spawn: 6.0.5 @@ -40,6 +42,7 @@ dependencies: pnpm-list: 2.0.1 process-exists: 3.1.0 ramda: 0.25.0 + read-ini-file: 1.0.0 retry: 0.12.0 signal-exit: 3.0.2 strip-color: 0.1.0 @@ -711,6 +714,10 @@ packages: '@types/node': 9.6.6 resolution: integrity: sha1-DmH8ucA+BH0hxEllVMcRYperYM0= + /@types/camelcase-keys/4.0.0: + dev: false + resolution: + integrity: sha1-Uo2iPnvUEGjuJeO6UqlqTQ0mPtU= /@types/camelcase/4.1.0: dev: false resolution: @@ -1543,7 +1550,6 @@ packages: camelcase: 4.1.0 map-obj: 2.0.0 quick-lru: 1.1.0 - dev: true engines: node: '>=4' resolution: @@ -4140,7 +4146,6 @@ packages: resolution: integrity: sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= /map-obj/2.0.0: - dev: true engines: node: '>=4' resolution: @@ -5443,7 +5448,6 @@ packages: resolution: integrity: sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== /quick-lru/1.1.0: - dev: true engines: node: '>=4' resolution: @@ -5478,6 +5482,15 @@ packages: dev: false resolution: integrity: sha1-6xiYnG1PTxYsOZ953dKfODVWgJI= + /read-ini-file/1.0.0: + dependencies: + graceful-fs: 4.1.11 + ini: 1.3.5 + pify: 2.3.0 + strip-bom: 3.0.0 + dev: false + resolution: + integrity: sha1-B92s/bnFmeSVQNCMf+32o6ISOPA= /read-package-json/2.0.13: dependencies: glob: 7.1.2 @@ -7214,6 +7227,7 @@ specifiers: '@pnpm/store-path': ^1.0.3 '@pnpm/types': ^1.5.0 '@types/byline': ^4.2.31 + '@types/camelcase-keys': ^4.0.0 '@types/common-tags': ^1.2.5 '@types/delay': ^2.0.1 '@types/get-port': ^3.2.0 @@ -7233,6 +7247,7 @@ specifiers: anonymous-npm-registry-client: ^0.1.2 byline: ^5.0.0 camelcase: ^4.1.0 + camelcase-keys: ^4.2.0 caw: ^2.0.0 chalk: ^2.2.0 common-tags: ^1.4.0 @@ -7271,6 +7286,7 @@ specifiers: pnpm-registry-mock: ^1.5.0 process-exists: ^3.0.0 ramda: ^0.25.0 + read-ini-file: ^1.0.0 read-pkg: ^3.0.0 retry: ^0.12.0 rimraf: ^2.5.4 diff --git a/src/cmd/recursive.ts b/src/cmd/recursive.ts index d7826ce64f..1513958101 100644 --- a/src/cmd/recursive.ts +++ b/src/cmd/recursive.ts @@ -1,4 +1,5 @@ import logger from '@pnpm/logger' +import camelcaseKeys = require('camelcase-keys') import findPackages from 'find-packages' import graphSequencer = require('graph-sequencer') import loadYamlFile = require('load-yaml-file') @@ -6,6 +7,7 @@ import pLimit = require('p-limit') import { StoreController } from 'package-store' import path = require('path') import createPkgGraph, {PackageNode} from 'pkgs-graph' +import readIniFile = require('read-ini-file') import sortPkgs = require('sort-pkgs') import { install, @@ -103,11 +105,17 @@ export default async ( limitInstallation(async () => { const hooks = opts.ignorePnpmfile ? {} : requireHooks(prefix, opts) try { + const localConfigs = await readLocalConfigs(prefix) return await action({ ...installOpts, + ...localConfigs, bin: path.join(prefix, 'node_modules', '.bin'), hooks, prefix, + rawNpmConfig: { + ...installOpts.rawNpmConfig, + ...localConfigs.rawNpmConfig, + }, storeController, }) } catch (err) { @@ -122,6 +130,16 @@ export default async ( await saveState() } +async function readLocalConfigs (prefix: string) { + try { + const ini = await readIniFile(path.join(prefix, '.npmrc')) + return camelcaseKeys(ini) + } catch (err) { + if (err.code !== 'ENOENT') throw err + return {} + } +} + function linkPackages ( graph: {[pkgPath: string]: {dependencies: string[]}}, opts: { diff --git a/test/recursive.ts b/test/recursive.ts index 5295c08c34..af16d31dc9 100644 --- a/test/recursive.ts +++ b/test/recursive.ts @@ -15,6 +15,7 @@ import { spawn, } from './utils' import mkdirp = require('mkdirp-promise') +import loadYamlFile = require('load-yaml-file') const test = promisifyTape(tape) @@ -44,6 +45,40 @@ test('recursive installation', async t => { t.end() }) +test('recursive installation with package-specific .npmrc', async t => { + 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', + }, + }, + ]) + + await fs.writeFile('project-1/.npmrc', 'shamefully-flatten = true', 'utf8') + + await execPnpm('recursive', 'install') + + t.ok(projects['project-1'].requireModule('is-positive')) + t.ok(projects['project-2'].requireModule('is-negative')) + + const modulesYaml1 = await projects['project-1'].loadModules() + t.ok(modulesYaml1.shamefullyFlatten) + + const modulesYaml2 = await projects['project-2'].loadModules() + t.notOk(modulesYaml2.shamefullyFlatten) + + t.end() +}) + test('recursive installation using server', async t => { const projects = prepare(t, [ { diff --git a/typings/local.d.ts b/typings/local.d.ts index fa1927f800..49661e866b 100644 --- a/typings/local.d.ts +++ b/typings/local.d.ts @@ -318,3 +318,8 @@ declare module 'npm-conf/lib/types' { const anything: any; export = anything; } + +declare module 'read-ini-file' { + function readIniFile (filename: string): Object; + export = readIniFile; +}