From 848922d551b06cd94a7d32c2aadfd874fb2ea78d Mon Sep 17 00:00:00 2001 From: zkochan Date: Sun, 5 Feb 2017 17:20:09 +0200 Subject: [PATCH] feat(CLI): add `pnpm verify` command Rel #585 --- src/api/verify.ts | 2 +- src/bin/pnpm.ts | 3 +++ src/cmd/publish.ts | 3 +++ src/cmd/verify.ts | 18 ++++++++++++++++++ src/errorTypes.ts | 5 ++++- test/verify.ts | 28 ++++++++++++++++++++++++++++ 6 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 src/cmd/verify.ts diff --git a/src/api/verify.ts b/src/api/verify.ts index 6fd04a1feb..7b4768de64 100644 --- a/src/api/verify.ts +++ b/src/api/verify.ts @@ -9,7 +9,7 @@ import dirsum from '../fs/dirsum' export default async function (maybeOpts: PnpmOptions) { const opts = extendOptions(maybeOpts) const ctx = await getContext(opts) - if (!ctx.graph) return + if (!ctx.graph) return [] const pkgPaths = Object.keys(ctx.graph) .filter(pkgPath => !isProjectPath(pkgPath)) diff --git a/src/bin/pnpm.ts b/src/bin/pnpm.ts index 9dcecb145a..1a4859d8d9 100755 --- a/src/bin/pnpm.ts +++ b/src/bin/pnpm.ts @@ -18,6 +18,7 @@ import publishCmd from '../cmd/publish' import pruneCmd from '../cmd/prune' import installTestCmd from '../cmd/installTest' import runCmd from '../cmd/run' +import verifyCmd from '../cmd/verify' import bole = require('bole') import initReporter from '../reporter' @@ -32,6 +33,7 @@ const pnpmCmds = { prune: pruneCmd, 'install-test': installTestCmd, run: runCmd, + verify: verifyCmd, } const supportedCmds = new Set([ @@ -44,6 +46,7 @@ const supportedCmds = new Set([ 'prune', 'install-test', 'run', + 'verify', ]) async function run (argv: string[]) { diff --git a/src/cmd/publish.ts b/src/cmd/publish.ts index 8ac9acf695..5f185739cc 100644 --- a/src/cmd/publish.ts +++ b/src/cmd/publish.ts @@ -4,8 +4,11 @@ import delocalizeDeps = require('delocalize-dependencies') import readPkgUp = require('read-pkg-up') import {PnpmOptions} from '../types' import writePkg = require('write-pkg') +import verifyCmd from './verify' export default async function (input: string[], opts: PnpmOptions) { + await verifyCmd(input, opts) + if (!opts.linkLocal) { runNpmPublish() } diff --git a/src/cmd/verify.ts b/src/cmd/verify.ts new file mode 100644 index 0000000000..83b877664a --- /dev/null +++ b/src/cmd/verify.ts @@ -0,0 +1,18 @@ +import verify from '../api/verify' +import {PnpmOptions} from '../types' +import {PnpmError} from '../errorTypes' + +export default async function (input: string[], opts: PnpmOptions) { + const modifiedPkgs = await verify(opts) + if (!modifiedPkgs || !modifiedPkgs.length) return + + throw new VerificationError(modifiedPkgs) +} + +class VerificationError extends PnpmError { + constructor (modified: string[]) { + super('MODIFIED_DEPENDENCY', '') + this.modified = modified + } + modified: string[] +} diff --git a/src/errorTypes.ts b/src/errorTypes.ts index 9458698d9b..757a0ea01e 100644 --- a/src/errorTypes.ts +++ b/src/errorTypes.ts @@ -1,4 +1,7 @@ -export type PnpmErrorCode = 'UNEXPECTED_STORE' | 'STORE_BREAKING_CHANGE' | 'MODULES_BREAKING_CHANGE' +export type PnpmErrorCode = 'UNEXPECTED_STORE' + | 'STORE_BREAKING_CHANGE' + | 'MODULES_BREAKING_CHANGE' + | 'MODIFIED_DEPENDENCY' export class PnpmError extends Error { constructor (code: PnpmErrorCode, message: string) { diff --git a/test/verify.ts b/test/verify.ts index 46cf2203d0..713bb9dd5c 100644 --- a/test/verify.ts +++ b/test/verify.ts @@ -4,6 +4,7 @@ import rimraf = require('rimraf-then') import prepare from './support/prepare' import testDefaults from './support/testDefaults' import {verify, installPkgs} from '../src' +import execPnpm from './support/execPnpm' const test = promisifyTape(tape) @@ -32,3 +33,30 @@ test('verify returns path to the modified package', async function (t: tape.Test t.equal(mutatedPkgs && mutatedPkgs.length, 1, '1 package was modified') t.ok(mutatedPkgs && mutatedPkgs[0].indexOf('is-positive') !== -1, 'is-positive was modified') }) + +test('CLI fails when verify finds modified packages', async function (t: tape.Test) { + const project = prepare(t) + + const opts = testDefaults() + await installPkgs(['is-positive@3.1.0'], opts) + + const isPositive = await project.resolve('is-positive', '3.1.0', 'index.js') + await rimraf(isPositive) + + try { + await execPnpm('verify') + t.fail('CLI should have failed') + } catch (err) { + t.pass('CLI failed') + } +}) + +test('CLI does not fail when verify does not find modified packages', async function (t: tape.Test) { + const project = prepare(t) + + const opts = testDefaults() + await installPkgs(['is-positive@3.1.0'], opts) + + await execPnpm('verify') + t.pass('CLI did not fail') +})