@blzsky/variant 0.2.1 → 0.3.0-canary.0
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/README.md +110 -56
- package/dist/{build-3DSBMMI3.js → build-GKWNLU4Q.js} +9 -8
- package/dist/{check-SIQJU6Z2.js → check-KO5VY67Z.js} +6 -6
- package/dist/{chunk-FA64KWJ2.js → chunk-7NC7AO75.js} +15 -28
- package/dist/{chunk-VYWPQKMS.js → chunk-ACTY42RE.js} +20 -0
- package/dist/{chunk-ZH2PQUNL.js → chunk-CN25SRKD.js} +6 -6
- package/dist/{chunk-43VLELTL.js → chunk-CWF6QXEW.js} +1 -1
- package/dist/{chunk-7OPTWU6E.js → chunk-DMDAJPFJ.js} +1 -1
- package/dist/{chunk-RC23JQKI.js → chunk-DSQDMFQ6.js} +9 -1
- package/dist/chunk-H5C4SE73.js +184 -0
- package/dist/chunk-IFFZ46YS.js +575 -0
- package/dist/chunk-IHXJ72XA.js +31 -0
- package/dist/chunk-KCEGA56S.js +670 -0
- package/dist/{chunk-FZEXZBXB.js → chunk-MAK3HG46.js} +41 -9
- package/dist/chunk-MT4BOAAV.js +167 -0
- package/dist/{chunk-TCISS2AS.js → chunk-NFFXYYM6.js} +120 -25
- package/dist/{chunk-26DHEXGS.js → chunk-RJBFCURK.js} +1 -1
- package/dist/{chunk-6BXSZPHC.js → chunk-RSIOYQOQ.js} +67 -8
- package/dist/chunk-SGP5JX6I.js +377 -0
- package/dist/chunk-X3VVGTEV.js +268 -0
- package/dist/{chunk-Q7RLUZSN.js → chunk-YII4TAKS.js} +10 -3
- package/dist/cli.js +62 -27
- package/dist/{diff-HSJBZFMC.js → diff-A3TQWWUJ.js} +5 -5
- package/dist/{doctor-B7MHFIYJ.js → doctor-6ONS6LKY.js} +4 -4
- package/dist/{env-I7JZRWDN.js → env-XF2US3CB.js} +6 -6
- package/dist/git-W6N3WMYQ.js +24 -0
- package/dist/impact-DPZIAJR4.js +263 -0
- package/dist/index.js +2 -2
- package/dist/init-VNK5E4H3.js +777 -0
- package/dist/{insight-JQLTGFYB.js → insight-LNYVMCAE.js} +7 -7
- package/dist/pr-6CYMM2XU.js +707 -0
- package/dist/{run-C6VAQOVM.js → run-44PKMOV5.js} +9 -8
- package/dist/{symbol-graph-E5GXKDFZ.js → symbol-graph-OB4AJCLW.js} +3 -3
- package/dist/{tsconfig-paths-E3UEDGXZ.js → tsconfig-paths-SV3PULCW.js} +3 -1
- package/dist/vitest.cjs +629 -0
- package/dist/vitest.d.cts +181 -0
- package/dist/vitest.d.ts +181 -0
- package/dist/vitest.js +356 -0
- package/dist/workspace-PIQXG4ZD.js +65 -0
- package/package.json +13 -2
- package/dist/chunk-DRMASVYN.js +0 -25
- package/dist/chunk-KSHWC2XN.js +0 -78
- package/dist/chunk-XTYVVUWW.js +0 -279
- package/dist/impact-PRZ6HEP5.js +0 -735
- package/dist/init-O2BY3FOY.js +0 -158
- package/dist/pr-Y724QAHE.js +0 -165
- package/dist/workspace-HRTFGWKN.js +0 -186
package/README.md
CHANGED
|
@@ -8,56 +8,68 @@
|
|
|
8
8
|
|
|
9
9
|
## What is variant?
|
|
10
10
|
|
|
11
|
-
variant
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
variant answers one question about a change to a TypeScript repository: what
|
|
12
|
+
has to be verified before this is safe to merge?
|
|
13
|
+
|
|
14
|
+
It reads the diff at the level of the syntax tree, not the line, follows every
|
|
15
|
+
import across workspace packages, and says, on the pull request:
|
|
16
|
+
|
|
17
|
+
- how risky each changed file is, and why;
|
|
18
|
+
- which test files reach the change, with the import chain from each test to
|
|
19
|
+
the file that changed;
|
|
20
|
+
- which typecheck, build and lint commands apply to the packages it affects;
|
|
21
|
+
- which changed files no test reaches at all.
|
|
22
|
+
|
|
23
|
+
You set it up once. After that nobody types a variant command: your own test
|
|
24
|
+
command and your pull requests are the interface.
|
|
16
25
|
|
|
17
26
|
```bash
|
|
18
|
-
npx @blzsky/variant
|
|
27
|
+
npx @blzsky/variant init
|
|
19
28
|
```
|
|
20
29
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
30
|
+
`init` finds out how the repository installs, tests and runs CI, shows every
|
|
31
|
+
change it would make as a diff, and makes them when you agree. It adds one
|
|
32
|
+
line to your Vitest config and one workflow that keeps a comment on each pull
|
|
33
|
+
request.
|
|
34
|
+
|
|
35
|
+
It does not skip tests. Your full suite runs as it always did; in CI variant
|
|
36
|
+
predicts beside it which test files the change needs, then checks that
|
|
37
|
+
prediction against what failed and prints one line:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
variant: predicted 8 of 55 test files (high). 2 failed, all predicted.
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Leaving tests out is something variant has to earn in each repository, from
|
|
44
|
+
that record, and is not built yet.
|
|
24
45
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
The same analysis powers `pr check`, which rolls a branch's changes into one
|
|
37
|
-
build verdict for a pull request comment, and `workspace check`, which fails CI
|
|
38
|
-
when a package imports something it never declared.
|
|
39
|
-
|
|
40
|
-
> **Status**: `0.x`, report-only. `impact`, `impact verify`, `diff`,
|
|
41
|
-
> `pr check`, `pr report` and `workspace check` work today and are where
|
|
42
|
-
> development happens. Test skipping is **not implemented**, deliberately, and
|
|
43
|
-
> will not be until the false-skip rate is measured on real repositories; see
|
|
44
|
-
> [Help measure it](#help-measure-it). The task runner underneath (`build`,
|
|
45
|
-
> `run`, `insight`) works but is frozen. Any minor release can break, and every
|
|
46
|
-
> break is in the [CHANGELOG](./CHANGELOG.md).
|
|
46
|
+
> **Status**: `0.x`. What is described here is published as a canary,
|
|
47
|
+
> `0.3.0-canary.0`, under the `canary` tag: write `@blzsky/variant@canary`
|
|
48
|
+
> wherever this page says `@blzsky/variant`. Without the tag npm serves
|
|
49
|
+
> 0.2.1, which has `impact`, `pr check`, `pr report` and `workspace check`,
|
|
50
|
+
> an `init` that only writes a task-runner config, and no adapter. The
|
|
51
|
+
> adapter is for Vitest; a Jest repository gets the pull request report
|
|
52
|
+
> only. Test skipping is **not implemented**, deliberately.
|
|
53
|
+
> The task runner underneath (`build`, `run`, `insight`) works but is frozen.
|
|
54
|
+
> Any minor release can break, and every break is in the
|
|
55
|
+
> [CHANGELOG](./CHANGELOG.md).
|
|
47
56
|
|
|
48
57
|
## Install
|
|
49
58
|
|
|
50
|
-
variant needs Node 20 or newer and a git repository
|
|
51
|
-
before the one you are checking. There is nothing to configure.
|
|
59
|
+
variant needs Node 20 or newer and a git repository.
|
|
52
60
|
|
|
53
61
|
```bash
|
|
54
|
-
#
|
|
55
|
-
npx @blzsky/variant
|
|
56
|
-
|
|
57
|
-
# keep it in a project
|
|
58
|
-
npm install -D @blzsky/variant # or pnpm add -D / yarn add -D
|
|
62
|
+
npx @blzsky/variant init # shows the changes, asks, then applies
|
|
63
|
+
npx @blzsky/variant init --dry-run # only look
|
|
59
64
|
```
|
|
60
65
|
|
|
66
|
+
`init` installs `@blzsky/variant` as a dev dependency with your package
|
|
67
|
+
manager (npm, pnpm, Yarn or Bun), adds the
|
|
68
|
+
[Vitest adapter](./docs/vitest-adapter.md) to your test config, ignores
|
|
69
|
+
`.variant/`, gives your test workflow's checkout the history a prediction
|
|
70
|
+
needs, and writes `.github/workflows/variant.yml`. Anything it cannot edit
|
|
71
|
+
with confidence it leaves alone and tells you the lines to add.
|
|
72
|
+
|
|
61
73
|
The package is `@blzsky/variant`; the binary it installs is `variant`.
|
|
62
74
|
`npx variant` fetches an unrelated package, so always use the scope with `npx`.
|
|
63
75
|
|
|
@@ -67,26 +79,43 @@ The package is `@blzsky/variant`; the binary it installs is `variant`.
|
|
|
67
79
|
npm install -D @blzsky/variant@latest
|
|
68
80
|
```
|
|
69
81
|
|
|
70
|
-
Because variant is `0.x`,
|
|
71
|
-
|
|
82
|
+
Because variant is `0.x`, read the CHANGELOG before moving to a new minor
|
|
83
|
+
version.
|
|
72
84
|
|
|
73
85
|
## Usage
|
|
74
86
|
|
|
87
|
+
After `init` there is nothing to run. What you see:
|
|
88
|
+
|
|
89
|
+
- **On every pull request**, one comment, kept up to date: the risk of each
|
|
90
|
+
changed file, the tests to run and why, the checks, and what is not
|
|
91
|
+
verified. [An example](./docs/api.md#pr-report).
|
|
92
|
+
- **In every CI test run**, one line saying what was predicted and whether a
|
|
93
|
+
failure fell outside it.
|
|
94
|
+
|
|
95
|
+
The first runs after setup select every test, because the setup itself changes
|
|
96
|
+
the lockfile and the test config. Narrowed predictions start with the next
|
|
97
|
+
pull request.
|
|
98
|
+
|
|
99
|
+
The commands underneath are still there when you want them:
|
|
100
|
+
|
|
75
101
|
```bash
|
|
76
|
-
variant
|
|
77
|
-
|
|
78
|
-
variant impact verify report.json # did the prediction miss a failure?
|
|
79
|
-
variant pr check --base origin/main # one build verdict for the branch
|
|
102
|
+
variant pr report --markdown # the pull request comment, locally
|
|
103
|
+
variant impact # which tests does this change need?
|
|
80
104
|
variant workspace check # undeclared dependencies (exits 1)
|
|
81
105
|
```
|
|
82
106
|
|
|
107
|
+
<p align="center">
|
|
108
|
+
<img alt="Running `variant impact --base main` after changing formatPrice's signature and documenting slugify: price.ts is breaking, slug.ts is non-impacting, 2 of 4 test files run" src="./docs/assets/impact.gif" width="840">
|
|
109
|
+
</p>
|
|
110
|
+
|
|
83
111
|
| Command | What it does |
|
|
84
112
|
|---|---|
|
|
85
113
|
| `impact` | Predict which test files a change requires, and how much of the import graph resolved. Report-only. |
|
|
86
|
-
| `impact verify <report
|
|
114
|
+
| `impact verify <report...>` | Reconcile the last prediction against one or more Vitest or Jest JSON reports and report false skips |
|
|
87
115
|
| `diff <file>` | Classify one file's change and list the exported symbols that changed |
|
|
116
|
+
| `init` | Set a repository up: the dependency, the adapter, the workflow. Once. |
|
|
88
117
|
| `pr check` | Classify every TypeScript change on the branch and roll them into one build verdict |
|
|
89
|
-
| `pr report` |
|
|
118
|
+
| `pr report` | What the branch changes and what has to be verified, as JSON or as markdown for a PR comment |
|
|
90
119
|
| `workspace check` | Fail when a package imports a dependency it does not declare |
|
|
91
120
|
|
|
92
121
|
Run `variant <command> --help` for its flags, or see the
|
|
@@ -103,7 +132,9 @@ setup file selects every test.
|
|
|
103
132
|
|
|
104
133
|
### In CI
|
|
105
134
|
|
|
106
|
-
|
|
135
|
+
`init` writes what CI needs. To wire the commands in by hand: check out
|
|
136
|
+
with `fetch-depth: 0`; the base is detected on GitHub Actions, and elsewhere
|
|
137
|
+
pass `--base origin/<branch>`. A shallow
|
|
107
138
|
clone has no base commit to compare against, and `actions/checkout` creates no
|
|
108
139
|
local branch for the target; variant stops with `GIT_REF_ERROR` rather than
|
|
109
140
|
guess.
|
|
@@ -117,6 +148,9 @@ Ready-to-copy GitHub Actions workflows are in
|
|
|
117
148
|
the build on an undeclared dependency.
|
|
118
149
|
- [`impact-shadow.yml`](./examples/github-actions/impact-shadow.yml) logs a
|
|
119
150
|
prediction, runs the full suite anyway, and reconciles the two.
|
|
151
|
+
- [`impact-shadow-workspace.yml`](./examples/github-actions/impact-shadow-workspace.yml)
|
|
152
|
+
does the same for a pnpm workspace that tests each package on its own. It
|
|
153
|
+
needs a release newer than 0.2.1.
|
|
120
154
|
|
|
121
155
|
### Help measure it
|
|
122
156
|
|
|
@@ -128,7 +162,8 @@ If you add `impact-shadow.yml` to your CI, it changes nothing about your build.
|
|
|
128
162
|
It uploads the counts as a `variant-reconciliation` artifact: commit SHAs,
|
|
129
163
|
branch names and numbers, no file paths and no source.
|
|
130
164
|
[Share them in an issue](https://github.com/saintparish4/variant/issues/new?template=3.shadow_results.yml),
|
|
131
|
-
and they go into the measurement that decides whether skipping ever ships.
|
|
165
|
+
and they go into the measurement that decides whether skipping ever ships. The
|
|
166
|
+
[measurement log](./docs/measurement.md) has every number collected so far.
|
|
132
167
|
|
|
133
168
|
## Benchmarks
|
|
134
169
|
|
|
@@ -182,24 +217,41 @@ confidence wherever it can tell it is missing something, but some edges it
|
|
|
182
217
|
cannot see at all:
|
|
183
218
|
|
|
184
219
|
- **Runtime-only wiring is invisible.** Dependency injection by token,
|
|
185
|
-
string-keyed registries
|
|
186
|
-
|
|
187
|
-
|
|
220
|
+
string-keyed registries and `eval` never appear as imports. A test that
|
|
221
|
+
reaches code only this way is not selected, and nothing in the output says
|
|
222
|
+
so. This is the largest blind spot.
|
|
188
223
|
- **Service boundaries end the graph.** An end-to-end test that calls a running
|
|
189
224
|
server imports none of the code it exercises.
|
|
190
225
|
- **Setup files are recognized by name.** `vitest.setup.ts`, `setupTests.ts`,
|
|
191
226
|
`global-setup.ts` and the like select every test; a setup file named
|
|
192
227
|
anything else selects none. variant does not read the runner config.
|
|
193
|
-
- **
|
|
194
|
-
|
|
195
|
-
|
|
228
|
+
- **Files read at runtime are outside the closure.** A changed stylesheet or
|
|
229
|
+
JSON file that a TypeScript file imports selects that file's tests, but a
|
|
230
|
+
fixture, snapshot or asset a test reads with `fs` is invisible. A changed
|
|
231
|
+
file that reaches no test is listed as `Unreached`.
|
|
232
|
+
- **Only the directory it runs in is indexed.** A file changed elsewhere in
|
|
233
|
+
the repository selects the tests of the files that import it by relative
|
|
234
|
+
path, and is listed as `Unreached` otherwise.
|
|
235
|
+
- **Unreached is not the same as untested.** A changed file no test reaches
|
|
236
|
+
is listed as `Unreached` and the prediction reads `low`. variant cannot tell
|
|
237
|
+
an untested file from one a runtime lookup uses.
|
|
238
|
+
- **JavaScript is indexed when git says it is yours.** Tracked or new
|
|
239
|
+
`.js`, `.jsx`, `.mjs` and `.cjs` files are read like TypeScript; build
|
|
240
|
+
output and bundles are not. A changed CommonJS module reaches everything
|
|
241
|
+
that requires it.
|
|
242
|
+
- **Computed imports are followed only as far as their literal start.**
|
|
243
|
+
`` import(`./locales/${lang}.js`) `` reaches everything under `./locales/`;
|
|
244
|
+
`import(name)` could load anything, and is a standing note on every run.
|
|
196
245
|
- **Dynamic `import()` is assumed to use everything.** The change propagates
|
|
197
246
|
and a note is printed; the run gets wider, not narrower.
|
|
247
|
+
- **Workspace discovery can miss a package**, and a bare import of a package it
|
|
248
|
+
missed counts as external. `impact` prints how many packages it found and
|
|
249
|
+
notes imports no discovered package or manifest accounts for.
|
|
198
250
|
- **Type-only changes are not narrowed.** Changing an interface selects every
|
|
199
251
|
test that imports the file, though no runtime behavior changed.
|
|
200
252
|
- **The confidence score is not a safety number.** It says how much of the
|
|
201
|
-
import graph resolved
|
|
202
|
-
have been.
|
|
253
|
+
import graph resolved, as `high`, `medium` or `low` and a percentage. Only
|
|
254
|
+
the false-skip rate says how safe a skip would have been.
|
|
203
255
|
|
|
204
256
|
The full list, with how each case is handled, is in
|
|
205
257
|
[Impact & workspace](./docs/impact-and-workspace.md#limitations).
|
|
@@ -212,11 +264,13 @@ The full list, with how each case is handled, is in
|
|
|
212
264
|
| [Getting started](./docs/getting-started.md) | Run it on your own repository, then set up the task runner |
|
|
213
265
|
| [Impact & workspace](./docs/impact-and-workspace.md) | How `impact` and `workspace check` work, and what static analysis cannot see |
|
|
214
266
|
| [PR commands](./docs/pr-commands.md) | `pr check` and `pr report` |
|
|
267
|
+
| [Vitest adapter](./docs/vitest-adapter.md) | One config line in place of the commands: predict and check on every test run |
|
|
215
268
|
| [CLI reference](./docs/cli-reference.md) | Every command, flag, exit code and file |
|
|
216
269
|
| [API reference](./docs/api.md) | `defineConfig`, the config types, and every JSON output |
|
|
217
270
|
| [Monorepo setup](./docs/monorepo.md) | Workspace tasks and `--affected` |
|
|
218
271
|
| [Config reference](./docs/config-reference.md) | Every `variant.config.ts` key |
|
|
219
272
|
| [Troubleshooting](./docs/troubleshooting.md) | Common problems and what they mean |
|
|
273
|
+
| [Measurement log](./docs/measurement.md) | Every prediction checked against a full run so far, and the gate skipping has to pass |
|
|
220
274
|
|
|
221
275
|
## Contributing
|
|
222
276
|
|
|
@@ -2,23 +2,24 @@ import {
|
|
|
2
2
|
executeTarget,
|
|
3
3
|
renderDryRunPlan,
|
|
4
4
|
reportRunInsights
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-7NC7AO75.js";
|
|
6
|
+
import "./chunk-IHXJ72XA.js";
|
|
7
|
+
import "./chunk-CWF6QXEW.js";
|
|
7
8
|
import "./chunk-QRPI6TJE.js";
|
|
8
9
|
import {
|
|
9
10
|
createContext,
|
|
10
11
|
toRunOptions
|
|
11
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-CN25SRKD.js";
|
|
12
13
|
import "./chunk-V5CTGXMM.js";
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-YYGCSKIQ.js";
|
|
14
|
+
import "./chunk-RJBFCURK.js";
|
|
15
15
|
import "./chunk-GDSZFIHM.js";
|
|
16
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-DMDAJPFJ.js";
|
|
17
17
|
import "./chunk-3E5LBU3O.js";
|
|
18
|
-
import "./chunk-
|
|
18
|
+
import "./chunk-YYGCSKIQ.js";
|
|
19
19
|
import "./chunk-6J4XDG44.js";
|
|
20
20
|
import "./chunk-EISTWXDW.js";
|
|
21
|
-
import "./chunk-
|
|
21
|
+
import "./chunk-RSIOYQOQ.js";
|
|
22
|
+
import "./chunk-ACTY42RE.js";
|
|
22
23
|
|
|
23
24
|
// src/core/scope/task-filter.ts
|
|
24
25
|
function taskPackage(taskName) {
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createContext
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-CN25SRKD.js";
|
|
4
4
|
import "./chunk-V5CTGXMM.js";
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-7OPTWU6E.js";
|
|
5
|
+
import "./chunk-RJBFCURK.js";
|
|
6
|
+
import "./chunk-DMDAJPFJ.js";
|
|
8
7
|
import "./chunk-3E5LBU3O.js";
|
|
9
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-YYGCSKIQ.js";
|
|
10
9
|
import {
|
|
11
10
|
lines
|
|
12
11
|
} from "./chunk-6J4XDG44.js";
|
|
13
12
|
import {
|
|
14
13
|
getPrinter
|
|
15
14
|
} from "./chunk-EISTWXDW.js";
|
|
15
|
+
import "./chunk-RSIOYQOQ.js";
|
|
16
16
|
import {
|
|
17
17
|
ConfigError
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-ACTY42RE.js";
|
|
19
19
|
|
|
20
20
|
// src/core/graph/validation.ts
|
|
21
21
|
function validateTaskGraph(tasks, graph) {
|
|
@@ -1,23 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CLEAR_LINE,
|
|
3
|
+
HIDE_CURSOR,
|
|
4
|
+
SHOW_CURSOR,
|
|
5
|
+
SYNC_END,
|
|
6
|
+
SYNC_START,
|
|
7
|
+
cursorUp,
|
|
8
|
+
fitWidth
|
|
9
|
+
} from "./chunk-IHXJ72XA.js";
|
|
1
10
|
import {
|
|
2
11
|
computeInsights,
|
|
3
12
|
evictStaleEntries,
|
|
4
13
|
readCache,
|
|
5
14
|
writeCache,
|
|
6
15
|
writeCacheSync
|
|
7
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-CWF6QXEW.js";
|
|
8
17
|
import {
|
|
9
18
|
renderInsights
|
|
10
19
|
} from "./chunk-QRPI6TJE.js";
|
|
11
20
|
import {
|
|
12
21
|
recordCacheMiss,
|
|
13
22
|
runScheduled
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import {
|
|
16
|
-
getColors
|
|
17
|
-
} from "./chunk-YYGCSKIQ.js";
|
|
23
|
+
} from "./chunk-CN25SRKD.js";
|
|
18
24
|
import {
|
|
19
25
|
mapLimit
|
|
20
26
|
} from "./chunk-GDSZFIHM.js";
|
|
27
|
+
import {
|
|
28
|
+
getColors
|
|
29
|
+
} from "./chunk-YYGCSKIQ.js";
|
|
21
30
|
import {
|
|
22
31
|
lines
|
|
23
32
|
} from "./chunk-6J4XDG44.js";
|
|
@@ -27,7 +36,7 @@ import {
|
|
|
27
36
|
import {
|
|
28
37
|
TaskExecutionError,
|
|
29
38
|
VariantError
|
|
30
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-ACTY42RE.js";
|
|
31
40
|
|
|
32
41
|
// src/core/execution/runner.ts
|
|
33
42
|
import { createHash as createHash2 } from "crypto";
|
|
@@ -283,28 +292,6 @@ async function runTasksWithDeps(target, graph, options, executor = executeTask)
|
|
|
283
292
|
return results;
|
|
284
293
|
}
|
|
285
294
|
|
|
286
|
-
// src/cli/visuals/ansi.ts
|
|
287
|
-
var ESC = "\x1B";
|
|
288
|
-
var HIDE_CURSOR = `${ESC}[?25l`;
|
|
289
|
-
var SHOW_CURSOR = `${ESC}[?25h`;
|
|
290
|
-
var CLEAR_LINE = `${ESC}[2K`;
|
|
291
|
-
var SYNC_START = `${ESC}[?2026h`;
|
|
292
|
-
var SYNC_END = `${ESC}[?2026l`;
|
|
293
|
-
function cursorUp(lines2) {
|
|
294
|
-
return lines2 > 0 ? `${ESC}[${lines2}A` : "";
|
|
295
|
-
}
|
|
296
|
-
var STYLE_PATTERN = new RegExp(`${ESC}\\[[0-9;]*m`, "g");
|
|
297
|
-
function stripStyles(text) {
|
|
298
|
-
return text.replace(STYLE_PATTERN, "");
|
|
299
|
-
}
|
|
300
|
-
function visibleLength(line) {
|
|
301
|
-
return stripStyles(line).length;
|
|
302
|
-
}
|
|
303
|
-
function fitWidth(line, columns) {
|
|
304
|
-
if (visibleLength(line) <= columns) return line;
|
|
305
|
-
return stripStyles(line).slice(0, Math.max(0, columns - 1));
|
|
306
|
-
}
|
|
307
|
-
|
|
308
295
|
// src/cli/visuals/progress.ts
|
|
309
296
|
var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
310
297
|
var TICK_MS = 80;
|
|
@@ -62,12 +62,30 @@ var GitRefError = class extends VariantError {
|
|
|
62
62
|
this.hint = "Check the ref with `git rev-parse --verify <ref>`. In CI, check out with `fetch-depth: 0` and pass a remote-tracking ref such as `origin/main`.";
|
|
63
63
|
}
|
|
64
64
|
};
|
|
65
|
+
var NoBaseCommitError = class extends VariantError {
|
|
66
|
+
constructor() {
|
|
67
|
+
super(
|
|
68
|
+
"NO_BASE_COMMIT",
|
|
69
|
+
"This push has no previous commit to compare against"
|
|
70
|
+
);
|
|
71
|
+
this.hint = "The first push of a branch, or a force-push whose old head is gone. Pass --base to compare against a commit of your choice.";
|
|
72
|
+
}
|
|
73
|
+
};
|
|
65
74
|
var ImpactReportError = class extends VariantError {
|
|
66
75
|
constructor(message) {
|
|
67
76
|
super("IMPACT_REPORT_ERROR", `Could not read the test report: ${message}`);
|
|
68
77
|
this.hint = "Pass a Vitest `--reporter=json --outputFile=<path>` or Jest `--json --outputFile=<path>` report.";
|
|
69
78
|
}
|
|
70
79
|
};
|
|
80
|
+
var NoTestFilesError = class extends VariantError {
|
|
81
|
+
constructor() {
|
|
82
|
+
super(
|
|
83
|
+
"NO_TEST_FILES",
|
|
84
|
+
"No test files found, so there is nothing to predict"
|
|
85
|
+
);
|
|
86
|
+
this.hint = "variant finds TypeScript tests named `*.test.ts` or `*.spec.ts` (also `.tsx`, `.mts`, `.cts`) or placed under `__tests__/`. JavaScript files are not indexed.";
|
|
87
|
+
}
|
|
88
|
+
};
|
|
71
89
|
var CliUsageError = class extends VariantError {
|
|
72
90
|
constructor(message) {
|
|
73
91
|
super("CLI_USAGE", message);
|
|
@@ -83,6 +101,8 @@ export {
|
|
|
83
101
|
CacheError,
|
|
84
102
|
GraphError,
|
|
85
103
|
GitRefError,
|
|
104
|
+
NoBaseCommitError,
|
|
86
105
|
ImpactReportError,
|
|
106
|
+
NoTestFilesError,
|
|
87
107
|
CliUsageError
|
|
88
108
|
};
|
|
@@ -7,19 +7,19 @@ import {
|
|
|
7
7
|
} from "./chunk-V5CTGXMM.js";
|
|
8
8
|
import {
|
|
9
9
|
loadConfig
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import {
|
|
12
|
-
getColors
|
|
13
|
-
} from "./chunk-YYGCSKIQ.js";
|
|
10
|
+
} from "./chunk-RJBFCURK.js";
|
|
14
11
|
import {
|
|
15
12
|
changedFilesToPackages,
|
|
16
13
|
getChangedFiles
|
|
17
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-DMDAJPFJ.js";
|
|
18
15
|
import {
|
|
19
16
|
computeAffectedPackages,
|
|
20
17
|
loadPackageGraph,
|
|
21
18
|
tasksFromPackageGraph
|
|
22
19
|
} from "./chunk-3E5LBU3O.js";
|
|
20
|
+
import {
|
|
21
|
+
getColors
|
|
22
|
+
} from "./chunk-YYGCSKIQ.js";
|
|
23
23
|
import {
|
|
24
24
|
errorLines
|
|
25
25
|
} from "./chunk-6J4XDG44.js";
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
import {
|
|
30
30
|
ConfigError,
|
|
31
31
|
CycleError
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-ACTY42RE.js";
|
|
33
33
|
|
|
34
34
|
// src/adapters/frameworks/plugin.ts
|
|
35
35
|
var wrapFrameworkAsPlugin = (a) => ({
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
// src/core/semantic/surface.ts
|
|
2
|
+
var STAR_REEXPORT_PREFIX = "* from ";
|
|
3
|
+
function starReexportKey(moduleSpec) {
|
|
4
|
+
return `${STAR_REEXPORT_PREFIX}${moduleSpec}`;
|
|
5
|
+
}
|
|
6
|
+
function isStarReexportKey(name) {
|
|
7
|
+
return name.startsWith(STAR_REEXPORT_PREFIX);
|
|
8
|
+
}
|
|
2
9
|
function collectExportedSurface(file, tsm) {
|
|
3
10
|
const symbols = /* @__PURE__ */ new Map();
|
|
4
11
|
const notes = [];
|
|
@@ -42,7 +49,7 @@ function collectExportedSurface(file, tsm) {
|
|
|
42
49
|
});
|
|
43
50
|
continue;
|
|
44
51
|
}
|
|
45
|
-
symbols.set(
|
|
52
|
+
symbols.set(starReexportKey(moduleSpec), {
|
|
46
53
|
signature: reexportSignature("*", moduleSpec, declTypeOnly),
|
|
47
54
|
body: "",
|
|
48
55
|
typeSpace: declTypeOnly,
|
|
@@ -345,6 +352,7 @@ function normalize(text) {
|
|
|
345
352
|
}
|
|
346
353
|
|
|
347
354
|
export {
|
|
355
|
+
isStarReexportKey,
|
|
348
356
|
collectExportedSurface,
|
|
349
357
|
significantText
|
|
350
358
|
};
|