@tlog/cli 0.1.3
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 +307 -0
- package/bin/.gitkeep +0 -0
- package/bin/tlog.js +4 -0
- package/dist/commands/delete.d.ts +8 -0
- package/dist/commands/delete.d.ts.map +1 -0
- package/dist/commands/delete.js +104 -0
- package/dist/commands/delete.js.map +1 -0
- package/dist/commands/init-template.d.ts +12 -0
- package/dist/commands/init-template.d.ts.map +1 -0
- package/dist/commands/init-template.js +168 -0
- package/dist/commands/init-template.js.map +1 -0
- package/dist/commands/related.d.ts +13 -0
- package/dist/commands/related.d.ts.map +1 -0
- package/dist/commands/related.js +193 -0
- package/dist/commands/related.js.map +1 -0
- package/dist/commands/stats.d.ts +8 -0
- package/dist/commands/stats.d.ts.map +1 -0
- package/dist/commands/stats.js +62 -0
- package/dist/commands/stats.js.map +1 -0
- package/dist/commands/suite-case.d.ts +20 -0
- package/dist/commands/suite-case.d.ts.map +1 -0
- package/dist/commands/suite-case.js +83 -0
- package/dist/commands/suite-case.js.map +1 -0
- package/dist/commands/update.d.ts +33 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +159 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/validate-list.d.ts +36 -0
- package/dist/commands/validate-list.d.ts.map +1 -0
- package/dist/commands/validate-list.js +270 -0
- package/dist/commands/validate-list.js.map +1 -0
- package/dist/core.d.ts +30 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +143 -0
- package/dist/core.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +218 -0
- package/dist/index.js.map +1 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# @tlog/cli
|
|
2
|
+
|
|
3
|
+
`tlog` is a YAML-first test management CLI.
|
|
4
|
+
|
|
5
|
+
It helps you bootstrap a test workspace, create suites/cases, validate schema consistency, and manage related links from the terminal.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
### Option 1: Global install (recommended for daily use)
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g @tlog/cli
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Check installation:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
tlog --version
|
|
19
|
+
tlog --help
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Option 2: Run without installing globally
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx @tlog/cli --help
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
This is the fastest path from an empty repo to usable test files.
|
|
31
|
+
|
|
32
|
+
1. Initialize a workspace directory (recommended: always pass `--output`; default is `tests`).
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
tlog init --output tests
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
2. Create your first suite.
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
tlog suite create --id auth --title "Authentication"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
3. Create your first case in that suite.
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
tlog case create --suite-dir tests/auth --id login-success --title "User can log in"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
4. Validate everything.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
tlog validate
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Expected structure after steps 1-3:
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
tests/
|
|
60
|
+
├─ index.yaml
|
|
61
|
+
├─ default-case.testcase.yaml
|
|
62
|
+
└─ auth/
|
|
63
|
+
├─ index.yaml
|
|
64
|
+
└─ login-success.testcase.yaml
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Need command-level help?
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
tlog --help
|
|
71
|
+
tlog suite --help
|
|
72
|
+
tlog case --help
|
|
73
|
+
tlog related --help
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Core Concepts
|
|
77
|
+
|
|
78
|
+
- `suite`: represented by `index.yaml` (or `*.suite.yaml` in broader ecosystem usage).
|
|
79
|
+
- `case`: represented by `*.testcase.yaml`.
|
|
80
|
+
- IDs must match `^[A-Za-z0-9_-]+$`.
|
|
81
|
+
- By default, most commands search under `tests/`.
|
|
82
|
+
|
|
83
|
+
## Deep Dive: `init`
|
|
84
|
+
|
|
85
|
+
`init` creates a ready-to-use base workspace.
|
|
86
|
+
|
|
87
|
+
### Recommended usage (explicit output directory)
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
tlog init --output tests
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Creates:
|
|
94
|
+
|
|
95
|
+
- `tests/index.yaml`
|
|
96
|
+
- `tests/default-case.testcase.yaml`
|
|
97
|
+
|
|
98
|
+
(`--output` is optional; if omitted, `tests` is used.)
|
|
99
|
+
|
|
100
|
+
### Use a custom output directory
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
tlog init --output qa-tests
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Initialize from a local template directory
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
tlog init --template templates/default --output tests
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Template requirements:
|
|
113
|
+
|
|
114
|
+
- Must contain `index.yaml`.
|
|
115
|
+
- May include one or more case YAML files; the first one is used as the case template.
|
|
116
|
+
- Template must pass schema validation.
|
|
117
|
+
|
|
118
|
+
### Preview changes before writing files
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
tlog init --dry-run
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Machine-readable output
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
tlog init --json
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Deep Dive: `suite create` and `case create`
|
|
131
|
+
|
|
132
|
+
Creation commands are designed to be strict and predictable.
|
|
133
|
+
|
|
134
|
+
### `suite create`
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
tlog suite create \
|
|
138
|
+
--id auth \
|
|
139
|
+
--title "Authentication" \
|
|
140
|
+
--dir tests \
|
|
141
|
+
--owners qa-team,backend \
|
|
142
|
+
--tags smoke,critical \
|
|
143
|
+
--scheduled-start 2026-02-01 \
|
|
144
|
+
--scheduled-end 2026-02-15
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Behavior:
|
|
148
|
+
|
|
149
|
+
- Creates suite directory: `tests/<id>/`
|
|
150
|
+
- Writes suite file: `tests/<id>/index.yaml`
|
|
151
|
+
- Rejects duplicate IDs across YAML files under `--dir`
|
|
152
|
+
- Rejects invalid IDs
|
|
153
|
+
|
|
154
|
+
### `case create`
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
tlog case create \
|
|
158
|
+
--suite-dir tests/auth \
|
|
159
|
+
--id login-success \
|
|
160
|
+
--title "User can log in" \
|
|
161
|
+
--status todo \
|
|
162
|
+
--tags smoke,auth
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Behavior:
|
|
166
|
+
|
|
167
|
+
- Writes case file: `<suite-dir>/<id>.testcase.yaml`
|
|
168
|
+
- Verifies `--suite-dir` exists
|
|
169
|
+
- Rejects duplicate IDs (searched in parent root of the suite directory)
|
|
170
|
+
- Supports status: `todo | doing | done | null`
|
|
171
|
+
|
|
172
|
+
## Template Workflow (Reusable Bootstrap)
|
|
173
|
+
|
|
174
|
+
Create a reusable template from defaults:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
tlog template --output templates/default
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Extract template from existing test directory:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
tlog template --from tests --output templates/team-standard
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
List available templates:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
tlog list templates --dir templates --format text
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Command Reference
|
|
193
|
+
|
|
194
|
+
### Global options
|
|
195
|
+
|
|
196
|
+
- `--dry-run`: preview without writing files
|
|
197
|
+
- `--json`: force JSON output
|
|
198
|
+
- `--yes`: skip confirmation prompts (mainly for delete flows)
|
|
199
|
+
|
|
200
|
+
### Workspace bootstrap
|
|
201
|
+
|
|
202
|
+
- `tlog init [--template <dir>] [--output <dir>]`
|
|
203
|
+
- `tlog template [--from <dir>] [--output <dir>]`
|
|
204
|
+
|
|
205
|
+
### Suite commands
|
|
206
|
+
|
|
207
|
+
- `tlog suite create --id <id> --title <title> [--dir <dir>] [--owners <a,b>] [--tags <a,b>] [--scheduled-start <YYYY-MM-DD>] [--scheduled-end <YYYY-MM-DD>]`
|
|
208
|
+
- `tlog suite update --id <id> [--dir <dir>] [--title <title>] [--description <text>] [--tags <a,b>] [--owners <a,b>] [--related <a,b>] [--remarks <a,b>] [--scoped <true|false>] [--scheduled-start <YYYY-MM-DD>] [--scheduled-end <YYYY-MM-DD>] [--actual-start <YYYY-MM-DD>] [--actual-end <YYYY-MM-DD>]`
|
|
209
|
+
- `tlog suite delete --id <id> [--dir <dir>] [--yes]`
|
|
210
|
+
- `tlog suite stats --id <id> [--dir <dir>] [--format <text|json>]`
|
|
211
|
+
- `tlog suite list [--dir <dir>] [--id <pattern>] [--format <text|json|csv>] [--output <path>]`
|
|
212
|
+
|
|
213
|
+
### Case commands
|
|
214
|
+
|
|
215
|
+
- `tlog case create --suite-dir <dir> --id <id> --title <title> [--status <todo|doing|done|null>] [--tags <a,b>]`
|
|
216
|
+
- `tlog case update --id <id> [--dir <dir>] [--status <todo|doing|done|null>] [--tags <a,b>] [--description <text>] [--operations <a,b>] [--related <a,b>] [--remarks <a,b>] [--scoped <true|false>] [--completed-day <YYYY-MM-DD|null>] [--tests-file <path>] [--issues-file <path>]`
|
|
217
|
+
- `tlog case delete --id <id> [--dir <dir>] [--yes]`
|
|
218
|
+
- `tlog case list [--dir <dir>] [--id <pattern>] [--tag <tag>] [--owners <a,b>] [--scoped-only] [--issue-has <keyword>] [--issue-status <open|doing|resolved|pending>] [--status <todo|doing|done|null>] [--format <text|json|csv>] [--output <path>]`
|
|
219
|
+
|
|
220
|
+
### Related link commands
|
|
221
|
+
|
|
222
|
+
- `tlog related sync [--dir <dir>] [--id <id>]`
|
|
223
|
+
- `tlog related list --id <id> [--dir <dir>] [--format <text|json|csv>]`
|
|
224
|
+
|
|
225
|
+
### Validation and listing
|
|
226
|
+
|
|
227
|
+
- `tlog validate [--dir <dir>] [--fail-on-warning] [--watch] [--watch-interval <ms>] [--format <text|json>]`
|
|
228
|
+
- `tlog list templates [--dir <dir>] [--format <text|json|csv>] [--output <path>]`
|
|
229
|
+
|
|
230
|
+
## Practical Usage Patterns
|
|
231
|
+
|
|
232
|
+
### 1) CI-friendly validation
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
tlog validate --dir tests --format json --fail-on-warning
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
- Exit code is non-zero on validation failure.
|
|
239
|
+
- Useful for pull request gates.
|
|
240
|
+
|
|
241
|
+
### 2) Bulk case filtering and export
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
tlog case list --dir tests --status doing --format csv --output reports/doing-cases.csv
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### 3) Safe delete with explicit confirmation skip
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
tlog case delete --dir tests --id login-success --yes
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Delete behavior:
|
|
254
|
+
|
|
255
|
+
- Files are moved to `.tlog-trash/` (near the root directory parent), not immediately hard-deleted.
|
|
256
|
+
|
|
257
|
+
## JSON Output Contract
|
|
258
|
+
|
|
259
|
+
Success shape:
|
|
260
|
+
|
|
261
|
+
```json
|
|
262
|
+
{
|
|
263
|
+
"ok": true,
|
|
264
|
+
"command": "suite create",
|
|
265
|
+
"data": {
|
|
266
|
+
"id": "auth",
|
|
267
|
+
"path": "tests/auth/index.yaml",
|
|
268
|
+
"dryRun": false
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Failure shape:
|
|
274
|
+
|
|
275
|
+
```json
|
|
276
|
+
{
|
|
277
|
+
"ok": false,
|
|
278
|
+
"command": "suite create",
|
|
279
|
+
"error": {
|
|
280
|
+
"message": "ID already exists: auth",
|
|
281
|
+
"details": ["tests/auth/index.yaml"]
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## Troubleshooting
|
|
287
|
+
|
|
288
|
+
### `ID already exists`
|
|
289
|
+
|
|
290
|
+
- IDs are unique across YAML files under the search root.
|
|
291
|
+
- Use `tlog suite list` / `tlog case list` to find conflicts.
|
|
292
|
+
|
|
293
|
+
### `... not found`
|
|
294
|
+
|
|
295
|
+
- Confirm your `--dir` or `--suite-dir` path.
|
|
296
|
+
- Default root is `tests` for most commands.
|
|
297
|
+
|
|
298
|
+
### Validation errors on update
|
|
299
|
+
|
|
300
|
+
- `suite update` and `case update` validate before writing.
|
|
301
|
+
- Check reported `path: message` details and retry.
|
|
302
|
+
|
|
303
|
+
## Version
|
|
304
|
+
|
|
305
|
+
```bash
|
|
306
|
+
tlog --version
|
|
307
|
+
```
|
package/bin/.gitkeep
ADDED
|
File without changes
|
package/bin/tlog.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type GlobalOptions } from "../core.js";
|
|
2
|
+
export interface DeleteOptions {
|
|
3
|
+
dir: string;
|
|
4
|
+
id: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function runSuiteDelete(cwd: string, options: DeleteOptions, globalOptions: GlobalOptions): void;
|
|
7
|
+
export declare function runCaseDelete(cwd: string, options: DeleteOptions, globalOptions: GlobalOptions): void;
|
|
8
|
+
//# sourceMappingURL=delete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"AAIA,OAAO,EAAmE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAEjH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;CACZ;AAoDD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,GAAG,IAAI,CAiCtG;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,GAAG,IAAI,CAgCrG"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { mkdirSync, readFileSync, readSync, renameSync } from "node:fs";
|
|
2
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
3
|
+
import { randomUUID } from "node:crypto";
|
|
4
|
+
import { detectEntityType, normalizeTlogPath, parseYaml } from "@tlog/shared";
|
|
5
|
+
import { CliError, emitSuccess, ensureDirectory, formatOf, walkYamlFiles } from "../core.js";
|
|
6
|
+
function findById(rootDir, id, type) {
|
|
7
|
+
const matches = walkYamlFiles(rootDir).filter((path) => {
|
|
8
|
+
if (detectEntityType(path) !== type) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
const raw = parseYaml(readFileSync(path, "utf8"));
|
|
13
|
+
return raw.id === id;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
if (matches.length === 0) {
|
|
20
|
+
throw new CliError(`${type} not found: ${id}`);
|
|
21
|
+
}
|
|
22
|
+
if (matches.length > 1) {
|
|
23
|
+
throw new CliError(`Multiple ${type} entries found for id: ${id}`, {
|
|
24
|
+
details: matches.map((item) => normalizeTlogPath(item))
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return matches[0];
|
|
28
|
+
}
|
|
29
|
+
function confirm(prompt) {
|
|
30
|
+
if (!process.stdin.isTTY) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
process.stdout.write(`${prompt} [y/N]: `);
|
|
34
|
+
const buffer = Buffer.alloc(32);
|
|
35
|
+
const bytes = readSync(process.stdin.fd, buffer, 0, buffer.length, null);
|
|
36
|
+
const input = buffer.toString("utf8", 0, bytes).trim().toLowerCase();
|
|
37
|
+
return input === "y" || input === "yes";
|
|
38
|
+
}
|
|
39
|
+
function ensureInsideRoot(rootDir, targetPath) {
|
|
40
|
+
const normalizedRoot = normalizeTlogPath(resolve(rootDir));
|
|
41
|
+
const normalizedTarget = normalizeTlogPath(resolve(targetPath));
|
|
42
|
+
if (!normalizedTarget.startsWith(`${normalizedRoot}/`) && normalizedTarget !== normalizedRoot) {
|
|
43
|
+
throw new CliError(`Target is outside root directory: ${normalizedTarget}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function moveToTrash(trashBaseDir, sourcePath) {
|
|
47
|
+
const trashDir = join(trashBaseDir, ".tlog-trash");
|
|
48
|
+
mkdirSync(trashDir, { recursive: true });
|
|
49
|
+
const target = join(trashDir, `${Date.now()}-${randomUUID()}-${basename(sourcePath)}`);
|
|
50
|
+
renameSync(sourcePath, target);
|
|
51
|
+
return target;
|
|
52
|
+
}
|
|
53
|
+
export function runSuiteDelete(cwd, options, globalOptions) {
|
|
54
|
+
const format = formatOf(globalOptions);
|
|
55
|
+
const rootDir = resolve(cwd, options.dir);
|
|
56
|
+
const trashBaseDir = dirname(rootDir);
|
|
57
|
+
ensureDirectory(rootDir, "Suite search directory does not exist");
|
|
58
|
+
const suitePath = findById(rootDir, options.id, "suite");
|
|
59
|
+
const targetPath = dirname(suitePath);
|
|
60
|
+
ensureInsideRoot(rootDir, targetPath);
|
|
61
|
+
if (!globalOptions.yes) {
|
|
62
|
+
const accepted = confirm(`Delete suite ${options.id}?`);
|
|
63
|
+
if (!accepted) {
|
|
64
|
+
throw new CliError("Delete cancelled. Re-run with --yes to skip confirmation.");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const trashPath = normalizeTlogPath(join(trashBaseDir, ".tlog-trash", "<generated>"));
|
|
68
|
+
let movedTo = null;
|
|
69
|
+
if (!globalOptions.dryRun) {
|
|
70
|
+
movedTo = normalizeTlogPath(moveToTrash(trashBaseDir, targetPath));
|
|
71
|
+
}
|
|
72
|
+
emitSuccess("suite delete", {
|
|
73
|
+
id: options.id,
|
|
74
|
+
path: normalizeTlogPath(targetPath),
|
|
75
|
+
dryRun: globalOptions.dryRun,
|
|
76
|
+
movedTo: movedTo ?? trashPath
|
|
77
|
+
}, format, [`${globalOptions.dryRun ? "Would delete" : "Deleted"}: ${normalizeTlogPath(targetPath)}`]);
|
|
78
|
+
}
|
|
79
|
+
export function runCaseDelete(cwd, options, globalOptions) {
|
|
80
|
+
const format = formatOf(globalOptions);
|
|
81
|
+
const rootDir = resolve(cwd, options.dir);
|
|
82
|
+
const trashBaseDir = dirname(rootDir);
|
|
83
|
+
ensureDirectory(rootDir, "Case search directory does not exist");
|
|
84
|
+
const targetPath = findById(rootDir, options.id, "case");
|
|
85
|
+
ensureInsideRoot(rootDir, targetPath);
|
|
86
|
+
if (!globalOptions.yes) {
|
|
87
|
+
const accepted = confirm(`Delete case ${options.id}?`);
|
|
88
|
+
if (!accepted) {
|
|
89
|
+
throw new CliError("Delete cancelled. Re-run with --yes to skip confirmation.");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const trashPath = normalizeTlogPath(join(trashBaseDir, ".tlog-trash", "<generated>"));
|
|
93
|
+
let movedTo = null;
|
|
94
|
+
if (!globalOptions.dryRun) {
|
|
95
|
+
movedTo = normalizeTlogPath(moveToTrash(trashBaseDir, targetPath));
|
|
96
|
+
}
|
|
97
|
+
emitSuccess("case delete", {
|
|
98
|
+
id: options.id,
|
|
99
|
+
path: normalizeTlogPath(targetPath),
|
|
100
|
+
dryRun: globalOptions.dryRun,
|
|
101
|
+
movedTo: movedTo ?? trashPath
|
|
102
|
+
}, format, [`${globalOptions.dryRun ? "Would delete" : "Deleted"}: ${normalizeTlogPath(targetPath)}`]);
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=delete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type GlobalOptions } from "../core.js";
|
|
2
|
+
export interface InitOptions {
|
|
3
|
+
output: string;
|
|
4
|
+
template?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface TemplateOptions {
|
|
7
|
+
from?: string;
|
|
8
|
+
output: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function runInit(cwd: string, options: InitOptions, globalOptions: GlobalOptions): void;
|
|
11
|
+
export declare function runTemplate(cwd: string, options: TemplateOptions, globalOptions: GlobalOptions): void;
|
|
12
|
+
//# sourceMappingURL=init-template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-template.d.ts","sourceRoot":"","sources":["../../src/commands/init-template.ts"],"names":[],"mappings":"AAWA,OAAO,EAAoD,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAElG,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAuED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,GAAG,IAAI,CAiE7F;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,GAAG,IAAI,CAuErG"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join, normalize, resolve } from "node:path";
|
|
3
|
+
import { buildDefaultCase, buildDefaultSuite, parseYaml, stringifyYaml, validateTemplate } from "@tlog/shared";
|
|
4
|
+
import { CliError, emitSuccess, ensureDirectory, formatOf } from "../core.js";
|
|
5
|
+
function normalizeTemplateCase(input) {
|
|
6
|
+
const issues = Array.isArray(input.issues)
|
|
7
|
+
? input.issues.map((issue) => {
|
|
8
|
+
if (!issue || typeof issue !== "object") {
|
|
9
|
+
return issue;
|
|
10
|
+
}
|
|
11
|
+
const source = issue;
|
|
12
|
+
const normalized = { ...source };
|
|
13
|
+
if (!("detectedDay" in normalized)) {
|
|
14
|
+
normalized.detectedDay = null;
|
|
15
|
+
}
|
|
16
|
+
if (!("completedDay" in normalized)) {
|
|
17
|
+
normalized.completedDay = null;
|
|
18
|
+
}
|
|
19
|
+
return normalized;
|
|
20
|
+
})
|
|
21
|
+
: input.issues;
|
|
22
|
+
return {
|
|
23
|
+
...input,
|
|
24
|
+
issues
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function createDefaultTemplateData() {
|
|
28
|
+
const suite = buildDefaultSuite({ id: "default", title: "Default Suite", description: "tlog test suite" });
|
|
29
|
+
const testCase = buildDefaultCase({ id: "default-case", title: "Default Case", status: "todo" });
|
|
30
|
+
return { suite, testCase };
|
|
31
|
+
}
|
|
32
|
+
function safePath(path) {
|
|
33
|
+
return normalize(path).split("\\").join("/");
|
|
34
|
+
}
|
|
35
|
+
function readTemplateDirectory(templateDir) {
|
|
36
|
+
const indexPath = join(templateDir, "index.yaml");
|
|
37
|
+
if (!existsSync(indexPath)) {
|
|
38
|
+
throw new CliError("Template is missing required file", {
|
|
39
|
+
details: [safePath(indexPath)]
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const template = {
|
|
43
|
+
suite: parseYamlFile(indexPath),
|
|
44
|
+
testCase: {}
|
|
45
|
+
};
|
|
46
|
+
const yamlFiles = readdirSync(templateDir).filter((name) => name.endsWith(".yaml") && name !== "index.yaml");
|
|
47
|
+
if (yamlFiles.length > 0) {
|
|
48
|
+
const firstCase = join(templateDir, yamlFiles[0]);
|
|
49
|
+
template.testCase = normalizeTemplateCase(parseYamlFile(firstCase));
|
|
50
|
+
}
|
|
51
|
+
return template;
|
|
52
|
+
}
|
|
53
|
+
function parseYamlFile(path) {
|
|
54
|
+
const source = readFileSync(path, "utf8");
|
|
55
|
+
return parseYaml(source);
|
|
56
|
+
}
|
|
57
|
+
export function runInit(cwd, options, globalOptions) {
|
|
58
|
+
const format = formatOf(globalOptions);
|
|
59
|
+
const outputDir = resolve(cwd, options.output);
|
|
60
|
+
const indexPath = join(outputDir, "index.yaml");
|
|
61
|
+
const casePath = join(outputDir, "default-case.testcase.yaml");
|
|
62
|
+
const defaults = createDefaultTemplateData();
|
|
63
|
+
let suite = defaults.suite;
|
|
64
|
+
let testCase = defaults.testCase;
|
|
65
|
+
if (options.template) {
|
|
66
|
+
const templateDir = resolve(cwd, options.template);
|
|
67
|
+
ensureDirectory(templateDir, "Template directory does not exist");
|
|
68
|
+
const template = readTemplateDirectory(templateDir);
|
|
69
|
+
const validation = validateTemplate(template);
|
|
70
|
+
if (!validation.valid) {
|
|
71
|
+
throw new CliError("Invalid template", { details: validation.errors });
|
|
72
|
+
}
|
|
73
|
+
suite = {
|
|
74
|
+
...suite,
|
|
75
|
+
...template.suite,
|
|
76
|
+
duration: template.suite.duration ?? suite.duration
|
|
77
|
+
};
|
|
78
|
+
testCase = {
|
|
79
|
+
...testCase,
|
|
80
|
+
...template.testCase,
|
|
81
|
+
tests: template.testCase.tests ?? testCase.tests,
|
|
82
|
+
issues: template.testCase.issues ?? testCase.issues
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const alreadyExists = [indexPath, casePath].filter((path) => existsSync(path));
|
|
86
|
+
if (alreadyExists.length > 0) {
|
|
87
|
+
throw new CliError("Target files already exist", {
|
|
88
|
+
details: alreadyExists.map((path) => safePath(path))
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
const files = [
|
|
92
|
+
{ path: indexPath, content: stringifyYaml(suite) },
|
|
93
|
+
{ path: casePath, content: stringifyYaml(testCase) }
|
|
94
|
+
];
|
|
95
|
+
if (!globalOptions.dryRun) {
|
|
96
|
+
mkdirSync(outputDir, { recursive: true });
|
|
97
|
+
for (const file of files) {
|
|
98
|
+
writeFileSync(file.path, file.content, "utf8");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
emitSuccess("init", {
|
|
102
|
+
output: safePath(outputDir),
|
|
103
|
+
dryRun: globalOptions.dryRun,
|
|
104
|
+
files: files.map((file) => safePath(file.path))
|
|
105
|
+
}, format, [
|
|
106
|
+
`Initialized: ${safePath(outputDir)}`,
|
|
107
|
+
...files.map((file) => `${globalOptions.dryRun ? "Would create" : "Created"}: ${safePath(file.path)}`)
|
|
108
|
+
]);
|
|
109
|
+
}
|
|
110
|
+
export function runTemplate(cwd, options, globalOptions) {
|
|
111
|
+
const format = formatOf(globalOptions);
|
|
112
|
+
const outputDir = resolve(cwd, options.output);
|
|
113
|
+
const indexPath = join(outputDir, "index.yaml");
|
|
114
|
+
const casePath = join(outputDir, "sample.testcase.yaml");
|
|
115
|
+
if (existsSync(indexPath) || existsSync(casePath)) {
|
|
116
|
+
throw new CliError("Output already has template files", {
|
|
117
|
+
details: [safePath(indexPath), safePath(casePath)].filter((path) => existsSync(path))
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
let suite = buildDefaultSuite({ id: "template-suite", title: "Template Suite" });
|
|
121
|
+
let testCase = buildDefaultCase({ id: "template-case", title: "Template Case" });
|
|
122
|
+
if (options.from) {
|
|
123
|
+
const sourceDir = resolve(cwd, options.from);
|
|
124
|
+
ensureDirectory(sourceDir, "Source directory does not exist");
|
|
125
|
+
const fromIndex = join(sourceDir, "index.yaml");
|
|
126
|
+
if (!existsSync(fromIndex)) {
|
|
127
|
+
throw new CliError("Source is missing required file", {
|
|
128
|
+
details: [safePath(fromIndex)]
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
const extracted = readTemplateDirectory(sourceDir);
|
|
132
|
+
const validation = validateTemplate({ suite: extracted.suite, testCase: extracted.testCase });
|
|
133
|
+
if (!validation.valid) {
|
|
134
|
+
throw new CliError("Source template is invalid", { details: validation.errors });
|
|
135
|
+
}
|
|
136
|
+
suite = {
|
|
137
|
+
...suite,
|
|
138
|
+
...extracted.suite,
|
|
139
|
+
duration: extracted.suite.duration ?? suite.duration
|
|
140
|
+
};
|
|
141
|
+
testCase = {
|
|
142
|
+
...testCase,
|
|
143
|
+
...extracted.testCase,
|
|
144
|
+
tests: extracted.testCase.tests ?? testCase.tests,
|
|
145
|
+
issues: extracted.testCase.issues ?? testCase.issues
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
const files = [
|
|
149
|
+
{ path: indexPath, content: stringifyYaml(suite) },
|
|
150
|
+
{ path: casePath, content: stringifyYaml(testCase) }
|
|
151
|
+
];
|
|
152
|
+
if (!globalOptions.dryRun) {
|
|
153
|
+
mkdirSync(outputDir, { recursive: true });
|
|
154
|
+
for (const file of files) {
|
|
155
|
+
writeFileSync(file.path, file.content, "utf8");
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
emitSuccess("template", {
|
|
159
|
+
output: safePath(outputDir),
|
|
160
|
+
from: options.from ? safePath(resolve(cwd, options.from)) : null,
|
|
161
|
+
dryRun: globalOptions.dryRun,
|
|
162
|
+
files: files.map((file) => safePath(file.path))
|
|
163
|
+
}, format, [
|
|
164
|
+
`${globalOptions.dryRun ? "Preview" : "Created"} template: ${safePath(outputDir)}`,
|
|
165
|
+
...files.map((file) => `${globalOptions.dryRun ? "Would create" : "Created"}: ${safePath(file.path)}`)
|
|
166
|
+
]);
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=init-template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-template.js","sourceRoot":"","sources":["../../src/commands/init-template.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type GlobalOptions } from "../core.js";
|
|
2
|
+
export interface RelatedSyncOptions {
|
|
3
|
+
dir: string;
|
|
4
|
+
id?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface RelatedListOptions {
|
|
7
|
+
dir: string;
|
|
8
|
+
id: string;
|
|
9
|
+
format?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function runRelatedSync(cwd: string, options: RelatedSyncOptions, globalOptions: GlobalOptions): void;
|
|
12
|
+
export declare function runRelatedList(cwd: string, options: RelatedListOptions, globalOptions: GlobalOptions): void;
|
|
13
|
+
//# sourceMappingURL=related.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"related.d.ts","sourceRoot":"","sources":["../../src/commands/related.ts"],"names":[],"mappings":"AAWA,OAAO,EAAmE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAUjH,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAkCD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,aAAa,GAAG,IAAI,CA8G3G;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,aAAa,GAAG,IAAI,CAoE3G"}
|