refactor: inject CLI I/O and diagnostics

This commit is contained in:
vorotamoroz
2026-07-17 16:01:48 +00:00
parent 1b4a0d76dd
commit 97964fddf1
23 changed files with 422 additions and 236 deletions
+7 -1
View File
@@ -1,5 +1,6 @@
import { FileAccessBase, type FileAccessBaseDependencies } from "@vrtmrz/livesync-commonlib/compat/serviceModules/FileAccessBase";
import { NodeFileSystemAdapter } from "@/apps/cli/adapters/NodeFileSystemAdapter";
import { LOG_LEVEL_NOTICE } from "octagonal-wheels/common/logger";
/**
* CLI-specific implementation of FileAccessBase
@@ -7,7 +8,12 @@ import { NodeFileSystemAdapter } from "@/apps/cli/adapters/NodeFileSystemAdapter
*/
export class FileAccessCLI extends FileAccessBase<NodeFileSystemAdapter> {
constructor(basePath: string, dependencies: FileAccessBaseDependencies) {
const adapter = new NodeFileSystemAdapter(basePath);
const adapter = new NodeFileSystemAdapter(basePath, (message, detail) => {
dependencies.APIService.addLog(message, LOG_LEVEL_NOTICE);
if (detail !== undefined) {
dependencies.APIService.addLog(detail, LOG_LEVEL_NOTICE);
}
});
super(adapter, dependencies);
}
+7 -3
View File
@@ -1,5 +1,6 @@
import { Minimatch } from "minimatch";
import { fsPromises as fs, path } from "@vrtmrz/livesync-commonlib/node";
import type { CliDiagnosticReporter } from "@/apps/cli/cliOutput";
/**
* Loads and evaluates ignore rules from `.livesync/ignore` inside the vault.
@@ -19,7 +20,10 @@ import { fsPromises as fs, path } from "@vrtmrz/livesync-commonlib/node";
export class IgnoreRules {
private patterns: Minimatch[] = [];
constructor(private vaultPath: string) {}
constructor(
private vaultPath: string,
private reportDiagnostic: CliDiagnosticReporter = () => undefined
) {}
/**
* Reads `.livesync/ignore` (and optionally `.gitignore`) and populates the
@@ -53,7 +57,7 @@ export class IgnoreRules {
continue;
}
if (trimmed.startsWith("import:")) {
console.error(
this.reportDiagnostic(
`[IgnoreRules] Warning: unrecognised directive '${trimmed}' — only 'import: .gitignore' is supported`
);
continue;
@@ -61,7 +65,7 @@ export class IgnoreRules {
this._addPattern(trimmed);
}
if (this.patterns.length > 0) {
console.error(`[IgnoreRules] Loaded ${this.patterns.length} ignore patterns`);
this.reportDiagnostic(`[IgnoreRules] Loaded ${this.patterns.length} ignore patterns`);
}
}
@@ -138,11 +138,13 @@ describe("IgnoreRules", () => {
const vaultPath = await createVault();
// Typo: "import:.gitignore" instead of "import: .gitignore"
await writeIgnoreFile(vaultPath, "*.tmp\nimport:.gitignore\n");
const rules = new IgnoreRules(vaultPath);
const reportDiagnostic = vi.fn();
const rules = new IgnoreRules(vaultPath, reportDiagnostic);
await rules.load();
// *.tmp still loaded; import:.gitignore is skipped (not treated as a literal pattern)
expect(rules.shouldIgnore("scratch.tmp")).toBe(true);
expect(rules.shouldIgnore("import:.gitignore")).toBe(false);
expect(reportDiagnostic).toHaveBeenCalledWith(expect.stringContaining("unrecognised directive"));
});
});