Skip to main content

Crate cuke_dedup

Crate cuke_dedup 

Source
Expand description

CukeDedup’s reusable static-analysis library.

The CLI is the primary integration for repository-wide analysis. Embedders can also parse definitions and feature steps into the shared representation and run the same rules directly:

use cuke_dedup::analysis::analyze;
use cuke_dedup::config::{Config, ConfigOverrides};
use cuke_dedup::gherkin;
use cuke_dedup::source_adapter::{SourceFile, SourceLanguage};
use cuke_dedup::typescript;
use std::path::Path;

let root = std::env::current_dir()?;
let config = Config::load(&root, ConfigOverrides::default())?;
let definition_file = SourceFile {
    path: root.join("steps.ts"),
    language: SourceLanguage::TypeScript,
};
let definitions = typescript::extract(
    r#"import { Given } from "@cucumber/cucumber";
Given("a user exists", async () => { await createUser(); });"#,
    &definition_file,
)?;
let feature_steps = gherkin::extract(
    "Feature: Users\n  Scenario: Existing user\n    Given a user exists\n",
    Path::new("features/users.feature"),
)?;

let result = analyze(definitions, feature_steps, &config)?;
assert!(result.findings.is_empty());

§Public API stability

Extensibility follows the direction the data travels, and the two halves are deliberately different.

Types the analyzer produces carry #[non_exhaustive], so a later release can add a field without breaking embedders. Where a caller still needs to build one — to assemble a partial result, a diagnostic, or a baseline — the type also exposes a new constructor that takes the fields required at that version.

Types embedders construct to feed the analyzer stay exhaustive, because #[non_exhaustive] would make them impossible to build from outside this crate. That covers source_adapter::SourceFile, model::SourceLocation, model::StepDefinition, model::HandlerFingerprint, model::InlineSuppression, model::FeatureStep, config::Config, config::ConfigOverrides and config::SuppressionConfig. Adding a field to any of those is a breaking change and needs a major release.

When adding a public type, follow that rule rather than copying a neighbour: mark it #[non_exhaustive] if the analyzer returns it, leave it exhaustive if a caller has to build it, and give it a constructor if it travels both ways.

Machine-readable output is versioned independently of the crate, so a schema change is visible to consumers that never read the crate version: reporters::JSON_SCHEMA_VERSION, reporters::JSONL_SCHEMA_VERSION and modes::BASELINE_SCHEMA_VERSION. Rendering always goes through reporters::ReportContext and the reporters::render_json, reporters::render_jsonl, reporters::render_html, reporters::render_sarif and reporters::write_terminal wrappers, which are the only supported rendering entry points.

Modules§

analysis
Rule evaluation over the shared step-definition representation.
cli
Command-line parsing and analysis orchestration.
config
Configuration loading and precedence.
discovery
Gitignore-aware repository discovery.
gherkin
Full-syntax, localized Gherkin feature-step extraction.
model
Shared intermediate representation and diagnostics.
modes
Changed-files and existing-findings baseline modes for incremental CI adoption.
reporters
Terminal, JSON, JSON Lines, self-contained HTML, and SARIF reporters.
source_adapter
Definition-source adapter contracts and extension-based routing.
typescript
Tree-sitter based JavaScript and TypeScript step-definition extraction.