@ankurhalder/codebase-snapshot 2.0.0 → 2.1.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 +42 -0
- package/dist/bin.js +2330 -367
- package/dist/{chunk-RGDVLQTT.js → chunk-QEIOXPMU.js} +2242 -366
- package/dist/cli.cjs +2346 -390
- package/dist/cli.d.cts +9 -1
- package/dist/cli.d.ts +9 -1
- package/dist/cli.js +108 -27
- package/dist/index.cjs +2255 -365
- package/dist/index.d.cts +183 -6
- package/dist/index.d.ts +183 -6
- package/dist/index.js +1 -1
- package/dist/{types-S-5eRuRc.d.cts → types-CJqkePM4.d.cts} +20 -1
- package/dist/{types-S-5eRuRc.d.ts → types-CJqkePM4.d.ts} +20 -1
- package/docs/configuration.md +97 -1
- package/docs/install.md +136 -0
- package/package.json +3 -2
package/dist/cli.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { O as OutputFormat } from './types-
|
|
1
|
+
import { O as OutputFormat } from './types-CJqkePM4.cjs';
|
|
2
2
|
|
|
3
3
|
type Command = "generate" | "validate" | "report" | "init" | "explain" | "diff";
|
|
4
4
|
/** A user-input problem: printed without a stack trace, exits 2. */
|
|
@@ -11,6 +11,14 @@ interface ParsedInvocation {
|
|
|
11
11
|
format: OutputFormat;
|
|
12
12
|
dryRun: boolean;
|
|
13
13
|
watch: boolean;
|
|
14
|
+
preset?: string;
|
|
15
|
+
/** The size exactly as typed, so the generated config can keep `120k`. */
|
|
16
|
+
maxPartBytesRaw?: string;
|
|
17
|
+
include?: string;
|
|
18
|
+
exclude?: string;
|
|
19
|
+
yes: boolean;
|
|
20
|
+
minimal: boolean;
|
|
21
|
+
force: boolean;
|
|
14
22
|
cwd: string;
|
|
15
23
|
outDir?: string;
|
|
16
24
|
includeMonolith?: boolean;
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { O as OutputFormat } from './types-
|
|
1
|
+
import { O as OutputFormat } from './types-CJqkePM4.js';
|
|
2
2
|
|
|
3
3
|
type Command = "generate" | "validate" | "report" | "init" | "explain" | "diff";
|
|
4
4
|
/** A user-input problem: printed without a stack trace, exits 2. */
|
|
@@ -11,6 +11,14 @@ interface ParsedInvocation {
|
|
|
11
11
|
format: OutputFormat;
|
|
12
12
|
dryRun: boolean;
|
|
13
13
|
watch: boolean;
|
|
14
|
+
preset?: string;
|
|
15
|
+
/** The size exactly as typed, so the generated config can keep `120k`. */
|
|
16
|
+
maxPartBytesRaw?: string;
|
|
17
|
+
include?: string;
|
|
18
|
+
exclude?: string;
|
|
19
|
+
yes: boolean;
|
|
20
|
+
minimal: boolean;
|
|
21
|
+
force: boolean;
|
|
14
22
|
cwd: string;
|
|
15
23
|
outDir?: string;
|
|
16
24
|
includeMonolith?: boolean;
|
package/dist/cli.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseByteSize, GENERATOR_VERSION, ARTIFACT_NAMES, MIN_MAX_PART_BYTES, loadConfigFileDetailed, resolveConfig, validateSnapshot, explainPath, compareManifests, loadManifest, renderDiffText, generateSnapshot, GENERATOR_NAME,
|
|
1
|
+
import { parseByteSize, GENERATOR_VERSION, ARTIFACT_NAMES, getPreset, unknownPresetMessage, MIN_MAX_PART_BYTES, loadConfigFileDetailed, resolveConfig, validateSnapshot, explainPath, compareManifests, loadManifest, renderDiffText, generateSnapshot, GENERATOR_NAME, runInit, PromptCancelled, renderExplainText } from './chunk-QEIOXPMU.js';
|
|
2
2
|
import * as fs from 'fs';
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { parseArgs } from 'util';
|
|
@@ -35,6 +35,12 @@ var CLI_OPTIONS = {
|
|
|
35
35
|
mode: { type: "string" },
|
|
36
36
|
"dry-run": { type: "boolean" },
|
|
37
37
|
watch: { type: "boolean" },
|
|
38
|
+
preset: { type: "string" },
|
|
39
|
+
include: { type: "string" },
|
|
40
|
+
exclude: { type: "string" },
|
|
41
|
+
yes: { type: "boolean" },
|
|
42
|
+
minimal: { type: "boolean" },
|
|
43
|
+
force: { type: "boolean" },
|
|
38
44
|
help: { type: "boolean", short: "h" },
|
|
39
45
|
version: { type: "boolean", short: "v" }
|
|
40
46
|
};
|
|
@@ -72,6 +78,14 @@ Options:
|
|
|
72
78
|
--format <text|json> CLI output format (default: text)
|
|
73
79
|
--dry-run Compute the snapshot without writing anything
|
|
74
80
|
--watch Re-generate whenever the repository changes
|
|
81
|
+
|
|
82
|
+
init only:
|
|
83
|
+
--preset <name> Force a project preset instead of detecting one
|
|
84
|
+
--include <globs> Comma-separated allow-list
|
|
85
|
+
--exclude <globs> Comma-separated exclude patterns
|
|
86
|
+
--minimal Write only the settings that differ from defaults
|
|
87
|
+
--yes Accept every default without prompting
|
|
88
|
+
--force Overwrite an existing config
|
|
75
89
|
-h, --help Display this help message
|
|
76
90
|
-v, --version Display version
|
|
77
91
|
|
|
@@ -196,12 +210,37 @@ function parseCliArgs(argv) {
|
|
|
196
210
|
} else if (rawSkip !== void 0) {
|
|
197
211
|
skipArtifacts = parseArtifactList(String(rawSkip), "--skip-artifacts");
|
|
198
212
|
}
|
|
213
|
+
if (command !== "init") {
|
|
214
|
+
const initOnly = [];
|
|
215
|
+
if (values.preset !== void 0) initOnly.push("--preset");
|
|
216
|
+
if (values.include !== void 0) initOnly.push("--include");
|
|
217
|
+
if (values.exclude !== void 0) initOnly.push("--exclude");
|
|
218
|
+
if (values.yes === true) initOnly.push("--yes");
|
|
219
|
+
if (values.minimal === true) initOnly.push("--minimal");
|
|
220
|
+
if (values.force === true) initOnly.push("--force");
|
|
221
|
+
if (initOnly.length > 0) {
|
|
222
|
+
throw new UsageError(
|
|
223
|
+
`${initOnly.join(", ")} ${initOnly.length === 1 ? "is" : "are"} only valid with \`init\`. To scope \`${command}\`, set include/excludePatterns/preset in snapshot.config.ts (or run \`snap init\` to generate one).`
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (command === "init" && values.preset !== void 0) {
|
|
228
|
+
const requested = String(values.preset);
|
|
229
|
+
if (!getPreset(requested)) throw new UsageError(unknownPresetMessage(requested));
|
|
230
|
+
}
|
|
199
231
|
return {
|
|
200
232
|
command,
|
|
201
233
|
args,
|
|
202
234
|
format: rawFormat,
|
|
203
235
|
dryRun: values["dry-run"] === true,
|
|
204
236
|
watch: values.watch === true,
|
|
237
|
+
preset: values.preset === void 0 ? void 0 : String(values.preset),
|
|
238
|
+
maxPartBytesRaw: values["max-part-bytes"] === void 0 ? void 0 : String(values["max-part-bytes"]),
|
|
239
|
+
include: values.include === void 0 ? void 0 : String(values.include),
|
|
240
|
+
exclude: values.exclude === void 0 ? void 0 : String(values.exclude),
|
|
241
|
+
yes: values.yes === true,
|
|
242
|
+
minimal: values.minimal === true,
|
|
243
|
+
force: values.force === true,
|
|
205
244
|
cwd: values.cwd === void 0 ? process.cwd() : path.resolve(String(values.cwd)),
|
|
206
245
|
outDir: values["out-dir"] === void 0 ? void 0 : String(values["out-dir"]),
|
|
207
246
|
includeMonolith: values["include-monolith"] === true ? true : void 0,
|
|
@@ -242,32 +281,65 @@ function emit(format, payload, textRenderer) {
|
|
|
242
281
|
}
|
|
243
282
|
textRenderer();
|
|
244
283
|
}
|
|
245
|
-
function
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
284
|
+
function splitList(value) {
|
|
285
|
+
if (value === void 0) return void 0;
|
|
286
|
+
return value.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
287
|
+
}
|
|
288
|
+
function describeManifestShapeProblem(manifest) {
|
|
289
|
+
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
|
|
290
|
+
return "not a JSON object";
|
|
251
291
|
}
|
|
252
|
-
const
|
|
253
|
-
const
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
292
|
+
const candidate = manifest;
|
|
293
|
+
const counts = candidate.counts;
|
|
294
|
+
if (!counts || typeof counts !== "object") return "missing `counts`";
|
|
295
|
+
for (const key of ["totalFiles", "totalLines", "totalSizeBytes", "partsCount"]) {
|
|
296
|
+
if (typeof counts[key] !== "number") return `missing numeric \`counts.${key}\``;
|
|
297
|
+
}
|
|
298
|
+
if (!candidate.layers || typeof candidate.layers !== "object") return "missing `layers`";
|
|
299
|
+
if (!Array.isArray(candidate.files)) return "missing `files` array";
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
async function runInitCommand(invocation) {
|
|
303
|
+
try {
|
|
304
|
+
const result = await runInit({
|
|
305
|
+
cwd: invocation.cwd,
|
|
306
|
+
preset: invocation.preset,
|
|
307
|
+
maxPartBytes: invocation.maxPartBytesRaw ?? invocation.maxPartBytes,
|
|
308
|
+
include: splitList(invocation.include),
|
|
309
|
+
exclude: splitList(invocation.exclude),
|
|
310
|
+
skipArtifacts: invocation.skipArtifacts,
|
|
311
|
+
includeSensitiveFiles: invocation.includeSensitiveFiles,
|
|
312
|
+
yes: invocation.yes,
|
|
313
|
+
minimal: invocation.minimal,
|
|
314
|
+
force: invocation.force,
|
|
315
|
+
dryRun: invocation.dryRun
|
|
316
|
+
});
|
|
317
|
+
if (invocation.format === "json") {
|
|
318
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}
|
|
319
|
+
`);
|
|
320
|
+
return 0;
|
|
321
|
+
}
|
|
322
|
+
if (!result.written) {
|
|
323
|
+
info(result.configText);
|
|
324
|
+
return 0;
|
|
325
|
+
}
|
|
326
|
+
info(`\u2705 Created ${path.basename(result.configPath)} (preset: ${result.preset})`);
|
|
327
|
+
if (result.scripts.length > 0) info(` Added npm scripts: ${result.scripts.join(", ")}`);
|
|
328
|
+
if (result.gitignoreEntries.length > 0) {
|
|
329
|
+
info(` Added to .gitignore: ${result.gitignoreEntries.join(", ")}`);
|
|
330
|
+
}
|
|
331
|
+
for (const note of result.notes) info(` \u26A0 ${note}`);
|
|
332
|
+
info("");
|
|
333
|
+
info(" Next: npm run snapshot");
|
|
334
|
+
return 0;
|
|
335
|
+
} catch (err) {
|
|
336
|
+
if (err instanceof PromptCancelled) {
|
|
337
|
+
warn("\u274C Cancelled.");
|
|
338
|
+
return 1;
|
|
339
|
+
}
|
|
340
|
+
warn(`\u274C ${err.message}`);
|
|
341
|
+
return 1;
|
|
269
342
|
}
|
|
270
|
-
return 0;
|
|
271
343
|
}
|
|
272
344
|
function renderValidateText(result) {
|
|
273
345
|
if (result.valid) {
|
|
@@ -309,10 +381,14 @@ ${USAGE}
|
|
|
309
381
|
throw err;
|
|
310
382
|
}
|
|
311
383
|
if (invocation.command === "init") {
|
|
312
|
-
return
|
|
384
|
+
return await runInitCommand(invocation);
|
|
313
385
|
}
|
|
314
386
|
const loaded = await loadConfigFileDetailed(invocation.cwd);
|
|
315
387
|
for (const warning of loaded.warnings) warn(`\u26A0 Config: ${warning}`);
|
|
388
|
+
if (loaded.errors.length > 0) {
|
|
389
|
+
warn("\u274C The config file could not be read. Fix it, or delete it to use the defaults.");
|
|
390
|
+
return 1;
|
|
391
|
+
}
|
|
316
392
|
if (loaded.file) info(`\u2699 Using config ${path.relative(process.cwd(), loaded.file) || loaded.file}`);
|
|
317
393
|
const resolved = resolveConfig(
|
|
318
394
|
loaded.config,
|
|
@@ -337,7 +413,7 @@ ${USAGE}
|
|
|
337
413
|
return result.valid ? 0 : 1;
|
|
338
414
|
}
|
|
339
415
|
if (invocation.command === "report") {
|
|
340
|
-
const manifestPath = path.
|
|
416
|
+
const manifestPath = path.resolve(resolved.cwd, resolved.outDir, "manifest.json");
|
|
341
417
|
if (!fs.existsSync(manifestPath)) {
|
|
342
418
|
warn(`\u274C Manifest not found at ${manifestPath}. Run generate first.`);
|
|
343
419
|
return 1;
|
|
@@ -349,6 +425,11 @@ ${USAGE}
|
|
|
349
425
|
warn(`\u274C Could not read ${manifestPath}: ${err.message}`);
|
|
350
426
|
return 1;
|
|
351
427
|
}
|
|
428
|
+
const shapeError = describeManifestShapeProblem(manifest);
|
|
429
|
+
if (shapeError) {
|
|
430
|
+
warn(`\u274C ${manifestPath} is not a snapshot manifest: ${shapeError}`);
|
|
431
|
+
return 1;
|
|
432
|
+
}
|
|
352
433
|
const validation = validateSnapshot(resolved);
|
|
353
434
|
emit(invocation.format, { manifest, validation }, () => {
|
|
354
435
|
info(`
|