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
This commit is contained in:
Zoltan Kochan
2019-12-25 01:10:26 +02:00
committed by GitHub
parent 793c8420f1
commit fa74b516ec
25 changed files with 330 additions and 80 deletions

View File

@@ -1,8 +1,19 @@
import { IncludedDependencies, Registries } from '@pnpm/types'
import { ImporterManifest, IncludedDependencies, Registries } from '@pnpm/types'
export type UniversalOptions = Pick<Config, 'color' | 'dir' | 'rawConfig' | 'rawLocalConfig'>
export type WsPkg = {
dir: string,
manifest: ImporterManifest,
writeImporterManifest: (manifest: ImporterManifest) => Promise<void>,
}
export type WsPkgsGraph = Record<string, { dependencies: string[], package: WsPkg }>
export interface Config {
allWsPkgs?: WsPkg[],
selectedWsPkgsGraph?: WsPkgsGraph,
allowNew: boolean,
bail: boolean,
color: 'always' | 'auto' | 'never',

View File

@@ -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

View File

@@ -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<T> (
pkgs: Array<Package & T>,
filter: string[],
opts: {
prefix: string,
workspaceDir: string,
},
): Promise<PackageGraph<T>> {
const packageSelectors = filter.
map((f) => parsePackageSelector(f, opts.prefix))
return filterPkgsBySelectorObjects(pkgs, packageSelectors, opts)
}
export async function filterPkgsBySelectorObjects<T> (
pkgs: Array<Package & T>,
packageSelectors: PackageSelector[],
opts: {
workspaceDir: string,
},
): Promise<PackageGraph<T>> {
const { graph } = createPkgGraph<T>(pkgs)
if (packageSelectors && packageSelectors.length) {
return filterGraph(graph, packageSelectors, {
workspaceDir: opts.workspaceDir,
})
} else {
return graph
}
}
export default async function filterGraph<T> (
pkgGraph: PackageGraph<T>,
packageSelectors: PackageSelector[],
@@ -84,7 +115,7 @@ function matchPackages<T> (
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<T> (

View File

@@ -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<void>
}
@@ -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] = {}
}

View File

@@ -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<T> (pkgs: Array<Package & T>): {
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

View File

@@ -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",

View File

@@ -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')

View File

@@ -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) {

View File

@@ -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 <T> (
packageChunks: string[][],
graph: {[id: string]: PackageNode<T>},
graph: WsPkgsGraph,
args: string[],
cmd: string,
opts: {

View File

@@ -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<Config, 'filter' | 'depth' | 'engineStrict' | 'tag' | 'workspaceDir'> & { long?: boolean, table?: boolean },
opts: RecursiveOptions & Pick<Config, 'filter' | 'depth' | 'engineStrict' | 'tag' | 'workspaceDir'> & { long?: boolean, table?: boolean } & Required<Pick<Config, 'allWsPkgs' | 'selectedWsPkgsGraph'>>,
) {
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<Config,
}
export async function recursive (
allPkgs: Array<{dir: string, manifest: DependencyManifest, writeImporterManifest: (manifest: ImporterManifest) => Promise<void>}>,
allWsPkgs: WsPkg[],
input: string[],
opts: RecursiveOptions & {
allowNew?: boolean,
packageSelectors?: PackageSelector[],
ignoredPackages?: Set<string>,
update?: boolean,
useBetaCli?: boolean,
selectedWsPkgsGraph: WsPkgsGraph,
} & Required<Pick<Config, 'workspaceDir'>>,
cmdFullName: string,
cmd: string,
): Promise<boolean | string> {
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<void> }>
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<T> (pkgGraph: {[nodeId: string]: PackageNode<T>}): string[][] {
function sortPackages (pkgGraph: WsPkgsGraph): string[][] {
const keys = Object.keys(pkgGraph)
const setOfKeys = new Set(keys)
const graph = new Map(

View File

@@ -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 <T> (
packageChunks: string[][],
graph: {[id: string]: PackageNode<T>},
graph: WsPkgsGraph,
args: string[],
cmd: string,
opts: {

View File

@@ -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,
})

View File

@@ -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')

View File

@@ -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) {

View File

@@ -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(),

View File

@@ -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`

View File

@@ -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',
})

View File

@@ -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[]

View File

@@ -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']

View File

@@ -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[]

View File

@@ -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<Lockfile>('./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(),
})

View File

@@ -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 }
}

View File

@@ -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"

View File

@@ -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(() => {

6
pnpm-lock.yaml generated
View File

@@ -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