From cd2ac7967e77da786d0b81cbd50b125a59580a83 Mon Sep 17 00:00:00 2001 From: MongLong0214 Date: Fri, 31 Jul 2026 13:54:22 +0900 Subject: [PATCH] Stop sending users after a package the product does not carry Closes #303. Found while narrowing whether musl still has an obstacle: the only remaining better-sqlite3 string in the shipped bundle was a user-facing message. index --help documented exit 2 as "conflicting flags, or better-sqlite3 is not installed". ADR-0012 replaced better-sqlite3 with node:sqlite so there would be no native dependency, and package.json declares no runtime dependencies at all. The one place a failing user is sent pointed at a package that is not part of the product and never will be. The message now names what actually produces exit 2 -- conflicting flags, or the SQLite binding being unavailable -- and says what happens then, which is that every read still answers from git with --no-index. That is the useful half a missing-package message never had. The comments in index-db.ts that mention better-sqlite3 stay: they explain why the dependency was dropped, which is worth keeping. The new assertion covers strings that reach a user, not prose that explains a decision. Record-Id: r-idxhelp303 Ruled-out: Deleting the better-sqlite3 mentions in index-db.ts as well | those comments explain why node:sqlite was chosen, and removing the reason leaves a future reader wondering whether the native option was considered Ruled-out: Asserting the package name appears nowhere in src at all | that forbids the explanation along with the defect, so the check reads only lines that reach a user Ruled-out: Naming node:sqlite in the message | the failure a user hits is that the binding is unavailable, and the module name adds nothing they can act on Certainty: firm Blast: local Undo: easy Verified: the assertion seen failing on the shipped string first, then passing; the shipped bundle now contains zero occurrences of the package name; the corrected help text read back from the built CLI; full suite 69 files, 1797 passed, 1 skipped; tsc exit 0; dist rebuilt and committed --- dist/commands/index-cmd.js | 5 ++- dist/commands/index-cmd.js.map | 2 +- dist/commitlore.mjs | 2 +- src/commands/index-cmd.ts | 5 ++- test/help-text-honesty.test.ts | 75 ++++++++++++++++++++++++++++++++++ 5 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 test/help-text-honesty.test.ts diff --git a/dist/commands/index-cmd.js b/dist/commands/index-cmd.js index 5c12fcb7..18c035b1 100644 --- a/dist/commands/index-cmd.js +++ b/dist/commands/index-cmd.js @@ -92,8 +92,9 @@ export const register = (program) => { .option('--no-index', 'answer from git alone, writing nothing (the fallback path)') .option('--json', 'emit the run as JSON') .option('--stats', 'report what the index currently holds') - .addHelpText('after', '\nExit codes: 0 built or refreshed, 2 could not run -- conflicting flags, or better-sqlite3 is not ' + - 'installed (SPEC §10).') + .addHelpText('after', '\nExit codes: 0 built or refreshed, 2 could not run -- conflicting flags, or the SQLite ' + + 'binding is unavailable, in which case every read still answers from git with --no-index ' + + '(SPEC §10).') .action((options) => { try { if (!options.index) { diff --git a/dist/commands/index-cmd.js.map b/dist/commands/index-cmd.js.map index 0ab0bb27..1ab7995f 100644 --- a/dist/commands/index-cmd.js.map +++ b/dist/commands/index-cmd.js.map @@ -1 +1 @@ -{"version":3,"file":"index-cmd.js","sourceRoot":"","sources":["../../src/commands/index-cmd.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index-cmd.js","sourceRoot":"","sources":["../../src/commands/index-cmd.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/commitlore.mjs b/dist/commitlore.mjs index ffe3baa5..b188105c 100755 --- a/dist/commitlore.mjs +++ b/dist/commitlore.mjs @@ -18422,7 +18422,7 @@ var runIndex = (options) => { var register12 = (program3) => { program3.command("index").description("build or refresh the derived record index (.git/commitlore/index.db)").option("--rebuild", "discard the index and rebuild it from git").option("--no-index", "answer from git alone, writing nothing (the fallback path)").option("--json", "emit the run as JSON").option("--stats", "report what the index currently holds").addHelpText( "after", - "\nExit codes: 0 built or refreshed, 2 could not run -- conflicting flags, or better-sqlite3 is not installed (SPEC \xA710)." + "\nExit codes: 0 built or refreshed, 2 could not run -- conflicting flags, or the SQLite binding is unavailable, in which case every read still answers from git with --no-index (SPEC \xA710)." ).action((options) => { try { if (!options.index) { diff --git a/src/commands/index-cmd.ts b/src/commands/index-cmd.ts index 31925c71..3ca8be2f 100644 --- a/src/commands/index-cmd.ts +++ b/src/commands/index-cmd.ts @@ -131,8 +131,9 @@ export const register = (program: Command): void => { .option('--stats', 'report what the index currently holds') .addHelpText( 'after', - '\nExit codes: 0 built or refreshed, 2 could not run -- conflicting flags, or better-sqlite3 is not ' + - 'installed (SPEC §10).', + '\nExit codes: 0 built or refreshed, 2 could not run -- conflicting flags, or the SQLite ' + + 'binding is unavailable, in which case every read still answers from git with --no-index ' + + '(SPEC §10).', ) .action((options: IndexCommandOptions) => { try { diff --git a/test/help-text-honesty.test.ts b/test/help-text-honesty.test.ts new file mode 100644 index 00000000..b14763c2 --- /dev/null +++ b/test/help-text-honesty.test.ts @@ -0,0 +1,75 @@ +/** + * #303: a user-facing message must not send someone after a package the product + * does not carry. + * + * `index --help` documented exit 2 as "conflicting flags, or better-sqlite3 is + * not installed". ADR-0012 replaced `better-sqlite3` with `node:sqlite` + * specifically so there is no native dependency, and `package.json` declares no + * runtime dependencies at all — so that message named a package that is not part + * of the product and never will be. The one place a failing user is sent has to + * be somewhere real. + * + * Comments that explain *why* a dependency was dropped are legitimate and are + * deliberately not covered: this asserts strings that reach a user, which are the + * ones with a cost attached. + */ +import { readFileSync, readdirSync } from 'node:fs'; +import { dirname, join, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +import { describe, expect, it } from 'vitest'; + +const REPO_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..'); + +const manifest = JSON.parse(readFileSync(join(REPO_ROOT, 'package.json'), 'utf8')) as { + dependencies?: Record; + devDependencies?: Record; +}; + +const declared = new Set([ + ...Object.keys(manifest.dependencies ?? {}), + ...Object.keys(manifest.devDependencies ?? {}), +]); + +const sourceFiles = (dir: string): string[] => { + const out: string[] = []; + for (const entry of readdirSync(dir, { withFileTypes: true })) { + const full = join(dir, entry.name); + if (entry.isDirectory()) out.push(...sourceFiles(full)); + else if (entry.name.endsWith('.ts')) out.push(full); + } + return out; +}; + +/** Lines that end up in front of a user: help text, stderr, thrown messages. */ +const userFacingLines = (body: string): string[] => + body + .split('\n') + .filter((line) => { + const code = line.trim(); + if (code.startsWith('*') || code.startsWith('//') || code.startsWith('/*')) return false; + return /Exit codes:|addHelpText|stderr\.write|new Error\(|\.description\(/.test(code); + }); + +describe('#303 user-facing text names only packages the manifest carries', () => { + it('no help text, error or diagnostic names an undeclared package', () => { + const offenders: string[] = []; + for (const file of sourceFiles(join(REPO_ROOT, 'src'))) { + const body = readFileSync(file, 'utf8'); + for (const line of userFacingLines(body)) { + // Any bare package-looking token this project once used but no longer declares. + for (const suspect of ['better-sqlite3', 'node-gyp', 'prebuild-install']) { + if (line.includes(suspect) && !declared.has(suspect)) { + offenders.push(`${file.replace(REPO_ROOT + '/', '')}: ${line.trim().slice(0, 100)}`); + } + } + } + } + expect(offenders, offenders.join('\n')).toEqual([]); + }); + + it('better-sqlite3 is genuinely not a declared dependency, so the rule has teeth', () => { + expect(declared.has('better-sqlite3')).toBe(false); + expect(manifest.dependencies ?? {}).toEqual({}); + }); +});