Skip to content

Commit b61f5ac

Browse files
authored
Merge pull request #126 from Chrilleweb/cmn/dev
Added warnings to scan stats.
2 parents 8418fde + 49a3101 commit b61f5ac

File tree

6 files changed

+94
-4
lines changed

6 files changed

+94
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ This project follows [Keep a Changelog](https://keepachangelog.com/) and [Semant
77

88
### Added
99

10-
-
10+
- Added warnings count to scan usage stats.
1111

1212
### Changed
1313

src/commands/scanUsage.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ export async function scanUsage(
5050
const endTime = performance.now();
5151
scanResult.stats.duration = (endTime - startTime) / 1000; // Convert to seconds
5252

53-
// Recalculate stats after filtering
54-
calculateStats(scanResult);
55-
5653
// If user explicitly passed --example flag, but the file doesn't exist:
5754
if (printMissingExample(opts)) {
5855
return { exitWithError: true };
@@ -128,6 +125,9 @@ export async function scanUsage(
128125
}
129126
}
130127

128+
// Recalculate stats after filtering
129+
calculateStats(scanResult);
130+
131131
// JSON output
132132
if (opts.json) {
133133
const jsonOutput = createJsonOutput(
@@ -237,10 +237,25 @@ function calculateStats(scanResult: ScanResult): ScanResult {
237237
scanResult.used.map((u: EnvUsage) => u.variable),
238238
).size;
239239

240+
const warningsCount =
241+
(scanResult.frameworkWarnings?.length ?? 0) +
242+
(scanResult.exampleWarnings?.length ?? 0) +
243+
(scanResult.t3EnvWarnings?.length ?? 0) +
244+
(scanResult.logged?.length ?? 0) +
245+
(scanResult.uppercaseWarnings?.length ?? 0) +
246+
(scanResult.expireWarnings?.length ?? 0) +
247+
(scanResult.inconsistentNamingWarnings?.length ?? 0) +
248+
(scanResult.secrets?.length ?? 0) +
249+
(scanResult.missing.length ?? 0) +
250+
(scanResult.unused.length ?? 0) +
251+
(scanResult.duplicates?.env?.length ?? 0) +
252+
(scanResult.duplicates?.example?.length ?? 0);
253+
240254
scanResult.stats = {
241255
filesScanned: scanResult.stats.filesScanned,
242256
totalUsages: scanResult.used.length,
243257
uniqueVariables,
258+
warningsCount: warningsCount,
244259
duration: scanResult.stats.duration,
245260
};
246261

src/config/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ export interface ScanResult {
149149
filesScanned: number;
150150
totalUsages: number;
151151
uniqueVariables: number;
152+
warningsCount: number;
152153
duration: number;
153154
};
154155
secrets: SecretFinding[];
@@ -188,6 +189,7 @@ export interface ScanJsonEntry {
188189
filesScanned: number;
189190
totalUsages: number;
190191
uniqueVariables: number;
192+
warningsCount: number;
191193
duration: number;
192194
};
193195
missing: Array<{

src/services/codeBaseScanner.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export async function scanCodebase(opts: ScanOptions): Promise<ScanResult> {
7070
filesScanned,
7171
totalUsages: filteredUsages.length,
7272
uniqueVariables: uniqueVariables.length,
73+
warningsCount: 0,
7374
duration: 0,
7475
},
7576
duplicates: {

src/ui/scan/printStats.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ interface ScanStats {
44
filesScanned: number;
55
totalUsages: number;
66
uniqueVariables: number;
7+
warningsCount: number;
78
duration: number;
89
}
910

@@ -25,6 +26,9 @@ export function printStats(
2526
console.log(
2627
chalk.magenta.dim(` Unique variables: ${stats.uniqueVariables}`),
2728
);
29+
console.log(
30+
chalk.magenta.dim(` Warnings: ${stats.warningsCount}`),
31+
);
2832
console.log(
2933
chalk.magenta.dim(` Scan duration: ${stats.duration.toFixed(2)}s`),
3034
);
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { describe, it, expect, beforeAll, afterAll, afterEach } from 'vitest';
2+
import fs from 'fs';
3+
import path from 'path';
4+
import { makeTmpDir, rmrf } from '../utils/fs-helpers.js';
5+
import { buildOnce, runCli, cleanupBuild } from '../utils/cli-helpers.js';
6+
7+
const tmpDirs: string[] = [];
8+
9+
beforeAll(() => {
10+
buildOnce();
11+
});
12+
13+
afterAll(() => {
14+
cleanupBuild();
15+
});
16+
17+
afterEach(() => {
18+
while (tmpDirs.length) {
19+
const dir = tmpDirs.pop();
20+
if (dir) rmrf(dir);
21+
}
22+
});
23+
24+
function tmpDir() {
25+
const dir = makeTmpDir();
26+
tmpDirs.push(dir);
27+
return dir;
28+
}
29+
30+
describe('cli warnings count', () => {
31+
it('should show correct warnings count in scan statistics', () => {
32+
const cwd = tmpDir();
33+
34+
// Code using two env vars
35+
fs.writeFileSync(
36+
path.join(cwd, 'index.js'),
37+
`
38+
const apiKey = process.env.API_KEY;
39+
const apiUrl = process.env.API_URL;
40+
`,
41+
);
42+
43+
// .env.example contains:
44+
// - lowercase key (uppercase warning)
45+
// - unused key (unused warning)
46+
fs.writeFileSync(
47+
path.join(cwd, '.env.example'),
48+
`
49+
api_key=test
50+
UNUSED_KEY=value
51+
`,
52+
);
53+
54+
const res = runCli(cwd, ['--scan-usage']);
55+
56+
/**
57+
* Expected warnings:
58+
* - 2x missing (API_KEY, API_URL)
59+
* - 1x uppercase warning (api_key)
60+
* - 1x unused warning (UNUSED_KEY)
61+
*
62+
* Total: 4
63+
*/
64+
expect(res.status).toBe(1);
65+
expect(res.stdout).toContain('📊 Scan Statistics:');
66+
expect(res.stdout).toContain('Warnings: 5');
67+
});
68+
});

0 commit comments

Comments
 (0)