Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

- [x] Python ecosystem support (`requirements.txt`, `pyproject.toml`)
- [x] Severity filtering (`--min-severity`)
- [ ] File/path exclusion patterns
- [x] File/path exclusion patterns
- [ ] Performance optimization for large repositories
- [ ] More comprehensive test fixtures

Expand Down
23 changes: 0 additions & 23 deletions pr_body.md

This file was deleted.

47 changes: 28 additions & 19 deletions src/scanner/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,24 @@ const SKIP_FILES = new Set([
'Thumbs.db',
]);

async function discoverFiles(rootDir: string): Promise<string[]> {
interface OpkConfig {
rules?: Record<string, boolean>;
exclude?: string[];
}

function loadConfig(rootDir: string): OpkConfig | null {
const configPath = path.join(rootDir, 'opk.config.json');
try {
const content = fs.readFileSync(configPath, 'utf8');
return JSON.parse(content);
} catch {
return null;
}
}

async function discoverFiles(rootDir: string, excludePatterns: string[] = []): Promise<string[]> {
const files: string[] = [];
const excludeRegexes = excludePatterns.map((pattern) => new RegExp(pattern));

async function walk(dir: string): Promise<void> {
let entries: fs.Dirent[];
Expand All @@ -35,6 +51,13 @@ async function discoverFiles(rootDir: string): Promise<string[]> {
}

const fullPath = path.join(dir, entry.name);
let relativePath = path.relative(rootDir, fullPath);
// Normalize slashes for consistent regex matching across platforms
relativePath = relativePath.replace(/\\/g, '/');

if (excludeRegexes.some((r) => r.test(relativePath))) {
continue;
}

if (entry.isDirectory()) {
if (SKIP_DIRS.has(entry.name)) {
Expand All @@ -45,7 +68,6 @@ async function discoverFiles(rootDir: string): Promise<string[]> {
if (SKIP_FILES.has(entry.name)) {
continue;
}
const relativePath = path.relative(rootDir, fullPath);
files.push(relativePath);
}
}
Expand All @@ -55,35 +77,22 @@ async function discoverFiles(rootDir: string): Promise<string[]> {
return files;
}

interface OpkConfig {
rules?: Record<string, boolean>;
}

function loadConfig(rootDir: string): OpkConfig | null {
const configPath = path.join(rootDir, 'opk.config.json');
try {
const content = fs.readFileSync(configPath, 'utf8');
return JSON.parse(content);
} catch {
return null;
}
}

export async function scan(
rootDir: string,
minSeverity: 'info' | 'warning' | 'error' = 'info'
): Promise<ScanResult> {
const startTime = Date.now();
const absoluteRoot = path.resolve(rootDir);

const files = await discoverFiles(absoluteRoot);
const config = loadConfig(absoluteRoot);
const excludePatterns = config?.exclude || [];

const files = await discoverFiles(absoluteRoot, excludePatterns);

const context: ScanContext = {
rootDir: absoluteRoot,
files,
};

const config = loadConfig(absoluteRoot);
const disabledRules = new Set<string>();

if (config?.rules) {
Expand Down
2 changes: 2 additions & 0 deletions tests/fixtures/scanner-config-exclude/has-finding.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// TODO: implement
function c() {}
2 changes: 2 additions & 0 deletions tests/fixtures/scanner-config-exclude/has-ignored-file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// TODO implement
function a() {}
6 changes: 6 additions & 0 deletions tests/fixtures/scanner-config-exclude/opk.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"exclude": [
".*ignored.*",
"tests/.*"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// TODO implement
function b() {}
11 changes: 11 additions & 0 deletions tests/scanner/scanner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,15 @@ test('Scanner Integration', async (t) => {
const errorResult = await scan(rootDir, 'error');
assert.strictEqual(errorResult.findings.length, 0);
});

await t.test('should skip excluded paths specified in opk.config.json', async () => {
const rootDir = path.join(FIXTURES_DIR, 'scanner-config-exclude');
const result = await scan(rootDir);

// opk.config.json excludes ".*ignored.*" and "tests/".
// has-ignored-file.ts and tests/should-be-ignored.ts should be skipped.
// has-finding.ts should be scanned and return a finding.
assert.strictEqual(result.findings.length, 1);
assert.ok(result.findings[0].filePath.includes('has-finding.ts'));
});
});
Loading