rule

package
v0.23.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 21, 2026 License: MIT Imports: 3 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Register

func Register(r Rule)

Register adds a rule to the global registry.

func Reset

func Reset()

Reset clears the registry. Used for testing.

func WalkNodes added in v0.23.0

func WalkNodes(r NodeChecker, f *lint.File) []lint.Diagnostic

WalkNodes runs r.CheckNode over a single ast.Walk of f. A NodeChecker's standalone Check delegates here so direct callers (the LSP, unit tests) get behaviour identical to the engine's multiplexed dispatch, which feeds CheckNode the same node stream. Files with a nil AST short-circuit to no diagnostics; the engine never produces such files, but unit tests construct `&lint.File{}` literals to exercise rule guards.

Types

type ConfigTarget added in v0.10.0

type ConfigTarget interface {
	IsConfigFileRule() bool
}

ConfigTarget is implemented by rules that validate the project config file (.mdsmith.yml) rather than individual Markdown files. The engine runner runs these rules once against a synthetic lint.File for the config file before per-file markdown processing; they return nil for all other file paths when configured in production mode.

type Configurable

type Configurable interface {
	ApplySettings(settings map[string]any) error
	DefaultSettings() map[string]any
}

Configurable is implemented by rules that have user-tunable settings.

type Defaultable

type Defaultable interface {
	EnabledByDefault() bool
}

Defaultable is implemented by rules that override the default enabled state in generated/runtime configs.

type FixableRule

type FixableRule interface {
	Rule
	Fix(f *lint.File) []byte
}

FixableRule is a Rule that can also auto-fix violations.

type ListMerger added in v0.7.0

type ListMerger interface {
	SettingMergeMode(key string) MergeMode
}

ListMerger is implemented by Configurable rules that opt one or more list-typed settings out of the default MergeReplace behavior. The merge function calls SettingMergeMode(key) at config-resolution time and treats unknown keys as MergeReplace.

type MergeMode added in v0.7.0

type MergeMode int

MergeMode describes how a list-typed rule setting combines across config layers (defaults, kinds, overrides).

const (
	// MergeReplace is the default: a later layer's list replaces the
	// earlier layer's list wholesale.
	MergeReplace MergeMode = iota
	// MergeAppend concatenates a later layer's list onto the earlier
	// layer's list, preserving layer-chain order.
	MergeAppend
)

type NodeChecker added in v0.23.0

type NodeChecker interface {
	Rule
	// CheckNode is invoked for every node, once entering and (for
	// container nodes) once leaving, in the exact pre-order
	// goldmark ast.Walk uses. It must return precisely the
	// diagnostics the rule's own ast.Walk Check would, and must not
	// rely on ast.WalkSkipChildren or ast.WalkStop.
	CheckNode(n ast.Node, entering bool, f *lint.File) []lint.Diagnostic
}

NodeChecker is an optional capability for a rule whose Check is a pure per-node pass: it inspects each AST node independently, keeps no state across nodes, and does not depend on skipping a subtree or stopping the walk for correctness. The engine drives ONE shared ast.Walk for every enabled NodeChecker instead of each rule re-walking the whole tree (goldmark walkHelper was ~44% cumulative with N per-rule walks). The engine still appends each rule's diagnostics as one contiguous group in rule order, so the result is byte-identical to running each rule's Check sequentially.

type RepoScoped added in v0.20.0

type RepoScoped interface {
	RepoScopedDiagnostics() bool
}

RepoScoped is implemented by rules whose diagnostics are anchored to a repository artifact rather than the linted host file. A rule is repo-scoped when its (File, Line, Column, RuleID, Message) diagnostic tuple is independent of the host file path — so two host files can emit the same tuple and DedupeDiagnostics collapses it.

ConfigTarget rules are never repo-scoped: they run once via runConfigTargetRules rather than once per markdown file, so per-file duplicate tuples cannot occur.

The engine uses this marker to skip the DedupeDiagnostics map+slice allocation when no enabled markdown rule is repo-scoped. Without the marker a blunt skip would silently drop diagnostics when repo-scoped rules are enabled.

type Rule

type Rule interface {
	ID() string
	Name() string
	Category() string
	Check(f *lint.File) []lint.Diagnostic
}

Rule is a single lint rule that checks a Markdown file.

func All

func All() []Rule

All returns a copy of all registered rules.

func ByID

func ByID(id string) Rule

ByID returns the registered rule with the given ID, or nil.

func ByName added in v0.7.0

func ByName(name string) Rule

ByName returns the registered rule with the given Name, or nil.

func CloneInstance added in v0.20.0

func CloneInstance(r Rule) Rule

CloneInstance returns an independent copy of r that preserves its identity and current state. Unlike CloneRule — which, for a Configurable rule, builds a zero value and applies DefaultSettings — CloneInstance is a faithful shallow copy of the same rule: every field, including a rule's struct-stored name/ID and any already-applied config, carries over, and the result is a distinct pointer. It exists so each Run worker can hold its own rule set: the per-file effective-config lookup is keyed by Name(), so a clone that zeroed Name() would silently skip the rule.

An embedded sync.Mutex (or similar) is copied while unlocked — clones are taken from pristine, idle rule instances before any Check runs — so the copy is a valid, independent lock. The shallow copy shares slice/map backing with the source; that is safe because the engine clones again per file via ConfigureRule before applying per-file settings, and rules do not mutate their own config during Check.

func CloneRule

func CloneRule(r Rule) Rule

CloneRule creates a deep copy of a rule. If the rule implements Configurable, the clone is produced by creating a new zero-value instance and applying the original's DefaultSettings. Otherwise it falls back to a reflect-based shallow copy of the struct.

type SettingsTranslator added in v0.17.1

type SettingsTranslator interface {
	// TranslateLayerSettings returns the settings the merge layer
	// should use for one layer. Implementations must treat the
	// input as read-only and return a new map when they change
	// anything; returning the input unchanged signals "no
	// translation applies".
	TranslateLayerSettings(settings map[string]any) map[string]any
}

SettingsTranslator is implemented by Configurable rules that rewrite one config layer's settings map before the deep-merge runs. The config merge layer calls TranslateLayerSettings on every layer that configures the rule, so merge logic stays free of rule-name special cases.

required-structure implements this to collapse the user-facing `schema:` / `inline-schema:` keys into an append-mode `schema-sources` list, letting multiple kinds compose their schemas instead of overwriting (plan 156).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL