Skip to content

feat: add baseline support for tracking and suppressing existing violations#2154

Open
benfdking wants to merge 2 commits intomainfrom
claude/add-baseline-support-vqBmd
Open

feat: add baseline support for tracking and suppressing existing violations#2154
benfdking wants to merge 2 commits intomainfrom
claude/add-baseline-support-vqBmd

Conversation

@benfdking
Copy link
Collaborator

Baselines allow you to track existing violations in a codebase and only
report new violations. This enables:

  • Adopting sqruff in existing projects without fixing all violations first
  • Preventing regressions while allowing legacy issues to be addressed over time
  • Enabling incremental improvement of code quality

Usage:

  1. Generate a baseline:
    sqruff baseline <paths...> -o .sqruff-baseline

  2. Lint using the baseline (only report new violations):
    sqruff lint <paths...> --baseline .sqruff-baseline

The baseline uses a count-based approach (similar to elm-review and ESLint),
tracking how many violations of each rule type exist per file. This is more
stable than line-number-based approaches because it doesn't get invalidated
when unrelated code changes shift line numbers.

claude and others added 2 commits January 11, 2026 02:26
…ations

Baselines allow you to track existing violations in a codebase and only
report new violations. This enables:

- Adopting sqruff in existing projects without fixing all violations first
- Preventing regressions while allowing legacy issues to be addressed over time
- Enabling incremental improvement of code quality

Usage:

1. Generate a baseline:
   sqruff baseline <paths...> -o .sqruff-baseline

2. Lint using the baseline (only report new violations):
   sqruff lint <paths...> --baseline .sqruff-baseline

The baseline uses a count-based approach (similar to elm-review and ESLint),
tracking how many violations of each rule type exist per file. This is more
stable than line-number-based approaches because it doesn't get invalidated
when unrelated code changes shift line numbers.
@github-actions
Copy link

Benchmark for 727f950

Click to view benchmark
Test Base PR %
DepthMap::from_parent 52.5±0.70µs 53.4±0.71µs +1.71%
fix_complex_query 12.8±0.15ms 12.8±0.46ms 0.00%
fix_superlong 215.2±10.74ms 204.2±9.09ms -5.11%
parse_complex_query 4.2±0.07µs 4.2±0.05µs 0.00%
parse_expression_recursion 7.1±0.11µs 7.3±0.10µs +2.82%
parse_simple_query 1076.7±23.22ns 1056.9±16.89ns -1.84%

Copy link
Contributor

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 PR adds baseline support for tracking and suppressing existing violations in a codebase, enabling incremental adoption of sqruff without requiring all violations to be fixed upfront. The baseline uses a count-based approach (similar to elm-review and ESLint) that tracks violation counts per rule per file, which is more stable than line-number-based approaches.

Changes:

  • Added new baseline module with serialization, filtering, and comparison logic for violation baselines
  • Added sqruff baseline command to generate baseline files from existing violations
  • Extended sqruff lint command with --baseline flag to filter violations against a baseline
  • Added comprehensive integration tests for baseline generation and lint filtering

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
crates/cli-lib/src/baseline.rs New module implementing baseline data structures, serialization/deserialization, and filtering logic
crates/cli-lib/src/commands_baseline.rs New command handler for generating baselines from paths or stdin
crates/cli-lib/src/commands_lint.rs Extended lint command to support baseline filtering with custom formatter creation and violation filtering
crates/cli-lib/src/commands.rs Added BaselineArgs and baseline field to LintArgs for CLI argument parsing
crates/cli-lib/src/lib.rs Integrated baseline command into main command dispatch logic
crates/cli/tests/baseline.rs Added comprehensive integration tests for baseline generation and lint filtering scenarios
crates/cli/Cargo.toml Added test configuration and serde_json dev-dependency
Cargo.lock Updated dependencies with serde_json
docs/cli.md Generated documentation for new baseline command and --baseline option

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

}

/// Run baseline generation from stdin.
pub(crate) fn run_baseline_stdin(config: FluffConfig, output: Option<std::path::PathBuf>) -> i32 {
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

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

The run_baseline_stdin function is missing the collect_parse_errors parameter. This function should accept this parameter like run_baseline does (line 16) to maintain API consistency, and it should be passed from the caller at line 140 in lib.rs.

Copilot uses AI. Check for mistakes.
Comment on lines +200 to +221
fn create_formatter(format: Format, config: &FluffConfig) -> Arc<dyn Formatter> {
match format {
Format::Human => {
let output_stream = std::io::stderr().into();
let formatter = OutputStreamFormatter::new(
output_stream,
config.get("nocolor", "core").as_bool().unwrap_or_default(),
config.get("verbose", "core").as_int().unwrap_or_default(),
);
Arc::new(formatter)
}
Format::GithubAnnotationNative => {
let output_stream = std::io::stderr();
let formatter = GithubAnnotationNativeFormatter::new(output_stream);
Arc::new(formatter)
}
Format::Json => {
let formatter = JsonFormatter::default();
Arc::new(formatter)
}
}
}
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

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

The create_formatter function duplicates the formatter creation logic from the linter function in lib.rs (lines 148-167). Consider extracting this into a shared utility function to reduce code duplication and ensure consistency when formatter creation logic changes.

Copilot uses AI. Check for mistakes.
Comment on lines +7 to +13
fn main() {
test_baseline_generation();
test_baseline_lint_suppresses_existing();
test_baseline_lint_detects_new_violations();
test_baseline_lint_reports_fixed_violations();
test_baseline_file_not_found();
}
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

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

This test file uses a non-standard test structure with a main function calling individual test functions. While this pattern works with harness = false, it means test failures won't be properly reported - if one test fails, subsequent tests won't run. Consider using proper Rust test attributes (#[test]) or at least add error handling to ensure all tests run even if one fails.

Copilot uses AI. Check for mistakes.
};

// Create a linter WITHOUT a formatter (we don't want to output violations during baseline generation)
let linter = Linter::new(config, None, None, false);
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

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

The collect_parse_errors parameter is not used when creating the Linter on line 78. It's hardcoded to false. This should use the parameter passed from the caller to maintain consistency with the non-stdin baseline generation path (line 21 in run_baseline).

Copilot uses AI. Check for mistakes.
Copy link
Contributor

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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

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.

2 participants