fix(list): should not fail on skipped deps

This commit is contained in:
Zoltan Kochan
2019-08-05 23:42:46 +03:00
committed by Zoltan Kochan
parent 35b1958114
commit b7e044e632
6 changed files with 231 additions and 32 deletions

View File

@@ -1,8 +1,10 @@
import {
getLockfileImporterId,
LockfileImporter,
PackageSnapshot,
PackageSnapshots,
readCurrentLockfile,
readWantedLockfile,
} from '@pnpm/lockfile-file'
import {
nameVerFromPkgSnapshot,
@@ -11,7 +13,11 @@ import {
import { read as readModulesYaml } from '@pnpm/modules-yaml'
import readModulesDir from '@pnpm/read-modules-dir'
import { DEPENDENCIES_FIELDS, DependenciesField, Registries } from '@pnpm/types'
import { normalizeRegistries, safeReadPackageFromDir } from '@pnpm/utils'
import {
normalizeRegistries,
realNodeModulesDir,
safeReadPackageFromDir,
} from '@pnpm/utils'
import assert = require('assert')
import { refToAbsolute, refToRelative } from 'dependency-path'
import minimatch = require('minimatch')
@@ -31,6 +37,8 @@ export interface PackageNode {
dependencies?: PackageNode[],
dev?: boolean,
isPeer: boolean,
isSkipped: boolean,
isMissing: boolean,
name: string,
optional?: true,
path: string,
@@ -84,15 +92,16 @@ async function dependenciesHierarchy (
lockfileDirectory?: string,
},
): Promise<DependenciesHierarchy> {
const modules = await readModulesYaml(projectPath)
const lockfileDirectory = maybeOpts && maybeOpts.lockfileDirectory || projectPath
const virtualStoreDir = await realNodeModulesDir(lockfileDirectory)
const modules = await readModulesYaml(virtualStoreDir)
const registries = normalizeRegistries({
...maybeOpts && maybeOpts.registries,
...modules && modules.registries,
})
const lockfileDirectory = maybeOpts && maybeOpts.lockfileDirectory || projectPath
const lockfile = await readCurrentLockfile(lockfileDirectory, { ignoreIncompatible: false })
const currentLockfile = await readCurrentLockfile(lockfileDirectory, { ignoreIncompatible: false })
if (!lockfile) return {}
if (!currentLockfile) return {}
const opts = {
depth: 0,
@@ -105,33 +114,39 @@ async function dependenciesHierarchy (
}
const importerId = getLockfileImporterId(lockfileDirectory, projectPath)
if (!lockfile.importers[importerId]) return {}
if (!currentLockfile.importers[importerId]) return {}
const modulesDir = path.join(projectPath, 'node_modules')
const savedDeps = getAllDirectDependencies(lockfile.importers[importerId])
const savedDeps = getAllDirectDependencies(currentLockfile.importers[importerId])
const allDirectDeps = await readModulesDir(modulesDir) || []
const unsavedDeps = allDirectDeps.filter((directDep) => !savedDeps[directDep])
const wantedLockfile = await readWantedLockfile(lockfileDirectory, { ignoreIncompatible: false }) || { packages: {} }
const getChildrenTree = getTree.bind(null, {
currentDepth: 1,
currentPackages: currentLockfile.packages,
includeOptionalDependencies: include.optionalDependencies === true,
maxDepth: opts.depth,
modulesDir,
registries,
searched,
}, lockfile.packages)
skipped: new Set(modules && modules.skipped || []),
wantedPackages: wantedLockfile.packages || {},
})
const result: DependenciesHierarchy = {}
for (const dependenciesField of DEPENDENCIES_FIELDS.sort().filter(dependenciedField => include[dependenciedField])) {
const topDeps = lockfile.importers[importerId][dependenciesField] || {}
const topDeps = currentLockfile.importers[importerId][dependenciesField] || {}
result[dependenciesField] = []
Object.keys(topDeps).forEach((alias) => {
const { packageInfo, packageAbsolutePath } = getPkgInfo({
alias,
currentPackages: currentLockfile.packages || {},
modulesDir,
packages: lockfile.packages || {},
ref: topDeps[alias],
registries,
skipped: new Set(modules && modules.skipped || []),
wantedPackages: wantedLockfile.packages || {},
})
let newEntry: PackageNode | null = null
const matchedSearched = searched.length && matches(searched, packageInfo)
@@ -140,14 +155,16 @@ async function dependenciesHierarchy (
newEntry = packageInfo
} else {
const relativeId = refToRelative(topDeps[alias], alias)
const dependencies = getChildrenTree([relativeId], relativeId)
if (dependencies.length) {
newEntry = {
...packageInfo,
dependencies,
if (relativeId) {
const dependencies = getChildrenTree([relativeId], relativeId)
if (dependencies.length) {
newEntry = {
...packageInfo,
dependencies,
}
} else if (!searched.length || matches(searched, packageInfo)) {
newEntry = packageInfo
}
} else if (!searched.length || matches(searched, packageInfo)) {
newEntry = packageInfo
}
}
if (newEntry) {
@@ -173,7 +190,9 @@ async function dependenciesHierarchy (
}
const pkg = {
alias: unsavedDep,
isMissing: false,
isPeer: false,
isSkipped: false,
name: unsavedDep,
path: pkgPath,
version,
@@ -207,19 +226,21 @@ function getTree (
modulesDir: string,
includeOptionalDependencies: boolean,
searched: PackageSelector[],
skipped: Set<string>,
registries: Registries,
currentPackages: PackageSnapshots,
wantedPackages: PackageSnapshots,
},
packages: PackageSnapshots,
keypath: string[],
parentId: string,
): PackageNode[] {
if (opts.currentDepth > opts.maxDepth || !packages || !packages[parentId]) return []
if (opts.currentDepth > opts.maxDepth || !opts.currentPackages || !opts.currentPackages[parentId]) return []
const deps = opts.includeOptionalDependencies === false
? packages[parentId].dependencies
? opts.currentPackages[parentId].dependencies
: {
...packages[parentId].dependencies,
...packages[parentId].optionalDependencies,
...opts.currentPackages[parentId].dependencies,
...opts.currentPackages[parentId].optionalDependencies,
}
if (!deps) return []
@@ -227,18 +248,20 @@ function getTree (
const getChildrenTree = getTree.bind(null, {
...opts,
currentDepth: opts.currentDepth + 1,
}, packages)
})
const peers = new Set(Object.keys(packages[parentId].peerDependencies || {}))
const peers = new Set(Object.keys(opts.currentPackages[parentId].peerDependencies || {}))
const result: PackageNode[] = []
Object.keys(deps).forEach((alias) => {
const { packageInfo, packageAbsolutePath } = getPkgInfo({
alias,
currentPackages: opts.currentPackages,
modulesDir: opts.modulesDir,
packages,
peers,
ref: deps[alias],
registries: opts.registries,
skipped: opts.skipped,
wantedPackages: opts.wantedPackages,
})
let circular: boolean
const matchedSearched = opts.searched.length && matches(opts.searched, packageInfo)
@@ -278,9 +301,11 @@ function getPkgInfo (
alias: string,
modulesDir: string,
ref: string,
packages: PackageSnapshots,
currentPackages: PackageSnapshots,
peers?: Set<string>,
registries: Registries,
skipped: Set<string>,
wantedPackages: PackageSnapshots,
},
) {
let name!: string
@@ -288,14 +313,27 @@ function getPkgInfo (
let resolved: string | undefined = undefined
let dev: boolean | undefined = undefined
let optional: true | undefined = undefined
let isSkipped: boolean = false
let isMissing: boolean = false
const relDepPath = refToRelative(opts.ref, opts.alias)
if (relDepPath) {
const parsed = nameVerFromPkgSnapshot(relDepPath, opts.packages[relDepPath])
name = parsed.name
version = parsed.version
resolved = pkgSnapshotToResolution(relDepPath, opts.packages[relDepPath], opts.registries)['tarball']
dev = opts.packages[relDepPath].dev
optional = opts.packages[relDepPath].optional
let pkgSnapshot!: PackageSnapshot
if (opts.currentPackages[relDepPath]) {
pkgSnapshot = opts.currentPackages[relDepPath]
const parsed = nameVerFromPkgSnapshot(relDepPath, pkgSnapshot)
name = parsed.name
version = parsed.version
} else {
pkgSnapshot = opts.wantedPackages[relDepPath]
const parsed = nameVerFromPkgSnapshot(relDepPath, pkgSnapshot)
name = parsed.name
version = parsed.version
isMissing = true
isSkipped = opts.skipped.has(relDepPath)
}
resolved = pkgSnapshotToResolution(relDepPath, pkgSnapshot, opts.registries)['tarball']
dev = pkgSnapshot.dev
optional = pkgSnapshot.optional
} else {
name = opts.alias
version = opts.ref
@@ -303,7 +341,9 @@ function getPkgInfo (
const packageAbsolutePath = refToAbsolute(opts.ref, opts.alias, opts.registries)
const packageInfo = {
alias: opts.alias,
isMissing,
isPeer: Boolean(opts.peers && opts.peers.has(opts.alias)),
isSkipped,
name,
path: packageAbsolutePath && path.join(opts.modulesDir, `.${packageAbsolutePath}`) || path.join(opts.modulesDir, '..', opts.ref.substr(5)),
version,

View File

@@ -3,7 +3,9 @@
{
"path": "registry.npmjs.org/es6-iterator/2.0.1",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz",
"name": "es6-iterator",
"version": "2.0.1",
@@ -11,7 +13,9 @@
{
"path": "registry.npmjs.org/d/1.0.0",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
"name": "d",
"version": "1.0.0",
@@ -19,7 +23,9 @@
{
"path": "registry.npmjs.org/es5-ext/0.10.24",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.24.tgz",
"name": "es5-ext",
"version": "0.10.24",
@@ -27,7 +33,9 @@
{
"path": "registry.npmjs.org/es6-iterator/2.0.1",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz",
"name": "es6-iterator",
"version": "2.0.1",
@@ -36,7 +44,9 @@
{
"path": "registry.npmjs.org/es6-symbol/3.1.1",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
"name": "es6-symbol",
"version": "3.1.1",
@@ -44,7 +54,9 @@
{
"path": "registry.npmjs.org/d/1.0.0",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
"name": "d",
"version": "1.0.0",
@@ -53,7 +65,9 @@
{
"path": "registry.npmjs.org/es5-ext/0.10.24",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.24.tgz",
"name": "es5-ext",
"version": "0.10.24",
@@ -68,7 +82,9 @@
{
"path": "registry.npmjs.org/es5-ext/0.10.24",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.24.tgz",
"name": "es5-ext",
"version": "0.10.24",
@@ -76,7 +92,9 @@
{
"path": "registry.npmjs.org/es6-iterator/2.0.1",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz",
"name": "es6-iterator",
"version": "2.0.1",
@@ -85,7 +103,9 @@
{
"path": "registry.npmjs.org/es6-symbol/3.1.1",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
"name": "es6-symbol",
"version": "3.1.1",
@@ -93,7 +113,9 @@
{
"path": "registry.npmjs.org/d/1.0.0",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
"name": "d",
"version": "1.0.0",
@@ -101,7 +123,9 @@
{
"path": "registry.npmjs.org/es5-ext/0.10.24",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.24.tgz",
"name": "es5-ext",
"version": "0.10.24",
@@ -112,7 +136,9 @@
{
"path": "registry.npmjs.org/es5-ext/0.10.24",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.24.tgz",
"name": "es5-ext",
"version": "0.10.24",
@@ -125,7 +151,9 @@
{
"path": "registry.npmjs.org/es6-symbol/3.1.1",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
"name": "es6-symbol",
"version": "3.1.1",
@@ -133,7 +161,9 @@
{
"path": "registry.npmjs.org/d/1.0.0",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
"name": "d",
"version": "1.0.0",
@@ -141,7 +171,9 @@
{
"path": "registry.npmjs.org/es5-ext/0.10.24",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.24.tgz",
"name": "es5-ext",
"version": "0.10.24",
@@ -149,7 +181,9 @@
{
"path": "registry.npmjs.org/es6-iterator/2.0.1",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz",
"name": "es6-iterator",
"version": "2.0.1",
@@ -158,7 +192,9 @@
{
"path": "registry.npmjs.org/es6-symbol/3.1.1",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
"name": "es6-symbol",
"version": "3.1.1",
@@ -171,7 +207,9 @@
{
"path": "registry.npmjs.org/es5-ext/0.10.24",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.24.tgz",
"name": "es5-ext",
"version": "0.10.24",
@@ -179,7 +217,9 @@
{
"path": "registry.npmjs.org/es6-iterator/2.0.1",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz",
"name": "es6-iterator",
"version": "2.0.1",
@@ -188,7 +228,9 @@
{
"path": "registry.npmjs.org/es6-symbol/3.1.1",
"dev": false,
"isMissing": false,
"isPeer": false,
"isSkipped": false,
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
"name": "es6-symbol",
"version": "3.1.1",

View File

@@ -23,7 +23,9 @@ test('one package depth 0', async t => {
{
alias: 'minimatch',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'minimatch',
path: path.join(modulesDir, '.registry.npmjs.org/minimatch/3.0.4'),
resolved: 'https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz',
@@ -32,7 +34,9 @@ test('one package depth 0', async t => {
{
alias: 'rimraf',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'rimraf',
path: path.join(modulesDir, '.registry.npmjs.org/rimraf/2.5.1'),
resolved: 'https://registry.npmjs.org/rimraf/-/rimraf-2.5.1.tgz',
@@ -43,7 +47,9 @@ test('one package depth 0', async t => {
{
alias: 'is-positive',
dev: true,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'is-positive',
path: path.join(modulesDir, '.registry.npmjs.org/is-positive/1.0.0'),
resolved: 'https://registry.npmjs.org/is-positive/-/is-positive-1.0.0.tgz',
@@ -54,7 +60,9 @@ test('one package depth 0', async t => {
{
alias: 'is-negative',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'is-negative',
optional: true,
path: path.join(modulesDir, '.registry.npmjs.org/is-negative/1.0.0'),
@@ -76,7 +84,9 @@ test('one package depth 1', async t => {
{
alias: 'minimatch',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'minimatch',
path: path.join(modulesDir, '.registry.npmjs.org/minimatch/3.0.4'),
resolved: 'https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz',
@@ -86,7 +96,9 @@ test('one package depth 1', async t => {
{
alias: 'brace-expansion',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'brace-expansion',
path: path.join(modulesDir, '.registry.npmjs.org/brace-expansion/1.1.8'),
resolved: 'https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz',
@@ -97,7 +109,9 @@ test('one package depth 1', async t => {
{
alias: 'rimraf',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'rimraf',
path: path.join(modulesDir, '.registry.npmjs.org/rimraf/2.5.1'),
resolved: 'https://registry.npmjs.org/rimraf/-/rimraf-2.5.1.tgz',
@@ -107,7 +121,9 @@ test('one package depth 1', async t => {
{
alias: 'glob',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'glob',
path: path.join(modulesDir, '.registry.npmjs.org/glob/6.0.4'),
resolved: 'https://registry.npmjs.org/glob/-/glob-6.0.4.tgz',
@@ -120,7 +136,9 @@ test('one package depth 1', async t => {
{
alias: 'is-positive',
dev: true,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'is-positive',
path: path.join(modulesDir, '.registry.npmjs.org/is-positive/1.0.0'),
resolved: 'https://registry.npmjs.org/is-positive/-/is-positive-1.0.0.tgz',
@@ -131,7 +149,9 @@ test('one package depth 1', async t => {
{
alias: 'is-negative',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'is-negative',
optional: true,
path: path.join(modulesDir, '.registry.npmjs.org/is-negative/1.0.0'),
@@ -163,7 +183,9 @@ test('only prod depth 0', async t => {
{
alias: 'minimatch',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'minimatch',
path: path.join(modulesDir, '.registry.npmjs.org/minimatch/3.0.4'),
resolved: 'https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz',
@@ -172,7 +194,9 @@ test('only prod depth 0', async t => {
{
alias: 'rimraf',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'rimraf',
path: path.join(modulesDir, '.registry.npmjs.org/rimraf/2.5.1'),
resolved: 'https://registry.npmjs.org/rimraf/-/rimraf-2.5.1.tgz',
@@ -203,7 +227,9 @@ test('only dev depth 0', async t => {
{
alias: 'is-positive',
dev: true,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'is-positive',
path: path.join(modulesDir, '.registry.npmjs.org/is-positive/1.0.0'),
resolved: 'https://registry.npmjs.org/is-positive/-/is-positive-1.0.0.tgz',
@@ -232,7 +258,9 @@ test('filter 1 package with depth 0', async t => {
{
alias: 'rimraf',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'rimraf',
path: path.join(modulesDir, '.registry.npmjs.org/rimraf/2.5.1'),
resolved: 'https://registry.npmjs.org/rimraf/-/rimraf-2.5.1.tgz',
@@ -255,7 +283,9 @@ test('filter by pattern', async t => {
{
alias: 'rimraf',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'rimraf',
path: path.join(modulesDir, '.registry.npmjs.org/rimraf/2.5.1'),
resolved: 'https://registry.npmjs.org/rimraf/-/rimraf-2.5.1.tgz',
@@ -278,7 +308,9 @@ test('filter by pattern', async t => {
{
alias: 'rimraf',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'rimraf',
path: path.join(modulesDir, '.registry.npmjs.org/rimraf/2.5.1'),
resolved: 'https://registry.npmjs.org/rimraf/-/rimraf-2.5.1.tgz',
@@ -312,7 +344,9 @@ test('filter 2 packages with depth 100', async t => {
{
alias: 'minimatch',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'minimatch',
path: path.join(modulesDir, '.registry.npmjs.org/minimatch/3.0.4'),
resolved: 'https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz',
@@ -322,7 +356,9 @@ test('filter 2 packages with depth 100', async t => {
{
alias: 'rimraf',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'rimraf',
path: path.join(modulesDir, '.registry.npmjs.org/rimraf/2.5.1'),
resolved: 'https://registry.npmjs.org/rimraf/-/rimraf-2.5.1.tgz',
@@ -332,7 +368,9 @@ test('filter 2 packages with depth 100', async t => {
{
alias: 'glob',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'glob',
path: path.join(modulesDir, '.registry.npmjs.org/glob/6.0.4'),
resolved: 'https://registry.npmjs.org/glob/-/glob-6.0.4.tgz',
@@ -342,7 +380,9 @@ test('filter 2 packages with depth 100', async t => {
{
alias: 'inflight',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'inflight',
path: path.join(modulesDir, '.registry.npmjs.org/inflight/1.0.6'),
resolved: 'https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz',
@@ -352,7 +392,9 @@ test('filter 2 packages with depth 100', async t => {
{
alias: 'once',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'once',
path: path.join(modulesDir, '.registry.npmjs.org/once/1.4.0'),
resolved: 'https://registry.npmjs.org/once/-/once-1.4.0.tgz',
@@ -364,7 +406,9 @@ test('filter 2 packages with depth 100', async t => {
{
alias: 'minimatch',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'minimatch',
path: path.join(modulesDir, '.registry.npmjs.org/minimatch/3.0.4'),
resolved: 'https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz',
@@ -374,7 +418,9 @@ test('filter 2 packages with depth 100', async t => {
{
alias: 'once',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'once',
path: path.join(modulesDir, '.registry.npmjs.org/once/1.4.0'),
resolved: 'https://registry.npmjs.org/once/-/once-1.4.0.tgz',
@@ -449,7 +495,9 @@ test('local package depth 0', async t => {
dependencies: [
{
alias: 'general',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'general',
path: generalFixture,
version: 'link:../general',
@@ -457,7 +505,9 @@ test('local package depth 0', async t => {
{
alias: 'is-positive',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'is-positive',
path: path.join(modulesDir, '.registry.npmjs.org/is-positive/3.1.0'),
resolved: 'https://registry.npmjs.org/is-positive/-/is-positive-3.1.0.tgz',
@@ -478,7 +528,9 @@ test('on a package that has only links', async t => {
dependencies: [
{
alias: 'general',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'general',
path: path.join(__dirname, '..', 'fixtureWithLinks', 'general'),
version: 'link:../general',
@@ -506,7 +558,9 @@ test('filter on a package that has only links', async t => {
dependencies: [
{
alias: 'general',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'general',
path: path.join(__dirname, '..', 'fixtureWithLinks', 'general'),
searched: true,
@@ -527,7 +581,9 @@ test('unsaved dependencies are listed', async t => {
{
alias: 'symlink-dir',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'symlink-dir',
path: path.join(modulesDir, '.registry.npmjs.org/symlink-dir/2.0.2'),
resolved: 'https://registry.npmjs.org/symlink-dir/-/symlink-dir-2.0.2.tgz',
@@ -539,14 +595,18 @@ test('unsaved dependencies are listed', async t => {
unsavedDependencies: [
{
alias: 'general',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'general',
path: generalFixture,
version: 'link:../general',
},
{
alias: 'is-positive',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'is-positive',
path: path.join(modulesDir, 'is-positive'),
version: '3.1.0',
@@ -563,7 +623,9 @@ test('unsaved dependencies are listed and filtered', async t => {
{
alias: 'symlink-dir',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'symlink-dir',
path: path.join(modulesDir, '.registry.npmjs.org/symlink-dir/2.0.2'),
resolved: 'https://registry.npmjs.org/symlink-dir/-/symlink-dir-2.0.2.tgz',
@@ -590,7 +652,9 @@ test('dependency with an alias', async t => {
{
alias: 'positive',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'is-positive',
path: path.join(modulesDir, '.registry.npmjs.org/is-positive/1.0.0'),
resolved: 'https://registry.npmjs.org/is-positive/-/is-positive-1.0.0.tgz',

View File

@@ -122,6 +122,9 @@ function printLabel (getPkgColor: GetPkgColor, node: PackageNode) {
if (node.isPeer) {
txt += ' peer'
}
if (node.isSkipped) {
txt += ' skipped'
}
return txt
}

View File

@@ -466,7 +466,9 @@ test('unsaved dependencies are marked', async (t) => {
unsavedDependencies: [
{
alias: 'foo',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'foo',
path: '',
version: '1.0.0',
@@ -501,77 +503,99 @@ test('write long lists in columns', async (t) => {
dependencies: [
{
alias: 'a',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'a',
path: '',
version: '1.0.0',
},
{
alias: 'b',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'b',
path: '',
version: '1.0.0',
},
{
alias: 'c',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'c',
path: '',
version: '1.0.0',
},
{
alias: 'd',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'd',
path: '',
version: '1.0.0',
},
{
alias: 'e',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'e',
path: '',
version: '1.0.0',
},
{
alias: 'f',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'f',
path: '',
version: '1.0.0',
},
{
alias: 'g',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'g',
path: '',
version: '1.0.0',
},
{
alias: 'h',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'h',
path: '',
version: '1.0.0',
},
{
alias: 'i',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'i',
path: '',
version: '1.0.0',
},
{
alias: 'k',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'k',
path: '',
version: '1.0.0',
},
{
alias: 'l',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'l',
path: '',
version: '1.0.0',
@@ -617,7 +641,9 @@ test('sort list items', async (t) => {
dependencies: [
{
alias: 'foo',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'foo',
path: '',
version: '1.0.0',
@@ -625,14 +651,18 @@ test('sort list items', async (t) => {
dependencies: [
{
alias: 'qar',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'qar',
path: '',
version: '1.0.0',
},
{
alias: 'bar',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'bar',
path: '',
version: '1.0.0',

View File

@@ -224,3 +224,23 @@ test(`listing packages of a project that has an external ${WANTED_LOCKFILE}`, as
is-positive 1.0.0
` + '\n', 'prints all deps')
})
test('list on a project with skipped optional dependencies', async (t: tape.Test) => {
prepare(t)
await execPnpm('add', '--no-optional', 'pkg-with-optional')
const result = execPnpmSync('list', '--depth', '10')
t.equal(result.status, 0)
t.equal(result.stdout.toString(), stripIndent`
Legend: production dependency, optional only, dev only
project@0.0.0 /home/zoltan/src/pnpm/.tmp/1/project
dependencies:
pkg-with-optional 1.0.0
└── not-compatible-with-any-os 1.0.0 skipped
` + '\n')
})