Documentation
¶
Index ¶
- func CheckRules(f *lint.File, rules []rule.Rule, effective map[string]config.RuleCfg) ([]lint.Diagnostic, []error)
- func ConfigureRule(rl rule.Rule, cfg config.RuleCfg) (rule.Rule, error)
- func DedupeDiagnostics(diags []lint.Diagnostic) []lint.Diagnostic
- func ResolveWorkers(concurrency, n int) int
- type Result
- type Runner
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CheckRules ¶
func CheckRules(f *lint.File, rules []rule.Rule, effective map[string]config.RuleCfg) ([]lint.Diagnostic, []error)
CheckRules runs all enabled rules against f, cloning and applying settings for Configurable rules. It adjusts diagnostics using f.AdjustDiagnostics and returns the collected diagnostics and any settings-application errors. Source context is populated; callers that discard SourceLines should use checkRules with skipSourceContext=true to avoid that allocation.
func ConfigureRule ¶
ConfigureRule clones a rule and applies settings from cfg if the rule implements Configurable and cfg has settings. Returns the configured rule (or the original if no settings apply) and any error from ApplySettings.
func DedupeDiagnostics ¶ added in v0.9.0
func DedupeDiagnostics(diags []lint.Diagnostic) []lint.Diagnostic
DedupeDiagnostics returns a new slice with duplicate (file, line, column, rule, message) tuples collapsed to a single entry. Repo- level rules (notably MDS048 git-hook-sync) emit a diagnostic anchored to the repository artifact for every linted file in the repo, so a fresh `mdsmith check` over a large tree would otherwise print the same warning N times and duplicate that entry in the returned diagnostics. Earlier-encountered duplicates win so the diagnostic order from the first hit is preserved. The input slice is never modified; nil input returns nil and a non-nil input always produces a freshly-allocated slice so callers can keep the original around without worrying about aliasing.
func ResolveWorkers ¶ added in v0.20.0
ResolveWorkers maps the Runner.Concurrency knob to an actual worker count for a run over n files. concurrency <= 0 means "use runtime.GOMAXPROCS"; a positive value is taken literally. The result is clamped to n (never more workers than files) and is 0 when there is nothing to do.
Types ¶
type Result ¶
type Result struct {
// FilesChecked is the number of files processed (after ignore filtering).
FilesChecked int
Diagnostics []lint.Diagnostic
Errors []error
}
Result holds the output of a lint run.
type Runner ¶
type Runner struct {
Config *config.Config
Rules []rule.Rule
StripFrontMatter bool
Logger *vlog.Logger
// RootDir is the project root directory (parent of .mdsmith.yml).
// Used by rules that need to read files relative to the project root.
RootDir string
// MaxInputBytes is the maximum file size in bytes before a file is
// skipped with an error. Zero or negative means unlimited.
MaxInputBytes int64
// Explain, when true, attaches per-leaf rule provenance to each
// diagnostic so output formatters can render an explanation trailer.
Explain bool
// SkipSourceContext, when true, suppresses per-diagnostic
// SourceLines population. Set it for callers that never render the
// source window (the check benchmark/gate, machine output that
// omits it) to avoid its large per-diagnostic allocation. Default
// false preserves the CLI text formatter's context display.
SkipSourceContext bool
// ConfigPath is the path to the loaded .mdsmith.yml. When set,
// config-target rules (rule.ConfigTarget) are run once against a
// synthetic lint.File for this path before per-file processing.
ConfigPath string
// SourceFS, when non-nil, is set as lint.File.FS for RunSource so
// in-memory linting (e.g. an LSP buffer) sees the same filesystem
// view processFile constructs for on-disk runs. Rules like
// include/catalog short-circuit on a nil FS; without this hook
// LSP diagnostics drift from the CLI's. Run() (path-based)
// ignores this field and continues to derive FS from filepath.Dir
// per file.
SourceFS fs.FS
// Concurrency controls how many files Run lints in parallel.
// Zero or negative means "use runtime.GOMAXPROCS"; 1 forces the
// sequential path; n>1 uses n workers. The worker count is
// clamped to the file count. Output is merged in input order and
// then sorted, so the value never changes observable results —
// it only trades CPU for wall time. RunSource (single in-memory
// file) ignores this field.
Concurrency int
// IntraFileConcurrency caps how many non-NodeChecker rules run
// concurrently inside one file's checkRules call. The default
// (0 = auto) computes `max(1, GOMAXPROCS / fileWorkers)` so the
// inner pool fills whichever cores the outer file-level pool
// leaves idle: 1 when the file pool saturates cores (mdsmith
// check on many files), N when the file pool is small (a 5-file
// PR check on a 16-core host, mdsmith lsp single-file). A
// caller-set 1 forces serial dispatch; n>1 is taken as the
// explicit cap. RunSource uses GOMAXPROCS directly because the
// file-level pool does not run for single-file in-memory paths.
IntraFileConcurrency int
// RunCache is the engine-owned read cache shared by every File
// processed in one Run / RunSource pass. The catalog rule reads
// through it so a target globbed by N host catalogs is read once
// per run instead of N times. nil means "create a fresh cache
// for the next Run" (the CLI case where the corpus is immutable
// for one process). Callers with a long-lived process — the LSP
// — install a shared instance so it survives across runLint
// calls and call its Invalidate seam on document edits.
RunCache *lint.RunCache
// contains filtered or unexported fields
}
Runner drives the linting pipeline: for each file it reads the content, builds a File (parsing the AST once), determines the effective rule configuration, runs enabled rules, and collects diagnostics.
func (*Runner) Run ¶
Run lints the files at the given paths and returns a Result containing all diagnostics (sorted by file, line, column, message) and any errors encountered. Files are linted concurrently (see Runner.Concurrency); per-file results are merged in input order before dedupe and sort, so the output is identical to a sequential run regardless of scheduling.
func (*Runner) RunSource ¶
RunSource lints in-memory source bytes (e.g. from stdin or an LSP buffer) and returns a Result. It creates a File via NewFileFromSource, determines the effective config, and uses CheckRules (which includes clone+settings logic and line-offset adjustment).
When Runner.SourceFS is non-nil, RunSource wires it onto the File as f.FS so include/catalog/cross-file rules see the same filesystem view processFile sets up for on-disk runs.
f.GitignoreFunc is wired against a directory chosen in this order:
- Runner.RootDir, when set (matches processFile's anchoring).
- filepath.Dir(path), when path is absolute and RootDir is empty.
With a relative path and no RootDir (the bare `<stdin>` case), GitignoreFunc stays nil — the matcher would have no meaningful root to walk anyway. FS-aware rules still see SourceFS regardless.
When SourceFS is nil (the stdin case), FS stays nil and rules that require it short-circuit just as they did before.