From fa74b516ec22d170af237cd163949495ba1003be Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Wed, 25 Dec 2019 01:10:26 +0200 Subject: [PATCH] refactor: plugin-commands-recursive This changes will allow to move the recursive commands to the plugins they belong to. For instance, "pnpm install -r" should be handled by the same plugin as "pnpm install" PR #2236 BREAKING CHANGE: @pnpm/plugin-commands-recursive --- packages/config/src/Config.ts | 13 ++++- packages/config/src/index.ts | 4 +- .../filter-workspace-packages/src/index.ts | 35 +++++++++++- packages/find-workspace-packages/src/index.ts | 6 +- packages/pkgs-graph/src/index.ts | 7 ++- .../plugin-commands-installation/package.json | 1 + .../src/install.ts | 20 ++++--- .../plugin-commands-installation/src/link.ts | 3 +- .../plugin-commands-recursive/src/exec.ts | 4 +- .../src/recursive.ts | 57 ++++++------------- packages/plugin-commands-recursive/src/run.ts | 4 +- .../plugin-commands-recursive/test/exec.ts | 22 ++++++- .../plugin-commands-recursive/test/link.ts | 12 +++- .../plugin-commands-recursive/test/list.ts | 18 +++++- .../plugin-commands-recursive/test/misc.ts | 29 +++++++++- .../test/outdated.ts | 22 ++++++- .../plugin-commands-recursive/test/publish.ts | 4 +- .../plugin-commands-recursive/test/rebuild.ts | 12 +++- .../plugin-commands-recursive/test/run.ts | 52 +++++++++++++++-- .../plugin-commands-recursive/test/test.ts | 23 +++++++- .../plugin-commands-recursive/test/update.ts | 19 ++++++- .../plugin-commands-recursive/test/utils.ts | 17 ++++++ packages/pnpm/package.json | 2 + packages/pnpm/src/main.ts | 18 ++++++ pnpm-lock.yaml | 6 ++ 25 files changed, 330 insertions(+), 80 deletions(-) diff --git a/packages/config/src/Config.ts b/packages/config/src/Config.ts index 45252c9716..84cc30ca55 100644 --- a/packages/config/src/Config.ts +++ b/packages/config/src/Config.ts @@ -1,8 +1,19 @@ -import { IncludedDependencies, Registries } from '@pnpm/types' +import { ImporterManifest, IncludedDependencies, Registries } from '@pnpm/types' export type UniversalOptions = Pick +export type WsPkg = { + dir: string, + manifest: ImporterManifest, + writeImporterManifest: (manifest: ImporterManifest) => Promise, +} + +export type WsPkgsGraph = Record + export interface Config { + allWsPkgs?: WsPkg[], + selectedWsPkgsGraph?: WsPkgsGraph, + allowNew: boolean, bail: boolean, color: 'always' | 'auto' | 'never', diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index 03d9b8b7a7..0cfe582834 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -6,11 +6,11 @@ import camelcase from 'camelcase' import path = require('path') import R = require('ramda') import whichcb = require('which') -import { Config, ConfigWithDeprecatedSettings, UniversalOptions } from './Config' +import { Config, ConfigWithDeprecatedSettings, UniversalOptions, WsPkg, WsPkgsGraph } from './Config' import findBestGlobalPrefixOnWindows from './findBestGlobalPrefixOnWindows' import getScopeRegistries, { normalizeRegistry } from './getScopeRegistries' -export { Config, UniversalOptions } +export { Config, UniversalOptions, WsPkg, WsPkgsGraph } const npmDefaults = loadNpmConf.defaults diff --git a/packages/filter-workspace-packages/src/index.ts b/packages/filter-workspace-packages/src/index.ts index 18399d2ac5..5e8c66327b 100644 --- a/packages/filter-workspace-packages/src/index.ts +++ b/packages/filter-workspace-packages/src/index.ts @@ -1,6 +1,6 @@ import matcher from '@pnpm/matcher' import isSubdir = require('is-subdir') -import { PackageNode } from 'pkgs-graph' +import createPkgGraph, { Package, PackageNode } from 'pkgs-graph' import R = require('ramda') import getChangedPkgs from './getChangedPackages' import parsePackageSelector, { PackageSelector } from './parsePackageSelector' @@ -15,6 +15,37 @@ interface Graph { [nodeId: string]: string[], } +export async function filterPackages ( + pkgs: Array, + filter: string[], + opts: { + prefix: string, + workspaceDir: string, + }, +): Promise> { + const packageSelectors = filter. + map((f) => parsePackageSelector(f, opts.prefix)) + + return filterPkgsBySelectorObjects(pkgs, packageSelectors, opts) +} + +export async function filterPkgsBySelectorObjects ( + pkgs: Array, + packageSelectors: PackageSelector[], + opts: { + workspaceDir: string, + }, +): Promise> { + const { graph } = createPkgGraph(pkgs) + if (packageSelectors && packageSelectors.length) { + return filterGraph(graph, packageSelectors, { + workspaceDir: opts.workspaceDir, + }) + } else { + return graph + } +} + export default async function filterGraph ( pkgGraph: PackageGraph, packageSelectors: PackageSelector[], @@ -84,7 +115,7 @@ function matchPackages ( pattern: string, ) { const match = matcher(pattern) - return Object.keys(graph).filter((id) => graph[id].package.manifest.name && match(graph[id].package.manifest.name)) + return Object.keys(graph).filter((id) => graph[id].package.manifest.name && match(graph[id].package.manifest.name!)) } function matchPackagesByPath ( diff --git a/packages/find-workspace-packages/src/index.ts b/packages/find-workspace-packages/src/index.ts index 6ced8b7063..432627cce0 100644 --- a/packages/find-workspace-packages/src/index.ts +++ b/packages/find-workspace-packages/src/index.ts @@ -1,13 +1,13 @@ import { packageIsInstallable } from '@pnpm/cli-utils' import { WORKSPACE_MANIFEST_FILENAME } from '@pnpm/constants' -import { DependencyManifest, ImporterManifest } from '@pnpm/types' +import { ImporterManifest } from '@pnpm/types' import findPackages from 'find-packages' import path = require('path') import readYamlFile from 'read-yaml-file' interface WorkspaceDependencyPackage { dir: string - manifest: DependencyManifest + manifest: ImporterManifest writeImporterManifest (manifest: ImporterManifest, force?: boolean | undefined): Promise } @@ -29,7 +29,6 @@ export default async ( packageIsInstallable(pkg.dir, pkg.manifest, opts) } - // FIXME: `name` and `version` might be missing from entries in `pkgs`. return pkgs as WorkspaceDependencyPackage[] } @@ -48,6 +47,7 @@ export function arrayOfWorkspacePackagesToMap ( pkgs: WorkspaceDependencyPackage[], ) { return pkgs.reduce((acc, pkg) => { + if (!pkg.manifest.name || !pkg.manifest.version) return acc if (!acc[pkg.manifest.name]) { acc[pkg.manifest.name] = {} } diff --git a/packages/pkgs-graph/src/index.ts b/packages/pkgs-graph/src/index.ts index 0c31f1d085..030397941d 100644 --- a/packages/pkgs-graph/src/index.ts +++ b/packages/pkgs-graph/src/index.ts @@ -4,8 +4,8 @@ import R = require('ramda') import semver = require('semver') export type Manifest = { - name: string, - version: string, + name?: string, + version?: string, dependencies?: { [name: string]: string, }, @@ -75,7 +75,8 @@ export default function (pkgs: Array): { const pkgs = R.values(pkgMap).filter(pkg => pkg.manifest.name === depName) if (!pkgs.length) return '' - const versions = pkgs.map(pkg => pkg.manifest.version) + const versions = pkgs.filter(({ manifest }) => manifest.version) + .map(pkg => pkg.manifest.version) as string[] if (versions.includes(rawSpec)) { const matchedPkg = pkgs.find(pkg => pkg.manifest.name === depName && pkg.manifest.version === rawSpec) return matchedPkg!.dir diff --git a/packages/plugin-commands-installation/package.json b/packages/plugin-commands-installation/package.json index c4f43279da..4e614fcfdb 100644 --- a/packages/plugin-commands-installation/package.json +++ b/packages/plugin-commands-installation/package.json @@ -41,6 +41,7 @@ "@pnpm/config": "workspace:6.0.0", "@pnpm/constants": "workspace:3.0.0", "@pnpm/error": "workspace:1.0.0", + "@pnpm/filter-workspace-packages": "workspace:1.0.1", "@pnpm/find-workspace-dir": "workspace:1.0.0", "@pnpm/find-workspace-packages": "workspace:2.0.8", "@pnpm/package-store": "workspace:7.0.2", diff --git a/packages/plugin-commands-installation/src/install.ts b/packages/plugin-commands-installation/src/install.ts index bbe3d27f34..0eda639fd5 100644 --- a/packages/plugin-commands-installation/src/install.ts +++ b/packages/plugin-commands-installation/src/install.ts @@ -11,6 +11,7 @@ import { FILTERING, OPTIONS, UNIVERSAL_OPTIONS } from '@pnpm/common-cli-options- import { Config, types as allTypes } from '@pnpm/config' import { WANTED_LOCKFILE } from '@pnpm/constants' import PnpmError from '@pnpm/error' +import { filterPkgsBySelectorObjects } from '@pnpm/filter-workspace-packages' import findWorkspacePackages, { arrayOfWorkspacePackagesToMap } from '@pnpm/find-workspace-packages' import { rebuild } from '@pnpm/plugin-commands-rebuild/lib/implementation' import { recursive } from '@pnpm/plugin-commands-recursive/lib/recursive' @@ -397,17 +398,20 @@ export async function handler ( if (opts.linkWorkspacePackages && opts.workspaceDir) { // TODO: reuse somehow the previous read of packages // this is not optimal - const allWorkspacePkgs = await findWorkspacePackages(opts.workspaceDir, opts) - await recursive(allWorkspacePkgs, [], { + const allWsPkgs = await findWorkspacePackages(opts.workspaceDir, opts) + const selectedWsPkgsGraph = await filterPkgsBySelectorObjects(allWsPkgs, [ + { + includeDependencies: true, + parentDir: dir, + }, + ], { + workspaceDir: opts.workspaceDir, + }) + await recursive(allWsPkgs, [], { ...opts, ...OVERWRITE_UPDATE_OPTIONS, ignoredPackages: new Set([dir]), - packageSelectors: [ - { - includeDependencies: true, - parentDir: dir, - }, - ], + selectedWsPkgsGraph, workspaceDir: opts.workspaceDir, // Otherwise TypeScript doesn't understant that is is not undefined }, 'install', 'install') diff --git a/packages/plugin-commands-installation/src/link.ts b/packages/plugin-commands-installation/src/link.ts index d383e011bb..2aefaec3ce 100644 --- a/packages/plugin-commands-installation/src/link.ts +++ b/packages/plugin-commands-installation/src/link.ts @@ -122,7 +122,8 @@ export async function handler ( if (opts.workspaceDir) { workspacePackagesArr = await findWorkspacePackages(opts.workspaceDir, opts) - const pkgsFoundInWorkspace = workspacePackagesArr.filter((pkg) => pkgNames.includes(pkg.manifest.name)) + const pkgsFoundInWorkspace = workspacePackagesArr + .filter(({ manifest }) => manifest.name && pkgNames.includes(manifest.name)) pkgsFoundInWorkspace.forEach((pkgFromWorkspace) => pkgPaths.push(pkgFromWorkspace.dir)) if (pkgsFoundInWorkspace.length && !linkOpts.targetDependenciesField) { diff --git a/packages/plugin-commands-recursive/src/exec.ts b/packages/plugin-commands-recursive/src/exec.ts index a466e93554..bbed357029 100644 --- a/packages/plugin-commands-recursive/src/exec.ts +++ b/packages/plugin-commands-recursive/src/exec.ts @@ -1,12 +1,12 @@ +import { WsPkgsGraph } from '@pnpm/config' import logger from '@pnpm/logger' import execa = require('execa') import pLimit from 'p-limit' -import { PackageNode } from 'pkgs-graph' import RecursiveSummary from './recursiveSummary' export default async ( packageChunks: string[][], - graph: {[id: string]: PackageNode}, + graph: WsPkgsGraph, args: string[], cmd: string, opts: { diff --git a/packages/plugin-commands-recursive/src/recursive.ts b/packages/plugin-commands-recursive/src/recursive.ts index c42ea4c97d..3165ddc169 100755 --- a/packages/plugin-commands-recursive/src/recursive.ts +++ b/packages/plugin-commands-recursive/src/recursive.ts @@ -6,7 +6,7 @@ import { updateToLatestSpecsFromManifest, } from '@pnpm/cli-utils' import { FILTERING } from '@pnpm/common-cli-options-help' -import { Config, types as allTypes } from '@pnpm/config' +import { Config, types as allTypes, WsPkg, WsPkgsGraph } from '@pnpm/config' import { WANTED_LOCKFILE } from '@pnpm/constants' import { scopeLogger } from '@pnpm/core-loggers' import PnpmError from '@pnpm/error' @@ -221,7 +221,7 @@ export function help () { export async function handler ( input: string[], - opts: RecursiveOptions & Pick & { long?: boolean, table?: boolean }, + opts: RecursiveOptions & Pick & { long?: boolean, table?: boolean } & Required>, ) { if (opts.workspaceConcurrency < 1) { throw new PnpmError('INVALID_WORKSPACE_CONCURRENCY', 'Workspace concurrency should be at least 1') @@ -240,21 +240,8 @@ export async function handler ( } const workspaceDir = opts.workspaceDir ?? process.cwd() - const allWorkspacePkgs = await findWorkspacePackages(workspaceDir, opts) - if (!allWorkspacePkgs.length) { - logger.info({ message: `No packages found in "${workspaceDir}"`, prefix: workspaceDir }) - return undefined - } - - if (opts.filter) { - // TODO: maybe @pnpm/config should return this in a parsed form already? - // We don't use opts.prefix in this case because opts.prefix searches for a package.json in parent directories and - // selects the directory where it finds one - opts['packageSelectors'] = opts.filter.map((f) => parsePackageSelector(f, process.cwd())) // tslint:disable-line - } - - const atLeastOnePackageMatched = await recursive(allWorkspacePkgs, input, { ...opts, workspaceDir }, cmdFullName, cmd) + const atLeastOnePackageMatched = await recursive(opts.allWsPkgs, input, { ...opts, workspaceDir }, cmdFullName, cmd) if (typeof atLeastOnePackageMatched === 'string') { return atLeastOnePackageMatched @@ -303,33 +290,25 @@ type RecursiveOptions = CreateStoreControllerOptions & Pick Promise}>, + allWsPkgs: WsPkg[], input: string[], opts: RecursiveOptions & { allowNew?: boolean, - packageSelectors?: PackageSelector[], ignoredPackages?: Set, update?: boolean, useBetaCli?: boolean, + selectedWsPkgsGraph: WsPkgsGraph, } & Required>, cmdFullName: string, cmd: string, ): Promise { - if (allPkgs.length === 0) { + if (allWsPkgs.length === 0) { // It might make sense to throw an exception in this case return false } - const pkgGraphResult = createPkgGraph(allPkgs) - let pkgs: Array<{dir: string, manifest: ImporterManifest, writeImporterManifest: (manifest: ImporterManifest) => Promise }> - if (opts.packageSelectors && opts.packageSelectors.length) { - pkgGraphResult.graph = await filterGraph(pkgGraphResult.graph, opts.packageSelectors, { workspaceDir: opts.workspaceDir }) - pkgs = allPkgs.filter(({ dir }) => pkgGraphResult.graph[dir]) - } else { - pkgs = allPkgs - } - - const allPackagesAreSelected = pkgs.length === allPkgs.length + const pkgs = Object.values(opts.selectedWsPkgsGraph).map((wsPkg) => wsPkg.package) + const allPackagesAreSelected = pkgs.length === allWsPkgs.length if (pkgs.length === 0) { return false @@ -341,7 +320,7 @@ export async function recursive ( scopeLogger.debug({ selected: pkgs.length, - total: allPkgs.length, + total: allWsPkgs.length, workspacePrefix: opts.workspaceDir, }) @@ -365,21 +344,21 @@ export async function recursive ( } const chunks = opts.sort - ? sortPackages(pkgGraphResult.graph) - : [Object.keys(pkgGraphResult.graph).sort()] + ? sortPackages(opts.selectedWsPkgsGraph) + : [Object.keys(opts.selectedWsPkgsGraph).sort()] switch (cmdFullName) { case 'test': - throwOnFail(await run(chunks, pkgGraphResult.graph, ['test', ...input], cmd, opts as any)) // tslint:disable-line:no-any + throwOnFail(await run(chunks, opts.selectedWsPkgsGraph, ['test', ...input], cmd, opts as any)) // tslint:disable-line:no-any return true case 'run': - throwOnFail(await run(chunks, pkgGraphResult.graph, input, cmd, { ...opts, allPackagesAreSelected } as any)) // tslint:disable-line:no-any + throwOnFail(await run(chunks, opts.selectedWsPkgsGraph, input, cmd, { ...opts, allPackagesAreSelected } as any)) // tslint:disable-line:no-any return true case 'update': opts = { ...opts, update: true, allowNew: false } as any // tslint:disable-line:no-any break case 'exec': - throwOnFail(await exec(chunks, pkgGraphResult.graph, input, cmd, opts as any)) // tslint:disable-line:no-any + throwOnFail(await exec(chunks, opts.selectedWsPkgsGraph, input, cmd, opts as any)) // tslint:disable-line:no-any return true } @@ -396,13 +375,13 @@ export async function recursive ( } const workspacePackages = cmdFullName !== 'unlink' - ? arrayOfWorkspacePackagesToMap(allPkgs) + ? arrayOfWorkspacePackagesToMap(allWsPkgs) : {} const installOpts = Object.assign(opts, { ownLifecycleHooksStdio: 'pipe', peer: opts.savePeer, pruneLockfileImporters: (!opts.ignoredPackages || opts.ignoredPackages.size === 0) - && pkgs.length === allPkgs.length, + && pkgs.length === allWsPkgs.length, storeController, storeDir: store.dir, workspacePackages, @@ -551,7 +530,7 @@ export async function recursive ( let pkgPaths = chunks.length === 0 ? chunks[0] - : Object.keys(pkgGraphResult.graph).sort() + : Object.keys(opts.selectedWsPkgsGraph).sort() const limitInstallation = pLimit(opts.workspaceConcurrency) await Promise.all(pkgPaths.map((rootDir: string) => @@ -747,7 +726,7 @@ async function unlinkPkgs (dependencyNames: string[], manifest: ImporterManifest ) } -function sortPackages (pkgGraph: {[nodeId: string]: PackageNode}): string[][] { +function sortPackages (pkgGraph: WsPkgsGraph): string[][] { const keys = Object.keys(pkgGraph) const setOfKeys = new Set(keys) const graph = new Map( diff --git a/packages/plugin-commands-recursive/src/run.ts b/packages/plugin-commands-recursive/src/run.ts index 6df450fc2c..26efab7a3e 100644 --- a/packages/plugin-commands-recursive/src/run.ts +++ b/packages/plugin-commands-recursive/src/run.ts @@ -1,15 +1,15 @@ +import { WsPkgsGraph } from '@pnpm/config' import PnpmError from '@pnpm/error' import runLifecycleHooks from '@pnpm/lifecycle' import logger from '@pnpm/logger' import { PackageManifest } from '@pnpm/types' import { realNodeModulesDir } from '@pnpm/utils' import pLimit from 'p-limit' -import { PackageNode } from 'pkgs-graph' import RecursiveSummary from './recursiveSummary' export default async ( packageChunks: string[][], - graph: {[id: string]: PackageNode}, + graph: WsPkgsGraph, args: string[], cmd: string, opts: { diff --git a/packages/plugin-commands-recursive/test/exec.ts b/packages/plugin-commands-recursive/test/exec.ts index 7bbc36fdd3..bfd43238e6 100644 --- a/packages/plugin-commands-recursive/test/exec.ts +++ b/packages/plugin-commands-recursive/test/exec.ts @@ -5,7 +5,7 @@ import rimraf = require('@zkochan/rimraf') import fs = require('mz/fs') import path = require('path') import test = require('tape') -import { DEFAULT_OPTS } from './utils' +import { DEFAULT_OPTS, readWsPkgs } from './utils' test('pnpm recursive exec', async (t) => { const projects = preparePackages(t, [ @@ -48,13 +48,18 @@ test('pnpm recursive exec', async (t) => { }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) await recursive.handler(['exec', 'npm', 'run', 'build'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) const outputs1 = await import(path.resolve('output1.json')) as string[] @@ -74,9 +79,12 @@ test('pnpm recursive exec sets PNPM_PACKAGE_NAME env var', async (t) => { }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['exec', 'node', '-e', `require('fs').writeFileSync('pkgname', process.env.PNPM_PACKAGE_NAME, 'utf8')`], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) t.equal(await fs.readFile('foo/pkgname', 'utf8'), 'foo', '$PNPM_PACKAGE_NAME is correct') @@ -122,9 +130,12 @@ test('testing the bail config with "pnpm recursive exec"', async (t) => { }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) let failed = false @@ -132,7 +143,9 @@ test('testing the bail config with "pnpm recursive exec"', async (t) => { try { await recursive.handler(['exec', 'npm', 'run', 'build', '--no-bail'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) } catch (_err) { err1 = _err @@ -151,7 +164,9 @@ test('testing the bail config with "pnpm recursive exec"', async (t) => { try { await recursive.handler(['exec', 'npm', 'run', 'build'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) } catch (_err) { err2 = _err @@ -190,14 +205,19 @@ test('pnpm recursive exec --no-sort', async (t) => { }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), linkWorkspacePackages: true, + selectedWsPkgsGraph, }) await recursive.handler(['exec', 'npm', 'run', 'build'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, sort: false, workspaceConcurrency: 1, }) diff --git a/packages/plugin-commands-recursive/test/link.ts b/packages/plugin-commands-recursive/test/link.ts index 47c4d3465d..01d70f2384 100644 --- a/packages/plugin-commands-recursive/test/link.ts +++ b/packages/plugin-commands-recursive/test/link.ts @@ -4,7 +4,7 @@ import { preparePackages } from '@pnpm/prepare' import path = require('path') import exists = require('path-exists') import test = require('tape') -import { DEFAULT_OPTS } from './utils' +import { DEFAULT_OPTS, readWsPkgs } from './utils' test('recursive linking/unlinking', async (t) => { const projects = preparePackages(t, [ @@ -26,9 +26,12 @@ test('recursive linking/unlinking', async (t) => { }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) t.ok(projects['is-positive'].requireModule('is-negative')) @@ -41,7 +44,9 @@ test('recursive linking/unlinking', async (t) => { await recursive.handler(['unlink'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) process.chdir('project-1') @@ -80,9 +85,12 @@ test('recursive unlink specific package', async (t) => { }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) t.ok(projects['is-positive'].requireModule('is-negative')) @@ -95,7 +103,9 @@ test('recursive unlink specific package', async (t) => { await recursive.handler(['unlink', 'is-positive'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) process.chdir('project-1') diff --git a/packages/plugin-commands-recursive/test/list.ts b/packages/plugin-commands-recursive/test/list.ts index dfff9645de..4f59a16495 100644 --- a/packages/plugin-commands-recursive/test/list.ts +++ b/packages/plugin-commands-recursive/test/list.ts @@ -8,7 +8,7 @@ import path = require('path') import stripAnsi = require('strip-ansi') import test = require('tape') import writeYamlFile = require('write-yaml-file') -import { DEFAULT_OPTS } from './utils' +import { DEFAULT_OPTS, readWsPkgs } from './utils' test('recursive list', async (t) => { const projects = preparePackages(t, [ @@ -34,14 +34,19 @@ test('recursive list', async (t) => { }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) const output = await recursive.handler(['list'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) t.equal(stripAnsi(output as unknown as string), stripIndent` @@ -91,15 +96,20 @@ test('recursive list with shared-workspace-lockfile', async (t) => { await writeYamlFile('pnpm-workspace.yaml', { packages: ['**', '!store/**'] }) await fs.writeFile('.npmrc', 'shared-workspace-lockfile = true', 'utf8') + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) const output = await recursive.handler(['list'], { ...DEFAULT_OPTS, + allWsPkgs, depth: 2, dir: process.cwd(), + selectedWsPkgsGraph, }) t.equal(stripAnsi(output as unknown as string), stripIndent` @@ -153,13 +163,16 @@ test('recursive list --filter', async (t) => { await recursive.handler(['install'], { ...DEFAULT_OPTS, + ...await readWsPkgs(process.cwd(), []), dir: process.cwd(), }) const output = await recursive.handler(['list'], { ...DEFAULT_OPTS, dir: process.cwd(), - filter: ['project-1...'], + ...await readWsPkgs(process.cwd(), [ + { includeDependencies: true, namePattern: 'project-1' }, + ]), }) t.equal(stripAnsi(output as unknown as string), stripIndent` @@ -188,6 +201,7 @@ test('`pnpm recursive why` should fail if no package name was provided', async ( try { const output = await recursive.handler(['why'], { ...DEFAULT_OPTS, + ...await readWsPkgs(process.cwd(), []), dir: process.cwd(), }) } catch (_err) { diff --git a/packages/plugin-commands-recursive/test/misc.ts b/packages/plugin-commands-recursive/test/misc.ts index 7af2225946..92883308e1 100644 --- a/packages/plugin-commands-recursive/test/misc.ts +++ b/packages/plugin-commands-recursive/test/misc.ts @@ -7,7 +7,7 @@ import path = require('path') import test = require('tape') import writeJsonFile = require('write-json-file') import writeYamlFile = require('write-yaml-file') -import { DEFAULT_OPTS } from './utils' +import { DEFAULT_OPTS, readWsPkgs } from './utils' test('recursive install/uninstall', async (t) => { const projects = preparePackages(t, [ @@ -29,9 +29,12 @@ test('recursive install/uninstall', async (t) => { }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) t.ok(projects['project-1'].requireModule('is-positive')) @@ -40,7 +43,9 @@ test('recursive install/uninstall', async (t) => { await recursive.handler(['add', 'noop'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) t.ok(projects['project-1'].requireModule('noop')) @@ -48,7 +53,9 @@ test('recursive install/uninstall', async (t) => { await recursive.handler(['remove', 'is-negative'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) await projects['project-2'].hasNot('is-negative') @@ -80,6 +87,7 @@ test('recursive install with package that has link', async (t) => { await recursive.handler(['install'], { ...DEFAULT_OPTS, + ...await readWsPkgs(process.cwd(), []), dir: process.cwd(), }) @@ -113,6 +121,7 @@ test('running `pnpm recursive` on a subset of packages', async t => { await recursive.handler(['install'], { ...DEFAULT_OPTS, + ...await readWsPkgs(process.cwd(), []), dir: process.cwd(), }) @@ -163,6 +172,7 @@ test('running `pnpm recursive` only for packages in subdirectories of cwd', asyn await recursive.handler(['install'], { ...DEFAULT_OPTS, + ...await readWsPkgs(process.cwd(), []), dir: process.cwd(), }) @@ -196,6 +206,7 @@ test('recursive installation fails when installation in one of the packages fail try { await recursive.handler(['install'], { ...DEFAULT_OPTS, + ...await readWsPkgs(process.cwd(), []), dir: process.cwd(), }) } catch (_err) { @@ -221,9 +232,12 @@ test('second run of `recursive install` after package.json has been edited manua }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) await writeJsonFile('is-negative/package.json', { @@ -237,7 +251,9 @@ test('second run of `recursive install` after package.json has been edited manua await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) t.ok(projects['is-negative'].requireModule('is-positive/package.json')) @@ -282,8 +298,10 @@ test('recursive --filter ignore excluded packages', async (t) => { await recursive.handler(['install'], { ...DEFAULT_OPTS, + ...await readWsPkgs(process.cwd(), [ + { includeDependencies: true, namePattern: 'project-1' }, + ]), dir: process.cwd(), - filter: ['project-1...'], }) projects['project-1'].hasNot('is-positive') @@ -323,8 +341,11 @@ test('recursive filter multiple times', async (t) => { await recursive.handler(['install'], { ...DEFAULT_OPTS, + ...await readWsPkgs(process.cwd(), [ + { namePattern: 'project-1' }, + { namePattern: 'project-2' }, + ]), dir: process.cwd(), - filter: ['project-1', 'project-2'], }) projects['project-1'].has('is-positive') @@ -357,6 +378,7 @@ test('recursive install --no-bail', async (t) => { try { await recursive.handler(['install'], { ...DEFAULT_OPTS, + ...await readWsPkgs(process.cwd(), []), bail: false, dir: process.cwd(), }) @@ -388,6 +410,7 @@ test('installing with "workspace=true" should work even if link-workspace-packag await recursive.handler(['update', 'project-2'], { ...DEFAULT_OPTS, + ...await readWsPkgs(process.cwd(), []), dir: process.cwd(), linkWorkspacePackages: false, lockfileDir: process.cwd(), diff --git a/packages/plugin-commands-recursive/test/outdated.ts b/packages/plugin-commands-recursive/test/outdated.ts index 16a15ed70d..10722d8e7f 100644 --- a/packages/plugin-commands-recursive/test/outdated.ts +++ b/packages/plugin-commands-recursive/test/outdated.ts @@ -4,7 +4,7 @@ import { stripIndent } from 'common-tags' import stripAnsi = require('strip-ansi') import test = require('tape') import writeYamlFile = require('write-yaml-file') -import { DEFAULT_OPTS } from './utils' +import { DEFAULT_OPTS, readWsPkgs } from './utils' test('pnpm recursive outdated', async (t) => { preparePackages(t, [ @@ -37,15 +37,20 @@ test('pnpm recursive outdated', async (t) => { }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) { const output = await recursive.handler(['outdated'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) t.equal(stripAnsi(output as unknown as string), stripIndent` @@ -64,8 +69,10 @@ test('pnpm recursive outdated', async (t) => { { const output = await recursive.handler(['outdated'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), long: true, + selectedWsPkgsGraph, }) t.equal(stripAnsi(output as unknown as string), stripIndent` @@ -84,7 +91,9 @@ test('pnpm recursive outdated', async (t) => { { const output = await recursive.handler(['outdated'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, table: false, }) @@ -106,8 +115,10 @@ test('pnpm recursive outdated', async (t) => { { const output = await recursive.handler(['outdated'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), long: true, + selectedWsPkgsGraph, table: false, }) @@ -132,7 +143,9 @@ test('pnpm recursive outdated', async (t) => { { const output = await recursive.handler(['outdated', 'is-positive'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) t.equal(stripAnsi(output as unknown as string), stripIndent` @@ -179,15 +192,20 @@ test('pnpm recursive outdated in workspace with shared lockfile', async (t) => { await writeYamlFile('pnpm-workspace.yaml', { packages: ['**', '!store/**'] }) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) { const output = await recursive.handler(['outdated'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) t.equal(stripAnsi(output as unknown as string), stripIndent` @@ -206,7 +224,9 @@ test('pnpm recursive outdated in workspace with shared lockfile', async (t) => { { const output = await recursive.handler(['outdated', 'is-positive'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) t.equal(stripAnsi(output as unknown as string), stripIndent` diff --git a/packages/plugin-commands-recursive/test/publish.ts b/packages/plugin-commands-recursive/test/publish.ts index 842d48213c..0b3c588905 100644 --- a/packages/plugin-commands-recursive/test/publish.ts +++ b/packages/plugin-commands-recursive/test/publish.ts @@ -4,7 +4,7 @@ import { REGISTRY_MOCK_PORT } from '@pnpm/registry-mock' import execa = require('execa') import fs = require('mz/fs') import test = require('tape') -import { DEFAULT_OPTS } from './utils' +import { DEFAULT_OPTS, readWsPkgs } from './utils' const CREDENTIALS = [ `--registry=http://localhost:${REGISTRY_MOCK_PORT}/`, @@ -67,6 +67,7 @@ test('recursive publish', async (t) => { await recursive.handler(['publish'], { ...DEFAULT_OPTS, + ...await readWsPkgs(process.cwd(), []), dir: process.cwd(), }) @@ -83,6 +84,7 @@ test('recursive publish', async (t) => { await recursive.handler(['publish'], { ...DEFAULT_OPTS, + ...await readWsPkgs(process.cwd(), []), dir: process.cwd(), tag: 'next', }) diff --git a/packages/plugin-commands-recursive/test/rebuild.ts b/packages/plugin-commands-recursive/test/rebuild.ts index b2f748b2a3..3535b0cf20 100644 --- a/packages/plugin-commands-recursive/test/rebuild.ts +++ b/packages/plugin-commands-recursive/test/rebuild.ts @@ -4,7 +4,7 @@ import { PackageManifest } from '@pnpm/types' import path = require('path') import test = require('tape') import writeYamlFile = require('write-yaml-file') -import { DEFAULT_OPTS } from './utils' +import { DEFAULT_OPTS, readWsPkgs } from './utils' test('pnpm recursive rebuild', async (t) => { const projects = preparePackages(t, [ @@ -26,10 +26,13 @@ test('pnpm recursive rebuild', async (t) => { }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), ignoreScripts: true, + selectedWsPkgsGraph, }) await projects['project-1'].hasNot('pre-and-postinstall-scripts-example/generated-by-preinstall.js') @@ -39,7 +42,9 @@ test('pnpm recursive rebuild', async (t) => { await recursive.handler(['rebuild'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) await projects['project-1'].has('pre-and-postinstall-scripts-example/generated-by-preinstall.js') @@ -97,15 +102,20 @@ test.skip('rebuild multiple packages in correct order', async (t) => { preparePackages(t, pkgs) await writeYamlFile('pnpm-workspace.yaml', { packages: ['project-1'] }) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), ignoreScripts: true, + selectedWsPkgsGraph, }) await recursive.handler(['rebuild'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) const outputs1 = await import(path.resolve('output1.json')) as string[] diff --git a/packages/plugin-commands-recursive/test/run.ts b/packages/plugin-commands-recursive/test/run.ts index 3f7c2d813d..47e6daf11c 100644 --- a/packages/plugin-commands-recursive/test/run.ts +++ b/packages/plugin-commands-recursive/test/run.ts @@ -1,4 +1,5 @@ import PnpmError from '@pnpm/error' +import { filterPkgsBySelectorObjects } from '@pnpm/filter-workspace-packages' import { recursive } from '@pnpm/plugin-commands-recursive' import { preparePackages } from '@pnpm/prepare' import rimraf = require('@zkochan/rimraf') @@ -6,7 +7,7 @@ import fs = require('mz/fs') import path = require('path') import test = require('tape') import writeYamlFile = require('write-yaml-file') -import { DEFAULT_OPTS } from './utils' +import { DEFAULT_OPTS, readWsPkgs } from './utils' test('pnpm recursive run', async (t) => { const projects = preparePackages(t, [ @@ -55,13 +56,18 @@ test('pnpm recursive run', async (t) => { }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) await recursive.handler(['run', 'build'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) const outputs1 = await import(path.resolve('output1.json')) as string[] @@ -98,13 +104,18 @@ test('pnpm recursive run concurrently', async (t) => { }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) await recursive.handler(['run', 'build'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) const outputs1 = await import(path.resolve('output1.json')) as number[] @@ -142,16 +153,21 @@ test('`pnpm recursive run` fails when run without filters and no package has the }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) let err!: PnpmError try { await recursive.handler(['run', 'this-command-does-not-exist'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) } catch (_err) { err = _err @@ -192,8 +208,8 @@ test('`pnpm recursive run` fails when run with a filter that includes all packag try { await recursive.handler(['run', 'this-command-does-not-exist'], { ...DEFAULT_OPTS, + ...await readWsPkgs(process.cwd(), [{ namePattern: '*' }]), dir: process.cwd(), - filter: ['*'], }) } catch (_err) { err = _err @@ -230,14 +246,22 @@ test('`pnpm recursive run` succeeds when run against a subset of packages and no }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) await recursive.handler(['run', 'this-command-does-not-exist'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), - filter: ['project-1'], + selectedWsPkgsGraph: await filterPkgsBySelectorObjects( + allWsPkgs, + [{ namePattern: 'project-1' }], + { workspaceDir: process.cwd() }, + ), }) t.end() }) @@ -281,16 +305,21 @@ test('testing the bail config with "pnpm recursive run"', async (t) => { }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) let err1!: PnpmError try { await recursive.handler(['run', 'build', '--no-bail'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) } catch (_err) { err1 = _err @@ -306,7 +335,9 @@ test('testing the bail config with "pnpm recursive run"', async (t) => { try { await recursive.handler(['run', 'build'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) } catch (_err) { err2 = _err @@ -345,14 +376,22 @@ test('pnpm recursive run with filtering', async (t) => { }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) await recursive.handler(['run', 'build'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), - filter: ['project-1'], + selectedWsPkgsGraph: await filterPkgsBySelectorObjects( + allWsPkgs, + [{ namePattern: 'project-1' }], + { workspaceDir: process.cwd() }, + ), }) const outputs = await import(path.resolve('output.json')) as string[] @@ -376,15 +415,20 @@ test('`pnpm recursive run` should always trust the scripts', async (t) => { }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) process.env['npm_config_unsafe_perm'] = 'false' await recursive.handler(['run', 'build'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + ...await readWsPkgs(process.cwd(), []), }) delete process.env['npm_config_unsafe_perm'] diff --git a/packages/plugin-commands-recursive/test/test.ts b/packages/plugin-commands-recursive/test/test.ts index 685b251968..82104241b7 100644 --- a/packages/plugin-commands-recursive/test/test.ts +++ b/packages/plugin-commands-recursive/test/test.ts @@ -1,8 +1,9 @@ +import { filterPkgsBySelectorObjects } from '@pnpm/filter-workspace-packages' import { recursive } from '@pnpm/plugin-commands-recursive' import { preparePackages } from '@pnpm/prepare' import path = require('path') import test = require('tape') -import { DEFAULT_OPTS } from './utils' +import { DEFAULT_OPTS, readWsPkgs } from './utils' test('pnpm recursive test', async (t) => { const projects = preparePackages(t, [ @@ -49,13 +50,18 @@ test('pnpm recursive test', async (t) => { }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) await recursive.handler(['test'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) const outputs1 = await import(path.resolve('output1.json')) as string[] @@ -96,14 +102,19 @@ test('`pnpm recursive test` does not fail if none of the packaegs has a test com }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) await recursive.handler(['test'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) t.pass('command did not fail') @@ -137,14 +148,22 @@ test('pnpm recursive test with filtering', async (t) => { }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) await recursive.handler(['test'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), - filter: ['project-1'], + selectedWsPkgsGraph: await filterPkgsBySelectorObjects( + allWsPkgs, + [{ namePattern: 'project-1' }], + { workspaceDir: process.cwd() }, + ), }) const outputs = await import(path.resolve('output.json')) as string[] diff --git a/packages/plugin-commands-recursive/test/update.ts b/packages/plugin-commands-recursive/test/update.ts index c81ac96a96..83201dd5fe 100644 --- a/packages/plugin-commands-recursive/test/update.ts +++ b/packages/plugin-commands-recursive/test/update.ts @@ -4,7 +4,7 @@ import { preparePackages } from '@pnpm/prepare' import { addDistTag } from '@pnpm/registry-mock' import readYamlFile from 'read-yaml-file' import test = require('tape') -import { DEFAULT_OPTS } from './utils' +import { DEFAULT_OPTS, readWsPkgs } from './utils' test('recursive update', async (t) => { const projects = preparePackages(t, [ @@ -26,14 +26,19 @@ test('recursive update', async (t) => { }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) await recursive.handler(['update', 'is-positive@2.0.0'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) t.equal(projects['project-1'].requireModule('is-positive/package.json').version, '2.0.0') @@ -69,10 +74,13 @@ test('recursive update --latest foo should only update workspace packages that h const lockfileDir = process.cwd() + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), lockfileDir, + selectedWsPkgsGraph, }) await addDistTag({ package: 'foo', version: '100.1.0', distTag: 'latest' }) @@ -80,9 +88,11 @@ test('recursive update --latest foo should only update workspace packages that h await recursive.handler(['update', '@zkochan/async-regex-replace', 'foo', 'qar@100.1.0'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), latest: true, lockfileDir, + selectedWsPkgsGraph, }) const lockfile = await readYamlFile('./pnpm-lock.yaml') @@ -116,9 +126,12 @@ test('recursive update --latest foo should only update packages that have foo', }, ]) + const { allWsPkgs, selectedWsPkgsGraph } = await readWsPkgs(process.cwd(), []) await recursive.handler(['install'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), + selectedWsPkgsGraph, }) await addDistTag({ package: 'foo', version: '100.1.0', distTag: 'latest' }) @@ -126,8 +139,10 @@ test('recursive update --latest foo should only update packages that have foo', await recursive.handler(['update', 'foo', 'qar@100.1.0'], { ...DEFAULT_OPTS, + allWsPkgs, dir: process.cwd(), latest: true, + selectedWsPkgsGraph, }) { @@ -158,6 +173,7 @@ test('recursive update in workspace should not add new dependencies', async (t) await recursive.handler(['update', 'is-positive'], { ...DEFAULT_OPTS, + ...await readWsPkgs(process.cwd(), []), dir: process.cwd(), }) @@ -180,6 +196,7 @@ test('recursive update should not add new dependencies', async (t) => { await recursive.handler(['update', 'is-positive'], { ...DEFAULT_OPTS, + ...await readWsPkgs(process.cwd(), []), dir: process.cwd(), }) diff --git a/packages/plugin-commands-recursive/test/utils.ts b/packages/plugin-commands-recursive/test/utils.ts index 4916e73764..7a3b8cdf86 100644 --- a/packages/plugin-commands-recursive/test/utils.ts +++ b/packages/plugin-commands-recursive/test/utils.ts @@ -1,3 +1,5 @@ +import { filterPkgsBySelectorObjects, PackageSelector } from '@pnpm/filter-workspace-packages' +import findWorkspacePackages from '@pnpm/find-workspace-packages' import { REGISTRY_MOCK_PORT } from '@pnpm/registry-mock' const REGISTRY = `http://localhost:${REGISTRY_MOCK_PORT}` @@ -44,3 +46,18 @@ export const DEFAULT_OPTS = { useStoreServer: false, workspaceConcurrency: 4, } + +export async function readWsPkgs ( + workspaceDir: string, + pkgSelectors: PackageSelector[], +) { + const allWsPkgs = await findWorkspacePackages(workspaceDir, {}) + const selectedWsPkgsGraph = await filterPkgsBySelectorObjects( + allWsPkgs, + pkgSelectors, + { + workspaceDir, + }, + ) + return { allWsPkgs, selectedWsPkgsGraph } +} diff --git a/packages/pnpm/package.json b/packages/pnpm/package.json index a8dd55c121..ab0a9c5079 100644 --- a/packages/pnpm/package.json +++ b/packages/pnpm/package.json @@ -26,6 +26,7 @@ "@pnpm/core-loggers": "workspace:4.0.0", "@pnpm/default-reporter": "workspace:5.0.5", "@pnpm/file-reporter": "0.1.0", + "@pnpm/filter-workspace-packages": "workspace:1.0.1", "@pnpm/find-workspace-dir": "workspace:1.0.0", "@pnpm/logger": "3.1.0", "@pnpm/parse-cli-args": "workspace:0.1.3", @@ -48,6 +49,7 @@ "graceful-fs": "4.2.1", "is-ci": "2.0.0", "loud-rejection": "2.2.0", + "pkgs-graph": "workspace:5.0.1", "ramda": "0.26.1", "render-help": "0.0.0", "update-notifier": "4.0.0" diff --git a/packages/pnpm/src/main.ts b/packages/pnpm/src/main.ts index 0073b3e850..0688c28ce9 100644 --- a/packages/pnpm/src/main.ts +++ b/packages/pnpm/src/main.ts @@ -19,6 +19,8 @@ import { types as allTypes, } from '@pnpm/config' import { scopeLogger } from '@pnpm/core-loggers' +import { filterPackages } from '@pnpm/filter-workspace-packages' +import findWorkspacePackages from '@pnpm/find-workspace-packages' import logger from '@pnpm/logger' import parseCliArgs from '@pnpm/parse-cli-args' import isCI = require('is-ci') @@ -170,6 +172,22 @@ export default async function run (inputArgv: string[]) { await pnpmCmds.server(['stop'], config as any) // tslint:disable-line:no-any } + if (cmd === 'recursive') { + const wsDir = workspaceDir ?? process.cwd() + const allWsPkgs = await findWorkspacePackages(wsDir, config) + + if (!allWsPkgs.length) { + console.log(`No packages found in "${wsDir}"`) + process.exit(0) + return + } + config.selectedWsPkgsGraph = await filterPackages(allWsPkgs, config.filter ?? [], { + prefix: process.cwd(), + workspaceDir: wsDir, + }) + config.allWsPkgs = allWsPkgs + } + // NOTE: we defer the next stage, otherwise reporter might not catch all the logs await new Promise((resolve, reject) => { setTimeout(() => { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fad89d4e03..105e2210e3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1338,6 +1338,7 @@ importers: '@pnpm/config': 'link:../config' '@pnpm/constants': 'link:../constants' '@pnpm/error': 'link:../error' + '@pnpm/filter-workspace-packages': 'link:../filter-workspace-packages' '@pnpm/find-workspace-dir': 'link:../find-workspace-dir' '@pnpm/find-workspace-packages': 'link:../find-workspace-packages' '@pnpm/package-store': 'link:../package-store' @@ -1365,6 +1366,7 @@ importers: '@pnpm/config': 'workspace:6.0.0' '@pnpm/constants': 'workspace:3.0.0' '@pnpm/error': 'workspace:1.0.0' + '@pnpm/filter-workspace-packages': 'workspace:1.0.1' '@pnpm/find-workspace-dir': 'workspace:1.0.0' '@pnpm/find-workspace-packages': 'workspace:2.0.8' '@pnpm/package-store': 'workspace:7.0.2' @@ -1910,6 +1912,7 @@ importers: '@pnpm/core-loggers': 'link:../core-loggers' '@pnpm/default-reporter': 'link:../default-reporter' '@pnpm/file-reporter': 0.1.0 + '@pnpm/filter-workspace-packages': 'link:../filter-workspace-packages' '@pnpm/find-workspace-dir': 'link:../find-workspace-dir' '@pnpm/logger': 3.1.0 '@pnpm/parse-cli-args': 'link:../parse-cli-args' @@ -1932,6 +1935,7 @@ importers: graceful-fs: 4.2.1 is-ci: 2.0.0 loud-rejection: 2.2.0 + pkgs-graph: 'link:../pkgs-graph' ramda: 0.26.1 render-help: 0.0.0 update-notifier: 4.0.0 @@ -1996,6 +2000,7 @@ importers: '@pnpm/core-loggers': 'workspace:4.0.0' '@pnpm/default-reporter': 'workspace:5.0.5' '@pnpm/file-reporter': 0.1.0 + '@pnpm/filter-workspace-packages': 'workspace:1.0.1' '@pnpm/find-workspace-dir': 'workspace:1.0.0' '@pnpm/find-workspace-packages': 'workspace:2.0.8' '@pnpm/lockfile-types': 'workspace:1.1.0' @@ -2057,6 +2062,7 @@ importers: npm-run-all: 4.1.5 p-any: 2.1.0 path-exists: 4.0.0 + pkgs-graph: 'workspace:5.0.1' pnpm: 'link:' ramda: 0.26.1 read-yaml-file: 1.1.0