diff --git a/README.md b/README.md index 55573555..e0575107 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,10 @@ $ ultra -r --filter "apps/*" pwd ... ``` +When the filter is prefixed with a `+`, then all dependencies of the filtered packages will also be included. +For example, let's say you have a package "app1" that depends on "lib1", then using the filter `+app1`, will execute the command +on both `app1` **and** `lib1`, using the workspace topology. + ## :package: Builds `Ultra` automatically detects workspace dependencies, while still allowing parallel builds. Packages are build concurrently as soon as their dependencies are build (also concurrently). diff --git a/src/options.ts b/src/options.ts index 279f733c..24923efc 100644 --- a/src/options.ts +++ b/src/options.ts @@ -66,7 +66,8 @@ export const RunnerOptionDefs: Record = { }, filter: { type: "string", - description: "Filter package name or directory using wildcard pattern", + description: + "Filter package name or directory using wildcard pattern. Prefix the filter with '+' to always include dependencies.", }, root: { type: "boolean", diff --git a/src/workspace.ts b/src/workspace.ts index efddfdc6..153af2d4 100644 --- a/src/workspace.ts +++ b/src/workspace.ts @@ -118,12 +118,20 @@ export class Workspace { let ret = [...this.packages.values()] if (filter) { + const withDeps = filter.startsWith("+") + if (withDeps) filter = filter.slice(1) const regex: RegExp = globrex(filter, { filepath: true }).regex - ret = ret.filter( - (p) => + const names = new Set() + ret.forEach((p) => { + if ( regex.test(p.name || "") || regex.test(path.relative(this.root, p.root).replace(/\\/gu, "/")) - ) + ) { + names.add(p.name) + if (withDeps) this.getDepTree(p.name).forEach((dep) => names.add(dep)) + } + }) + ret = ret.filter((p) => names.has(p.name)) } return ret.sort( (a, b) => this.order.indexOf(a.name) - this.order.indexOf(b.name)