From 17425eefbd9f2351cdca988359cd6fe2d4cbee7b Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Tue, 23 Jan 2018 23:25:51 +0200 Subject: [PATCH] fix: optional dependency that does not exist should be skipped ref pnpm/pnpm#1004 --- src/install/installMultiple.ts | 43 +++++++++++++++++++--------- test/install/optionalDependencies.ts | 23 +++++++++++++++ 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/src/install/installMultiple.ts b/src/install/installMultiple.ts index 3f70d2438f..f9099658d2 100644 --- a/src/install/installMultiple.ts +++ b/src/install/installMultiple.ts @@ -8,6 +8,7 @@ import url = require('url') import { PackageFilesResponse, Resolution, + PackageResponse, } from '@pnpm/package-requester' import {InstallContext, InstalledPackages} from '../api/install' import { @@ -272,19 +273,35 @@ async function install ( pkg: loggedPkg, }) - const pkgResponse = await ctx.storeController.requestPackage(wantedDependency, { - loggedPkg, - update: options.update, - registry, - prefix: ctx.prefix, - shrinkwrapResolution: options.shrinkwrapResolution, - currentPkgId: options.pkgId, - verifyStoreIntegrity: ctx.verifyStoreInegrity, - downloadPriority: -options.currentDepth, - preferredVersions: ctx.preferredVersions, - skipFetch: ctx.dryRun, - sideEffectsCache: options.sideEffectsCache - }) + let pkgResponse: PackageResponse | undefined + try { + pkgResponse = await ctx.storeController.requestPackage(wantedDependency, { + loggedPkg, + update: options.update, + registry, + prefix: ctx.prefix, + shrinkwrapResolution: options.shrinkwrapResolution, + currentPkgId: options.pkgId, + verifyStoreIntegrity: ctx.verifyStoreInegrity, + downloadPriority: -options.currentDepth, + preferredVersions: ctx.preferredVersions, + skipFetch: ctx.dryRun, + sideEffectsCache: options.sideEffectsCache + }) + } catch (err) { + if (wantedDependency.optional) { + logger.warn({ + message: `Skipping optional dependency ${wantedDependency.raw}. ${err.toString()}`, + err, + }) + return null + } + throw err + } + + if (!pkgResponse) { + throw new Error(`Store returned nothing for ${wantedDependency.raw} request`) + } pkgResponse.body.id = encodePkgId(pkgResponse.body.id) diff --git a/test/install/optionalDependencies.ts b/test/install/optionalDependencies.ts index 97f2ecc435..e71b4352c0 100644 --- a/test/install/optionalDependencies.ts +++ b/test/install/optionalDependencies.ts @@ -30,6 +30,29 @@ test('skip failing optional dependencies', async (t: tape.Test) => { t.ok(m(-1), 'package with failed optional dependency has the dependencies installed correctly') }) +test('skip non-existing optional dependency', async (t: tape.Test) => { + const project = prepare(t, { + dependencies: { + 'is-positive': '*', + }, + optionalDependencies: { + 'i-do-not-exist': '1000', + }, + }) + + const reporter = sinon.spy() + await install(await testDefaults({reporter})) + + t.ok(reporter.calledWithMatch({ + name: 'pnpm', + level: 'warn', + message: 'Skipping optional dependency i-do-not-exist@1000. Error: 404 Not Found: i-do-not-exist', + }), 'warning reported') + + const m = project.requireModule('is-positive') + t.ok(m, 'installation succeded') +}) + test('skip optional dependency that does not support the current OS', async (t: tape.Test) => { const project = prepare(t, { optionalDependencies: {