Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: print info if some of the filters don't match any projects #2337

Merged
merged 3 commits into from Feb 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
34 changes: 28 additions & 6 deletions packages/filter-workspace-packages/src/index.ts
Expand Up @@ -21,7 +21,7 @@ export async function readProjects (
pkgSelectors: PackageSelector[],
) {
const allProjects = await findWorkspacePackages(workspaceDir, {})
const selectedProjectsGraph = await filterPkgsBySelectorObjects(
const { selectedProjectsGraph } = await filterPkgsBySelectorObjects(
allProjects,
pkgSelectors,
{
Expand All @@ -38,7 +38,10 @@ export async function filterPackages<T> (
prefix: string,
workspaceDir: string,
},
): Promise<PackageGraph<T>> {
): Promise<{
selectedProjectsGraph: PackageGraph<T>,
unmatchedFilters: string[],
}> {
const packageSelectors = filter.
map((f) => parsePackageSelector(f, opts.prefix))

Expand All @@ -51,14 +54,17 @@ export async function filterPkgsBySelectorObjects<T> (
opts: {
workspaceDir: string,
},
): Promise<PackageGraph<T>> {
): Promise<{
selectedProjectsGraph: PackageGraph<T>,
unmatchedFilters: string[],
}> {
const { graph } = createPkgGraph<T>(pkgs)
if (packageSelectors && packageSelectors.length) {
return filterGraph(graph, packageSelectors, {
workspaceDir: opts.workspaceDir,
})
} else {
return graph
return { selectedProjectsGraph: graph, unmatchedFilters: [] }
}
}

Expand All @@ -68,11 +74,15 @@ export default async function filterGraph<T> (
opts: {
workspaceDir: string,
},
): Promise<PackageGraph<T>> {
): Promise<{
selectedProjectsGraph: PackageGraph<T>,
unmatchedFilters: string[],
}> {
const cherryPickedPackages = [] as string[]
const walkedDependencies = new Set<string>()
const walkedDependents = new Set<string>()
const graph = pkgGraphToGraph(pkgGraph)
const unmatchedFilters = [] as string[]
let reversedGraph: Graph | undefined
for (const selector of packageSelectors) {
let entryPackages: string[] | null = null
Expand All @@ -94,6 +104,15 @@ export default async function filterGraph<T> (
throw new Error(`Unsupported package selector: ${JSON.stringify(selector)}`)
}

if (entryPackages.length === 0) {
if (selector.namePattern) {
unmatchedFilters.push(selector.namePattern)
}
if (selector.parentDir) {
unmatchedFilters.push(selector.parentDir)
}
}

if (selector.includeDependencies) {
pickSubgraph(graph, entryPackages, walkedDependencies, { includeRoot: !selector.excludeSelf })
}
Expand All @@ -109,7 +128,10 @@ export default async function filterGraph<T> (
}
const walked = new Set([...walkedDependencies, ...walkedDependents])
cherryPickedPackages.forEach((cherryPickedPackage) => walked.add(cherryPickedPackage))
return R.pick(Array.from(walked), pkgGraph)
return {
selectedProjectsGraph: R.pick(Array.from(walked), pkgGraph),
unmatchedFilters,
}
}

function pkgGraphToGraph<T> (pkgGraph: PackageGraph<T>): Graph {
Expand Down
58 changes: 36 additions & 22 deletions packages/filter-workspace-packages/test/index.ts
Expand Up @@ -91,35 +91,35 @@ const PKGS_GRAPH: PackageGraph<{}> = {
}

test('select only package dependencies (excluding the package itself)', async (t) => {
const selection = await filterWorkspacePackages(PKGS_GRAPH, [
const { selectedProjectsGraph } = await filterWorkspacePackages(PKGS_GRAPH, [
{
excludeSelf: true,
includeDependencies: true,
namePattern: 'project-1',
},
], { workspaceDir: process.cwd() })

t.deepEqual(Object.keys(selection), ['/project-2', '/project-4'])
t.deepEqual(Object.keys(selectedProjectsGraph), ['/project-2', '/project-4'])

t.end()
})

test('select package with dependencies', async (t) => {
const selection = await filterWorkspacePackages(PKGS_GRAPH, [
const { selectedProjectsGraph } = await filterWorkspacePackages(PKGS_GRAPH, [
{
excludeSelf: false,
includeDependencies: true,
namePattern: 'project-1',
},
], { workspaceDir: process.cwd() })

t.deepEqual(Object.keys(selection), ['/packages/project-1', '/project-2', '/project-4'])
t.deepEqual(Object.keys(selectedProjectsGraph), ['/packages/project-1', '/project-2', '/project-4'])

t.end()
})

test('select package with dependencies and dependents', async (t) => {
const selection = await filterWorkspacePackages(PKGS_GRAPH, [
const { selectedProjectsGraph } = await filterWorkspacePackages(PKGS_GRAPH, [
{
excludeSelf: true,
includeDependencies: true,
Expand All @@ -128,41 +128,41 @@ test('select package with dependencies and dependents', async (t) => {
},
], { workspaceDir: process.cwd() })

t.deepEqual(Object.keys(selection), ['/project-2', '/project-4', '/packages/project-0'])
t.deepEqual(Object.keys(selectedProjectsGraph), ['/project-2', '/project-4', '/packages/project-0'])

t.end()
})

test('select package with dependents', async (t) => {
const selection = await filterWorkspacePackages(PKGS_GRAPH, [
const { selectedProjectsGraph } = await filterWorkspacePackages(PKGS_GRAPH, [
{
excludeSelf: false,
includeDependents: true,
namePattern: 'project-2',
},
], { workspaceDir: process.cwd() })

t.deepEqual(Object.keys(selection), ['/project-2', '/packages/project-1', '/packages/project-0'])
t.deepEqual(Object.keys(selectedProjectsGraph), ['/project-2', '/packages/project-1', '/packages/project-0'])

t.end()
})

test('select dependents excluding package itself', async (t) => {
const selection = await filterWorkspacePackages(PKGS_GRAPH, [
const { selectedProjectsGraph } = await filterWorkspacePackages(PKGS_GRAPH, [
{
excludeSelf: true,
includeDependents: true,
namePattern: 'project-2',
},
], { workspaceDir: process.cwd() })

t.deepEqual(Object.keys(selection), ['/packages/project-1', '/packages/project-0'])
t.deepEqual(Object.keys(selectedProjectsGraph), ['/packages/project-1', '/packages/project-0'])

t.end()
})

test('filter using two selectors: one selects dependencies another selects dependents', async (t) => {
const selection = await filterWorkspacePackages(PKGS_GRAPH, [
const { selectedProjectsGraph } = await filterWorkspacePackages(PKGS_GRAPH, [
{
excludeSelf: true,
includeDependents: true,
Expand All @@ -175,33 +175,33 @@ test('filter using two selectors: one selects dependencies another selects depen
},
], { workspaceDir: process.cwd() })

t.deepEqual(Object.keys(selection), ['/project-2', '/project-4', '/packages/project-1', '/packages/project-0'])
t.deepEqual(Object.keys(selectedProjectsGraph), ['/project-2', '/project-4', '/packages/project-1', '/packages/project-0'])

t.end()
})

test('select just a package by name', async (t) => {
const selection = await filterWorkspacePackages(PKGS_GRAPH, [
const { selectedProjectsGraph } = await filterWorkspacePackages(PKGS_GRAPH, [
{
excludeSelf: false,
namePattern: 'project-2',
},
], { workspaceDir: process.cwd() })

t.deepEqual(Object.keys(selection), ['/project-2'])
t.deepEqual(Object.keys(selectedProjectsGraph), ['/project-2'])

t.end()
})

test('select by parentDir', async (t) => {
const selection = await filterWorkspacePackages(PKGS_GRAPH, [
const { selectedProjectsGraph } = await filterWorkspacePackages(PKGS_GRAPH, [
{
excludeSelf: false,
parentDir: '/packages',
},
], { workspaceDir: process.cwd() })

t.deepEqual(Object.keys(selection), ['/packages/project-0', '/packages/project-1'])
t.deepEqual(Object.keys(selectedProjectsGraph), ['/packages/project-0', '/packages/project-1'])

t.end()
})
Expand Down Expand Up @@ -275,27 +275,27 @@ test('select changed packages', async (t) => {
}

{
const selection = await filterWorkspacePackages(pkgsGraph, [{
const { selectedProjectsGraph } = await filterWorkspacePackages(pkgsGraph, [{
diff: 'HEAD~1',
}], { workspaceDir })

t.deepEqual(Object.keys(selection), [pkg1Dir, pkg2Dir])
t.deepEqual(Object.keys(selectedProjectsGraph), [pkg1Dir, pkg2Dir])
}
{
const selection = await filterWorkspacePackages(pkgsGraph, [{
const { selectedProjectsGraph } = await filterWorkspacePackages(pkgsGraph, [{
diff: 'HEAD~1',
parentDir: pkg2Dir,
}], { workspaceDir })

t.deepEqual(Object.keys(selection), [pkg2Dir])
t.deepEqual(Object.keys(selectedProjectsGraph), [pkg2Dir])
}
{
const selection = await filterWorkspacePackages(pkgsGraph, [{
const { selectedProjectsGraph } = await filterWorkspacePackages(pkgsGraph, [{
diff: 'HEAD~1',
namePattern: 'package-2*',
}], { workspaceDir })

t.deepEqual(Object.keys(selection), [pkg2Dir])
t.deepEqual(Object.keys(selectedProjectsGraph), [pkg2Dir])
}

t.end()
Expand All @@ -313,3 +313,17 @@ test('selection should fail when diffing to a branch that does not exist', async
t.equal(err.message, "Filtering by changed packages failed. fatal: bad revision 'branch-does-no-exist'")
t.end()
})

test('should return unmatched filters', async (t) => {
const { unmatchedFilters } = await filterWorkspacePackages(PKGS_GRAPH, [
{
excludeSelf: true,
includeDependencies: true,
namePattern: 'project-5',
},
], { workspaceDir: process.cwd() })

t.deepEqual(unmatchedFilters, ['project-5'])

t.end()
})
2 changes: 1 addition & 1 deletion packages/plugin-commands-installation/src/installDeps.ts
Expand Up @@ -209,7 +209,7 @@ export default async function handler (

if (opts.linkWorkspacePackages && opts.workspaceDir) {
allProjects = allProjects ?? await findWorkspacePackages(opts.workspaceDir, opts)
const selectedProjectsGraph = await filterPkgsBySelectorObjects(allProjects, [
const { selectedProjectsGraph } = await filterPkgsBySelectorObjects(allProjects, [
{
excludeSelf: true,
includeDependencies: true,
Expand Down
22 changes: 12 additions & 10 deletions packages/plugin-commands-script-runners/test/runRecursive.ts
Expand Up @@ -270,16 +270,17 @@ test('`pnpm recursive run` succeeds when run against a subset of packages and no
'--store-dir',
path.resolve(DEFAULT_OPTS.storeDir),
])
const { selectedProjectsGraph } = await filterPkgsBySelectorObjects(
allProjects,
[{ namePattern: 'project-1' }],
{ workspaceDir: process.cwd() },
)
await run.handler(['this-command-does-not-exist'], {
...DEFAULT_OPTS,
allProjects,
dir: process.cwd(),
recursive: true,
selectedProjectsGraph: await filterPkgsBySelectorObjects(
allProjects,
[{ namePattern: 'project-1' }],
{ workspaceDir: process.cwd() },
),
selectedProjectsGraph,
workspaceDir: process.cwd(),
})
t.end()
Expand Down Expand Up @@ -402,6 +403,11 @@ test('pnpm recursive run with filtering', async (t) => {
])

const { allProjects } = await readProjects(process.cwd(), [])
const { selectedProjectsGraph } = await filterPkgsBySelectorObjects(
allProjects,
[{ namePattern: 'project-1' }],
{ workspaceDir: process.cwd() },
)
await execa('pnpm', [
'install',
'-r',
Expand All @@ -415,11 +421,7 @@ test('pnpm recursive run with filtering', async (t) => {
allProjects,
dir: process.cwd(),
recursive: true,
selectedProjectsGraph: await filterPkgsBySelectorObjects(
allProjects,
[{ namePattern: 'project-1' }],
{ workspaceDir: process.cwd() },
),
selectedProjectsGraph,
workspaceDir: process.cwd(),
})

Expand Down
11 changes: 6 additions & 5 deletions packages/plugin-commands-script-runners/test/testRecursive.ts
Expand Up @@ -158,6 +158,11 @@ test('pnpm recursive test with filtering', async (t) => {
])

const { allProjects } = await readProjects(process.cwd(), [])
const { selectedProjectsGraph } = await filterPkgsBySelectorObjects(
allProjects,
[{ namePattern: 'project-1' }],
{ workspaceDir: process.cwd() },
)
await execa('pnpm', [
'install',
'-r',
Expand All @@ -171,11 +176,7 @@ test('pnpm recursive test with filtering', async (t) => {
allProjects,
dir: process.cwd(),
recursive: true,
selectedProjectsGraph: await filterPkgsBySelectorObjects(
allProjects,
[{ namePattern: 'project-1' }],
{ workspaceDir: process.cwd() },
),
selectedProjectsGraph,
workspaceDir: process.cwd(),
})

Expand Down
10 changes: 9 additions & 1 deletion packages/pnpm/src/main.ts
Expand Up @@ -124,17 +124,25 @@ export default async function run (inputArgv: string[]) {
process.exit(0)
return
}
config.selectedProjectsGraph = await filterPackages(allProjects, config.filter ?? [], {
const filterResults = await filterPackages(allProjects, config.filter ?? [], {
prefix: process.cwd(),
workspaceDir: wsDir,
})
config.selectedProjectsGraph = filterResults.selectedProjectsGraph
if (R.isEmpty(config.selectedProjectsGraph)) {
if (!config['parseable']) {
console.log(`No projects matched the filters in "${wsDir}"`)
}
process.exit(0)
return
yaodingyd marked this conversation as resolved.
Show resolved Hide resolved
}
if (filterResults.unmatchedFilters.length !== 0) {
if (!config['parseable']) {
console.log(`No projects matched the filters "${filterResults.unmatchedFilters.join(', ')}" in "${wsDir}"`)
}
process.exit(0)
return
}
config.allProjects = allProjects
config.workspaceDir = wsDir
}
Expand Down