From de79f1313606fbd1bfbcfbf13046fb488aa2e9ed Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Wed, 23 May 2018 23:27:44 +0300 Subject: [PATCH] feat: pnpm recursive outdated close #1182 --- packages/pnpm/src/cmd/help.ts | 9 ++- packages/pnpm/src/cmd/recursive/index.ts | 20 +++++-- packages/pnpm/src/cmd/recursive/outdated.ts | 66 +++++++++++++++++++++ packages/pnpm/test/recursive.ts | 47 ++++++++++++++- 4 files changed, 134 insertions(+), 8 deletions(-) create mode 100644 packages/pnpm/src/cmd/recursive/outdated.ts diff --git a/packages/pnpm/src/cmd/help.ts b/packages/pnpm/src/cmd/help.ts index 5edc603b39..3cb7b963fe 100644 --- a/packages/pnpm/src/cmd/help.ts +++ b/packages/pnpm/src/cmd/help.ts @@ -261,10 +261,16 @@ function getHelpText (command: string) { * * * - pnpm recursive list + pnpm recursive list [[<@scope>/] ...] List packages in each project of the multi-package repo. Accepts the same arguments and flags as the regular \`pnpm list\` command. + + * * * + + pnpm recursive outdated [[<@scope>/] ...] + + Check for outdated packages in every project of the multi-package repo. ` default: @@ -291,6 +297,7 @@ function getHelpText (command: string) { - recursive install - recursive update - recursive list + - recursive outdated Experimental commands: - server start diff --git a/packages/pnpm/src/cmd/recursive/index.ts b/packages/pnpm/src/cmd/recursive/index.ts index 797780f97a..bbb6acb06c 100644 --- a/packages/pnpm/src/cmd/recursive/index.ts +++ b/packages/pnpm/src/cmd/recursive/index.ts @@ -20,6 +20,7 @@ import getCommandFullName from '../../getCommandFullName' import requireHooks from '../../requireHooks' import {PnpmOptions} from '../../types' import list from './list' +import outdated from './outdated' const supportedRecursiveCommands = new Set([ 'install', @@ -27,6 +28,7 @@ const supportedRecursiveCommands = new Set([ 'link', 'unlink', 'list', + 'outdated', ]) export default async ( @@ -61,13 +63,19 @@ export default async ( ], patterns: packagesManifest && packagesManifest.packages || undefined, }) - if (cmdFullName === 'list') { - await list(pkgs, input, cmd, opts as any) // tslint:disable-line:no-any - return - } - if (cmdFullName === 'update') { - opts = {...opts, update: true} + + switch (cmdFullName) { + case 'list': + await list(pkgs, input, cmd, opts as any) // tslint:disable-line:no-any + return + case 'outdated': + await outdated(pkgs, input, cmd, opts as any) // tslint:disable-line:no-any + return + case 'update': + opts = {...opts, update: true} + break } + const pkgGraphResult = createPkgGraph(pkgs) const store = await createStoreController(opts) diff --git a/packages/pnpm/src/cmd/recursive/outdated.ts b/packages/pnpm/src/cmd/recursive/outdated.ts new file mode 100644 index 0000000000..ee936dff05 --- /dev/null +++ b/packages/pnpm/src/cmd/recursive/outdated.ts @@ -0,0 +1,66 @@ +import outdated, { + forPackages as outdatedForPackages, +} from '@pnpm/outdated' +import {PackageJson} from '@pnpm/types' +import chalk from 'chalk' +import path = require('path') +import stripColor = require('strip-color') +import table = require('text-table') + +export default async ( + pkgs: Array<{path: string, manifest: PackageJson}>, + args: string[], + cmd: string, + opts: { + prefix: string, + global: boolean, + independentLeaves: boolean, + offline: boolean, + store: string, + proxy?: string, + httpsProxy?: string, + localAddress?: string, + cert?: string, + key?: string, + ca?: string, + strictSsl: boolean, + fetchRetries: number, + fetchRetryFactor: number, + fetchRetryMintimeout: number, + fetchRetryMaxtimeout: number, + userAgent: string, + tag: string, + networkConcurrency: number, + rawNpmConfig: object, + alwaysAuth: boolean, + }, +) => { + const outdatedPkgs = [] as Array<{ + packageName: string, + current?: string, + wanted: string, + latest?: string, + prefix: string, + }> + const getOutdated = args.length ? outdatedForPackages.bind(null, args) : outdated + for (const pkg of pkgs) { + const op = await getOutdated(pkg.path, opts) + const prefix = path.relative(opts.prefix, pkg.path) + op.forEach((outdatedPkg: any) => outdatedPkgs.push({...outdatedPkg, prefix})) // tslint:disable-line:no-any + } + + const columnNames = ['', 'Package', 'Current', 'Wanted', 'Latest'].map((txt) => chalk.underline(txt)) + console.log( + table([columnNames].concat( + outdatedPkgs.map((outdatedPkg) => [ + outdatedPkg.prefix, + chalk.yellow(outdatedPkg.packageName), + outdatedPkg.current || 'missing', + chalk.green(outdatedPkg.wanted), + chalk.magenta(outdatedPkg.latest || ''), + ]), + ), { + stringLength: (s: string) => stripColor(s).length, + }), + ) +} diff --git a/packages/pnpm/test/recursive.ts b/packages/pnpm/test/recursive.ts index 5fa8a498b5..a5f37d796e 100644 --- a/packages/pnpm/test/recursive.ts +++ b/packages/pnpm/test/recursive.ts @@ -1,4 +1,4 @@ -import {stripIndent} from 'common-tags' +import {stripIndent, stripIndents} from 'common-tags' import delay = require('delay') import fs = require('mz/fs') import isCI = require('is-ci') @@ -17,6 +17,7 @@ import { spawn, } from './utils' import mkdirp = require('mkdirp-promise') +import normalizeNewline = require('normalize-newline') import loadYamlFile = require('load-yaml-file') const test = promisifyTape(tape) @@ -407,3 +408,47 @@ test('recursive list', async (t: tape.Test) => { └── is-negative@1.0.0 ` + '\n\n') }) + +test('pnpm recursive outdated', async (t: tape.Test) => { + 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 execPnpm('recursive', 'install') + + { + const result = execPnpmSync('recursive', 'outdated') + + t.equal(result.status, 0) + + t.equal(normalizeNewline(result.stdout.toString()), ' ' + stripIndents` + Package Current Wanted Latest + project-1 is-positive 1.0.0 1.0.0 3.1.0 + project-2 is-negative 1.0.0 1.0.0 2.1.0 + ` + '\n') + } + + { + const result = execPnpmSync('recursive', 'outdated', 'is-positive') + + t.equal(result.status, 0) + + t.equal(normalizeNewline(result.stdout.toString()), ' ' + stripIndents` + Package Current Wanted Latest + project-1 is-positive 1.0.0 1.0.0 3.1.0 + ` + '\n') + } +})