Workspace discovery passed directory patterns to wax without the POSIX path normalization that pnpm11 receives from tinyglobby. This could omit projects from installs and recursive commands, or include projects a negation excluded. Add a POSIX normalization entry point to pnpm-fs, sharing the existing dot and parent-component reduction with native-path normalization. POSIX separators are interpreted consistently on every platform, preserving glob backslashes. Normalize each configured pattern before selecting the existing literal, one-level wildcard, or generic glob discovery path. Preserve the original pattern in invalid-glob diagnostics. The TypeScript implementation already normalizes these paths through tinyglobby. Add matching TypeScript regression coverage alongside Rust filesystem/discovery tests and a CLI install/list/recursive-script test. Fixes pnpm/pnpm#14571. --------- Co-authored-by: Zoltan Kochan <z@kochan.io>
73 lines
2.9 KiB
TypeScript
73 lines
2.9 KiB
TypeScript
import path from 'node:path'
|
|
|
|
import { expect, test } from '@jest/globals'
|
|
import { findPackages } from '@pnpm/workspace.projects-reader'
|
|
|
|
const root = path.join(import.meta.dirname, 'findPackages-fixtures/many-pkgs-2')
|
|
|
|
test.each([
|
|
'./components/component-1',
|
|
'././components/component-1/',
|
|
'./components/./component-1',
|
|
'components/./component-1',
|
|
'components/component-1/.',
|
|
'components//component-1',
|
|
'.//components/component-1',
|
|
'components/missing/../component-1',
|
|
])('normalizes literal pattern %s', async (pattern) => {
|
|
const projects = await findPackages(root, { patterns: [pattern], includeRoot: true })
|
|
expect(projects.map(({ manifest }) => manifest.name).sort()).toStrictEqual(['component-1', 'many-pkgs-2'])
|
|
})
|
|
|
|
test.each([
|
|
'./components/*',
|
|
'././components/*',
|
|
'./components/**',
|
|
'./components/{component-1,component-2}',
|
|
'components//./*',
|
|
'components/missing/../*',
|
|
])('normalizes glob pattern %s', async (pattern) => {
|
|
const projects = await findPackages(root, { patterns: [pattern], includeRoot: true })
|
|
expect(projects.map(({ manifest }) => manifest.name).sort()).toStrictEqual(['component-1', 'component-2', 'many-pkgs-2'])
|
|
})
|
|
|
|
test.each([
|
|
'!./components/component-1',
|
|
'!././components/component-1/',
|
|
'!components/./component-1',
|
|
'!./components//component-1',
|
|
'!components/missing/../component-1',
|
|
].flatMap((pattern) => ['components/*', './components/**'].map((include) => ({ include, pattern }))))('normalizes $pattern with $include', async ({ include, pattern }) => {
|
|
const projects = await findPackages(root, { patterns: [include, pattern], includeRoot: true })
|
|
expect(projects.map(({ manifest }) => manifest.name).sort()).toStrictEqual(['component-2', 'many-pkgs-2'])
|
|
})
|
|
|
|
test.each([
|
|
'./../many-pkgs-2/components/*',
|
|
'././../many-pkgs-2/components/*',
|
|
'../many-pkgs-2/components/missing/../*',
|
|
])('normalizes parent-relative pattern %s', async (pattern) => {
|
|
const projects = await findPackages(root, {
|
|
patterns: [pattern, '!./../many-pkgs-2/components/./component-1'],
|
|
includeRoot: true,
|
|
})
|
|
expect(projects.map(({ manifest }) => manifest.name).sort()).toStrictEqual(['component-2', 'many-pkgs-2'])
|
|
})
|
|
|
|
test('deduplicates normalized patterns and preserves the workspace root', async () => {
|
|
const projects = await findPackages(root, {
|
|
patterns: ['././', 'components/../', 'components/component-1', './components/./component-1'],
|
|
includeRoot: true,
|
|
})
|
|
expect(projects.map(({ manifest }) => manifest.name).sort()).toStrictEqual(['component-1', 'many-pkgs-2'])
|
|
})
|
|
|
|
test.each([
|
|
'!.',
|
|
'!./',
|
|
'!components/..',
|
|
])('drops negation %s that normalizes to the workspace root', async (pattern) => {
|
|
const projects = await findPackages(root, { patterns: ['components/*', pattern], includeRoot: true })
|
|
expect(projects.map(({ manifest }) => manifest.name).sort()).toStrictEqual(['component-1', 'component-2', 'many-pkgs-2'])
|
|
})
|