commit-cop 1.1.0 → 1.1.2
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 +72 -15
- package/dist/brand.d.ts +4 -0
- package/dist/brand.d.ts.map +1 -0
- package/{src/brand.ts → dist/brand.js} +4 -3
- package/dist/brand.js.map +1 -0
- package/dist/checks/binaryFileCheck.js +2 -2
- package/dist/checks/binaryFileCheck.js.map +1 -1
- package/dist/checks/consoleLogCheck.d.ts.map +1 -1
- package/dist/checks/consoleLogCheck.js +2 -2
- package/dist/checks/consoleLogCheck.js.map +1 -1
- package/dist/checks/debuggerCheck.d.ts.map +1 -1
- package/dist/checks/debuggerCheck.js +2 -2
- package/dist/checks/debuggerCheck.js.map +1 -1
- package/dist/checks/envFileCheck.d.ts.map +1 -1
- package/dist/checks/envFileCheck.js +2 -2
- package/dist/checks/envFileCheck.js.map +1 -1
- package/dist/checks/focusedTestCheck.js +2 -2
- package/dist/checks/focusedTestCheck.js.map +1 -1
- package/dist/checks/generatedFolderCheck.js +2 -2
- package/dist/checks/generatedFolderCheck.js.map +1 -1
- package/dist/checks/junkFileCheck.d.ts.map +1 -1
- package/dist/checks/junkFileCheck.js +2 -2
- package/dist/checks/junkFileCheck.js.map +1 -1
- package/dist/checks/largeFileCheck.js +2 -2
- package/dist/checks/largeFileCheck.js.map +1 -1
- package/dist/checks/localHostCheck.js +2 -2
- package/dist/checks/localHostCheck.js.map +1 -1
- package/dist/checks/lockfileDriftCheck.d.ts.map +1 -1
- package/dist/checks/lockfileDriftCheck.js +4 -4
- package/dist/checks/lockfileDriftCheck.js.map +1 -1
- package/dist/checks/mergeConflictCheck.d.ts.map +1 -1
- package/dist/checks/mergeConflictCheck.js +2 -2
- package/dist/checks/mergeConflictCheck.js.map +1 -1
- package/dist/checks/secretCheck.js +19 -19
- package/dist/checks/secretCheck.js.map +1 -1
- package/dist/checks/sensitiveFilenameCheck.d.ts.map +1 -1
- package/dist/checks/sensitiveFilenameCheck.js +2 -2
- package/dist/checks/sensitiveFilenameCheck.js.map +1 -1
- package/dist/fix/debugCode.d.ts +3 -0
- package/dist/fix/debugCode.d.ts.map +1 -0
- package/dist/fix/debugCode.js +55 -0
- package/dist/fix/debugCode.js.map +1 -0
- package/dist/fix/focusedTests.d.ts +2 -0
- package/dist/fix/focusedTests.d.ts.map +1 -0
- package/dist/fix/focusedTests.js +22 -0
- package/dist/fix/focusedTests.js.map +1 -0
- package/dist/fix/gitignore.d.ts +2 -0
- package/dist/fix/gitignore.d.ts.map +1 -0
- package/dist/fix/gitignore.js +82 -0
- package/dist/fix/gitignore.js.map +1 -0
- package/dist/fix/junkFiles.d.ts +2 -0
- package/dist/fix/junkFiles.d.ts.map +1 -0
- package/dist/fix/junkFiles.js +14 -0
- package/dist/fix/junkFiles.js.map +1 -0
- package/dist/fix/lockfile.d.ts +2 -0
- package/dist/fix/lockfile.d.ts.map +1 -0
- package/dist/fix/lockfile.js +18 -0
- package/dist/fix/lockfile.js.map +1 -0
- package/dist/fix/matchers.d.ts +9 -0
- package/dist/fix/matchers.d.ts.map +1 -0
- package/dist/fix/matchers.js +118 -0
- package/dist/fix/matchers.js.map +1 -0
- package/dist/fix/runFix.d.ts +3 -0
- package/dist/fix/runFix.d.ts.map +1 -0
- package/dist/fix/runFix.js +82 -0
- package/dist/fix/runFix.js.map +1 -0
- package/dist/fix/unstage.d.ts +2 -0
- package/dist/fix/unstage.d.ts.map +1 -0
- package/dist/fix/unstage.js +22 -0
- package/dist/fix/unstage.js.map +1 -0
- package/dist/fix/utils.d.ts +4 -0
- package/dist/fix/utils.d.ts.map +1 -0
- package/dist/fix/utils.js +39 -0
- package/dist/fix/utils.js.map +1 -0
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +2 -1
- package/dist/git.js.map +1 -1
- package/dist/hook.d.ts +3 -0
- package/dist/hook.d.ts.map +1 -0
- package/dist/hook.js +87 -0
- package/dist/hook.js.map +1 -0
- package/dist/index.js +38 -21
- package/dist/index.js.map +1 -1
- package/dist/reporter.d.ts +1 -1
- package/dist/reporter.d.ts.map +1 -1
- package/dist/reporter.js +86 -28
- package/dist/reporter.js.map +1 -1
- package/dist/runScan.d.ts +2 -0
- package/dist/runScan.d.ts.map +1 -0
- package/dist/runScan.js +18 -0
- package/dist/runScan.js.map +1 -0
- package/dist/scanner.d.ts.map +1 -1
- package/dist/scanner.js +4 -1
- package/dist/scanner.js.map +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +7 -2
- package/src/checks/binaryFileCheck.ts +0 -64
- package/src/checks/consoleLogCheck.ts +0 -40
- package/src/checks/debuggerCheck.ts +0 -33
- package/src/checks/envFileCheck.ts +0 -26
- package/src/checks/focusedTestCheck.ts +0 -41
- package/src/checks/generatedFolderCheck.ts +0 -45
- package/src/checks/junkFileCheck.ts +0 -40
- package/src/checks/largeFileCheck.ts +0 -31
- package/src/checks/localHostCheck.ts +0 -40
- package/src/checks/lockfileDriftCheck.ts +0 -40
- package/src/checks/mergeConflictCheck.ts +0 -41
- package/src/checks/secretCheck.ts +0 -60
- package/src/checks/sensitiveFilenameCheck.ts +0 -51
- package/src/checks/utils.ts +0 -62
- package/src/fix/debugCode.ts +0 -74
- package/src/fix/focusedTests.ts +0 -26
- package/src/fix/gitignore.ts +0 -108
- package/src/fix/junkFiles.ts +0 -16
- package/src/fix/lockfile.ts +0 -23
- package/src/fix/matchers.ts +0 -141
- package/src/fix/runFix.ts +0 -96
- package/src/fix/unstage.ts +0 -25
- package/src/fix/utils.ts +0 -50
- package/src/git.ts +0 -17
- package/src/hook.ts +0 -98
- package/src/index.ts +0 -59
- package/src/reporter.ts +0 -88
- package/src/runScan.ts +0 -35
- package/src/scanner.ts +0 -44
- package/src/types.ts +0 -25
- package/test.ts +0 -6
- package/testing.ts +0 -3
- package/tsconfig.json +0 -44
package/dist/hook.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { CLI_NAME, PRODUCT_NAME } from "./brand.js";
|
|
5
|
+
const HOOK_MARKER = "# Generated by Commit Cop";
|
|
6
|
+
const BACKUP_SUFFIX = ".commit-cop.backup";
|
|
7
|
+
function getGitHooksDir() {
|
|
8
|
+
try {
|
|
9
|
+
const gitPath = execSync("git rev-parse --git-path hooks", {
|
|
10
|
+
encoding: "utf-8",
|
|
11
|
+
}).trim();
|
|
12
|
+
return path.resolve(gitPath);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
throw new Error(`${PRODUCT_NAME} install must be run inside a Git repository.`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function buildHookScript(strict) {
|
|
19
|
+
const strictFlag = strict ? " --strict" : "";
|
|
20
|
+
return `#!/bin/sh
|
|
21
|
+
${HOOK_MARKER}
|
|
22
|
+
# Re-run: npx ${CLI_NAME} install
|
|
23
|
+
|
|
24
|
+
cd "$(git rev-parse --show-toplevel)" || exit 1
|
|
25
|
+
|
|
26
|
+
# Local development: run from source when working on Commit Cop itself
|
|
27
|
+
if [ -f package.json ] && [ -f src/index.ts ] && command -v npm >/dev/null 2>&1; then
|
|
28
|
+
exec npm run dev --${strictFlag}
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
if [ -x "./node_modules/.bin/${CLI_NAME}" ]; then
|
|
32
|
+
exec ./node_modules/.bin/${CLI_NAME}${strictFlag}
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
if command -v ${CLI_NAME} >/dev/null 2>&1; then
|
|
36
|
+
exec ${CLI_NAME}${strictFlag}
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
exec npx ${CLI_NAME}${strictFlag}
|
|
40
|
+
`;
|
|
41
|
+
}
|
|
42
|
+
export function installHook(strict = false) {
|
|
43
|
+
const hooksDir = getGitHooksDir();
|
|
44
|
+
const hookPath = path.join(hooksDir, "pre-commit");
|
|
45
|
+
const backupPath = `${hookPath}${BACKUP_SUFFIX}`;
|
|
46
|
+
fs.mkdirSync(hooksDir, { recursive: true });
|
|
47
|
+
if (fs.existsSync(hookPath)) {
|
|
48
|
+
const existing = fs.readFileSync(hookPath, "utf-8");
|
|
49
|
+
if (existing.includes(HOOK_MARKER)) {
|
|
50
|
+
console.log(`${PRODUCT_NAME}: Updating existing pre-commit hook.`);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
fs.copyFileSync(hookPath, backupPath);
|
|
54
|
+
console.log(`${PRODUCT_NAME}: Backed up existing pre-commit hook to ${path.basename(backupPath)}.`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
fs.writeFileSync(hookPath, buildHookScript(strict), { mode: 0o755 });
|
|
58
|
+
console.log(`${PRODUCT_NAME}: Pre-commit hook installed.`);
|
|
59
|
+
console.log(` ${hookPath}`);
|
|
60
|
+
console.log("");
|
|
61
|
+
console.log("Commit Cop will now run automatically on git commit.");
|
|
62
|
+
if (strict) {
|
|
63
|
+
console.log("Strict mode is enabled for this hook.");
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export function uninstallHook() {
|
|
67
|
+
const hooksDir = getGitHooksDir();
|
|
68
|
+
const hookPath = path.join(hooksDir, "pre-commit");
|
|
69
|
+
const backupPath = `${hookPath}${BACKUP_SUFFIX}`;
|
|
70
|
+
if (!fs.existsSync(hookPath)) {
|
|
71
|
+
console.log(`${PRODUCT_NAME}: No pre-commit hook found.`);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const existing = fs.readFileSync(hookPath, "utf-8");
|
|
75
|
+
if (!existing.includes(HOOK_MARKER)) {
|
|
76
|
+
throw new Error(`${PRODUCT_NAME} did not install this pre-commit hook. Remove it manually if needed.`);
|
|
77
|
+
}
|
|
78
|
+
fs.unlinkSync(hookPath);
|
|
79
|
+
if (fs.existsSync(backupPath)) {
|
|
80
|
+
fs.copyFileSync(backupPath, hookPath);
|
|
81
|
+
fs.unlinkSync(backupPath);
|
|
82
|
+
console.log(`${PRODUCT_NAME}: Pre-commit hook removed and previous hook restored.`);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
console.log(`${PRODUCT_NAME}: Pre-commit hook removed.`);
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=hook.js.map
|
package/dist/hook.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook.js","sourceRoot":"","sources":["../src/hook.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,30 +1,47 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { CLI_NAME, PRODUCT_NAME, TAGLINE } from "./brand.js";
|
|
2
3
|
import { Command } from "commander";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { runWipFix } from "./fix/runFix.js";
|
|
5
|
+
import { installHook, uninstallHook } from "./hook.js";
|
|
6
|
+
import { runScan } from "./runScan.js";
|
|
6
7
|
const program = new Command();
|
|
7
8
|
program
|
|
8
|
-
.name(
|
|
9
|
-
.description(
|
|
9
|
+
.name(CLI_NAME)
|
|
10
|
+
.description(`${PRODUCT_NAME} — ${TAGLINE}`);
|
|
11
|
+
program
|
|
12
|
+
.command("scan", { isDefault: true })
|
|
13
|
+
.description("Scan staged files for risky commits")
|
|
10
14
|
.option("--strict", "Treat warnings as errors")
|
|
15
|
+
.option("--allow-console-log", "Skip console.log warnings (for projects that keep console.log on purpose)")
|
|
11
16
|
.action(async (options) => {
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
17
|
+
const exitCode = await runScan(Boolean(options.strict), Boolean(options.allowConsoleLog));
|
|
18
|
+
process.exit(exitCode);
|
|
19
|
+
});
|
|
20
|
+
program
|
|
21
|
+
.command("wip-fix")
|
|
22
|
+
.description("Apply common repo fixes matching commit-cop checks (.gitignore, debug code, unstaging, etc.)")
|
|
23
|
+
.option("--fix-console-log", "Also remove standalone console.log lines from staged files (debugger lines are always removed)")
|
|
24
|
+
.action((options) => {
|
|
25
|
+
runWipFix({ fixConsoleLog: Boolean(options.fixConsoleLog) });
|
|
26
|
+
});
|
|
27
|
+
program
|
|
28
|
+
.command("install")
|
|
29
|
+
.description("Install a Git pre-commit hook that runs Commit Cop on every commit")
|
|
30
|
+
.option("--strict", "Treat warnings as errors in the hook")
|
|
31
|
+
.action((options) => {
|
|
32
|
+
installHook(Boolean(options.strict));
|
|
33
|
+
});
|
|
34
|
+
program
|
|
35
|
+
.command("uninstall")
|
|
36
|
+
.description("Remove the Commit Cop pre-commit hook")
|
|
37
|
+
.action(() => {
|
|
38
|
+
uninstallHook();
|
|
39
|
+
});
|
|
40
|
+
program
|
|
41
|
+
.command("wip-fix")
|
|
42
|
+
.description("Apply common repo fixes (work in progress)")
|
|
43
|
+
.action(() => {
|
|
44
|
+
runWipFix();
|
|
28
45
|
});
|
|
29
46
|
program.parse();
|
|
30
47
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,GAAG,YAAY,MAAM,OAAO,EAAE,CAAC,CAAC;AAE/C,OAAO;KACJ,OAAO,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;KACpC,WAAW,CAAC,qCAAqC,CAAC;KAClD,MAAM,CAAC,UAAU,EAAE,0BAA0B,CAAC;KAC9C,MAAM,CACL,qBAAqB,EACrB,2EAA2E,CAC5E;KACA,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAC5B,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EACvB,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CACjC,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AACzB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CACV,8FAA8F,CAC/F;KACA,MAAM,CACL,mBAAmB,EACnB,gGAAgG,CACjG;KACA,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;IAClB,SAAS,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;AAC/D,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,oEAAoE,CAAC;KACjF,MAAM,CAAC,UAAU,EAAE,sCAAsC,CAAC;KAC1D,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;IAClB,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AACvC,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,WAAW,CAAC;KACpB,WAAW,CAAC,uCAAuC,CAAC;KACpD,MAAM,CAAC,GAAG,EAAE;IACX,aAAa,EAAE,CAAC;AAClB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,4CAA4C,CAAC;KACzD,MAAM,CAAC,GAAG,EAAE;IACX,SAAS,EAAE,CAAC;AACd,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
package/dist/reporter.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { Finding } from "./types.js";
|
|
2
|
-
export declare function printReport(findings: Finding[], scannedCount: number):
|
|
2
|
+
export declare function printReport(findings: Finding[], scannedCount: number, strict: boolean): number;
|
|
3
3
|
//# sourceMappingURL=reporter.d.ts.map
|
package/dist/reporter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AA4G1C,wBAAgB,WAAW,CACzB,QAAQ,EAAE,OAAO,EAAE,EACnB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,OAAO,GACd,MAAM,CA2BR"}
|
package/dist/reporter.js
CHANGED
|
@@ -1,38 +1,96 @@
|
|
|
1
|
+
import { PRODUCT_NAME } from "./brand.js";
|
|
1
2
|
import chalk from "chalk";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
console.log(
|
|
8
|
-
console.log(
|
|
9
|
-
console.log(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
printFinding(finding);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
if (warnings.length > 0) {
|
|
21
|
-
console.log(chalk.yellow.bold("\n⚠️ Warnings"));
|
|
22
|
-
for (const finding of warnings) {
|
|
23
|
-
printFinding(finding);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
3
|
+
const WIDTH = 52;
|
|
4
|
+
function line(char = "─") {
|
|
5
|
+
return chalk.dim(char.repeat(WIDTH));
|
|
6
|
+
}
|
|
7
|
+
function printHeader(title) {
|
|
8
|
+
console.log("");
|
|
9
|
+
console.log(line("═"));
|
|
10
|
+
console.log(chalk.bold(` ${title}`));
|
|
11
|
+
console.log(line("═"));
|
|
12
|
+
}
|
|
13
|
+
function printSection(title, color) {
|
|
14
|
+
console.log("");
|
|
15
|
+
console.log(line());
|
|
16
|
+
console.log(color(chalk.bold(` ${title}`)));
|
|
17
|
+
console.log(line());
|
|
26
18
|
console.log("");
|
|
27
19
|
}
|
|
28
|
-
function printFinding(finding) {
|
|
20
|
+
function printFinding(finding, index) {
|
|
29
21
|
const location = finding.line
|
|
30
22
|
? `${finding.file}:${finding.line}`
|
|
31
23
|
: finding.file;
|
|
32
|
-
|
|
33
|
-
console.log(` ${
|
|
24
|
+
const checkLabel = chalk.dim(`[${finding.checkName}]`);
|
|
25
|
+
console.log(chalk.bold(` ${index}.`) + ` ${checkLabel}`);
|
|
26
|
+
console.log(` ${chalk.cyan(location)}`);
|
|
27
|
+
console.log(` ${finding.message}`);
|
|
34
28
|
if (finding.suggestion) {
|
|
35
|
-
console.log(chalk.gray(`
|
|
29
|
+
console.log(chalk.gray(` → ${finding.suggestion}`));
|
|
30
|
+
}
|
|
31
|
+
console.log("");
|
|
32
|
+
}
|
|
33
|
+
function printFindings(findings, severity) {
|
|
34
|
+
const filtered = findings.filter((finding) => finding.severity === severity);
|
|
35
|
+
filtered.forEach((finding, index) => {
|
|
36
|
+
printFinding(finding, index + 1);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function printSummary(strict, errorCount, warningCount) {
|
|
40
|
+
console.log("");
|
|
41
|
+
console.log(`Strict Mode: ${strict ? "ON" : "OFF"}`);
|
|
42
|
+
console.log(` ${chalk.red(`Errors: ${errorCount}`)}${chalk.dim(" │ ")}${chalk.yellow(`Warnings: ${warningCount}`)}`);
|
|
43
|
+
console.log("");
|
|
44
|
+
}
|
|
45
|
+
function colorErrors(text) {
|
|
46
|
+
return text.replace(/\berrors\b/gi, (match) => chalk.red(match));
|
|
47
|
+
}
|
|
48
|
+
function colorWarnings(text) {
|
|
49
|
+
return text.replace(/\bwarnings\b/gi, (match) => chalk.yellow(match));
|
|
50
|
+
}
|
|
51
|
+
function colorOutcomeMessage(text) {
|
|
52
|
+
return colorErrors(colorWarnings(text));
|
|
53
|
+
}
|
|
54
|
+
function resolveOutcome(strict, errorCount, warningCount) {
|
|
55
|
+
if (errorCount > 0) {
|
|
56
|
+
console.error(colorOutcomeMessage(`${PRODUCT_NAME} found errors.`));
|
|
57
|
+
console.error(colorOutcomeMessage("Please fix the errors before committing successfully."));
|
|
58
|
+
return 1;
|
|
59
|
+
}
|
|
60
|
+
if (strict && warningCount > 0) {
|
|
61
|
+
console.error(colorOutcomeMessage(`${PRODUCT_NAME} found warnings.`));
|
|
62
|
+
console.error(colorOutcomeMessage("Please fix the warnings before committing successfully."));
|
|
63
|
+
return 1;
|
|
36
64
|
}
|
|
65
|
+
if (!strict && warningCount > 0) {
|
|
66
|
+
console.warn(colorOutcomeMessage(`${PRODUCT_NAME} found warnings, but no errors.`));
|
|
67
|
+
console.warn(`Your commit was ${chalk.green("successful")}.`);
|
|
68
|
+
console.warn(colorOutcomeMessage(`If you still like to clean up these ${chalk.yellow("warnings")}, review these before commiting again.`));
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
71
|
+
console.log(`${PRODUCT_NAME} passed.`);
|
|
72
|
+
console.log(colorOutcomeMessage("No errors or warnings found."));
|
|
73
|
+
console.log(`Your commit was ${chalk.green("successful")}.`);
|
|
74
|
+
return 0;
|
|
75
|
+
}
|
|
76
|
+
export function printReport(findings, scannedCount, strict) {
|
|
77
|
+
const errorCount = findings.filter((finding) => finding.severity === "error").length;
|
|
78
|
+
const warningCount = findings.filter((finding) => finding.severity === "warning").length;
|
|
79
|
+
printHeader(`${PRODUCT_NAME} Report`);
|
|
80
|
+
console.log("");
|
|
81
|
+
console.log(chalk.dim(` Scanned ${scannedCount} staged file(s)`));
|
|
82
|
+
printSummary(strict, errorCount, warningCount);
|
|
83
|
+
if (errorCount > 0) {
|
|
84
|
+
printSection(`ERRORS (${errorCount})`, chalk.red);
|
|
85
|
+
printFindings(findings, "error");
|
|
86
|
+
}
|
|
87
|
+
if (warningCount > 0) {
|
|
88
|
+
printSection(`WARNINGS (${warningCount})`, chalk.yellow);
|
|
89
|
+
printFindings(findings, "warning");
|
|
90
|
+
}
|
|
91
|
+
const exitCode = resolveOutcome(strict, errorCount, warningCount);
|
|
92
|
+
console.log(line("═"));
|
|
93
|
+
console.log("");
|
|
94
|
+
return exitCode;
|
|
37
95
|
}
|
|
38
96
|
//# sourceMappingURL=reporter.js.map
|
package/dist/reporter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,
|
|
1
|
+
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runScan.d.ts","sourceRoot":"","sources":["../src/runScan.ts"],"names":[],"mappings":"AAKA,wBAAsB,OAAO,CAC3B,MAAM,UAAQ,EACd,eAAe,UAAQ,GACtB,OAAO,CAAC,MAAM,CAAC,CAejB"}
|
package/dist/runScan.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PRODUCT_NAME } from "./brand.js";
|
|
2
|
+
import { getStagedFiles } from "./git.js";
|
|
3
|
+
import { runChecks } from "./scanner.js";
|
|
4
|
+
import { printReport } from "./reporter.js";
|
|
5
|
+
export async function runScan(strict = false, allowConsoleLog = false) {
|
|
6
|
+
const stagedFiles = getStagedFiles();
|
|
7
|
+
if (stagedFiles.length === 0) {
|
|
8
|
+
console.log(`${PRODUCT_NAME}: No staged files found.`);
|
|
9
|
+
return 0;
|
|
10
|
+
}
|
|
11
|
+
const findings = await runChecks({
|
|
12
|
+
stagedFiles,
|
|
13
|
+
strict,
|
|
14
|
+
allowConsoleLog,
|
|
15
|
+
});
|
|
16
|
+
return printReport(findings, stagedFiles.length, strict);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=runScan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runScan.js","sourceRoot":"","sources":["../src/runScan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,MAAM,GAAG,KAAK,EACd,eAAe,GAAG,KAAK;IAEvB,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IAErC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,GAAG,YAAY,0BAA0B,CAAC,CAAC;QACvD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC;QAC/B,WAAW;QACX,MAAM;QACN,eAAe;KAChB,CAAC,CAAC;IAEH,OAAO,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC3D,CAAC"}
|
package/dist/scanner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AA+BxD,wBAAsB,SAAS,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AA+BxD,wBAAsB,SAAS,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAYzE"}
|
package/dist/scanner.js
CHANGED
|
@@ -28,7 +28,10 @@ const checks = [
|
|
|
28
28
|
];
|
|
29
29
|
export async function runChecks(context) {
|
|
30
30
|
const allFindings = [];
|
|
31
|
-
|
|
31
|
+
const activeChecks = context.allowConsoleLog
|
|
32
|
+
? checks.filter((check) => check !== consoleLogCheck)
|
|
33
|
+
: checks;
|
|
34
|
+
for (const check of activeChecks) {
|
|
32
35
|
const findings = await check.run(context);
|
|
33
36
|
allFindings.push(...findings);
|
|
34
37
|
}
|
package/dist/scanner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,MAAM,MAAM,GAAG;IACb,kBAAkB;IAClB,YAAY;IACZ,sBAAsB;IACtB,oBAAoB;IACpB,WAAW;IACX,gBAAgB;IAChB,eAAe;IACf,aAAa;IACb,cAAc;IACd,aAAa;IACb,kBAAkB;IAClB,cAAc;IACd,eAAe;CAChB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAqB;IACnD,MAAM,WAAW,GAAc,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,MAAM,MAAM,GAAG;IACb,kBAAkB;IAClB,YAAY;IACZ,sBAAsB;IACtB,oBAAoB;IACpB,WAAW;IACX,gBAAgB;IAChB,eAAe;IACf,aAAa;IACb,cAAc;IACd,aAAa;IACb,kBAAkB;IAClB,cAAc;IACd,eAAe;CAChB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAqB;IACnD,MAAM,WAAW,GAAc,EAAE,CAAC;IAClC,MAAM,YAAY,GAAG,OAAO,CAAC,eAAe;QAC1C,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,eAAe,CAAC;QACrD,CAAC,CAAC,MAAM,CAAC;IAEX,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC1C,WAAW,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
package/dist/types.d.ts
CHANGED
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEpD,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEpD,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;CACpD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "commit-cop",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "Commit Cop — a pre-commit safety checker that scans staged files for risky commits.",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
6
9
|
"bin": {
|
|
7
10
|
"commit-cop": "./dist/index.js"
|
|
8
11
|
},
|
|
9
12
|
"scripts": {
|
|
10
13
|
"dev": "tsx src/index.ts",
|
|
11
14
|
"build": "tsc",
|
|
15
|
+
"prepublishOnly": "npm run build",
|
|
12
16
|
"start": "node dist/index.js",
|
|
13
17
|
"commit-cop": "tsx src/index.ts",
|
|
14
18
|
"demo:setup": "node scripts/setup-demo.mjs"
|
|
@@ -37,6 +41,7 @@
|
|
|
37
41
|
},
|
|
38
42
|
"dependencies": {
|
|
39
43
|
"chalk": "^5.6.2",
|
|
40
|
-
"commander": "^14.0.3"
|
|
44
|
+
"commander": "^14.0.3",
|
|
45
|
+
"commit-cop": "^1.0.1"
|
|
41
46
|
}
|
|
42
47
|
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import type { Check, Finding } from "../types.js";
|
|
3
|
-
import { getBaseName } from "./utils.js";
|
|
4
|
-
|
|
5
|
-
const binaryExtensions = new Set([
|
|
6
|
-
".zip",
|
|
7
|
-
".exe",
|
|
8
|
-
".dll",
|
|
9
|
-
".mp4",
|
|
10
|
-
".mov",
|
|
11
|
-
".sqlite",
|
|
12
|
-
".db",
|
|
13
|
-
]);
|
|
14
|
-
|
|
15
|
-
function hasNullBytes(file: string): boolean {
|
|
16
|
-
const buffer = fs.readFileSync(file);
|
|
17
|
-
const sampleSize = Math.min(buffer.length, 8192);
|
|
18
|
-
|
|
19
|
-
for (let index = 0; index < sampleSize; index += 1) {
|
|
20
|
-
if (buffer[index] === 0) {
|
|
21
|
-
return true;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const binaryFileCheck: Check = {
|
|
29
|
-
name: "binary-file-check",
|
|
30
|
-
|
|
31
|
-
async run(context) {
|
|
32
|
-
const findings: Finding[] = [];
|
|
33
|
-
|
|
34
|
-
for (const file of context.stagedFiles) {
|
|
35
|
-
if (!fs.existsSync(file)) continue;
|
|
36
|
-
|
|
37
|
-
const baseName = getBaseName(file);
|
|
38
|
-
const extension = baseName.includes(".")
|
|
39
|
-
? baseName.slice(baseName.lastIndexOf(".")).toLowerCase()
|
|
40
|
-
: "";
|
|
41
|
-
|
|
42
|
-
let isBinary = binaryExtensions.has(extension);
|
|
43
|
-
|
|
44
|
-
try {
|
|
45
|
-
isBinary ||= hasNullBytes(file);
|
|
46
|
-
} catch {
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (isBinary) {
|
|
51
|
-
findings.push({
|
|
52
|
-
severity: "warning",
|
|
53
|
-
checkName: this.name,
|
|
54
|
-
file,
|
|
55
|
-
message:
|
|
56
|
-
"Binary file detected — archives, executables, and media don't belong in source control.",
|
|
57
|
-
suggestion: "Remove it from the commit or store it with Git LFS.",
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return findings;
|
|
63
|
-
},
|
|
64
|
-
};
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import type { Check, Finding } from "../types.js";
|
|
3
|
-
|
|
4
|
-
const codeExtensions = [".js", ".jsx", ".ts", ".tsx"];
|
|
5
|
-
|
|
6
|
-
function isCodeFile(file: string): boolean {
|
|
7
|
-
return codeExtensions.some((ext) => file.endsWith(ext));
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const consoleLogCheck: Check = {
|
|
11
|
-
name: "console-log-check",
|
|
12
|
-
|
|
13
|
-
async run(context) {
|
|
14
|
-
const findings: Finding[] = [];
|
|
15
|
-
|
|
16
|
-
for (const file of context.stagedFiles) {
|
|
17
|
-
if (!isCodeFile(file)) continue;
|
|
18
|
-
if (!fs.existsSync(file)) continue;
|
|
19
|
-
|
|
20
|
-
const content = fs.readFileSync(file, "utf-8");
|
|
21
|
-
const lines = content.split("\n");
|
|
22
|
-
|
|
23
|
-
lines.forEach((line, index) => {
|
|
24
|
-
if (line.includes("console.log")) {
|
|
25
|
-
findings.push({
|
|
26
|
-
severity: "warning",
|
|
27
|
-
checkName: this.name,
|
|
28
|
-
file,
|
|
29
|
-
line: index + 1,
|
|
30
|
-
message:
|
|
31
|
-
"Debug log left in code — easy to miss and clutters production output.",
|
|
32
|
-
suggestion: "Delete the console.log before committing.",
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return findings;
|
|
39
|
-
},
|
|
40
|
-
};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import type { Check, Finding } from "../types.js";
|
|
2
|
-
import { isCodeFile, readFileLines } from "./utils.js";
|
|
3
|
-
|
|
4
|
-
export const debuggerCheck: Check = {
|
|
5
|
-
name: "debugger-check",
|
|
6
|
-
|
|
7
|
-
async run(context) {
|
|
8
|
-
const findings: Finding[] = [];
|
|
9
|
-
|
|
10
|
-
for (const file of context.stagedFiles) {
|
|
11
|
-
if (!isCodeFile(file)) continue;
|
|
12
|
-
|
|
13
|
-
const lines = readFileLines(file);
|
|
14
|
-
if (!lines) continue;
|
|
15
|
-
|
|
16
|
-
lines.forEach((line, index) => {
|
|
17
|
-
if (/\bdebugger\b/.test(line)) {
|
|
18
|
-
findings.push({
|
|
19
|
-
severity: "warning",
|
|
20
|
-
checkName: this.name,
|
|
21
|
-
file,
|
|
22
|
-
line: index + 1,
|
|
23
|
-
message:
|
|
24
|
-
"debugger statement left in code — pauses execution and breaks CI/headless runs.",
|
|
25
|
-
suggestion: "Delete the debugger statement before committing.",
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return findings;
|
|
32
|
-
},
|
|
33
|
-
};
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import type { Check, Finding } from "../types.js";
|
|
2
|
-
|
|
3
|
-
export const envFileCheck: Check = {
|
|
4
|
-
name: "env-file-check",
|
|
5
|
-
|
|
6
|
-
async run(context) {
|
|
7
|
-
const findings: Finding[] = [];
|
|
8
|
-
|
|
9
|
-
for (const file of context.stagedFiles) {
|
|
10
|
-
const fileName = file.split("/").pop() ?? "";
|
|
11
|
-
|
|
12
|
-
if (fileName === ".env" || fileName.startsWith(".env.")) {
|
|
13
|
-
findings.push({
|
|
14
|
-
severity: "error",
|
|
15
|
-
checkName: this.name,
|
|
16
|
-
file,
|
|
17
|
-
message:
|
|
18
|
-
".env file detected — these often hold API keys, passwords, and tokens.",
|
|
19
|
-
suggestion: `Unstage it: git restore --staged ${file}`,
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return findings;
|
|
25
|
-
},
|
|
26
|
-
};
|