@halecraft/verify 1.0.0 → 1.2.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 +216 -13
- package/bin/verify.mjs +120 -134
- package/dist/index.d.ts +157 -11
- package/dist/index.js +495 -111
- package/dist/index.js.map +1 -1
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -40,14 +40,14 @@ import { defineConfig } from "@halecraft/verify";
|
|
|
40
40
|
|
|
41
41
|
export default defineConfig({
|
|
42
42
|
tasks: [
|
|
43
|
-
{ key: "format", run: "
|
|
44
|
-
{ key: "types", run: "
|
|
45
|
-
{ key: "test", run: "
|
|
43
|
+
{ key: "format", run: "biome check ." },
|
|
44
|
+
{ key: "types", run: "tsc --noEmit" },
|
|
45
|
+
{ key: "test", run: "vitest run" },
|
|
46
46
|
],
|
|
47
47
|
});
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
Note
|
|
50
|
+
**Note:** Commands automatically have access to binaries in `node_modules/.bin` directories. You can write `run: "biome check ."` instead of `run: "./node_modules/.bin/biome check ."`. This works in monorepos too—verify walks up the directory tree to find all `node_modules/.bin` directories, just like npm/pnpm/yarn do when running package.json scripts.
|
|
51
51
|
|
|
52
52
|
### Run Verification
|
|
53
53
|
|
|
@@ -58,6 +58,16 @@ pnpm exec verify
|
|
|
58
58
|
# Run specific task
|
|
59
59
|
pnpm exec verify format
|
|
60
60
|
|
|
61
|
+
# Run nested task with full path
|
|
62
|
+
pnpm exec verify types:tsc
|
|
63
|
+
|
|
64
|
+
# Run nested task with shortcut (if unambiguous)
|
|
65
|
+
pnpm exec verify tsc
|
|
66
|
+
# → Resolving "tsc" to "types:tsc"
|
|
67
|
+
|
|
68
|
+
# Pass arguments to underlying command
|
|
69
|
+
pnpm exec verify logic -- -t "specific test name"
|
|
70
|
+
|
|
61
71
|
# Run with verbose output
|
|
62
72
|
pnpm exec verify --verbose
|
|
63
73
|
|
|
@@ -87,11 +97,16 @@ interface VerificationNode {
|
|
|
87
97
|
name?: string;
|
|
88
98
|
|
|
89
99
|
// Command to run (leaf nodes only)
|
|
90
|
-
// Supports: string, object with cmd/args/cwd
|
|
100
|
+
// Supports: string, object with cmd/args/cwd/env/timeout
|
|
91
101
|
run?:
|
|
92
102
|
| string
|
|
93
|
-
| {
|
|
94
|
-
|
|
103
|
+
| {
|
|
104
|
+
cmd: string;
|
|
105
|
+
args: string[];
|
|
106
|
+
cwd?: string;
|
|
107
|
+
env?: Record<string, string | null>;
|
|
108
|
+
timeout?: number;
|
|
109
|
+
};
|
|
95
110
|
|
|
96
111
|
// Child tasks (for grouping)
|
|
97
112
|
children?: VerificationNode[];
|
|
@@ -105,6 +120,13 @@ interface VerificationNode {
|
|
|
105
120
|
// Tasks that must pass for this task's failure to be reported
|
|
106
121
|
reportingDependsOn?: string[];
|
|
107
122
|
|
|
123
|
+
// Timeout in milliseconds (for string commands)
|
|
124
|
+
timeout?: number;
|
|
125
|
+
|
|
126
|
+
// Environment variables for this task and its children
|
|
127
|
+
// Set to null to unset an inherited variable
|
|
128
|
+
env?: Record<string, string | null>;
|
|
129
|
+
|
|
108
130
|
// Custom success message template (optional)
|
|
109
131
|
successLabel?: string;
|
|
110
132
|
|
|
@@ -222,13 +244,99 @@ Control how child tasks are executed:
|
|
|
222
244
|
- `sequential`: Run tasks one after another
|
|
223
245
|
- `fail-fast`: Run sequentially, stop on first failure
|
|
224
246
|
|
|
247
|
+
### Command Timeouts
|
|
248
|
+
|
|
249
|
+
Prevent hung processes by setting a timeout (in milliseconds):
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
import { defineConfig } from "@halecraft/verify";
|
|
253
|
+
|
|
254
|
+
export default defineConfig({
|
|
255
|
+
tasks: [
|
|
256
|
+
// String command with timeout
|
|
257
|
+
{ key: "test", run: "vitest run", timeout: 60000 }, // 60 seconds
|
|
258
|
+
|
|
259
|
+
// Object command with timeout
|
|
260
|
+
{
|
|
261
|
+
key: "build",
|
|
262
|
+
run: {
|
|
263
|
+
cmd: "tsup",
|
|
264
|
+
args: [],
|
|
265
|
+
timeout: 120000, // 2 minutes
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
],
|
|
269
|
+
});
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
When a command exceeds its timeout:
|
|
273
|
+
|
|
274
|
+
- The process is killed with `SIGTERM` (including child processes)
|
|
275
|
+
- The task is marked as failed with `timedOut: true`
|
|
276
|
+
- The summary shows: `task: timed out after 60000ms`
|
|
277
|
+
|
|
278
|
+
**Note:** For object commands, the `timeout` on the command takes precedence over the node-level `timeout`.
|
|
279
|
+
|
|
280
|
+
### Environment Variables
|
|
281
|
+
|
|
282
|
+
Set environment variables at the config level (applies to all tasks) or at the task level (inherits to children):
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
import { defineConfig } from "@halecraft/verify";
|
|
286
|
+
|
|
287
|
+
export default defineConfig({
|
|
288
|
+
// Global env vars - applied to all tasks
|
|
289
|
+
env: {
|
|
290
|
+
NO_COLOR: "1", // Recommended: disable colors for cleaner output parsing
|
|
291
|
+
CI: "true",
|
|
292
|
+
},
|
|
293
|
+
tasks: [
|
|
294
|
+
{ key: "format", run: "biome check ." },
|
|
295
|
+
{
|
|
296
|
+
key: "test",
|
|
297
|
+
// Enable colors for test output by unsetting NO_COLOR
|
|
298
|
+
env: { NO_COLOR: null },
|
|
299
|
+
children: [
|
|
300
|
+
{ key: "unit", run: "vitest run" },
|
|
301
|
+
{
|
|
302
|
+
key: "e2e",
|
|
303
|
+
run: "playwright test",
|
|
304
|
+
// E2E-specific env (still inherits CI: "true")
|
|
305
|
+
env: { PLAYWRIGHT_BROWSERS_PATH: "0" },
|
|
306
|
+
},
|
|
307
|
+
],
|
|
308
|
+
},
|
|
309
|
+
],
|
|
310
|
+
});
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**Environment merge order** (most specific wins):
|
|
314
|
+
|
|
315
|
+
1. `process.env` - System environment
|
|
316
|
+
2. `config.env` - Global config-level
|
|
317
|
+
3. Parent task `env` - Inherited from parent tasks
|
|
318
|
+
4. Node `env` - Current task
|
|
319
|
+
5. Command `env` - VerificationCommand object only
|
|
320
|
+
|
|
321
|
+
**Unsetting variables:** Set a value to `null` to explicitly unset an inherited variable:
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
{
|
|
325
|
+
key: "test",
|
|
326
|
+
env: { NO_COLOR: null }, // Re-enables colors for this task
|
|
327
|
+
run: "vitest run",
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
**Note:** Generated configs (via `--init`) include `env: { NO_COLOR: "1" }` by default to ensure consistent output parsing.
|
|
332
|
+
|
|
225
333
|
## CLI Options
|
|
226
334
|
|
|
227
335
|
```
|
|
228
336
|
Usage:
|
|
229
|
-
verify [
|
|
337
|
+
verify [flags...] [task] [--] [passthrough...]
|
|
230
338
|
|
|
231
|
-
|
|
339
|
+
Flags:
|
|
232
340
|
--json Output results as JSON
|
|
233
341
|
--verbose, -v Show all task output
|
|
234
342
|
--quiet, -q Show only final result
|
|
@@ -236,13 +344,83 @@ Options:
|
|
|
236
344
|
--no-tty Force sequential output (disable live dashboard)
|
|
237
345
|
--logs=MODE Log verbosity: all, failed, none (default: failed)
|
|
238
346
|
--config, -c PATH Path to config file (or output path for --init)
|
|
239
|
-
--filter, -f PATH Filter to specific task paths
|
|
240
347
|
--init Initialize a new verify.config.ts file
|
|
241
348
|
--force Overwrite existing config file (with --init)
|
|
242
349
|
--yes, -y Skip interactive prompts, auto-accept detected tasks
|
|
243
350
|
--help, -h Show this help message
|
|
244
351
|
```
|
|
245
352
|
|
|
353
|
+
### Passthrough Arguments
|
|
354
|
+
|
|
355
|
+
You can pass arguments directly to the underlying command using `--` (double-dash):
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
# Run a specific vitest test
|
|
359
|
+
verify logic -- -t "should handle edge case"
|
|
360
|
+
|
|
361
|
+
# Run with coverage
|
|
362
|
+
verify logic -- --coverage
|
|
363
|
+
|
|
364
|
+
# Multiple passthrough args
|
|
365
|
+
verify logic -- -t "foo" --reporter=verbose
|
|
366
|
+
|
|
367
|
+
# Combine with verify flags
|
|
368
|
+
verify logic --verbose -- -t "foo"
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
**Requirements:**
|
|
372
|
+
- Passthrough arguments require exactly one task filter
|
|
373
|
+
- The task must be a leaf node (has a `run` command)
|
|
374
|
+
- Arguments are appended to the command string
|
|
375
|
+
|
|
376
|
+
**How it works:**
|
|
377
|
+
- For string commands: args are shell-escaped and appended to the command
|
|
378
|
+
- For object commands: args are appended to the `args` array
|
|
379
|
+
|
|
380
|
+
### Exit Codes
|
|
381
|
+
|
|
382
|
+
- `0` - All tasks passed
|
|
383
|
+
- `1` - Some tasks failed
|
|
384
|
+
- `2` - Configuration/usage error (invalid task name, missing config)
|
|
385
|
+
|
|
386
|
+
### Task Name Validation
|
|
387
|
+
|
|
388
|
+
Verify validates task names before running any tasks. If you specify a task that doesn't exist, you'll get a helpful error:
|
|
389
|
+
|
|
390
|
+
```bash
|
|
391
|
+
$ verify test
|
|
392
|
+
Error: Task "test" not found.
|
|
393
|
+
|
|
394
|
+
Did you mean "types:tsc"?
|
|
395
|
+
|
|
396
|
+
Available tasks:
|
|
397
|
+
format
|
|
398
|
+
logic
|
|
399
|
+
types
|
|
400
|
+
types:tsc
|
|
401
|
+
types:tsgo
|
|
402
|
+
build
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
**Child task shortcuts:** You can use just the child key if it's unambiguous:
|
|
406
|
+
|
|
407
|
+
```bash
|
|
408
|
+
$ verify tsc
|
|
409
|
+
→ Resolving "tsc" to "types:tsc"
|
|
410
|
+
✓ verified types:tsc
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
If the shortcut is ambiguous (multiple tasks have the same child key), you'll get an error listing the options:
|
|
414
|
+
|
|
415
|
+
```bash
|
|
416
|
+
$ verify test # if both unit:test and e2e:test exist
|
|
417
|
+
Error: Task "test" is ambiguous.
|
|
418
|
+
|
|
419
|
+
Matches multiple tasks:
|
|
420
|
+
unit:test
|
|
421
|
+
e2e:test
|
|
422
|
+
```
|
|
423
|
+
|
|
246
424
|
## Programmatic API
|
|
247
425
|
|
|
248
426
|
```typescript
|
|
@@ -293,6 +471,7 @@ interface TaskResult {
|
|
|
293
471
|
summaryLine: string; // Parsed summary
|
|
294
472
|
suppressed?: boolean; // True if output was suppressed
|
|
295
473
|
suppressedBy?: string; // Path of dependency that caused suppression
|
|
474
|
+
timedOut?: boolean; // True if task exceeded its timeout
|
|
296
475
|
children?: TaskResult[]; // Child results (for group nodes)
|
|
297
476
|
}
|
|
298
477
|
```
|
|
@@ -301,14 +480,38 @@ interface TaskResult {
|
|
|
301
480
|
|
|
302
481
|
Built-in parsers for common tools:
|
|
303
482
|
|
|
304
|
-
- **vitest** - Vitest test runner
|
|
305
|
-
- **tsc** - TypeScript compiler
|
|
306
|
-
- **biome** - Biome linter/formatter
|
|
483
|
+
- **vitest** - Vitest/Jest test runner
|
|
484
|
+
- **tsc** - TypeScript compiler (tsc/tsgo)
|
|
485
|
+
- **biome** - Biome/ESLint linter/formatter
|
|
307
486
|
- **gotest** - Go test runner
|
|
308
487
|
- **generic** - Fallback for unknown tools
|
|
309
488
|
|
|
310
489
|
Parsers automatically extract metrics (passed/failed counts, duration) and provide concise summaries.
|
|
311
490
|
|
|
491
|
+
### Parser ID Constants
|
|
492
|
+
|
|
493
|
+
Use `parsers` for type-safe parser references instead of magic strings:
|
|
494
|
+
|
|
495
|
+
```typescript
|
|
496
|
+
import { defineConfig, parsers } from "@halecraft/verify";
|
|
497
|
+
|
|
498
|
+
export default defineConfig({
|
|
499
|
+
tasks: [
|
|
500
|
+
{ key: "test", run: "vitest run", parser: parsers.vitest },
|
|
501
|
+
{ key: "types", run: "tsc --noEmit", parser: parsers.tsc },
|
|
502
|
+
{ key: "lint", run: "biome check .", parser: parsers.biome },
|
|
503
|
+
],
|
|
504
|
+
});
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
Available constants:
|
|
508
|
+
|
|
509
|
+
- `parsers.vitest` - `"vitest"`
|
|
510
|
+
- `parsers.tsc` - `"tsc"`
|
|
511
|
+
- `parsers.biome` - `"biome"`
|
|
512
|
+
- `parsers.gotest` - `"gotest"`
|
|
513
|
+
- `parsers.generic` - `"generic"`
|
|
514
|
+
|
|
312
515
|
## License
|
|
313
516
|
|
|
314
517
|
MIT
|
package/bin/verify.mjs
CHANGED
|
@@ -1,140 +1,110 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
for (let i = 0; i < args.length; i++) {
|
|
25
|
-
const arg = args[i]
|
|
26
|
-
|
|
27
|
-
if (arg === "--json") {
|
|
28
|
-
options.json = true
|
|
29
|
-
} else if (arg === "--verbose" || arg === "-v") {
|
|
30
|
-
options.verbose = true
|
|
31
|
-
} else if (arg === "--quiet" || arg === "-q") {
|
|
32
|
-
options.quiet = true
|
|
33
|
-
} else if (arg === "--help" || arg === "-h") {
|
|
34
|
-
options.help = true
|
|
35
|
-
} else if (arg === "--init") {
|
|
36
|
-
options.init = true
|
|
37
|
-
} else if (arg === "--force") {
|
|
38
|
-
options.force = true
|
|
39
|
-
} else if (arg === "--yes" || arg === "-y") {
|
|
40
|
-
options.yes = true
|
|
41
|
-
} else if (arg === "--top-level" || arg === "-t") {
|
|
42
|
-
options.topLevelOnly = true
|
|
43
|
-
} else if (arg === "--no-tty") {
|
|
44
|
-
options.noTty = true
|
|
45
|
-
} else if (arg.startsWith("--logs=")) {
|
|
46
|
-
options.logs = arg.slice(7)
|
|
47
|
-
} else if (arg === "--logs") {
|
|
48
|
-
options.logs = args[++i]
|
|
49
|
-
} else if (arg.startsWith("--config=")) {
|
|
50
|
-
options.config = arg.slice(9)
|
|
51
|
-
} else if (arg === "--config" || arg === "-c") {
|
|
52
|
-
options.config = args[++i]
|
|
53
|
-
} else if (arg.startsWith("--filter=")) {
|
|
54
|
-
options.filter.push(arg.slice(9))
|
|
55
|
-
} else if (arg === "--filter" || arg === "-f") {
|
|
56
|
-
options.filter.push(args[++i])
|
|
57
|
-
} else if (!arg.startsWith("-")) {
|
|
58
|
-
// Positional argument treated as filter
|
|
59
|
-
options.filter.push(arg)
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return options
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Print help message
|
|
68
|
-
*/
|
|
69
|
-
function printHelp() {
|
|
70
|
-
console.log(`
|
|
71
|
-
@halecraft/verify - Hierarchical verification runner
|
|
72
|
-
|
|
73
|
-
Usage:
|
|
74
|
-
verify [options] [filter...]
|
|
75
|
-
|
|
76
|
-
Options:
|
|
77
|
-
--json Output results as JSON
|
|
78
|
-
--verbose, -v Show all task output
|
|
79
|
-
--quiet, -q Show only final result
|
|
80
|
-
--top-level, -t Show only top-level tasks (hide descendants)
|
|
81
|
-
--no-tty Force sequential output (disable live dashboard)
|
|
82
|
-
--logs=MODE Log verbosity: all, failed, none (default: failed)
|
|
83
|
-
--config, -c PATH Path to config file (or output path for --init)
|
|
84
|
-
--filter, -f PATH Filter to specific task paths
|
|
85
|
-
--init Initialize a new verify.config.ts file
|
|
86
|
-
--force Overwrite existing config file (with --init)
|
|
87
|
-
--yes, -y Skip interactive prompts, auto-accept detected tasks
|
|
88
|
-
--help, -h Show this help message
|
|
89
|
-
|
|
90
|
-
Examples:
|
|
91
|
-
verify Run all verifications
|
|
92
|
-
verify logic Run only 'logic' tasks
|
|
93
|
-
verify logic:ts Run only 'logic:ts' task
|
|
94
|
-
verify --top-level Show only top-level tasks
|
|
95
|
-
verify --json Output JSON for CI
|
|
96
|
-
verify --logs=all Show all output
|
|
97
|
-
verify --init Create config interactively
|
|
98
|
-
verify --init -y Create config with all detected tasks
|
|
99
|
-
verify --init --force Overwrite existing config
|
|
100
|
-
|
|
101
|
-
Config:
|
|
102
|
-
Create a verify.config.ts file in your project root:
|
|
103
|
-
|
|
104
|
-
import { defineConfig } from '@halecraft/verify'
|
|
3
|
+
import { cli } from "cleye"
|
|
4
|
+
import {
|
|
5
|
+
AmbiguousTaskError,
|
|
6
|
+
runInit,
|
|
7
|
+
TaskNotFoundError,
|
|
8
|
+
verifyFromConfig,
|
|
9
|
+
} from "../dist/index.js"
|
|
10
|
+
|
|
11
|
+
const argv = cli(
|
|
12
|
+
{
|
|
13
|
+
name: "verify",
|
|
14
|
+
version: "1.0.0",
|
|
15
|
+
description: "Hierarchical verification runner with parallel execution",
|
|
16
|
+
|
|
17
|
+
parameters: [
|
|
18
|
+
"[task]", // Optional single task filter
|
|
19
|
+
"--", // End-of-flags separator
|
|
20
|
+
"[passthrough...]", // Args to pass to underlying command
|
|
21
|
+
],
|
|
105
22
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
key: 'logic',
|
|
112
|
-
children: [
|
|
113
|
-
{ key: 'ts', run: 'vitest run' },
|
|
114
|
-
{ key: 'go', run: 'go test ./...' },
|
|
115
|
-
],
|
|
23
|
+
flags: {
|
|
24
|
+
json: {
|
|
25
|
+
type: Boolean,
|
|
26
|
+
description: "Output results as JSON",
|
|
27
|
+
default: false,
|
|
116
28
|
},
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
29
|
+
verbose: {
|
|
30
|
+
type: Boolean,
|
|
31
|
+
alias: "v",
|
|
32
|
+
description: "Show all task output",
|
|
33
|
+
default: false,
|
|
34
|
+
},
|
|
35
|
+
quiet: {
|
|
36
|
+
type: Boolean,
|
|
37
|
+
alias: "q",
|
|
38
|
+
description: "Show only final result",
|
|
39
|
+
default: false,
|
|
40
|
+
},
|
|
41
|
+
topLevel: {
|
|
42
|
+
type: Boolean,
|
|
43
|
+
alias: "t",
|
|
44
|
+
description: "Show only top-level tasks (hide descendants)",
|
|
45
|
+
default: false,
|
|
46
|
+
},
|
|
47
|
+
noTty: {
|
|
48
|
+
type: Boolean,
|
|
49
|
+
description: "Force sequential output (disable live dashboard)",
|
|
50
|
+
default: false,
|
|
51
|
+
},
|
|
52
|
+
logs: {
|
|
53
|
+
type: String,
|
|
54
|
+
description: "Log verbosity: all, failed, none (default: failed)",
|
|
55
|
+
},
|
|
56
|
+
config: {
|
|
57
|
+
type: String,
|
|
58
|
+
alias: "c",
|
|
59
|
+
description: "Path to config file (or output path for --init)",
|
|
60
|
+
},
|
|
61
|
+
init: {
|
|
62
|
+
type: Boolean,
|
|
63
|
+
description: "Initialize a new verify.config.ts file",
|
|
64
|
+
default: false,
|
|
65
|
+
},
|
|
66
|
+
force: {
|
|
67
|
+
type: Boolean,
|
|
68
|
+
description: "Overwrite existing config file (with --init)",
|
|
69
|
+
default: false,
|
|
70
|
+
},
|
|
71
|
+
yes: {
|
|
72
|
+
type: Boolean,
|
|
73
|
+
alias: "y",
|
|
74
|
+
description: "Skip interactive prompts, auto-accept detected tasks",
|
|
75
|
+
default: false,
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
help: {
|
|
80
|
+
examples: [
|
|
81
|
+
"verify Run all verifications",
|
|
82
|
+
"verify logic Run only 'logic' tasks",
|
|
83
|
+
"verify logic:ts Run only 'logic:ts' task",
|
|
84
|
+
"verify logic -- -t foo Run 'logic' with passthrough args",
|
|
85
|
+
"verify --top-level Show only top-level tasks",
|
|
86
|
+
"verify --json Output JSON for CI",
|
|
87
|
+
"verify --logs=all Show all output",
|
|
88
|
+
"verify --init Create config interactively",
|
|
89
|
+
"verify --init -y Create config with all detected tasks",
|
|
90
|
+
"verify --init --force Overwrite existing config",
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
undefined,
|
|
95
|
+
undefined,
|
|
96
|
+
)
|
|
121
97
|
|
|
122
98
|
async function main() {
|
|
123
|
-
const
|
|
124
|
-
const options = parseArgs(args)
|
|
125
|
-
|
|
126
|
-
if (options.help) {
|
|
127
|
-
printHelp()
|
|
128
|
-
process.exit(0)
|
|
129
|
-
}
|
|
99
|
+
const { flags, _ } = argv
|
|
130
100
|
|
|
131
101
|
// Handle --init command
|
|
132
|
-
if (
|
|
102
|
+
if (flags.init) {
|
|
133
103
|
try {
|
|
134
104
|
const result = await runInit({
|
|
135
|
-
config:
|
|
136
|
-
force:
|
|
137
|
-
yes:
|
|
105
|
+
config: flags.config,
|
|
106
|
+
force: flags.force,
|
|
107
|
+
yes: flags.yes,
|
|
138
108
|
cwd: process.cwd(),
|
|
139
109
|
})
|
|
140
110
|
process.exit(result.success ? 0 : 1)
|
|
@@ -148,22 +118,38 @@ async function main() {
|
|
|
148
118
|
}
|
|
149
119
|
}
|
|
150
120
|
|
|
121
|
+
// Get task filter from named parameter
|
|
122
|
+
const task = _.task
|
|
123
|
+
const passthrough = _.passthrough
|
|
124
|
+
|
|
125
|
+
// Validate: passthrough requires a single task filter
|
|
126
|
+
if (passthrough && passthrough.length > 0 && !task) {
|
|
127
|
+
console.error("Error: Passthrough arguments (after --) require a task filter")
|
|
128
|
+
console.error("Usage: verify <task> -- [args...]")
|
|
129
|
+
process.exit(2)
|
|
130
|
+
}
|
|
131
|
+
|
|
151
132
|
// Build verify options
|
|
152
133
|
const verifyOptions = {
|
|
153
|
-
format:
|
|
134
|
+
format: flags.json ? "json" : "human",
|
|
154
135
|
logs:
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
136
|
+
flags.logs ?? (flags.verbose ? "all" : flags.quiet ? "none" : "failed"),
|
|
137
|
+
filter: task ? [task] : undefined,
|
|
138
|
+
cwd: flags.config,
|
|
139
|
+
topLevelOnly: flags.topLevel,
|
|
140
|
+
noTty: flags.noTty,
|
|
141
|
+
passthrough: passthrough && passthrough.length > 0 ? passthrough : undefined,
|
|
161
142
|
}
|
|
162
143
|
|
|
163
144
|
try {
|
|
164
145
|
const result = await verifyFromConfig(process.cwd(), verifyOptions)
|
|
165
146
|
process.exit(result.ok ? 0 : 1)
|
|
166
147
|
} catch (error) {
|
|
148
|
+
// Handle task not found / ambiguous task errors with exit code 2
|
|
149
|
+
if (error instanceof TaskNotFoundError || error instanceof AmbiguousTaskError) {
|
|
150
|
+
console.error(`Error: ${error.message}`)
|
|
151
|
+
process.exit(2)
|
|
152
|
+
}
|
|
167
153
|
if (error instanceof Error) {
|
|
168
154
|
console.error(`Error: ${error.message}`)
|
|
169
155
|
} else {
|