Skip to content

Conversation

@mensfeld
Copy link
Owner

No description provided.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds support for 10 new linters and configuration tools to lostconf, expanding its capabilities for validating configuration file patterns across multiple ecosystems including JavaScript/TypeScript tooling, git hooks managers, DevOps tools, SQL linters, Protocol Buffers tools, and documentation linters.

Changes:

  • Added 10 new parser implementations with comprehensive pattern extraction for ESLint Flat Config, Oxlint, commitlint, lint-staged, lefthook, pre-commit, ansible-lint, SQLFluff, buf, and alex
  • Implemented 10 corresponding test suites with 100+ new test cases covering various configuration scenarios
  • Updated documentation in README.md and CHANGELOG.md to reflect the new tool support

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/parsers/sqlfluff.ts Implements parser for SQLFluff SQL linter configuration files (.sqlfluff, setup.cfg)
src/parsers/pre-commit.ts Implements parser for pre-commit framework YAML configuration files
src/parsers/oxlint.ts Implements parser for Oxlint JavaScript/TypeScript linter JSON configuration
src/parsers/lint-staged.ts Implements parser for lint-staged JSON configuration files
src/parsers/lefthook.ts Implements parser for lefthook git hooks manager YAML configuration
src/parsers/eslint-flat.ts Implements parser for ESLint v9+ flat configuration format (JSON only)
src/parsers/commitlint.ts Implements parser for commitlint commit message linting configuration
src/parsers/buf.ts Implements parser for buf Protocol Buffers linter YAML configuration
src/parsers/ansible-lint.ts Implements parser for ansible-lint DevOps tool YAML configuration
src/parsers/alex.ts Implements parser for alex inclusive language linter configuration and ignore files
src/parsers/index.ts Exports new parsers and registers them in getBuiltinParsers()
tests/parsers/*.test.ts Comprehensive test suites for all 10 new parsers (100+ tests total)
README.md Updates supported tools table and config file count from 48+ to 58+
CHANGELOG.md Documents new parser additions under Unreleased section

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 64 to 105
const lineMap = buildLineMap(content);

// Extract 'allow' patterns - these are words/phrases to allow
if (Array.isArray(config.allow)) {
for (const value of config.allow) {
if (typeof value !== 'string') continue;
const lineInfo = lineMap.get(value);

// Allow patterns are typically simple strings (words/phrases), not file paths
// We'll treat them as PATH type for validation purposes
patterns.push({
value,
type: PatternType.PATH,
line: lineInfo?.line ?? 1,
column: lineInfo?.column
});
}
}

return patterns;
}

function buildLineMap(content: string): Map<string, { line: number; column?: number }> {
const map = new Map<string, { line: number; column?: number }>();
const lines = content.split('\n');

for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const lineNum = i + 1;

const stringMatches = line.matchAll(/"([^"]+)"/g);
for (const match of stringMatches) {
const value = match[1];
if (value && !map.has(value)) {
map.set(value, { line: lineNum, column: (match.index ?? 0) + 1 });
}
}
}

return map;
}

Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'allow' field in alex configuration contains words or phrases to allow (e.g., 'boogeyman', 'garbageman'), not file paths. Treating these as PATH type patterns for validation doesn't make semantic sense, as they won't correspond to actual files in the filesystem. Consider either: (1) skipping the 'allow' field entirely since it's not related to file paths, or (2) creating a new pattern type for non-path configuration values if there's value in tracking them.

Suggested change
const lineMap = buildLineMap(content);
// Extract 'allow' patterns - these are words/phrases to allow
if (Array.isArray(config.allow)) {
for (const value of config.allow) {
if (typeof value !== 'string') continue;
const lineInfo = lineMap.get(value);
// Allow patterns are typically simple strings (words/phrases), not file paths
// We'll treat them as PATH type for validation purposes
patterns.push({
value,
type: PatternType.PATH,
line: lineInfo?.line ?? 1,
column: lineInfo?.column
});
}
}
return patterns;
}
function buildLineMap(content: string): Map<string, { line: number; column?: number }> {
const map = new Map<string, { line: number; column?: number }>();
const lines = content.split('\n');
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const lineNum = i + 1;
const stringMatches = line.matchAll(/"([^"]+)"/g);
for (const match of stringMatches) {
const value = match[1];
if (value && !map.has(value)) {
map.set(value, { line: lineNum, column: (match.index ?? 0) + 1 });
}
}
}
return map;
}
// The 'allow' field in alex configuration contains words/phrases to allow,
// not file paths. We intentionally do not convert these into PATH patterns
// to avoid misclassifying non-path values as filesystem paths.
return patterns;
}

Copilot uses AI. Check for mistakes.
import { isGlobPattern } from '../validator/glob.js';

/** Parse .sqlfluff or setup.cfg file */
function parseSqlfluff(filename: string, content: string): Pattern[] {
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filename parameter is not used in the function body. For consistency with other parsers in the codebase, it should be prefixed with an underscore (i.e., _filename: string) to indicate it's intentionally unused.

Suggested change
function parseSqlfluff(filename: string, content: string): Pattern[] {
function parseSqlfluff(_filename: string, content: string): Pattern[] {

Copilot uses AI. Check for mistakes.
}

/** Parse buf.yaml or buf.work.yaml configuration */
function parseBuf(filename: string, content: string): Pattern[] {
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filename parameter is not used in the function body. For consistency with other parsers in the codebase, it should be prefixed with an underscore (i.e., _filename: string) to indicate it's intentionally unused.

Suggested change
function parseBuf(filename: string, content: string): Pattern[] {
function parseBuf(_filename: string, content: string): Pattern[] {

Copilot uses AI. Check for mistakes.
Comment on lines 59 to 60
// Skip npm package names (start with @)
if (value.startsWith('@') || value.startsWith('.') === false) {
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition has incorrect operator precedence. The expression value.startsWith('.') === false should be !value.startsWith('.') or the entire condition should be value.startsWith('@') || (!value.startsWith('.') && !value.startsWith('/')) to properly skip npm package names while including relative and absolute file paths.

Suggested change
// Skip npm package names (start with @)
if (value.startsWith('@') || value.startsWith('.') === false) {
// Skip npm package names (start with @) and non-path-like strings
if (value.startsWith('@') || (!value.startsWith('.') && !value.startsWith('/'))) {

Copilot uses AI. Check for mistakes.
Comment on lines 64 to 69
'exclude_rules',
'ignore',
'ignore_templated_areas',
'template_path',
'library_path',
'sql_file_exts'
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fields 'exclude_rules' and 'sql_file_exts' should not be treated as path-related fields. 'exclude_rules' contains rule IDs (e.g., 'L001', 'L002') and 'sql_file_exts' contains file extensions (e.g., '.sql'), neither of which are file paths or glob patterns that point to actual files in the filesystem. These should be removed from the isPathField check.

Suggested change
'exclude_rules',
'ignore',
'ignore_templated_areas',
'template_path',
'library_path',
'sql_file_exts'
'ignore',
'ignore_templated_areas',
'template_path',
'library_path'

Copilot uses AI. Check for mistakes.
@mensfeld mensfeld merged commit 73de8ba into master Jan 26, 2026
4 checks passed
@mensfeld mensfeld deleted the add-extra-linters branch January 26, 2026 15:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant