@sammons/code-outline-cli 2.1.0 → 2.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 +47 -13
- package/dist/cli-argument-parser.d.ts +4 -1
- package/dist/cli-argument-parser.d.ts.map +1 -1
- package/dist/cli-argument-parser.js +186 -69
- package/dist/cli-argument-parser.js.map +1 -1
- package/dist/cli-orchestrator.d.ts +10 -3
- package/dist/cli-orchestrator.d.ts.map +1 -1
- package/dist/cli-orchestrator.js +96 -24
- package/dist/cli-orchestrator.js.map +1 -1
- package/dist/cli-output-handler.d.ts +4 -3
- package/dist/cli-output-handler.d.ts.map +1 -1
- package/dist/cli-output-handler.js +7 -9
- package/dist/cli-output-handler.js.map +1 -1
- package/dist/cli.js +2 -4
- package/dist/cli.js.map +1 -1
- package/dist/file-processor.d.ts +70 -3
- package/dist/file-processor.d.ts.map +1 -1
- package/dist/file-processor.js +134 -25
- package/dist/file-processor.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -51
- package/dist/index.js.map +1 -1
- package/package.json +12 -11
- package/dist/cli-orchestrator.unit.test.d.ts +0 -2
- package/dist/cli-orchestrator.unit.test.d.ts.map +0 -1
- package/dist/cli-orchestrator.unit.test.js +0 -140
- package/dist/cli-orchestrator.unit.test.js.map +0 -1
- package/dist/cli.integration.test.d.ts +0 -2
- package/dist/cli.integration.test.d.ts.map +0 -1
- package/dist/cli.integration.test.js +0 -342
- package/dist/cli.integration.test.js.map +0 -1
- package/dist/cli.unit.test.d.ts +0 -2
- package/dist/cli.unit.test.d.ts.map +0 -1
- package/dist/cli.unit.test.js +0 -411
- package/dist/cli.unit.test.js.map +0 -1
- package/dist/test.d.ts +0 -25
- package/dist/test.d.ts.map +0 -1
- package/dist/test.js +0 -41
- package/dist/test.js.map +0 -1
package/dist/cli-orchestrator.js
CHANGED
|
@@ -1,37 +1,110 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const file_processor_js_1 = require("./file-processor.js");
|
|
6
|
-
const cli_output_handler_js_1 = require("./cli-output-handler.js");
|
|
7
|
-
class CLIOrchestrator {
|
|
1
|
+
import { CLIArgumentParser, CLIArgumentError } from "./cli-argument-parser.js";
|
|
2
|
+
import { FileProcessor, FileProcessorError } from "./file-processor.js";
|
|
3
|
+
import { CLIOutputHandler } from "./cli-output-handler.js";
|
|
4
|
+
export class CLIOrchestrator {
|
|
8
5
|
argumentParser;
|
|
9
6
|
fileProcessor;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
outputHandlerFactory;
|
|
8
|
+
exit;
|
|
9
|
+
logError;
|
|
10
|
+
constructor(argumentParser = new CLIArgumentParser(), fileProcessor = new FileProcessor(), outputHandlerFactory = (format, llmtext) => new CLIOutputHandler(format, llmtext), exit = (code) => process.exit(code), logError = (message) => console.error(message)) {
|
|
11
|
+
this.argumentParser = argumentParser;
|
|
12
|
+
this.fileProcessor = fileProcessor;
|
|
13
|
+
this.outputHandlerFactory = outputHandlerFactory;
|
|
14
|
+
this.exit = exit;
|
|
15
|
+
this.logError = logError;
|
|
13
16
|
}
|
|
14
17
|
async run() {
|
|
15
18
|
try {
|
|
16
19
|
// Parse and validate arguments
|
|
17
|
-
const { options,
|
|
18
|
-
// Find matching files
|
|
19
|
-
|
|
20
|
-
//
|
|
21
|
-
|
|
20
|
+
const { options, patterns } = this.argumentParser.parse();
|
|
21
|
+
// Find matching files for every pattern and union the results, deduped
|
|
22
|
+
// by absolute path (findFiles already resolves to absolute paths). One
|
|
23
|
+
// call per pattern keeps the FileProcessor#findFiles contract at "one
|
|
24
|
+
// pattern in, its matches out" unchanged. A single pattern matching
|
|
25
|
+
// nothing is not fatal on its own -- it is common for one glob among
|
|
26
|
+
// several to legitimately miss -- so only the union being empty across
|
|
27
|
+
// every pattern is reported as "no files found".
|
|
28
|
+
const fileSets = await Promise.all(patterns.map(async (pattern) => {
|
|
29
|
+
try {
|
|
30
|
+
return await this.fileProcessor.findFiles(pattern);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
if (error instanceof FileProcessorError) {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
}));
|
|
39
|
+
const files = [...new Set(fileSets.flat())];
|
|
40
|
+
if (files.length === 0) {
|
|
41
|
+
throw new FileProcessorError(`No files found matching pattern: ${patterns.join(', ')}`);
|
|
42
|
+
}
|
|
43
|
+
// Process files in parallel. FileProcessor#parseFile returns a typed
|
|
44
|
+
// outcome per file instead of throwing or logging: 'parsed' carries
|
|
45
|
+
// the outline plus hasError, 'parse_failed' carries the reason
|
|
46
|
+
// directly. This replaces the previous console.error-monkeypatching
|
|
47
|
+
// trick (issue #9) that detected failures by intercepting a
|
|
48
|
+
// process-wide method -- the outcome kind is now the sole signal, no
|
|
49
|
+
// global patching anywhere.
|
|
50
|
+
const outcomes = await this.fileProcessor.processFiles(files, options.depth, options.namedOnly);
|
|
51
|
+
const results = outcomes.map((outcome) => outcome.kind === 'parsed'
|
|
52
|
+
? {
|
|
53
|
+
file: outcome.file,
|
|
54
|
+
outline: outcome.outline,
|
|
55
|
+
hasError: outcome.hasError,
|
|
56
|
+
errorCount: outcome.errorCount,
|
|
57
|
+
}
|
|
58
|
+
: {
|
|
59
|
+
file: outcome.file,
|
|
60
|
+
outline: null,
|
|
61
|
+
hasError: false,
|
|
62
|
+
errorCount: 0,
|
|
63
|
+
});
|
|
22
64
|
// Format and output results
|
|
23
|
-
const outputHandler =
|
|
65
|
+
const outputHandler = this.outputHandlerFactory(options.format, options.llmtext);
|
|
24
66
|
outputHandler.formatAndOutput(results);
|
|
67
|
+
// One diagnostic line per problem file, printed after the output so
|
|
68
|
+
// the full (possibly partial) result is always on stdout first. A
|
|
69
|
+
// parse_failed file gets the "Error parsing" line (issue #14's
|
|
70
|
+
// existing contract); a parsed file whose tree recovered from a
|
|
71
|
+
// syntax error gets the new "N syntax error(s)" warning (issue #9) --
|
|
72
|
+
// the two are independent signals and a file can only be one at a
|
|
73
|
+
// time (a thrown parse exception never also produces an outline).
|
|
74
|
+
let hadProblem = false;
|
|
75
|
+
for (const outcome of outcomes) {
|
|
76
|
+
if (outcome.kind === 'parse_failed') {
|
|
77
|
+
hadProblem = true;
|
|
78
|
+
this.logError(`Error parsing ${outcome.file}: ${outcome.reason}`);
|
|
79
|
+
}
|
|
80
|
+
else if (outcome.hasError) {
|
|
81
|
+
hadProblem = true;
|
|
82
|
+
const plural = outcome.errorCount === 1 ? '' : 's';
|
|
83
|
+
this.logError(`warning: ${outcome.file}: ${outcome.errorCount} syntax error${plural}; outline may be incomplete`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// The batch's output is still worth keeping when only some files had
|
|
87
|
+
// a problem, but the run as a whole is not a clean success (issue
|
|
88
|
+
// #14, extended to hasError by issue #9). This exits through the same
|
|
89
|
+
// "hint after the error" contract as the CLIArgumentError/
|
|
90
|
+
// FileProcessorError catch arms below so every documented error path
|
|
91
|
+
// in the Exit Codes table prints the hint, not just the two
|
|
92
|
+
// exception-based ones.
|
|
93
|
+
if (hadProblem) {
|
|
94
|
+
this.logError('Run with --help for usage.');
|
|
95
|
+
this.exit(1);
|
|
96
|
+
}
|
|
25
97
|
}
|
|
26
98
|
catch (error) {
|
|
27
|
-
if (error instanceof
|
|
28
|
-
|
|
29
|
-
this.
|
|
30
|
-
|
|
99
|
+
if (error instanceof CLIArgumentError) {
|
|
100
|
+
this.logError(`Error: ${error.message}`);
|
|
101
|
+
this.logError('Run with --help for usage.');
|
|
102
|
+
this.exit(1);
|
|
31
103
|
}
|
|
32
|
-
else if (error instanceof
|
|
33
|
-
|
|
34
|
-
|
|
104
|
+
else if (error instanceof FileProcessorError) {
|
|
105
|
+
this.logError(error.message);
|
|
106
|
+
this.logError('Run with --help for usage.');
|
|
107
|
+
this.exit(1);
|
|
35
108
|
}
|
|
36
109
|
else {
|
|
37
110
|
throw error; // Re-throw unexpected errors
|
|
@@ -39,5 +112,4 @@ class CLIOrchestrator {
|
|
|
39
112
|
}
|
|
40
113
|
}
|
|
41
114
|
}
|
|
42
|
-
exports.CLIOrchestrator = CLIOrchestrator;
|
|
43
115
|
//# sourceMappingURL=cli-orchestrator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-orchestrator.js","sourceRoot":"","sources":["../src/cli-orchestrator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli-orchestrator.js","sourceRoot":"","sources":["../src/cli-orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { OutputFormat } from '@sammons/code-outline-parser';
|
|
2
|
-
import type { ProcessedFile } from './file-processor.
|
|
2
|
+
import type { ProcessedFile } from './file-processor.ts';
|
|
3
3
|
export declare class CLIOutputHandler {
|
|
4
|
-
private formatter;
|
|
5
|
-
|
|
4
|
+
private readonly formatter;
|
|
5
|
+
private readonly log;
|
|
6
|
+
constructor(format: OutputFormat, llmtext?: boolean, log?: (message: string) => void);
|
|
6
7
|
formatAndOutput(results: ProcessedFile[]): void;
|
|
7
8
|
}
|
|
8
9
|
//# sourceMappingURL=cli-output-handler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-output-handler.d.ts","sourceRoot":"","sources":["../src/cli-output-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAY;
|
|
1
|
+
{"version":3,"file":"cli-output-handler.d.ts","sourceRoot":"","sources":["../src/cli-output-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA4B;gBAG9C,MAAM,EAAE,YAAY,EACpB,OAAO,CAAC,EAAE,OAAO,EACjB,GAAG,GAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAwC;IAM7D,eAAe,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,IAAI;CAIvD"}
|
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.CLIOutputHandler = void 0;
|
|
4
|
-
const code_outline_formatter_1 = require("@sammons/code-outline-formatter");
|
|
5
|
-
class CLIOutputHandler {
|
|
1
|
+
import { Formatter } from '@sammons/code-outline-formatter';
|
|
2
|
+
export class CLIOutputHandler {
|
|
6
3
|
formatter;
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
log;
|
|
5
|
+
constructor(format, llmtext, log = (message) => console.log(message)) {
|
|
6
|
+
this.formatter = new Formatter(format, llmtext);
|
|
7
|
+
this.log = log;
|
|
9
8
|
}
|
|
10
9
|
formatAndOutput(results) {
|
|
11
10
|
const output = this.formatter.format(results);
|
|
12
|
-
|
|
11
|
+
this.log(output);
|
|
13
12
|
}
|
|
14
13
|
}
|
|
15
|
-
exports.CLIOutputHandler = CLIOutputHandler;
|
|
16
14
|
//# sourceMappingURL=cli-output-handler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-output-handler.js","sourceRoot":"","sources":["../src/cli-output-handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli-output-handler.js","sourceRoot":"","sources":["../src/cli-output-handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAG5D,MAAM,OAAO,gBAAgB;IACV,SAAS,CAAY;IACrB,GAAG,CAA4B;IAEhD,YACE,MAAoB,EACpB,OAAiB,EACjB,MAAiC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;QAElE,IAAI,CAAC,SAAS,GAAG,IAAI,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChD,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAEM,eAAe,CAAC,OAAwB;QAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACnB,CAAC;CACF"}
|
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
const cli_orchestrator_js_1 = require("./cli-orchestrator.js");
|
|
2
|
+
import { CLIOrchestrator } from "./cli-orchestrator.js";
|
|
5
3
|
async function main() {
|
|
6
|
-
const orchestrator = new
|
|
4
|
+
const orchestrator = new CLIOrchestrator();
|
|
7
5
|
await orchestrator.run();
|
|
8
6
|
}
|
|
9
7
|
main().catch((error) => {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,KAAK,UAAU,IAAI;IACjB,MAAM,YAAY,GAAG,IAAI,eAAe,EAAE,CAAC;IAC3C,MAAM,YAAY,CAAC,GAAG,EAAE,CAAC;AAC3B,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC9B,MAAM,YAAY,GAChB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;IACjE,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;IAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/file-processor.d.ts
CHANGED
|
@@ -1,16 +1,83 @@
|
|
|
1
|
+
import fg from 'fast-glob';
|
|
1
2
|
import type { NodeInfo } from '@sammons/code-outline-parser';
|
|
3
|
+
import { Parser } from '@sammons/code-outline-parser';
|
|
2
4
|
export interface ProcessedFile {
|
|
3
5
|
file: string;
|
|
4
6
|
outline: NodeInfo | null;
|
|
7
|
+
hasError: boolean;
|
|
8
|
+
errorCount: number;
|
|
5
9
|
}
|
|
6
10
|
export declare class FileProcessorError extends Error {
|
|
7
11
|
constructor(message: string);
|
|
8
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Per-file outcome of a parse attempt. Replaces the previous console.error
|
|
15
|
+
* monkeypatch (issue #9): a file that throws during parsing reports itself
|
|
16
|
+
* as `parse_failed` with its reason directly, instead of the orchestrator
|
|
17
|
+
* detecting failure by intercepting a global console method.
|
|
18
|
+
*/
|
|
19
|
+
export type ParseFileOutcome = {
|
|
20
|
+
kind: 'parsed';
|
|
21
|
+
file: string;
|
|
22
|
+
outline: NodeInfo | null;
|
|
23
|
+
hasError: boolean;
|
|
24
|
+
errorCount: number;
|
|
25
|
+
} | {
|
|
26
|
+
kind: 'parse_failed';
|
|
27
|
+
file: string;
|
|
28
|
+
reason: string;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Converts one line of a root `.gitignore` into fast-glob ignore patterns,
|
|
32
|
+
* anchored to `cwd` where git semantics require anchoring.
|
|
33
|
+
*
|
|
34
|
+
* Scope: only the root `.gitignore` of the current working directory.
|
|
35
|
+
* Nested `.gitignore` files and negation patterns (`!foo`) are out of scope.
|
|
36
|
+
*
|
|
37
|
+
* A bare name with no `/` at all (`dist`) matches at any depth: `dist` and
|
|
38
|
+
* `**\/dist` (as a file or directory) plus their contents — these globs stay
|
|
39
|
+
* relative because depth-independent matching works the same whether the
|
|
40
|
+
* search pattern fast-glob resolves against is absolute or relative.
|
|
41
|
+
*
|
|
42
|
+
* Per real `git check-ignore` semantics, ANY other `/` in the pattern
|
|
43
|
+
* anchors it to the `.gitignore`'s directory: a leading slash (`/dist`) is
|
|
44
|
+
* the explicit form, but a mid-path slash (`src/generated`) anchors just as
|
|
45
|
+
* much — git does not treat it as depth-independent. Anchored patterns are
|
|
46
|
+
* emitted as absolute globs (`${cwd}/pattern`, `${cwd}/pattern/**`) rather
|
|
47
|
+
* than bare relative ones. fast-glob resolves a relative ignore glob against
|
|
48
|
+
* the search pattern's own base, not against `cwd`; when `findFiles` is
|
|
49
|
+
* called with an absolute search pattern (a supported path — see
|
|
50
|
+
* `cli-argument-parser.ts`'s `isAbsolute` check) that base becomes `/` and a
|
|
51
|
+
* relative anchored glob like `vendor` silently stops matching. Prefixing
|
|
52
|
+
* with `cwd` makes the ignore glob resolve correctly regardless of whether
|
|
53
|
+
* the search pattern itself is absolute or relative.
|
|
54
|
+
*
|
|
55
|
+
* A trailing slash (`dist/`) restricts the pattern to directories: git never
|
|
56
|
+
* excludes a file literally named `dist` in that case, so the emitted globs
|
|
57
|
+
* cover only `dist`-as-a-directory (`dist/**`) and never the bare `dist` /
|
|
58
|
+
* `**\/dist` forms that would also match a same-named file.
|
|
59
|
+
*
|
|
60
|
+
* `resolve()` returns OS-native separators (backslashes on Windows), which
|
|
61
|
+
* fast-glob's own docs call out as broken input — glob expressions must use
|
|
62
|
+
* forward slashes (see fast-glob's README, "Bad" example:
|
|
63
|
+
* `path.join(process.cwd(), '**')`; the fix is `fg.convertPathToPattern()`).
|
|
64
|
+
* Anchored globs run through `fg.convertPathToPattern()` before use so
|
|
65
|
+
* ignore matching works the same on Windows as on POSIX.
|
|
66
|
+
*/
|
|
67
|
+
export declare const gitignoreLineToGlobs: (line: string, cwd: string) => string[];
|
|
68
|
+
/**
|
|
69
|
+
* Reads the root `.gitignore` at `cwd` (if present) and returns fast-glob
|
|
70
|
+
* ignore patterns for its rules. Blank lines, comments (`#`), and negation
|
|
71
|
+
* lines (`!pattern`) are dropped silently — negation support is out of scope
|
|
72
|
+
* for a root-only reader.
|
|
73
|
+
*/
|
|
74
|
+
export declare const readGitignorePatterns: (cwd: string) => string[];
|
|
9
75
|
export declare class FileProcessor {
|
|
10
|
-
private parser;
|
|
11
|
-
|
|
76
|
+
private readonly parser;
|
|
77
|
+
private readonly glob;
|
|
78
|
+
constructor(parser?: Parser, glob?: typeof fg);
|
|
12
79
|
findFiles(pattern: string): Promise<string[]>;
|
|
13
80
|
private parseFile;
|
|
14
|
-
processFiles(files: string[], depth: number, namedOnly: boolean): Promise<
|
|
81
|
+
processFiles(files: string[], depth: number, namedOnly: boolean): Promise<ParseFileOutcome[]>;
|
|
15
82
|
}
|
|
16
83
|
//# sourceMappingURL=file-processor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-processor.d.ts","sourceRoot":"","sources":["../src/file-processor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"file-processor.d.ts","sourceRoot":"","sources":["../src/file-processor.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,WAAW,CAAC;AAC3B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAEtD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,QAAQ,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GACxB;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,QAAQ,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB,GACD;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM,EAAE,KAAK,MAAM,KAAG,MAAM,EAkCtE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,KAAK,MAAM,KAAG,MAAM,EAsBzD,CAAC;AAEF,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAY;gBAErB,MAAM,GAAE,MAAqB,EAAE,IAAI,GAAE,OAAO,EAAO;IAKlD,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YAgC5C,SAAS;IA6BV,YAAY,CACvB,KAAK,EAAE,MAAM,EAAE,EACf,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,OAAO,GACjB,OAAO,CAAC,gBAAgB,EAAE,CAAC;CAQ/B"}
|
package/dist/file-processor.js
CHANGED
|
@@ -1,48 +1,158 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
exports.FileProcessor = exports.FileProcessorError = void 0;
|
|
7
|
-
const node_path_1 = require("node:path");
|
|
8
|
-
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
9
|
-
const code_outline_parser_1 = require("@sammons/code-outline-parser");
|
|
10
|
-
class FileProcessorError extends Error {
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import fg from 'fast-glob';
|
|
4
|
+
import { Parser } from '@sammons/code-outline-parser';
|
|
5
|
+
export class FileProcessorError extends Error {
|
|
11
6
|
constructor(message) {
|
|
12
7
|
super(message);
|
|
13
8
|
this.name = 'FileProcessorError';
|
|
14
9
|
}
|
|
15
10
|
}
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Converts one line of a root `.gitignore` into fast-glob ignore patterns,
|
|
13
|
+
* anchored to `cwd` where git semantics require anchoring.
|
|
14
|
+
*
|
|
15
|
+
* Scope: only the root `.gitignore` of the current working directory.
|
|
16
|
+
* Nested `.gitignore` files and negation patterns (`!foo`) are out of scope.
|
|
17
|
+
*
|
|
18
|
+
* A bare name with no `/` at all (`dist`) matches at any depth: `dist` and
|
|
19
|
+
* `**\/dist` (as a file or directory) plus their contents — these globs stay
|
|
20
|
+
* relative because depth-independent matching works the same whether the
|
|
21
|
+
* search pattern fast-glob resolves against is absolute or relative.
|
|
22
|
+
*
|
|
23
|
+
* Per real `git check-ignore` semantics, ANY other `/` in the pattern
|
|
24
|
+
* anchors it to the `.gitignore`'s directory: a leading slash (`/dist`) is
|
|
25
|
+
* the explicit form, but a mid-path slash (`src/generated`) anchors just as
|
|
26
|
+
* much — git does not treat it as depth-independent. Anchored patterns are
|
|
27
|
+
* emitted as absolute globs (`${cwd}/pattern`, `${cwd}/pattern/**`) rather
|
|
28
|
+
* than bare relative ones. fast-glob resolves a relative ignore glob against
|
|
29
|
+
* the search pattern's own base, not against `cwd`; when `findFiles` is
|
|
30
|
+
* called with an absolute search pattern (a supported path — see
|
|
31
|
+
* `cli-argument-parser.ts`'s `isAbsolute` check) that base becomes `/` and a
|
|
32
|
+
* relative anchored glob like `vendor` silently stops matching. Prefixing
|
|
33
|
+
* with `cwd` makes the ignore glob resolve correctly regardless of whether
|
|
34
|
+
* the search pattern itself is absolute or relative.
|
|
35
|
+
*
|
|
36
|
+
* A trailing slash (`dist/`) restricts the pattern to directories: git never
|
|
37
|
+
* excludes a file literally named `dist` in that case, so the emitted globs
|
|
38
|
+
* cover only `dist`-as-a-directory (`dist/**`) and never the bare `dist` /
|
|
39
|
+
* `**\/dist` forms that would also match a same-named file.
|
|
40
|
+
*
|
|
41
|
+
* `resolve()` returns OS-native separators (backslashes on Windows), which
|
|
42
|
+
* fast-glob's own docs call out as broken input — glob expressions must use
|
|
43
|
+
* forward slashes (see fast-glob's README, "Bad" example:
|
|
44
|
+
* `path.join(process.cwd(), '**')`; the fix is `fg.convertPathToPattern()`).
|
|
45
|
+
* Anchored globs run through `fg.convertPathToPattern()` before use so
|
|
46
|
+
* ignore matching works the same on Windows as on POSIX.
|
|
47
|
+
*/
|
|
48
|
+
export const gitignoreLineToGlobs = (line, cwd) => {
|
|
49
|
+
const isDirectoryOnly = line.endsWith('/');
|
|
50
|
+
const withoutTrailingSlash = isDirectoryOnly ? line.slice(0, -1) : line;
|
|
51
|
+
const isLeadingSlash = withoutTrailingSlash.startsWith('/');
|
|
52
|
+
const pattern = isLeadingSlash
|
|
53
|
+
? withoutTrailingSlash.slice(1)
|
|
54
|
+
: withoutTrailingSlash;
|
|
55
|
+
if (pattern.length === 0) {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
// Per git semantics, any remaining `/` in the pattern (a mid-path slash,
|
|
59
|
+
// e.g. `src/generated`) anchors it to `cwd` just like a leading slash did.
|
|
60
|
+
// Only a pattern with zero slashes anywhere is depth-independent.
|
|
61
|
+
const isRootAnchored = isLeadingSlash || pattern.includes('/');
|
|
62
|
+
if (isRootAnchored) {
|
|
63
|
+
// Convert ONLY the cwd segment: fg.convertPathToPattern escapes every
|
|
64
|
+
// glob metacharacter it sees, so running the joined path through it
|
|
65
|
+
// would turn an intentional wildcard in the .gitignore line (e.g.
|
|
66
|
+
// `src/test-scenarios/*/temp/`) into a literal `\*`. Gitignore patterns
|
|
67
|
+
// are always `/`-separated per git, so joining with `/` is correct on
|
|
68
|
+
// every platform once cwd has been normalized.
|
|
69
|
+
const absoluteCwd = fg.convertPathToPattern(resolve(cwd));
|
|
70
|
+
const absolutePattern = `${absoluteCwd}/${pattern}`;
|
|
71
|
+
return isDirectoryOnly
|
|
72
|
+
? [`${absolutePattern}/**`]
|
|
73
|
+
: [absolutePattern, `${absolutePattern}/**`];
|
|
74
|
+
}
|
|
75
|
+
return isDirectoryOnly
|
|
76
|
+
? [`${pattern}/**`, `**/${pattern}/**`]
|
|
77
|
+
: [pattern, `**/${pattern}`, `${pattern}/**`, `**/${pattern}/**`];
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Reads the root `.gitignore` at `cwd` (if present) and returns fast-glob
|
|
81
|
+
* ignore patterns for its rules. Blank lines, comments (`#`), and negation
|
|
82
|
+
* lines (`!pattern`) are dropped silently — negation support is out of scope
|
|
83
|
+
* for a root-only reader.
|
|
84
|
+
*/
|
|
85
|
+
export const readGitignorePatterns = (cwd) => {
|
|
86
|
+
let contents;
|
|
87
|
+
try {
|
|
88
|
+
contents = readFileSync(resolve(cwd, '.gitignore'), 'utf8');
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// Treats every read failure (file absent, EACCES, EISDIR, etc.) as "no
|
|
92
|
+
// .gitignore to honor." The safe default is behaving as if there is no
|
|
93
|
+
// ignore file, so any I/O error collapses to the same empty-array
|
|
94
|
+
// fallback rather than surfacing a distinct error path.
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
const patterns = [];
|
|
98
|
+
for (const rawLine of contents.split('\n')) {
|
|
99
|
+
const line = rawLine.trim();
|
|
100
|
+
if (line.length === 0 || line.startsWith('#') || line.startsWith('!')) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
patterns.push(...gitignoreLineToGlobs(line, cwd));
|
|
104
|
+
}
|
|
105
|
+
return patterns;
|
|
106
|
+
};
|
|
107
|
+
export class FileProcessor {
|
|
18
108
|
parser;
|
|
19
|
-
|
|
20
|
-
|
|
109
|
+
glob;
|
|
110
|
+
constructor(parser = new Parser(), glob = fg) {
|
|
111
|
+
this.parser = parser;
|
|
112
|
+
this.glob = glob;
|
|
21
113
|
}
|
|
22
114
|
async findFiles(pattern) {
|
|
23
|
-
const
|
|
115
|
+
const gitignorePatterns = readGitignorePatterns(process.cwd());
|
|
116
|
+
// followSymbolicLinks: false stops fast-glob from descending into
|
|
117
|
+
// symlinked directories at all, so a directory symlink cycle cannot
|
|
118
|
+
// trigger an ELOOP crash. suppressErrors: true is a defense-in-depth
|
|
119
|
+
// backstop for any other per-entry stat/readdir error (permission
|
|
120
|
+
// denied, race with a deleted file) so one bad entry does not crash
|
|
121
|
+
// an otherwise-successful glob.
|
|
122
|
+
const files = await this.glob(pattern, {
|
|
24
123
|
absolute: true,
|
|
25
|
-
ignore: [
|
|
124
|
+
ignore: [
|
|
125
|
+
'**/node_modules/**',
|
|
126
|
+
'**/dist/**',
|
|
127
|
+
'**/build/**',
|
|
128
|
+
...gitignorePatterns,
|
|
129
|
+
],
|
|
130
|
+
followSymbolicLinks: false,
|
|
131
|
+
suppressErrors: true,
|
|
26
132
|
});
|
|
27
|
-
|
|
133
|
+
const sortedFiles = [...files].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
|
|
134
|
+
if (sortedFiles.length === 0) {
|
|
28
135
|
throw new FileProcessorError(`No files found matching pattern: ${pattern}`);
|
|
29
136
|
}
|
|
30
|
-
return
|
|
137
|
+
return sortedFiles;
|
|
31
138
|
}
|
|
32
139
|
async parseFile(file, depth, namedOnly) {
|
|
33
140
|
try {
|
|
34
|
-
const outline = await this.parser.parseFile(file, depth, namedOnly);
|
|
141
|
+
const { outline, hasError, errorCount } = await this.parser.parseFile(file, depth, namedOnly);
|
|
35
142
|
return {
|
|
36
|
-
|
|
143
|
+
kind: 'parsed',
|
|
144
|
+
file: resolve(file),
|
|
37
145
|
outline,
|
|
146
|
+
hasError,
|
|
147
|
+
errorCount,
|
|
38
148
|
};
|
|
39
149
|
}
|
|
40
150
|
catch (error) {
|
|
41
|
-
const
|
|
42
|
-
console.error(`Error parsing ${file}:`, errorMessage);
|
|
151
|
+
const reason = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
43
152
|
return {
|
|
44
|
-
|
|
45
|
-
|
|
153
|
+
kind: 'parse_failed',
|
|
154
|
+
file: resolve(file),
|
|
155
|
+
reason,
|
|
46
156
|
};
|
|
47
157
|
}
|
|
48
158
|
}
|
|
@@ -52,5 +162,4 @@ class FileProcessor {
|
|
|
52
162
|
return await Promise.all(parsePromises);
|
|
53
163
|
}
|
|
54
164
|
}
|
|
55
|
-
exports.FileProcessor = FileProcessor;
|
|
56
165
|
//# sourceMappingURL=file-processor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-processor.js","sourceRoot":"","sources":["../src/file-processor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"file-processor.js","sourceRoot":"","sources":["../src/file-processor.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { CLIOrchestrator } from './cli-orchestrator';
|
|
2
|
-
export { CLIArgumentParser } from './cli-argument-parser';
|
|
3
|
-
export { FileProcessor } from './file-processor';
|
|
4
|
-
export { CLIOutputHandler } from './cli-output-handler';
|
|
1
|
+
export { CLIOrchestrator } from './cli-orchestrator.ts';
|
|
2
|
+
export { CLIArgumentParser } from './cli-argument-parser.ts';
|
|
3
|
+
export { FileProcessor } from './file-processor.ts';
|
|
4
|
+
export { CLIOutputHandler } from './cli-output-handler.ts';
|
|
5
5
|
export declare function parseFiles(patterns: string | string[], options?: {
|
|
6
6
|
format?: 'ascii' | 'json' | 'yaml';
|
|
7
7
|
depth?: number;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAG3D,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,EAC3B,OAAO,CAAC,EAAE;IACR,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GACA,OAAO,CAAC,MAAM,CAAC,CAkDjB"}
|
package/dist/index.js
CHANGED
|
@@ -1,53 +1,12 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.CLIOutputHandler = exports.FileProcessor = exports.CLIArgumentParser = exports.CLIOrchestrator = void 0;
|
|
37
|
-
exports.parseFiles = parseFiles;
|
|
38
1
|
// Main orchestrator for programmatic usage
|
|
39
|
-
|
|
40
|
-
Object.defineProperty(exports, "CLIOrchestrator", { enumerable: true, get: function () { return cli_orchestrator_1.CLIOrchestrator; } });
|
|
2
|
+
export { CLIOrchestrator } from "./cli-orchestrator.js";
|
|
41
3
|
// Individual components
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
Object.defineProperty(exports, "FileProcessor", { enumerable: true, get: function () { return file_processor_1.FileProcessor; } });
|
|
46
|
-
var cli_output_handler_1 = require("./cli-output-handler");
|
|
47
|
-
Object.defineProperty(exports, "CLIOutputHandler", { enumerable: true, get: function () { return cli_output_handler_1.CLIOutputHandler; } });
|
|
4
|
+
export { CLIArgumentParser } from "./cli-argument-parser.js";
|
|
5
|
+
export { FileProcessor } from "./file-processor.js";
|
|
6
|
+
export { CLIOutputHandler } from "./cli-output-handler.js";
|
|
48
7
|
// Convenience function for simple usage
|
|
49
|
-
async function parseFiles(patterns, options) {
|
|
50
|
-
const { FileProcessor } = await
|
|
8
|
+
export async function parseFiles(patterns, options) {
|
|
9
|
+
const { FileProcessor } = await import("./file-processor.js");
|
|
51
10
|
const fileProcessor = new FileProcessor();
|
|
52
11
|
const patternArray = Array.isArray(patterns) ? patterns : [patterns];
|
|
53
12
|
// Find matching files for all patterns
|
|
@@ -59,14 +18,25 @@ async function parseFiles(patterns, options) {
|
|
|
59
18
|
// Remove duplicates
|
|
60
19
|
const uniqueFiles = [...new Set(allFiles)];
|
|
61
20
|
// Process files
|
|
62
|
-
const
|
|
21
|
+
const outcomes = await fileProcessor.processFiles(uniqueFiles, options?.depth ?? 10, // Default depth
|
|
63
22
|
options?.namedOnly ?? false);
|
|
64
|
-
// Format output
|
|
65
|
-
|
|
23
|
+
// Format output. A parse_failed outcome (issue #9) has no outline to
|
|
24
|
+
// show; it renders the same as a legitimately-empty file rather than
|
|
25
|
+
// this convenience wrapper growing its own diagnostic-printing contract
|
|
26
|
+
// -- that contract lives in CLIOrchestrator for the actual CLI entry
|
|
27
|
+
// point, which this function is not.
|
|
28
|
+
const results = outcomes.map((outcome) => outcome.kind === 'parsed'
|
|
29
|
+
? {
|
|
30
|
+
file: outcome.file,
|
|
31
|
+
outline: outcome.outline,
|
|
32
|
+
hasError: outcome.hasError,
|
|
33
|
+
}
|
|
34
|
+
: { file: outcome.file, outline: null, hasError: false });
|
|
35
|
+
const { Formatter } = await import('@sammons/code-outline-formatter');
|
|
66
36
|
const formatter = new Formatter(options?.format ?? 'ascii');
|
|
67
37
|
const output = formatter.format(results);
|
|
68
38
|
if (options?.output) {
|
|
69
|
-
const fs = await
|
|
39
|
+
const fs = await import('fs');
|
|
70
40
|
await fs.promises.writeFile(options.output, output, 'utf-8');
|
|
71
41
|
return `Results written to ${options.output}`;
|
|
72
42
|
}
|