semlint-cli 0.1.2 → 0.1.4
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/dist/diagnostics.js +7 -2
- package/dist/git.js +25 -24
- package/dist/main.js +4 -3
- package/package.json +1 -1
package/dist/diagnostics.js
CHANGED
|
@@ -12,8 +12,13 @@ const VALID_SEVERITIES = new Set(["error", "warn", "info"]);
|
|
|
12
12
|
function isPositiveInteger(value) {
|
|
13
13
|
return typeof value === "number" && Number.isInteger(value) && value >= 1;
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* @param resolveRoot - Directory to resolve diagnostic file paths against (e.g. git repo root).
|
|
17
|
+
* Git diff paths are repo-relative; resolving from repo root ensures paths exist when running from subdirs.
|
|
18
|
+
*/
|
|
19
|
+
function normalizeDiagnostics(ruleId, diagnostics, debug, resolveRoot) {
|
|
16
20
|
const out = [];
|
|
21
|
+
const baseDir = resolveRoot && resolveRoot.length > 0 ? resolveRoot : process.cwd();
|
|
17
22
|
for (const raw of diagnostics) {
|
|
18
23
|
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
19
24
|
if (debug) {
|
|
@@ -41,7 +46,7 @@ function normalizeDiagnostics(ruleId, diagnostics, debug) {
|
|
|
41
46
|
}
|
|
42
47
|
continue;
|
|
43
48
|
}
|
|
44
|
-
const absolute = node_path_1.default.resolve(file);
|
|
49
|
+
const absolute = node_path_1.default.resolve(baseDir, file);
|
|
45
50
|
if (!node_fs_1.default.existsSync(absolute)) {
|
|
46
51
|
if (debug) {
|
|
47
52
|
process.stderr.write(`[debug] Dropped diagnostic for ${ruleId}: file does not exist (${file})\n`);
|
package/dist/git.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getGitDiff = getGitDiff;
|
|
4
|
+
exports.getRepoRoot = getRepoRoot;
|
|
4
5
|
exports.getLocalBranchDiff = getLocalBranchDiff;
|
|
5
6
|
const node_child_process_1 = require("node:child_process");
|
|
6
7
|
const node_os_1 = require("node:os");
|
|
@@ -36,28 +37,19 @@ async function getGitDiff(base, head) {
|
|
|
36
37
|
const result = await runGitCommand(["diff", base, head]);
|
|
37
38
|
return result.stdout;
|
|
38
39
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
catch (error) {
|
|
53
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
54
|
-
if (!isMissingRefError(message)) {
|
|
55
|
-
throw error;
|
|
56
|
-
}
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
40
|
+
/**
|
|
41
|
+
* Returns the absolute path of the git repository root, or null if not in a git repo.
|
|
42
|
+
* Used to resolve diagnostic file paths, which are always repo-relative in git diff output.
|
|
43
|
+
*/
|
|
44
|
+
async function getRepoRoot() {
|
|
45
|
+
try {
|
|
46
|
+
const result = await runGitCommand(["rev-parse", "--show-toplevel"]);
|
|
47
|
+
const root = result.stdout.trim();
|
|
48
|
+
return root !== "" ? root : null;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return null;
|
|
59
52
|
}
|
|
60
|
-
return "HEAD";
|
|
61
53
|
}
|
|
62
54
|
async function getUntrackedFiles() {
|
|
63
55
|
const result = await runGitCommand(["ls-files", "--others", "--exclude-standard"]);
|
|
@@ -70,9 +62,16 @@ async function getNoIndexDiffForFile(filePath) {
|
|
|
70
62
|
const result = await runGitCommand(["diff", "--no-index", "--", node_os_1.devNull, filePath], [0, 1]);
|
|
71
63
|
return result.stdout;
|
|
72
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Returns the diff for the current branch limited to:
|
|
67
|
+
* - Staged changes (--cached: index vs HEAD)
|
|
68
|
+
* - Unstaged changes (working tree vs index)
|
|
69
|
+
* - Untracked files (as full-file diffs)
|
|
70
|
+
* Does not include already-committed changes on the branch.
|
|
71
|
+
*/
|
|
73
72
|
async function getLocalBranchDiff() {
|
|
74
|
-
const
|
|
75
|
-
const
|
|
73
|
+
const stagedResult = await runGitCommand(["diff", "--cached"]);
|
|
74
|
+
const unstagedResult = await runGitCommand(["diff"]);
|
|
76
75
|
const untrackedFiles = await getUntrackedFiles();
|
|
77
76
|
const untrackedDiffChunks = [];
|
|
78
77
|
for (const filePath of untrackedFiles) {
|
|
@@ -81,5 +80,7 @@ async function getLocalBranchDiff() {
|
|
|
81
80
|
untrackedDiffChunks.push(fileDiff);
|
|
82
81
|
}
|
|
83
82
|
}
|
|
84
|
-
return [
|
|
83
|
+
return [stagedResult.stdout, unstagedResult.stdout, ...untrackedDiffChunks]
|
|
84
|
+
.filter((chunk) => chunk !== "")
|
|
85
|
+
.join("\n");
|
|
85
86
|
}
|
package/dist/main.js
CHANGED
|
@@ -91,9 +91,10 @@ async function runSemlint(options) {
|
|
|
91
91
|
const diff = await timedAsync(config.debug, "Computed git diff", () => useLocalBranchDiff ? (0, git_1.getLocalBranchDiff)() : (0, git_1.getGitDiff)(config.base, config.head));
|
|
92
92
|
const changedFiles = timed(config.debug, "Parsed changed files from diff", () => (0, filter_1.extractChangedFilesFromDiff)(diff));
|
|
93
93
|
debugLog(config.debug, useLocalBranchDiff
|
|
94
|
-
? "Using local branch diff (
|
|
94
|
+
? "Using local branch diff (staged + unstaged + untracked only)"
|
|
95
95
|
: `Using explicit ref diff (${config.base}..${config.head})`);
|
|
96
96
|
debugLog(config.debug, `Detected ${changedFiles.length} changed file(s)`);
|
|
97
|
+
const repoRoot = await timedAsync(config.debug, "Resolved git repo root", () => (0, git_1.getRepoRoot)());
|
|
97
98
|
const backend = timed(config.debug, "Initialized backend runner", () => (0, backend_1.createBackendRunner)(config));
|
|
98
99
|
const runnableRules = rules.filter((rule) => {
|
|
99
100
|
const filterStartedAt = Date.now();
|
|
@@ -154,7 +155,7 @@ async function runSemlint(options) {
|
|
|
154
155
|
}
|
|
155
156
|
}
|
|
156
157
|
for (const rule of runnableRules) {
|
|
157
|
-
const normalized = timed(config.debug, `Batch: diagnostics normalization for ${rule.id}`, () => (0, diagnostics_1.normalizeDiagnostics)(rule.id, groupedByRule.get(rule.id) ?? [], config.debug));
|
|
158
|
+
const normalized = timed(config.debug, `Batch: diagnostics normalization for ${rule.id}`, () => (0, diagnostics_1.normalizeDiagnostics)(rule.id, groupedByRule.get(rule.id) ?? [], config.debug, repoRoot));
|
|
158
159
|
diagnostics.push(...normalized);
|
|
159
160
|
}
|
|
160
161
|
}
|
|
@@ -179,7 +180,7 @@ async function runSemlint(options) {
|
|
|
179
180
|
prompt,
|
|
180
181
|
timeoutMs: config.timeoutMs
|
|
181
182
|
}));
|
|
182
|
-
normalized = timed(config.debug, `Rule ${rule.id}: diagnostics normalization`, () => (0, diagnostics_1.normalizeDiagnostics)(rule.id, result.diagnostics, config.debug));
|
|
183
|
+
normalized = timed(config.debug, `Rule ${rule.id}: diagnostics normalization`, () => (0, diagnostics_1.normalizeDiagnostics)(rule.id, result.diagnostics, config.debug, repoRoot));
|
|
183
184
|
}
|
|
184
185
|
catch (error) {
|
|
185
186
|
backendError = true;
|