mirror of
https://github.com/pnpm/pnpm.git
synced 2026-07-26 07:27:20 -04:00
feat: add an option to list and why to exclude peer dependencies from the output (#8506)
This commit is contained in:
8
.changeset/odd-parrots-refuse.md
Normal file
8
.changeset/odd-parrots-refuse.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
"@pnpm/plugin-commands-listing": minor
|
||||
"@pnpm/reviewing.dependencies-hierarchy": minor
|
||||
"@pnpm/list": minor
|
||||
"pnpm": minor
|
||||
---
|
||||
|
||||
Support for a new CLI flag, `--exclude-peers`, added to the `list` and `why` commands. When `--exclude-peers` is used, peer dependencies are not printed in the results, but dependencies of peer dependencies are still scanned [#8506](https://github.com/pnpm/pnpm/pull/8506).
|
||||
@@ -34,6 +34,7 @@ export async function buildDependenciesHierarchy (
|
||||
projectPaths: string[] | undefined,
|
||||
maybeOpts: {
|
||||
depth: number
|
||||
excludePeerDependencies?: boolean
|
||||
include?: { [dependenciesField in DependenciesField]: boolean }
|
||||
registries?: Registries
|
||||
onlyProjects?: boolean
|
||||
@@ -70,6 +71,7 @@ export async function buildDependenciesHierarchy (
|
||||
|
||||
const opts = {
|
||||
depth: maybeOpts.depth || 0,
|
||||
excludePeerDependencies: maybeOpts.excludePeerDependencies,
|
||||
include: maybeOpts.include ?? {
|
||||
dependencies: true,
|
||||
devDependencies: true,
|
||||
@@ -103,6 +105,7 @@ async function dependenciesHierarchyForPackage (
|
||||
wantedLockfile: Lockfile | null,
|
||||
opts: {
|
||||
depth: number
|
||||
excludePeerDependencies?: boolean
|
||||
include: { [dependenciesField in DependenciesField]: boolean }
|
||||
registries: Registries
|
||||
onlyProjects?: boolean
|
||||
@@ -127,6 +130,7 @@ async function dependenciesHierarchyForPackage (
|
||||
const depTypes = detectDepTypes(currentLockfile)
|
||||
const getChildrenTree = getTree.bind(null, {
|
||||
currentPackages: currentLockfile.packages ?? {},
|
||||
excludePeerDependencies: opts.excludePeerDependencies,
|
||||
importers: currentLockfile.importers,
|
||||
includeOptionalDependencies: opts.include.optionalDependencies,
|
||||
depTypes,
|
||||
@@ -134,7 +138,6 @@ async function dependenciesHierarchyForPackage (
|
||||
onlyProjects: opts.onlyProjects,
|
||||
rewriteLinkVersionDir: projectPath,
|
||||
maxDepth: opts.depth,
|
||||
modulesDir,
|
||||
registries: opts.registries,
|
||||
search: opts.search,
|
||||
skipped: opts.skipped,
|
||||
|
||||
@@ -13,6 +13,7 @@ interface GetTreeOpts {
|
||||
maxDepth: number
|
||||
rewriteLinkVersionDir: string
|
||||
includeOptionalDependencies: boolean
|
||||
excludePeerDependencies?: boolean
|
||||
lockfileDir: string
|
||||
onlyProjects?: boolean
|
||||
search?: SearchFunction
|
||||
@@ -209,7 +210,9 @@ function getTreeHelper (
|
||||
if (matchedSearched) {
|
||||
newEntry.searched = true
|
||||
}
|
||||
resultDependencies.push(newEntry)
|
||||
if (!newEntry.isPeer || !opts.excludePeerDependencies || newEntry.dependencies?.length) {
|
||||
resultDependencies.push(newEntry)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -550,4 +550,68 @@ describe('getTree', () => {
|
||||
])
|
||||
})
|
||||
})
|
||||
test('exclude peers', () => {
|
||||
const version = '1.0.0'
|
||||
const currentPackages = {
|
||||
'foo@1.0.0': {
|
||||
dependencies: {
|
||||
peer1: '1.0.0',
|
||||
peer2: '1.0.0',
|
||||
qar: '1.0.0',
|
||||
},
|
||||
peerDependencies: {
|
||||
peer1: '^1.0.0',
|
||||
peer2: '^1.0.0',
|
||||
},
|
||||
resolution: { integrity: '000' },
|
||||
},
|
||||
'bar@1.0.0': {
|
||||
resolution: { integrity: '000' },
|
||||
},
|
||||
'qar@1.0.0': {
|
||||
resolution: { integrity: '000' },
|
||||
},
|
||||
'peer1@1.0.0': {
|
||||
dependencies: {
|
||||
bar: '1.0.0',
|
||||
},
|
||||
resolution: { integrity: '000' },
|
||||
},
|
||||
'peer2@1.0.0': {
|
||||
dependencies: {},
|
||||
resolution: { integrity: '000' },
|
||||
},
|
||||
}
|
||||
const rootNodeId: TreeNodeId = { type: 'package', depPath: refToRelativeOrThrow(version, 'foo') }
|
||||
|
||||
const getTreeArgs = {
|
||||
depTypes: {},
|
||||
excludePeerDependencies: true,
|
||||
maxDepth: 3,
|
||||
rewriteLinkVersionDir: '',
|
||||
virtualStoreDir: '.pnpm',
|
||||
importers: {},
|
||||
includeOptionalDependencies: false,
|
||||
lockfileDir: '',
|
||||
skipped: new Set<string>(),
|
||||
registries: {
|
||||
default: 'mock-registry-for-testing.example',
|
||||
},
|
||||
currentPackages,
|
||||
wantedPackages: currentPackages,
|
||||
}
|
||||
const result = normalizePackageNodeForTesting(getTree({ ...getTreeArgs, maxDepth: 9999, virtualStoreDirMaxLength: 120 }, rootNodeId))
|
||||
|
||||
expect(result).toEqual([
|
||||
expect.objectContaining({
|
||||
alias: 'peer1',
|
||||
dependencies: [
|
||||
expect.objectContaining({
|
||||
alias: 'bar',
|
||||
}),
|
||||
],
|
||||
}),
|
||||
expect.objectContaining({ alias: 'qar', dependencies: undefined }),
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
@@ -59,6 +59,7 @@ export async function searchForPackages (
|
||||
projectPaths: string[],
|
||||
opts: {
|
||||
depth: number
|
||||
excludePeerDependencies?: boolean
|
||||
lockfileDir: string
|
||||
include?: { [dependenciesField in DependenciesField]: boolean }
|
||||
onlyProjects?: boolean
|
||||
@@ -72,6 +73,7 @@ export async function searchForPackages (
|
||||
return Promise.all(
|
||||
Object.entries(await buildDependenciesHierarchy(projectPaths, {
|
||||
depth: opts.depth,
|
||||
excludePeerDependencies: opts.excludePeerDependencies,
|
||||
include: opts.include,
|
||||
lockfileDir: opts.lockfileDir,
|
||||
onlyProjects: opts.onlyProjects,
|
||||
@@ -130,6 +132,7 @@ export async function list (
|
||||
maybeOpts: {
|
||||
alwaysPrintRootPackage?: boolean
|
||||
depth?: number
|
||||
excludePeerDependencies?: boolean
|
||||
lockfileDir: string
|
||||
long?: boolean
|
||||
include?: { [dependenciesField in DependenciesField]: boolean }
|
||||
@@ -152,6 +155,7 @@ export async function list (
|
||||
}, {} as Record<string, DependenciesHierarchy>)
|
||||
: await buildDependenciesHierarchy(projectPaths, {
|
||||
depth: opts.depth,
|
||||
excludePeerDependencies: maybeOpts?.excludePeerDependencies,
|
||||
include: maybeOpts?.include,
|
||||
lockfileDir: maybeOpts?.lockfileDir,
|
||||
onlyProjects: maybeOpts?.onlyProjects,
|
||||
|
||||
@@ -7,6 +7,11 @@ import pick from 'ramda/src/pick'
|
||||
import renderHelp from 'render-help'
|
||||
import { listRecursive } from './recursive'
|
||||
|
||||
export const EXCLUDE_PEERS_HELP = {
|
||||
description: 'Exclude peer dependencies',
|
||||
name: '--exclude-peers',
|
||||
}
|
||||
|
||||
export function rcOptionsTypes (): Record<string, unknown> {
|
||||
return pick([
|
||||
'depth',
|
||||
@@ -24,6 +29,7 @@ export function rcOptionsTypes (): Record<string, unknown> {
|
||||
|
||||
export const cliOptionsTypes = (): Record<string, unknown> => ({
|
||||
...rcOptionsTypes(),
|
||||
'exclude-peers': Boolean,
|
||||
'only-projects': Boolean,
|
||||
recursive: Boolean,
|
||||
})
|
||||
@@ -100,6 +106,7 @@ For options that may be used with `-r`, see "pnpm help recursive"',
|
||||
description: "Don't display packages from `optionalDependencies`",
|
||||
name: '--no-optional',
|
||||
},
|
||||
EXCLUDE_PEERS_HELP,
|
||||
OPTIONS.globalDir,
|
||||
...UNIVERSAL_OPTIONS,
|
||||
],
|
||||
@@ -125,6 +132,7 @@ export type ListCommandOptions = Pick<Config,
|
||||
> & Partial<Pick<Config, 'cliOptions'>> & {
|
||||
alwaysPrintRootPackage?: boolean
|
||||
depth?: number
|
||||
excludePeers?: boolean
|
||||
lockfileDir?: string
|
||||
long?: boolean
|
||||
parseable?: boolean
|
||||
@@ -160,6 +168,7 @@ export async function render (
|
||||
opts: {
|
||||
alwaysPrintRootPackage?: boolean
|
||||
depth?: number
|
||||
excludePeers?: boolean
|
||||
include: IncludedDependencies
|
||||
lockfileDir: string
|
||||
long?: boolean
|
||||
@@ -173,6 +182,7 @@ export async function render (
|
||||
const listOpts = {
|
||||
alwaysPrintRootPackage: opts.alwaysPrintRootPackage,
|
||||
depth: opts.depth ?? 0,
|
||||
excludePeerDependencies: opts.excludePeers,
|
||||
include: opts.include,
|
||||
lockfileDir: opts.lockfileDir,
|
||||
long: opts.long,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { types as allTypes } from '@pnpm/config'
|
||||
import { PnpmError } from '@pnpm/error'
|
||||
import pick from 'ramda/src/pick'
|
||||
import renderHelp from 'render-help'
|
||||
import { handler as list, type ListCommandOptions } from './list'
|
||||
import { handler as list, type ListCommandOptions, EXCLUDE_PEERS_HELP } from './list'
|
||||
|
||||
export function rcOptionsTypes (): Record<string, unknown> {
|
||||
return pick([
|
||||
@@ -23,6 +23,7 @@ export function rcOptionsTypes (): Record<string, unknown> {
|
||||
|
||||
export const cliOptionsTypes = (): Record<string, unknown> => ({
|
||||
...rcOptionsTypes(),
|
||||
'exclude-peers': Boolean,
|
||||
recursive: Boolean,
|
||||
})
|
||||
|
||||
@@ -84,6 +85,7 @@ For options that may be used with `-r`, see "pnpm help recursive"',
|
||||
name: '--depth <number>',
|
||||
description: 'Max display depth of the dependency graph',
|
||||
},
|
||||
EXCLUDE_PEERS_HELP,
|
||||
OPTIONS.globalDir,
|
||||
...UNIVERSAL_OPTIONS,
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user