feat: new matching pattern

BREAKING CHANGE:

new wildcard matcher used

close #2048
PR #2052
This commit is contained in:
Zoltan Kochan
2019-10-05 20:54:07 +03:00
committed by GitHub
parent 889f71481e
commit 59759f7c6f
39 changed files with 345 additions and 589 deletions

View File

@@ -86,7 +86,7 @@ export interface Config {
pnpmfile: string,
independentLeaves?: boolean,
packageImportMethod?: 'auto' | 'hardlink' | 'copy' | 'clone',
hoistPattern?: string,
hoistPattern?: string[],
useStoreServer?: boolean,
useRunningStoreServer?: boolean,
workspaceConcurrency: number,

View File

@@ -32,7 +32,7 @@ export const types = Object.assign({
'global-path': path,
'global-pnpmfile': String,
'hoist': Boolean,
'hoist-pattern': String,
'hoist-pattern': Array,
'ignore-pnpmfile': Boolean,
'ignore-stop-requests': Boolean,
'ignore-upload-requests': Boolean,
@@ -148,7 +148,7 @@ export default async (
'fetch-retry-mintimeout': 10000,
'globalconfig': npmDefaults.globalconfig,
'hoist': true,
'hoist-pattern': '*',
'hoist-pattern': ['*'],
'ignore-workspace-root-check': false,
'latest': false,
'link-workspace-packages': true,
@@ -247,7 +247,7 @@ export default async (
}
pnpmConfig.independentLeaves = false
}
if (pnpmConfig.hoistPattern !== '*') {
if (pnpmConfig.hoistPattern && (pnpmConfig.hoistPattern.length > 1 || pnpmConfig.hoistPattern[0] !== '*')) {
if (opts.cliArgs['hoist-pattern']) {
throw new PnpmError('CONFIG_CONFLICT_HOIST_PATTERN_WITH_GLOBAL',
'Configuration conflict. "hoist-pattern" may not be used with "global"')
@@ -326,7 +326,7 @@ export default async (
}
if (pnpmConfig['shamefullyFlatten']) {
warnings.push('The "shamefully-flatten" setting is deprecated. Use "shamefully-hoist", "hoist" or "hoist-pattern" instead. Since v4, hoisting is on by default for all dependencies.')
pnpmConfig.hoistPattern = '*'
pnpmConfig.hoistPattern = ['*']
pnpmConfig.shamefullyHoist = true
}
if (pnpmConfig['hoist'] === false) {

View File

@@ -514,7 +514,7 @@ test('convert shamefully-flatten to hoist-pattern=* and warn', async (t) => {
},
})
t.equal(config.hoistPattern, '*')
t.deepEqual(config.hoistPattern, ['*'])
t.equal(config.shamefullyHoist, true)
t.deepEqual(warnings, ['The "shamefully-flatten" setting is deprecated. ' +
'Use "shamefully-hoist", "hoist" or "hoist-pattern" instead. ' +

View File

@@ -43,16 +43,12 @@
"@pnpm/types": "workspace:3.2.0",
"@pnpm/utils": "workspace:0.10.6",
"dependency-path": "workspace:3.0.8",
"micromatch": "4.0.2",
"normalize-path": "3.0.0",
"resolve-link-target": "1.0.1",
"semver": "6.3.0"
"resolve-link-target": "1.0.1"
},
"devDependencies": {
"@pnpm/constants": "link:../constants",
"@pnpm/logger": "2.1.1",
"@types/micromatch": "3.1.0",
"@types/semver": "6",
"dependencies-hierarchy": "link:",
"tape": "4.11.0"
}

View File

@@ -19,18 +19,12 @@ import {
realNodeModulesDir,
safeReadPackageFromDir,
} from '@pnpm/utils'
import assert = require('assert')
import { refToAbsolute, refToRelative } from 'dependency-path'
import { isMatch } from 'micromatch'
import normalizePath = require('normalize-path')
import path = require('path')
import resolveLinkTarget = require('resolve-link-target')
import semver = require('semver')
export type PackageSelector = string | {
name: string,
range: string,
}
export type SearchFunction = (pkg: { name: string, version: string }) => boolean
export interface PackageNode {
alias: string,
@@ -48,34 +42,6 @@ export interface PackageNode {
version: string,
}
export function forPackages (
packages: PackageSelector[],
projectPaths: string[],
opts: {
depth: number,
include?: { [dependenciesField in DependenciesField]: boolean },
registries?: Registries,
lockfileDirectory: string,
},
) {
assert(packages, 'packages should be defined')
if (!packages.length) return {}
return dependenciesHierarchy(projectPaths, packages, opts)
}
export default function (
projectPaths: string[],
opts: {
depth: number,
include?: { [dependenciesField in DependenciesField]: boolean },
registries?: Registries,
lockfileDirectory: string,
},
) {
return dependenciesHierarchy(projectPaths, [], opts)
}
export type DependenciesHierarchy = {
dependencies?: PackageNode[],
devDependencies?: PackageNode[],
@@ -83,13 +49,13 @@ export type DependenciesHierarchy = {
unsavedDependencies?: PackageNode[],
}
async function dependenciesHierarchy (
export default async function dependenciesHierarchy (
projectPaths: string[],
searched: PackageSelector[],
maybeOpts: {
depth: number,
include?: { [dependenciesField in DependenciesField]: boolean },
registries?: Registries,
search?: SearchFunction,
lockfileDirectory: string,
},
): Promise<{ [prefix: string]: DependenciesHierarchy }> {
@@ -122,13 +88,14 @@ async function dependenciesHierarchy (
},
lockfileDirectory: maybeOpts.lockfileDirectory,
registries,
search: maybeOpts.search,
skipped: new Set(modules && modules.skipped || []),
}
; (
await Promise.all(projectPaths.map(async (projectPath) => {
return [
projectPath,
await dependenciesHierarchyForPackage(projectPath, currentLockfile, searched, opts),
await dependenciesHierarchyForPackage(projectPath, currentLockfile, opts),
] as [string, DependenciesHierarchy]
}))
).forEach(([projectPath, dependenciesHierarchy]) => {
@@ -140,11 +107,11 @@ async function dependenciesHierarchy (
async function dependenciesHierarchyForPackage (
projectPath: string,
currentLockfile: Lockfile,
searched: PackageSelector[],
opts: {
depth: number,
include: { [dependenciesField in DependenciesField]: boolean },
registries: Registries,
search?: SearchFunction,
skipped: Set<string>,
lockfileDirectory: string,
},
@@ -167,7 +134,7 @@ async function dependenciesHierarchyForPackage (
maxDepth: opts.depth,
modulesDir,
registries: opts.registries,
searched,
search: opts.search,
skipped: opts.skipped,
wantedPackages: wantedLockfile.packages || {},
})
@@ -186,9 +153,9 @@ async function dependenciesHierarchyForPackage (
wantedPackages: wantedLockfile.packages || {},
})
let newEntry: PackageNode | null = null
const matchedSearched = searched.length && matches(searched, packageInfo)
const matchedSearched = opts.search && opts.search(packageInfo)
if (packageAbsolutePath === null) {
if (searched.length && !matchedSearched) return
if (opts.search && !matchedSearched) return
newEntry = packageInfo
} else {
const relativeId = refToRelative(topDeps[alias], alias)
@@ -199,7 +166,7 @@ async function dependenciesHierarchyForPackage (
...packageInfo,
dependencies,
}
} else if (!searched.length || matches(searched, packageInfo)) {
} else if (!opts.search || matchedSearched) {
newEntry = packageInfo
}
}
@@ -234,8 +201,8 @@ async function dependenciesHierarchyForPackage (
path: pkgPath,
version,
}
const matchedSearched = searched.length && matches(searched, pkg)
if (searched.length && !matchedSearched) return
const matchedSearched = opts.search && opts.search(pkg)
if (opts.search && !matchedSearched) return
const newEntry: PackageNode = pkg
if (matchedSearched) {
newEntry.searched = true
@@ -262,7 +229,7 @@ function getTree (
maxDepth: number,
modulesDir: string,
includeOptionalDependencies: boolean,
searched: PackageSelector[],
search?: SearchFunction,
skipped: Set<string>,
registries: Registries,
currentPackages: PackageSnapshots,
@@ -301,7 +268,7 @@ function getTree (
wantedPackages: opts.wantedPackages,
})
let circular: boolean
const matchedSearched = opts.searched.length && matches(opts.searched, packageInfo)
const matchedSearched = opts.search && opts.search(packageInfo)
let newEntry: PackageNode | null = null
if (packageAbsolutePath === null) {
circular = false
@@ -316,7 +283,7 @@ function getTree (
...packageInfo,
dependencies,
}
} else if (!opts.searched.length || matchedSearched) {
} else if (!opts.search || matchedSearched) {
newEntry = packageInfo
}
}
@@ -399,17 +366,3 @@ function getPkgInfo (
packageInfo,
}
}
function matches (
searched: PackageSelector[],
pkg: {name: string, version: string},
) {
return searched.some((searchedPkg) => {
if (typeof searchedPkg === 'string') {
return isMatch(pkg.name, searchedPkg)
}
return isMatch(pkg.name, searchedPkg.name) &&
!pkg.version.startsWith('link:') &&
semver.satisfies(pkg.version, searchedPkg.range)
})
}

View File

@@ -1,6 +1,6 @@
///<reference path="../../../typings/index.d.ts"/>
import { WANTED_LOCKFILE } from '@pnpm/constants'
import dh, { forPackages as dhForPackages, PackageNode } from 'dependencies-hierarchy'
import dh, { PackageNode } from 'dependencies-hierarchy'
import path = require('path')
import test = require('tape')
@@ -252,18 +252,31 @@ test('only dev depth 0', async t => {
})
test('hierarchy for no packages', async t => {
const tree = await dhForPackages([], [generalFixture], { depth: 100, lockfileDirectory: generalFixture })
const tree = await dh([generalFixture], {
depth: 100,
lockfileDirectory: generalFixture,
search: () => false,
})
t.deepEqual(tree, [])
t.deepEqual(tree, {
[generalFixture]: {
dependencies: [],
devDependencies: [],
optionalDependencies: [],
},
})
t.end()
})
test('filter 1 package with depth 0', async t => {
const tree = await dhForPackages(
[{ name: 'rimraf', range: '*' }],
const tree = await dh(
[generalFixture],
{ depth: 0, lockfileDirectory: generalFixture },
{
depth: 0,
lockfileDirectory: generalFixture,
search: ({ name }) => name === 'rimraf',
},
)
const modulesDir = path.join(generalFixture, 'node_modules')
@@ -291,214 +304,6 @@ test('filter 1 package with depth 0', async t => {
t.end()
})
test('filter by pattern', async t => {
const modulesDir = path.join(generalFixture, 'node_modules')
t.deepEqual(
await dhForPackages(['rim*'], [generalFixture], { depth: 0, lockfileDirectory: generalFixture }),
{
[generalFixture]: {
dependencies: [
{
alias: 'rimraf',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'rimraf',
path: path.join(modulesDir, '.pnpm/registry.npmjs.org/rimraf/2.5.1'),
resolved: 'https://registry.npmjs.org/rimraf/-/rimraf-2.5.1.tgz',
searched: true,
version: '2.5.1',
},
],
devDependencies: [],
optionalDependencies: [],
},
},
'matched by pattern',
)
t.deepEqual(
await dhForPackages(['rim1*'], [generalFixture], { depth: 0, lockfileDirectory: generalFixture }),
{
[generalFixture]: {
dependencies: [],
devDependencies: [],
optionalDependencies: [],
}
},
'not matched by pattern',
)
t.deepEqual(
await dhForPackages([{ name: 'rim*', range: '2' }], [generalFixture], { depth: 0, lockfileDirectory: generalFixture }),
{
[generalFixture]: {
dependencies: [
{
alias: 'rimraf',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'rimraf',
path: path.join(modulesDir, '.pnpm/registry.npmjs.org/rimraf/2.5.1'),
resolved: 'https://registry.npmjs.org/rimraf/-/rimraf-2.5.1.tgz',
searched: true,
version: '2.5.1',
},
],
devDependencies: [],
optionalDependencies: [],
},
},
'matched by pattern and range',
)
t.deepEqual(
await dhForPackages([{ name: 'rim*', range: '3' }], [generalFixture], { depth: 0, lockfileDirectory: generalFixture }),
{
[generalFixture]: {
dependencies: [],
devDependencies: [],
optionalDependencies: [],
},
},
'not matched by pattern and range',
)
t.end()
})
test('filter 2 packages with depth 100', async t => {
const searched = [
'minimatch',
{ name: 'once', range: '1.4' },
]
const tree = await dhForPackages(searched, [generalFixture], { depth: 100, lockfileDirectory: generalFixture })
const modulesDir = path.join(generalFixture, 'node_modules')
t.deepEqual(tree, {
[generalFixture]: {
dependencies: [
{
alias: 'minimatch',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'minimatch',
path: path.join(modulesDir, '.pnpm/registry.npmjs.org/minimatch/3.0.4'),
resolved: 'https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz',
searched: true,
version: '3.0.4',
},
{
alias: 'rimraf',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'rimraf',
path: path.join(modulesDir, '.pnpm/registry.npmjs.org/rimraf/2.5.1'),
resolved: 'https://registry.npmjs.org/rimraf/-/rimraf-2.5.1.tgz',
version: '2.5.1',
dependencies: [
{
alias: 'glob',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'glob',
path: path.join(modulesDir, '.pnpm/registry.npmjs.org/glob/6.0.4'),
resolved: 'https://registry.npmjs.org/glob/-/glob-6.0.4.tgz',
version: '6.0.4',
dependencies: [
{
alias: 'inflight',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'inflight',
path: path.join(modulesDir, '.pnpm/registry.npmjs.org/inflight/1.0.6'),
resolved: 'https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz',
version: '1.0.6',
dependencies: [
{
alias: 'once',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'once',
path: path.join(modulesDir, '.pnpm/registry.npmjs.org/once/1.4.0'),
resolved: 'https://registry.npmjs.org/once/-/once-1.4.0.tgz',
searched: true,
version: '1.4.0',
},
],
},
{
alias: 'minimatch',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'minimatch',
path: path.join(modulesDir, '.pnpm/registry.npmjs.org/minimatch/3.0.4'),
resolved: 'https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz',
searched: true,
version: '3.0.4',
},
{
alias: 'once',
dev: false,
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'once',
path: path.join(modulesDir, '.pnpm/registry.npmjs.org/once/1.4.0'),
resolved: 'https://registry.npmjs.org/once/-/once-1.4.0.tgz',
searched: true,
version: '1.4.0',
},
],
},
],
},
],
devDependencies: [],
optionalDependencies: [],
},
})
t.end()
})
test('filter 2 packages with ranges that are not satisfied', async t => {
const searched = [
{ name: 'minimatch', range: '100' },
{ name: 'once', range: '100' },
]
const tree = await dhForPackages(searched, [generalFixture], { depth: 100, lockfileDirectory: generalFixture })
t.deepEqual(tree, {
[generalFixture]: {
dependencies: [],
devDependencies: [],
optionalDependencies: [],
},
})
t.end()
})
test('circular dependency', async t => {
const tree = await dh([circularFixture], { depth: 1000, lockfileDirectory: circularFixture })
const modulesDir = path.join(circularFixture, 'node_modules')
@@ -593,55 +398,6 @@ test('on a package that has only links', async t => {
t.end()
})
test('filter on a package that has only links', async t => {
t.deepEqual(
await dhForPackages(['rimraf'], [withLinksOnlyFixture], { depth: 1000, lockfileDirectory: withLinksOnlyFixture }),
{
[withLinksOnlyFixture]: {
dependencies: [],
devDependencies: [],
optionalDependencies: [],
},
},
'not found',
)
t.deepEqual(
await dhForPackages([{ name: 'general', range: '2' }], [withLinksOnlyFixture], { depth: 1000, lockfileDirectory: withLinksOnlyFixture }),
{
[withLinksOnlyFixture]: {
dependencies: [],
devDependencies: [],
optionalDependencies: [],
},
},
'not found',
)
t.deepEqual(
await dhForPackages(['general'], [withLinksOnlyFixture], { depth: 1000, lockfileDirectory: withLinksOnlyFixture }),
{
[withLinksOnlyFixture]: {
dependencies: [
{
alias: 'general',
isMissing: false,
isPeer: false,
isSkipped: false,
name: 'general',
path: path.join(__dirname, '..', 'fixtureWithLinks', 'general'),
searched: true,
version: 'link:../general',
},
],
devDependencies: [],
optionalDependencies: [],
},
},
'found',
)
t.end()
})
test('unsaved dependencies are listed', async t => {
const modulesDir = path.join(withUnsavedDepsFixture, 'node_modules')
t.deepEqual(
@@ -692,10 +448,13 @@ test('unsaved dependencies are listed', async t => {
test('unsaved dependencies are listed and filtered', async t => {
const modulesDir = path.join(withUnsavedDepsFixture, 'node_modules')
t.deepEqual(
await dhForPackages(
[{ name: 'symlink-dir', range: '*' }],
await dh(
[withUnsavedDepsFixture],
{ depth: 0, lockfileDirectory: withUnsavedDepsFixture },
{
depth: 0,
lockfileDirectory: withUnsavedDepsFixture,
search: ({ name }) => name === 'symlink-dir',
},
),
{
[withUnsavedDepsFixture]: {

View File

@@ -87,6 +87,7 @@
"@pnpm/link-bins": "4.4.0",
"@pnpm/lockfile-file": "workspace:2.0.0-0",
"@pnpm/lockfile-utils": "workspace:1.0.10",
"@pnpm/matcher": "workspace:0.0.0",
"@pnpm/modules-cleaner": "workspace:5.0.0-2",
"@pnpm/modules-yaml": "workspace:4.0.0-1",
"@pnpm/package-requester": "workspace:8.0.0-0",

View File

@@ -38,6 +38,7 @@ import logger, {
LogBase,
streamParser,
} from '@pnpm/logger'
import matcher from '@pnpm/matcher'
import { prune } from '@pnpm/modules-cleaner'
import {
IncludedDependencies,
@@ -85,7 +86,7 @@ export interface HeadlessOptions {
pruneDirectDependencies?: boolean,
}>,
hoistedAliases: {[depPath: string]: string[]}
hoistPattern?: string,
hoistPattern?: string[],
lockfileDirectory: string,
shamefullyHoist: boolean,
storeController: StoreController,
@@ -237,7 +238,7 @@ export default async (opts: HeadlessOptions) => {
const rootImporterWithFlatModules = opts.hoistPattern && opts.importers.find((importer) => importer.id === '.')
let newHoistedAliases!: {[depPath: string]: string[]}
if (rootImporterWithFlatModules) {
newHoistedAliases = await hoist(opts.hoistPattern!, {
newHoistedAliases = await hoist(matcher(opts.hoistPattern!), {
getIndependentPackageLocation: opts.independentLeaves
? async (packageId: string, packageName: string) => {
const { directory } = await opts.storeController.getPackageLocation(packageId, packageName, {

View File

@@ -20,7 +20,6 @@
},
"devDependencies": {
"@pnpm/logger": "2.1.1",
"@types/micromatch": "3.1.0",
"@types/ramda": "0.26.21",
"rimraf": "3.0.0"
},
@@ -52,7 +51,6 @@
"@pnpm/symlink-dependency": "workspace:2.0.6",
"@pnpm/types": "workspace:3.2.0",
"dependency-path": "workspace:3.0.8",
"micromatch": "4.0.2",
"ramda": "0.26.1"
}
}

View File

@@ -11,12 +11,11 @@ import pkgIdToFilename from '@pnpm/pkgid-to-filename'
import symlinkDependency from '@pnpm/symlink-dependency'
import { Registries } from '@pnpm/types'
import * as dp from 'dependency-path'
import { matcher } from 'micromatch'
import path = require('path')
import R = require('ramda')
export default async function hoistByLockfile (
hoistPattern: string,
match: (dependencyName: string) => boolean,
opts: {
getIndependentPackageLocation?: (packageId: string, packageName: string) => Promise<string>,
lockfile: Lockfile,
@@ -51,8 +50,8 @@ export default async function hoistByLockfile (
const aliasesByDependencyPath = await hoistGraph(deps, opts.lockfile.importers['.'].specifiers, {
dryRun: false,
match,
modulesDir: opts.modulesDir,
pattern: hoistPattern,
})
const bin = path.join(opts.modulesDir, '.bin')
@@ -142,14 +141,13 @@ async function hoistGraph (
depNodes: Dependency[],
currentSpecifiers: {[alias: string]: string},
opts: {
match: (dependencyName: string) => boolean,
modulesDir: string,
dryRun: boolean,
pattern: string,
},
): Promise<{[alias: string]: string[]}> {
const hoistedAliases = new Set(R.keys(currentSpecifiers))
const aliasesByDependencyPath: {[depPath: string]: string[]} = {}
const match = opts.pattern === '*' ? () => true : matcher(opts.pattern)
await Promise.all(depNodes
// sort by depth and then alphabetically
@@ -160,7 +158,7 @@ async function hoistGraph (
// build the alias map and the id map
.map((depNode) => {
for (const childAlias of Object.keys(depNode.children)) {
if (!match(childAlias)) continue
if (!opts.match(childAlias)) continue
// if this alias has already been taken, skip it
if (hoistedAliases.has(childAlias)) {
continue

View File

@@ -36,6 +36,7 @@
},
"homepage": "https://github.com/pnpm/pnpm/blob/master/packages/list#readme",
"dependencies": {
"@pnpm/matcher": "workspace:0.0.0",
"@pnpm/read-importer-manifest": "workspace:1.0.9",
"@pnpm/read-package-json": "workspace:2.0.3",
"@pnpm/types": "workspace:3.2.0",
@@ -45,7 +46,8 @@
"cli-columns": "3.1.2",
"dependencies-hierarchy": "workspace:7.0.0-3",
"p-limit": "2.2.1",
"ramda": "0.26.1"
"ramda": "0.26.1",
"semver": "6.3.0"
},
"devDependencies": {
"@pnpm/list": "link:",
@@ -53,6 +55,7 @@
"@types/archy": "0.0.31",
"@types/common-tags": "1.8.0",
"@types/ramda": "0.26.21",
"@types/semver": "6",
"common-tags": "1.8.0",
"tape": "4.11.0"
}

View File

@@ -0,0 +1,43 @@
import matcher from '@pnpm/matcher'
import npa = require('@zkochan/npm-package-arg')
import { SearchFunction } from 'dependencies-hierarchy'
import semver = require('semver')
export default function createPatternSearcher (queries: string[]) {
const searchers: SearchFunction[] = queries
.map(parseSearchQuery)
.map((packageSelector) => search.bind(null, packageSelector))
return (pkg: { name: string, version: string }) => searchers.some((search) => search(pkg))
}
type MatchFunction = (entry: string) => boolean
function search (
packageSelector: {
matchName: MatchFunction,
matchVersion?: MatchFunction,
},
pkg: { name: string, version: string },
) {
if (!packageSelector.matchName(pkg.name)) {
return false
}
if (!packageSelector.matchVersion) {
return true
}
return !pkg.version.startsWith('link:') && packageSelector.matchVersion(pkg.version)
}
function parseSearchQuery (query: string) {
const parsed = npa(query)
if (parsed.raw === parsed.name) {
return { matchName: matcher(parsed.name) }
}
if (parsed.type !== 'version' && parsed.type !== 'range') {
throw new Error(`Invalid queryument - ${query}. List can search only by version or range`)
}
return {
matchName: matcher(parsed.name),
matchVersion: (version: string) => semver.satisfies(version, parsed.fetchSpec),
}
}

View File

@@ -1,11 +1,8 @@
import { readImporterManifestOnly } from '@pnpm/read-importer-manifest'
import { DependenciesField, Registries } from '@pnpm/types'
import npa = require('@zkochan/npm-package-arg')
import dh, {
forPackages as dhForPackages,
PackageSelector,
} from 'dependencies-hierarchy'
import dh from 'dependencies-hierarchy'
import R = require('ramda')
import createPackagesSearcher from './createPackagesSearcher'
import renderJson from './renderJson'
import renderParseable from './renderParseable'
import renderTree from './renderTree'
@@ -34,26 +31,15 @@ export async function forPackages (
) {
const opts = { ...DEFAULTS, ...maybeOpts }
const searched: PackageSelector[] = packages.map((arg) => {
const parsed = npa(arg)
if (parsed.raw === parsed.name) {
return parsed.name
}
if (parsed.type !== 'version' && parsed.type !== 'range') {
throw new Error(`Invalid argument - ${arg}. List can search only by version or range`)
}
return {
name: parsed.name,
range: parsed.fetchSpec,
}
})
const search = createPackagesSearcher(packages)
const pkgs = await Promise.all(
R.toPairs(await dhForPackages(searched, projectPaths, {
R.toPairs(await dh(projectPaths, {
depth: opts.depth,
include: maybeOpts && maybeOpts.include,
lockfileDirectory: maybeOpts && maybeOpts.lockfileDirectory,
registries: opts.registries,
search,
}))
.map(async ([projectPath, dependenciesHierarchy]) => {
const entryPkg = await readImporterManifestOnly(projectPath)

View File

@@ -0,0 +1,27 @@
import createPackagesSearcher from '@pnpm/list/lib/createPackagesSearcher'
import test = require('tape')
test('packages searcher', (t) => {
{
const search = createPackagesSearcher(['rimraf@*'])
t.ok(search({ name: 'rimraf', version: '1.0.0' }))
t.notOk(search({ name: 'express', version: '1.0.0' }))
}
{
const search = createPackagesSearcher(['rim*'])
t.ok(search({ name: 'rimraf', version: '1.0.0' }))
t.notOk(search({ name: 'express', version: '1.0.0' }))
}
{
const search = createPackagesSearcher(['rim*@2'])
t.ok(search({ name: 'rimraf', version: '2.0.0' }))
t.notOk(search({ name: 'rimraf', version: '1.0.0' }))
}
{
const search = createPackagesSearcher(['minimatch', 'once@1.4'])
t.ok(search({ name: 'minimatch', version: '2.0.0' }))
t.ok(search({ name: 'once', version: '1.4.1' }))
t.notOk(search({ name: 'rimraf', version: '1.0.0' }))
}
t.end()
})

View File

@@ -6,6 +6,7 @@ import cliColumns = require('cli-columns')
import { stripIndent } from 'common-tags'
import path = require('path')
import test = require('tape')
import './createPackagesSearcher.spec.ts'
const DEV_DEP_ONLY_CLR = chalk.yellow
const PROD_DEP_CLR = (s: string) => s // just use the default color

View File

@@ -0,0 +1,23 @@
# @pnpm/matcher
> A simple pattern matcher for pnpm
## Install
```
<pnpm|yarn|npm> add @pnpm/matcher
```
## Usage
```ts
import matcher from '@pnpm/matcher'
const match = matcher(['eslint-*'])
match('eslint-plugin-foo')
//> true
```
## License
[MIT](LICENSE)

View File

@@ -0,0 +1,44 @@
{
"name": "@pnpm/matcher",
"version": "0.0.0",
"description": "A simple pattern matcher for pnpm",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
"engines": {
"node": ">=10"
},
"files": [
"lib/"
],
"scripts": {
"lint": "tslint -c tslint.json src/**/*.ts test/**/*.ts",
"test": "pnpm run tsc && pnpm run lint && ts-node test --type-check",
"tsc": "rimraf lib && tsc",
"prepublishOnly": "pnpm run tsc"
},
"repository": "https://github.com/pnpm/pnpm/blob/master/packages/matcher",
"keywords": [
"pnpm",
"match",
"wildcard",
"pattern"
],
"author": {
"name": "Zoltan Kochan",
"email": "z@kochan.io",
"url": "https://www.kochan.io"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/pnpm/pnpm/issues"
},
"homepage": "https://github.com/pnpm/pnpm/blob/master/packages/matcher#readme",
"devDependencies": {
"@pnpm/matcher": "link:",
"rimraf": "3.0.0",
"tape": "4.11.0"
},
"dependencies": {
"escape-string-regexp": "2.0.0"
}
}

View File

@@ -0,0 +1,22 @@
import escapeStringRegexp = require('escape-string-regexp')
export default function matcher (patterns: string[] | string) {
if (typeof patterns === 'string') return matcherFromPattern(patterns)
if (patterns.length === 0) return matcherFromPattern(patterns[0])
const matchArr = patterns.map(matcherFromPattern)
return (input: string) => matchArr.some((match) => match(input))
}
function matcherFromPattern (pattern: string) {
if (pattern === '*') {
return () => true
}
const escapedPattern = escapeStringRegexp(pattern).replace(/\\\*/g, '.*')
if (escapedPattern === pattern) {
return (input: string) => input === pattern
}
const regexp = new RegExp(`^${escapedPattern}$`)
return (input: string) => regexp.test(input)
}

View File

@@ -0,0 +1,35 @@
import matcher from '@pnpm/matcher'
import test = require('tape')
test('matcher()', (t) => {
{
const match = matcher('*')
t.ok(match('@eslint/plugin-foo'))
t.ok(match('express'))
}
{
const match = matcher(['eslint-*'])
t.ok(match('eslint-plugin-foo'))
t.notOk(match('express'))
}
{
const match = matcher(['*plugin*'])
t.ok(match('@eslint/plugin-foo'))
t.notOk(match('express'))
}
{
const match = matcher(['a*c'])
t.ok(match('abc'))
}
{
const match = matcher(['*-positive'])
t.ok(match('is-positive'))
}
{
const match = matcher(['foo', 'bar'])
t.ok(match('foo'))
t.ok(match('bar'))
t.notOk(match('express'))
}
t.end()
})

View File

@@ -0,0 +1,10 @@
{
"extends": "@pnpm/tsconfig",
"compilerOptions": {
"outDir": "lib"
},
"include": [
"src/**/*.ts",
"../../typings/**/*.d.ts"
]
}

View File

@@ -0,0 +1,3 @@
{
"extends": "@pnpm/tslint-config"
}

View File

@@ -13,7 +13,7 @@ export type IncludedDependencies = {
export interface Modules {
hoistedAliases: {[depPath: string]: string[]}
hoistPattern?: string
hoistPattern?: string[]
included: IncludedDependencies,
independentLeaves: boolean,
layoutVersion: number,

View File

@@ -43,14 +43,12 @@
"@pnpm/lockfile-file": "workspace:2.0.0-0",
"@pnpm/lockfile-utils": "workspace:1.0.10",
"@pnpm/types": "workspace:3.2.0",
"dependency-path": "workspace:3.0.8",
"micromatch": "4.0.2"
"dependency-path": "workspace:3.0.8"
},
"devDependencies": {
"@pnpm/logger": "2.1.1",
"@pnpm/outdated": "link:",
"@pnpm/registry-mock": "1.5.0",
"@types/micromatch": "3.1.0",
"npm-run-all": "4.1.5",
"tape": "4.11.0"
}

View File

@@ -11,7 +11,6 @@ import {
PackageManifest,
} from '@pnpm/types'
import * as dp from 'dependency-path'
import { isMatch } from 'micromatch'
export type GetLatestManifestFunction = (packageName: string) => Promise<PackageManifest | null>
@@ -24,43 +23,16 @@ export interface OutdatedPackage {
wanted: string,
}
export default async function (
export default async function outdated (
opts: {
currentLockfile: Lockfile | null,
match?: (dependencyName: string) => boolean,
manifest: ImporterManifest,
prefix: string,
getLatestManifest: GetLatestManifestFunction,
lockfileDirectory: string,
wantedLockfile: Lockfile,
},
) {
return _outdated([], opts)
}
export async function forPackages (
packages: string[],
opts: {
currentLockfile: Lockfile | null,
manifest: ImporterManifest,
prefix: string,
getLatestManifest: GetLatestManifestFunction,
lockfileDirectory: string,
wantedLockfile: Lockfile,
},
) {
return _outdated(packages, opts)
}
async function _outdated (
forPkgs: string[],
opts: {
manifest: ImporterManifest,
prefix: string,
currentLockfile: Lockfile | null,
getLatestManifest: GetLatestManifestFunction,
lockfileDirectory: string,
wantedLockfile: Lockfile,
},
): Promise<OutdatedPackage[]> {
if (packageHasNoDeps(opts.manifest)) return []
const importerId = getLockfileImporterId(opts.lockfileDirectory, opts.prefix)
@@ -74,8 +46,8 @@ async function _outdated (
let pkgs = Object.keys(opts.wantedLockfile.importers[importerId][depType]!)
if (forPkgs.length) {
pkgs = pkgs.filter((pkgName) => forPkgs.some((forPkg) => isMatch(pkgName, forPkg)))
if (opts.match) {
pkgs = pkgs.filter((pkgName) => opts.match!(pkgName))
}
await Promise.all(

View File

@@ -1,5 +1,5 @@
///<reference path="../../../typings/index.d.ts"/>
import outdated, { forPackages as outdatedForPackages } from '@pnpm/outdated'
import outdated from '@pnpm/outdated'
import test = require('tape')
async function getLatestManifest (packageName: string) {
@@ -232,124 +232,8 @@ test('outdated() should return deprecated package even if its current version is
t.end()
})
test('forPackages()', async (t) => {
const outdatedPkgs = await outdatedForPackages(['is-negative'], {
currentLockfile: {
importers: {
'.': {
dependencies: {
'from-github': 'github.com/blabla/from-github/d5f8d5500f7faf593d32e134c1b0043ff69151b4',
'is-negative': '1.0.0',
'is-positive': '1.0.0',
'linked-1': 'link:../linked-1',
'linked-2': 'file:../linked-2',
},
specifiers: {
'is-negative': '^2.1.0',
'is-positive': '^1.0.0',
},
},
},
lockfileVersion: 5,
packages: {
'/is-negative/2.1.0': {
resolution: {
integrity: 'sha1-8Nhjd6oVpkw0lh84rCqb4rQKEYc=',
},
},
'/is-positive/1.0.0': {
resolution: {
integrity: 'sha1-iACYVrZKLx632LsBeUGEJK4EUss=',
},
},
'github.com/blabla/from-github/d5f8d5500f7faf593d32e134c1b0043ff69151b4': {
name: 'from-github',
version: '1.1.0',
resolution: {
tarball: 'https://codeload.github.com/blabla/from-github/tar.gz/d5f8d5500f7faf593d32e134c1b0043ff69151b3',
},
},
},
},
getLatestManifest,
lockfileDirectory: 'wanted-shrinkwrap',
manifest: {
name: 'wanted-shrinkwrap',
version: '1.0.0',
dependencies: {
'is-negative': '^2.1.0',
'is-positive': '^3.1.0',
},
},
prefix: 'wanted-shrinkwrap',
wantedLockfile: {
importers: {
'.': {
dependencies: {
'from-github': 'github.com/blabla/from-github/d5f8d5500f7faf593d32e134c1b0043ff69151b3',
'from-github-2': 'github.com/blabla/from-github-2/d5f8d5500f7faf593d32e134c1b0043ff69151b3',
'is-negative': '1.1.0',
'is-positive': '3.1.0',
'linked-1': 'link:../linked-1',
'linked-2': 'file:../linked-2',
},
specifiers: {
'is-negative': '^2.1.0',
'is-positive': '^3.1.0',
},
},
},
lockfileVersion: 5,
packages: {
'/is-negative/1.1.0': {
resolution: {
integrity: 'sha1-8Nhjd6oVpkw0lh84rCqb4rQKEYc=',
},
},
'/is-positive/3.1.0': {
resolution: {
integrity: 'sha1-hX21hKG6XRyymAUn/DtsQ103sP0=',
},
},
'github.com/blabla/from-github-2/d5f8d5500f7faf593d32e134c1b0043ff69151b3': {
name: 'from-github-2',
version: '1.0.0',
resolution: {
tarball: 'https://codeload.github.com/blabla/from-github-2/tar.gz/d5f8d5500f7faf593d32e134c1b0043ff69151b3',
},
},
'github.com/blabla/from-github/d5f8d5500f7faf593d32e134c1b0043ff69151b3': {
name: 'from-github',
version: '1.0.0',
resolution: {
tarball: 'https://codeload.github.com/blabla/from-github/tar.gz/d5f8d5500f7faf593d32e134c1b0043ff69151b3',
},
},
},
},
})
t.deepEqual(outdatedPkgs, [
{
alias: 'is-negative',
belongsTo: 'dependencies',
current: '1.0.0',
latestManifest: {
name: 'is-negative',
version: '2.1.0',
},
packageName: 'is-negative',
wanted: '1.1.0',
},
])
t.end()
})
test('forPackages() by pattern', async (t) => {
const outdatedPkgs = await outdatedForPackages(['*-negative'], {
test('using a matcher', async (t) => {
const outdatedPkgs = await outdated({
currentLockfile: {
importers: {
'.': {
@@ -399,6 +283,7 @@ test('forPackages() by pattern', async (t) => {
'is-positive': '^3.1.0',
},
},
match: (dependencyName) => dependencyName === 'is-negative',
prefix: 'wanted-shrinkwrap',
wantedLockfile: {
importers: {

View File

@@ -33,6 +33,7 @@
"@pnpm/list": "workspace:3.0.0-3",
"@pnpm/lockfile-file": "workspace:2.0.0-0",
"@pnpm/logger": "2.1.1",
"@pnpm/matcher": "workspace:0.0.0",
"@pnpm/outdated": "workspace:5.0.0-0",
"@pnpm/package-is-installable": "workspace:2.2.1",
"@pnpm/package-store": "workspace:5.0.0-1",
@@ -73,7 +74,6 @@
"lru-cache": "5.1.1",
"make-dir": "3.0.0",
"mem": "5.1.1",
"micromatch": "4.0.2",
"mz": "2.7.0",
"nopt": "4.0.1",
"p-filter": "2.1.0",
@@ -106,7 +106,6 @@
"@pnpm/write-importer-manifest": "link:../write-importer-manifest",
"@types/byline": "4.2.31",
"@types/common-tags": "1.8.0",
"@types/micromatch": "3.1.0",
"@types/mkdirp": "0.5.2",
"@types/nopt": "3.0.29",
"@types/ramda": "0.26.21",

View File

@@ -4,9 +4,8 @@ import {
readCurrentLockfile,
readWantedLockfile,
} from '@pnpm/lockfile-file'
import outdated, {
forPackages as outdatedForPackages, OutdatedPackage,
} from '@pnpm/outdated'
import matcher from '@pnpm/matcher'
import outdated, { OutdatedPackage } from '@pnpm/outdated'
import semverDiff, { SEMVER_CHANGE } from '@pnpm/semver-diff'
import storePath from '@pnpm/store-path'
import { PackageJson, Registries } from '@pnpm/types'
@@ -283,19 +282,18 @@ export async function outdatedDependenciesOfWorkspacePackages (
store,
})
return Promise.all(pkgs.map(async ({ manifest, path }) => {
const optsForOutdated = {
currentLockfile,
getLatestManifest,
lockfileDirectory,
manifest,
prefix: path,
wantedLockfile,
}
let match = args.length && matcher(args) || undefined
return {
manifest,
outdatedPackages: args.length
? await outdatedForPackages(args, optsForOutdated)
: await outdated(optsForOutdated),
outdatedPackages: await outdated({
currentLockfile,
getLatestManifest,
lockfileDirectory,
manifest,
match,
prefix: path,
wantedLockfile,
}),
prefix: getLockfileImporterId(lockfileDirectory, path),
}
}))

View File

@@ -1,5 +1,5 @@
import matcher from '@pnpm/matcher'
import isSubdir = require('is-subdir')
import { matcher } from 'micromatch'
import { PackageNode } from 'pkgs-graph'
import R = require('ramda')
import { PackageSelector } from '../../parsePackageSelectors'

View File

@@ -43,7 +43,7 @@ test('linking multiple packages', async (t: tape.Test) => {
project.has('linked-bar')
const modules = await readYamlFile<object>('../linked-bar/node_modules/.modules.yaml')
t.equal(modules['hoistPattern'], '*', 'the linked package used its own configs during installation') // tslint:disable-line:no-string-literal
t.deepEqual(modules['hoistPattern'], ['*'], 'the linked package used its own configs during installation') // tslint:disable-line:no-string-literal
})
test('link global bin', async function (t: tape.Test) {

View File

@@ -253,7 +253,7 @@ test('recursive installation with package-specific .npmrc', async t => {
t.ok(projects['project-2'].requireModule('is-negative'))
const modulesYaml1 = await readYamlFile<{ hoistPattern: string }>(path.resolve('project-1', 'node_modules', '.modules.yaml'))
t.equal(modulesYaml1 && modulesYaml1.hoistPattern, '*')
t.deepEqual(modulesYaml1 && modulesYaml1.hoistPattern, ['*'])
const modulesYaml2 = await readYamlFile<{ hoistPattern: string }>(path.resolve('project-2', 'node_modules', '.modules.yaml'))
t.notOk(modulesYaml2 && modulesYaml2.hoistPattern)
@@ -296,7 +296,7 @@ test('workspace .npmrc is always read', async (t: tape.Test) => {
t.ok(projects['project-1'].requireModule('is-positive'))
const modulesYaml1 = await readYamlFile<{ hoistPattern: string }>(path.resolve('node_modules', '.modules.yaml'))
t.equal(modulesYaml1 && modulesYaml1.hoistPattern, '*')
t.deepEqual(modulesYaml1 && modulesYaml1.hoistPattern, ['*'])
process.chdir('..')
process.chdir('project-2')

View File

@@ -16,7 +16,7 @@ export default async function <T>(
importers: (ImporterOptions & T)[],
lockfileDirectory: string,
): Promise<{
currentHoistPattern?: string,
currentHoistPattern?: string[],
hoist?: boolean,
hoistedAliases: { [depPath: string]: string[] },
importers: Array<{

View File

@@ -32,6 +32,7 @@
"@pnpm/link-bins": "4.4.0",
"@pnpm/lockfile-file": "workspace:2.0.0-0",
"@pnpm/lockfile-utils": "workspace:1.0.10",
"@pnpm/matcher": "workspace:0.0.0",
"@pnpm/modules-cleaner": "workspace:5.0.0-2",
"@pnpm/modules-yaml": "workspace:4.0.0-1",
"@pnpm/package-requester": "workspace:8.0.0-0",

View File

@@ -16,6 +16,7 @@ import {
import rimraf = require('@zkochan/rimraf')
import makeDir = require('make-dir')
import path = require('path')
import R = require('ramda')
import checkCompatibility from './checkCompatibility'
import readLockfileFile from './readLockfiles'
@@ -34,7 +35,7 @@ export interface PnpmContext<T> {
modulesFile: Modules | null,
pendingBuilds: string[],
rootModulesDir: string,
hoistPattern: string | undefined,
hoistPattern: string[] | undefined,
hoistedModulesDir: string,
lockfileDirectory: string,
virtualStoreDir: string,
@@ -69,7 +70,7 @@ export default async function getContext<T> (
independentLeaves?: boolean,
forceIndependentLeaves?: boolean,
hoistPattern?: string | undefined,
hoistPattern?: string[] | undefined,
forceHoistPattern?: boolean,
shamefullyHoist?: boolean,
@@ -164,7 +165,7 @@ async function validateNodeModules (
prefix: string,
}>,
opts: {
currentHoistPattern?: string,
currentHoistPattern?: string[],
force: boolean,
include?: IncludedDependencies,
lockfileDirectory: string,
@@ -173,7 +174,7 @@ async function validateNodeModules (
independentLeaves?: boolean,
forceIndependentLeaves?: boolean,
hoistPattern?: string | undefined,
hoistPattern?: string[] | undefined,
forceHoistPattern?: boolean,
shamefullyHoist?: boolean | undefined,
@@ -220,7 +221,7 @@ async function validateNodeModules (
}
if (opts.forceHoistPattern && rootImporter) {
try {
if (opts.currentHoistPattern !== (opts.hoistPattern || undefined)) {
if (!R.equals(opts.currentHoistPattern, (opts.hoistPattern || undefined))) {
if (opts.currentHoistPattern) {
throw new PnpmError(
'HOISTING_WANTED',
@@ -287,7 +288,7 @@ export interface PnpmSingleContext {
extraBinPaths: string[],
hoistedAliases: {[depPath: string]: string[]},
hoistedModulesDir: string,
hoistPattern: string | undefined,
hoistPattern: string[] | undefined,
manifest: ImporterManifest,
modulesDir: string,
importerId: string,
@@ -322,7 +323,7 @@ export async function getContextForSingleImporter (
store: string,
useLockfile: boolean,
hoistPattern?: string | undefined,
hoistPattern?: string[] | undefined,
forceHoistPattern?: boolean,
shamefullyHoist?: boolean,

View File

@@ -62,7 +62,7 @@ export interface StrictInstallOptions {
bin: string,
prefix: string,
hoistPattern: string | undefined,
hoistPattern: string[] | undefined,
forceHoistPattern: boolean,
shamefullyHoist: boolean,

View File

@@ -14,6 +14,7 @@ import {
import hoist from '@pnpm/hoist'
import { Lockfile } from '@pnpm/lockfile-file'
import logger from '@pnpm/logger'
import matcher from '@pnpm/matcher'
import { prune } from '@pnpm/modules-cleaner'
import { IncludedDependencies } from '@pnpm/modules-yaml'
import { DependenciesTree, LinkedDependency } from '@pnpm/resolve-dependencies'
@@ -62,7 +63,7 @@ export default async function linkPackages (
force: boolean,
hoistedAliases: {[depPath: string]: string[]},
hoistedModulesDir: string,
hoistPattern?: string,
hoistPattern?: string[],
include: IncludedDependencies,
independentLeaves: boolean,
lockfileDirectory: string,
@@ -309,7 +310,7 @@ export default async function linkPackages (
if (newDepPaths.length > 0 || removedDepPaths.size > 0) {
const rootImporterWithFlatModules = opts.hoistPattern && importers.find(({ id }) => id === '.')
if (rootImporterWithFlatModules) {
newHoistedAliases = await hoist(opts.hoistPattern!, {
newHoistedAliases = await hoist(matcher(opts.hoistPattern!), {
getIndependentPackageLocation: opts.independentLeaves
? async (packageId: string, packageName: string) => {
const { directory } = await opts.storeController.getPackageLocation(packageId, packageName, {

View File

@@ -21,7 +21,7 @@ interface StrictLinkOptions {
store: string,
reporter: ReporterFunction,
hoistPattern: string | undefined,
hoistPattern: string[] | undefined,
forceHoistPattern: boolean,
shamefullyHoist: boolean,

View File

@@ -31,7 +31,6 @@ export interface StrictRebuildOptions {
},
unsafePerm: boolean,
pending: boolean,
hoistPattern: string | undefined,
shamefullyHoist: boolean,
}
@@ -51,7 +50,6 @@ const defaults = async (opts: RebuildOptions) => {
development: true,
force: false,
forceSharedLockfile: false,
hoistPattern: undefined,
lockfileDirectory,
optional: true,
packageManager,

View File

@@ -170,7 +170,7 @@ export async function rebuild (
await writeModulesYaml(ctx.rootModulesDir, {
...ctx.modulesFile,
hoistedAliases: ctx.hoistedAliases,
hoistPattern: opts.hoistPattern,
hoistPattern: ctx.hoistPattern,
included: ctx.include,
independentLeaves: ctx.independentLeaves,
layoutVersion: LAYOUT_VERSION,

60
pnpm-lock.yaml generated
View File

@@ -208,15 +208,11 @@ importers:
'@pnpm/types': 'link:../types'
'@pnpm/utils': 'link:../utils'
dependency-path: 'link:../dependency-path'
micromatch: 4.0.2
normalize-path: 3.0.0
resolve-link-target: 1.0.1
semver: 6.3.0
devDependencies:
'@pnpm/constants': 'link:../constants'
'@pnpm/logger': 2.1.1
'@types/micromatch': 3.1.0
'@types/semver': 6.0.2
dependencies-hierarchy: 'link:'
tape: 4.11.0
specifiers:
@@ -228,14 +224,10 @@ importers:
'@pnpm/read-modules-dir': 'workspace:2.0.1'
'@pnpm/types': 'workspace:3.2.0'
'@pnpm/utils': 'workspace:0.10.6'
'@types/micromatch': 3.1.0
'@types/semver': '6'
dependencies-hierarchy: 'link:'
dependency-path: 'workspace:3.0.8'
micromatch: 4.0.2
normalize-path: 3.0.0
resolve-link-target: 1.0.1
semver: 6.3.0
tape: 4.11.0
packages/dependency-path:
dependencies:
@@ -408,6 +400,7 @@ importers:
'@pnpm/link-bins': 4.4.0
'@pnpm/lockfile-file': 'link:../lockfile-file'
'@pnpm/lockfile-utils': 'link:../lockfile-utils'
'@pnpm/matcher': 'link:../matcher'
'@pnpm/modules-cleaner': 'link:../modules-cleaner'
'@pnpm/modules-yaml': 'link:../modules-yaml'
'@pnpm/package-requester': 'link:../package-requester'
@@ -465,6 +458,7 @@ importers:
'@pnpm/lockfile-file': 'workspace:2.0.0-0'
'@pnpm/lockfile-utils': 'workspace:1.0.10'
'@pnpm/logger': 2.1.1
'@pnpm/matcher': 'workspace:0.0.0'
'@pnpm/modules-cleaner': 'workspace:5.0.0-2'
'@pnpm/modules-yaml': 'workspace:4.0.0-1'
'@pnpm/package-requester': 'workspace:8.0.0-0'
@@ -510,11 +504,9 @@ importers:
'@pnpm/symlink-dependency': 'link:../symlink-dependency'
'@pnpm/types': 'link:../types'
dependency-path: 'link:../dependency-path'
micromatch: 4.0.2
ramda: 0.26.1
devDependencies:
'@pnpm/logger': 2.1.1
'@types/micromatch': 3.1.0
'@types/ramda': 0.26.21
rimraf: 3.0.0
specifiers:
@@ -526,10 +518,8 @@ importers:
'@pnpm/pkgid-to-filename': 2.0.0
'@pnpm/symlink-dependency': 'workspace:2.0.6'
'@pnpm/types': 'workspace:3.2.0'
'@types/micromatch': 3.1.0
'@types/ramda': 0.26.21
dependency-path: 'workspace:3.0.8'
micromatch: 4.0.2
ramda: 0.26.1
rimraf: 3.0.0
packages/lifecycle:
@@ -564,6 +554,7 @@ importers:
tape: 4.11.0
packages/list:
dependencies:
'@pnpm/matcher': 'link:../matcher'
'@pnpm/read-importer-manifest': 'link:../read-importer-manifest'
'@pnpm/read-package-json': 'link:../read-package-json'
'@pnpm/types': 'link:../types'
@@ -574,23 +565,27 @@ importers:
dependencies-hierarchy: 'link:../dependencies-hierarchy'
p-limit: 2.2.1
ramda: 0.26.1
semver: 6.3.0
devDependencies:
'@pnpm/list': 'link:'
'@pnpm/logger': 2.1.1
'@types/archy': 0.0.31
'@types/common-tags': 1.8.0
'@types/ramda': 0.26.21
'@types/semver': 6.0.2
common-tags: 1.8.0
tape: 4.11.0
specifiers:
'@pnpm/list': 'link:'
'@pnpm/logger': 2.1.1
'@pnpm/matcher': 'workspace:0.0.0'
'@pnpm/read-importer-manifest': 'workspace:1.0.9'
'@pnpm/read-package-json': 'workspace:2.0.3'
'@pnpm/types': 'workspace:3.2.0'
'@types/archy': 0.0.31
'@types/common-tags': 1.8.0
'@types/ramda': 0.26.21
'@types/semver': '6'
'@zkochan/npm-package-arg': 1.0.2
archy: 1.0.0
chalk: 2.4.2
@@ -599,6 +594,7 @@ importers:
dependencies-hierarchy: 'workspace:7.0.0-3'
p-limit: 2.2.1
ramda: 0.26.1
semver: 6.3.0
tape: 4.11.0
packages/local-resolver:
dependencies:
@@ -704,6 +700,18 @@ importers:
tempy: 0.3.0
write-yaml-file: 3.0.1
yaml-tag: 1.1.0
packages/matcher:
dependencies:
escape-string-regexp: 2.0.0
devDependencies:
'@pnpm/matcher': 'link:'
rimraf: 3.0.0
tape: 4.11.0
specifiers:
'@pnpm/matcher': 'link:'
escape-string-regexp: 2.0.0
rimraf: 3.0.0
tape: 4.11.0
packages/modules-cleaner:
dependencies:
'@pnpm/core-loggers': 'link:../core-loggers'
@@ -847,12 +855,10 @@ importers:
'@pnpm/lockfile-utils': 'link:../lockfile-utils'
'@pnpm/types': 'link:../types'
dependency-path: 'link:../dependency-path'
micromatch: 4.0.2
devDependencies:
'@pnpm/logger': 2.1.1
'@pnpm/outdated': 'link:'
'@pnpm/registry-mock': 1.5.0
'@types/micromatch': 3.1.0
npm-run-all: 4.1.5
tape: 4.11.0
specifiers:
@@ -863,9 +869,7 @@ importers:
'@pnpm/outdated': 'link:'
'@pnpm/registry-mock': 1.5.0
'@pnpm/types': 'workspace:3.2.0'
'@types/micromatch': 3.1.0
dependency-path: 'workspace:3.0.8'
micromatch: 4.0.2
npm-run-all: 4.1.5
tape: 4.11.0
packages/package-is-installable:
@@ -1076,6 +1080,7 @@ importers:
'@pnpm/list': 'link:../list'
'@pnpm/lockfile-file': 'link:../lockfile-file'
'@pnpm/logger': 2.1.1
'@pnpm/matcher': 'link:../matcher'
'@pnpm/outdated': 'link:../outdated'
'@pnpm/package-is-installable': 'link:../package-is-installable'
'@pnpm/package-store': 'link:../package-store'
@@ -1116,7 +1121,6 @@ importers:
lru-cache: 5.1.1
make-dir: 3.0.0
mem: 5.1.1
micromatch: 4.0.2
mz: 2.7.0
nopt: 4.0.1
p-filter: 2.1.0
@@ -1148,7 +1152,6 @@ importers:
'@pnpm/write-importer-manifest': 'link:../write-importer-manifest'
'@types/byline': 4.2.31
'@types/common-tags': 1.8.0
'@types/micromatch': 3.1.0
'@types/mkdirp': 0.5.2
'@types/nopt': 3.0.29
'@types/ramda': 0.26.21
@@ -1189,6 +1192,7 @@ importers:
'@pnpm/lockfile-file': 'workspace:2.0.0-0'
'@pnpm/lockfile-types': 1.1.0
'@pnpm/logger': 2.1.1
'@pnpm/matcher': 'workspace:0.0.0'
'@pnpm/modules-yaml': 'link:../modules-yaml'
'@pnpm/outdated': 'workspace:5.0.0-0'
'@pnpm/package-is-installable': 'workspace:2.2.1'
@@ -1208,7 +1212,6 @@ importers:
'@types/byline': 4.2.31
'@types/common-tags': 1.8.0
'@types/lru-cache': ^5.1.0
'@types/micromatch': 3.1.0
'@types/mkdirp': 0.5.2
'@types/mz': ^0.0.32
'@types/nopt': 3.0.29
@@ -1248,7 +1251,6 @@ importers:
lru-cache: 5.1.1
make-dir: 3.0.0
mem: 5.1.1
micromatch: 4.0.2
mz: 2.7.0
ncp: 2.0.0
nopt: 4.0.1
@@ -1511,6 +1513,7 @@ importers:
'@pnpm/link-bins': 4.4.0
'@pnpm/lockfile-file': 'link:../lockfile-file'
'@pnpm/lockfile-utils': 'link:../lockfile-utils'
'@pnpm/matcher': 'link:../matcher'
'@pnpm/modules-cleaner': 'link:../modules-cleaner'
'@pnpm/modules-yaml': 'link:../modules-yaml'
'@pnpm/package-requester': 'link:../package-requester'
@@ -1610,6 +1613,7 @@ importers:
'@pnpm/lockfile-file': 'workspace:2.0.0-0'
'@pnpm/lockfile-utils': 'workspace:1.0.10'
'@pnpm/logger': 2.1.1
'@pnpm/matcher': 'workspace:0.0.0'
'@pnpm/modules-cleaner': 'workspace:5.0.0-2'
'@pnpm/modules-yaml': 'workspace:4.0.0-1'
'@pnpm/package-requester': 'workspace:8.0.0-0'
@@ -2340,10 +2344,6 @@ packages:
/@types/archy/0.0.31:
resolution:
integrity: sha512-v+dxizsFVyXgD3EpFuqT9YjdEjbJmPxNf1QIX9ohZOhxh1ZF2yhqv3vYaeum9lg3VghhxS5S0a6yldN9J9lPEQ==
/@types/braces/3.0.0:
dev: true
resolution:
integrity: sha512-TbH79tcyi9FHwbyboOKeRachRq63mSuWYXOflsNO9ZyE5ClQ/JaozNKl+aWUq87qPNsXasXxi2AbgfwIJ+8GQw==
/@types/byline/4.2.31:
dependencies:
'@types/node': 12.7.11
@@ -2397,12 +2397,6 @@ packages:
/@types/lru-cache/5.1.0:
resolution:
integrity: sha512-RaE0B+14ToE4l6UqdarKPnXwVDuigfFv+5j9Dze/Nqr23yyuqdNvzcZi3xB+3Agvi5R4EOgAksfv3lXX4vBt9w==
/@types/micromatch/3.1.0:
dependencies:
'@types/braces': 3.0.0
dev: true
resolution:
integrity: sha512-06uA9V7v68RTOzA3ky1Oi0HmCPa+YJ050vM+sTECwkxnHUQnO17TAcNCGX400QT6bldUiPb7ux5oKy0j8ccEDw==
/@types/minimatch/3.0.3:
resolution:
integrity: sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
@@ -4379,6 +4373,12 @@ packages:
node: '>=0.8.0'
resolution:
integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
/escape-string-regexp/2.0.0:
dev: false
engines:
node: '>=8'
resolution:
integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==
/escodegen/1.12.0:
dependencies:
esprima: 3.1.3