@vzn/vx 0.0.325 → 0.0.326
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -5
- package/src/workspace/filter.ts +31 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vzn/vx",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.326",
|
|
4
4
|
"description": "A fast, correct task runner and build cache for JavaScript monorepos.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
"node": ">=18"
|
|
22
22
|
},
|
|
23
23
|
"optionalDependencies": {
|
|
24
|
-
"@vzn/vx-linux-x64": "0.0.
|
|
25
|
-
"@vzn/vx-linux-arm64": "0.0.
|
|
26
|
-
"@vzn/vx-darwin-x64": "0.0.
|
|
27
|
-
"@vzn/vx-darwin-arm64": "0.0.
|
|
24
|
+
"@vzn/vx-linux-x64": "0.0.326",
|
|
25
|
+
"@vzn/vx-linux-arm64": "0.0.326",
|
|
26
|
+
"@vzn/vx-darwin-x64": "0.0.326",
|
|
27
|
+
"@vzn/vx-darwin-arm64": "0.0.326"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@anthropic-ai/sandbox-runtime": "^0.0.76"
|
package/src/workspace/filter.ts
CHANGED
|
@@ -41,6 +41,12 @@ export interface ParsedFilter {
|
|
|
41
41
|
* concrete set of project names before calling applyFilters.
|
|
42
42
|
*/
|
|
43
43
|
gitSince?: string
|
|
44
|
+
/**
|
|
45
|
+
* `<name>...[<since>]`: the named packages that changed OR depend on one
|
|
46
|
+
* that did, as Turbo reads it (2.5.8: `@acme/api...[HEAD]` is api when
|
|
47
|
+
* only its dependency db changed). Not a walk: no dependency is added.
|
|
48
|
+
*/
|
|
49
|
+
sinceViaDeps?: true
|
|
44
50
|
/** A path form carrying a glob (`./packages/*`): matched over the root-relative project dir. */
|
|
45
51
|
pathGlob?: Bun.Glob
|
|
46
52
|
/** The workspace root `pathGlob` is relative to. */
|
|
@@ -94,9 +100,16 @@ export function parseFilter(raw: string, workspaceRoot: string): ParsedFilter {
|
|
|
94
100
|
// An unbraced path keeps its brackets: `./packages/[abc]` is a glob
|
|
95
101
|
// class, and Turbo takes a directory with a ref only as `{dir}[ref]`.
|
|
96
102
|
const scoped = /^(.+)\[([^\]]+)\]$/.exec(s)
|
|
103
|
+
let sinceViaDeps = false
|
|
97
104
|
if (scoped !== null && !scoped[1]!.startsWith('./') && scoped[1] !== '.') {
|
|
98
105
|
s = scoped[1]!
|
|
99
106
|
gitSince = scoped[2]!
|
|
107
|
+
// The name glob kept the `...` and matched nothing (create-t3-turbo,
|
|
108
|
+
// `@acme/*...[HEAD]`).
|
|
109
|
+
if (s.endsWith('...') && !s.endsWith('^...')) {
|
|
110
|
+
s = s.slice(0, -3)
|
|
111
|
+
sinceViaDeps = true
|
|
112
|
+
}
|
|
100
113
|
}
|
|
101
114
|
|
|
102
115
|
// `...`, `!`, `^...`: the operators with no project between them. An
|
|
@@ -122,6 +135,7 @@ export function parseFilter(raw: string, workspaceRoot: string): ParsedFilter {
|
|
|
122
135
|
matcher: path.resolve(workspaceRoot),
|
|
123
136
|
exactDir: true,
|
|
124
137
|
...(gitSince !== undefined ? { gitSince } : {}),
|
|
138
|
+
...(sinceViaDeps ? { sinceViaDeps: true as const } : {}),
|
|
125
139
|
}
|
|
126
140
|
}
|
|
127
141
|
|
|
@@ -158,6 +172,7 @@ export function parseFilter(raw: string, workspaceRoot: string): ParsedFilter {
|
|
|
158
172
|
matcher,
|
|
159
173
|
...(pathGlob !== undefined ? { pathGlob, pathRoot: workspaceRoot } : {}),
|
|
160
174
|
...(gitSince !== undefined ? { gitSince } : {}),
|
|
175
|
+
...(sinceViaDeps ? { sinceViaDeps: true as const } : {}),
|
|
161
176
|
}
|
|
162
177
|
}
|
|
163
178
|
|
|
@@ -165,12 +180,18 @@ function matchProjects(
|
|
|
165
180
|
filter: ParsedFilter,
|
|
166
181
|
projects: ProjectMeta[],
|
|
167
182
|
affectedByFilter: Map<ParsedFilter, Set<string>> | undefined,
|
|
183
|
+
graph: PackageGraph,
|
|
168
184
|
): string[] {
|
|
169
185
|
// `[<since>]` selectors are pre-resolved by the caller (the parser
|
|
170
186
|
// is pure; git access happens upstream). Use the provided set as
|
|
171
187
|
// the match set for this filter.
|
|
172
188
|
if (filter.gitSince !== undefined) {
|
|
173
|
-
|
|
189
|
+
let changed = affectedByFilter?.get(filter) ?? new Set<string>()
|
|
190
|
+
if (filter.sinceViaDeps === true) {
|
|
191
|
+
changed = new Set(changed)
|
|
192
|
+
for (const name of [...changed])
|
|
193
|
+
for (const d of graph.transitiveDependents(name)) changed.add(d)
|
|
194
|
+
}
|
|
174
195
|
if (filter.matcher === '') return [...changed]
|
|
175
196
|
return matchSelector(filter, projects).filter((name) => changed.has(name))
|
|
176
197
|
}
|
|
@@ -268,7 +289,7 @@ export function applyFilters(opts: ApplyFiltersOptions): Set<string> {
|
|
|
268
289
|
// taken in argv order, so `onNoMatch` names the filters as typed.
|
|
269
290
|
const excludes: Set<string>[] = []
|
|
270
291
|
for (const f of opts.filters) {
|
|
271
|
-
const matched = matchProjects(f, opts.projects, opts.affectedByFilter)
|
|
292
|
+
const matched = matchProjects(f, opts.projects, opts.affectedByFilter, opts.graph)
|
|
272
293
|
if (matched.length === 0) opts.onNoMatch?.(f)
|
|
273
294
|
const expanded = new Set<string>()
|
|
274
295
|
for (const name of matched) {
|
|
@@ -277,7 +298,14 @@ export function applyFilters(opts: ApplyFiltersOptions): Set<string> {
|
|
|
277
298
|
for (const d of opts.graph.transitiveDeps(name)) expanded.add(d)
|
|
278
299
|
}
|
|
279
300
|
if (f.withDependents) {
|
|
280
|
-
|
|
301
|
+
// Both walks: the dependents' own dependencies too, as Turbo 2.5.8
|
|
302
|
+
// selects (`...db...` on create-t3-turbo ran the ui and validators
|
|
303
|
+
// its apps build on; vx ran db's dependencies alone).
|
|
304
|
+
const both = f.withDeps || f.onlyDeps
|
|
305
|
+
for (const d of opts.graph.transitiveDependents(name)) {
|
|
306
|
+
expanded.add(d)
|
|
307
|
+
if (both) for (const dd of opts.graph.transitiveDeps(d)) expanded.add(dd)
|
|
308
|
+
}
|
|
281
309
|
}
|
|
282
310
|
}
|
|
283
311
|
if (matched.length > 0 && expanded.size === 0) opts.onEmptyWalk?.(f, matched)
|