config

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: 15 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultFiles = []string{"**/*.md", "**/*.markdown"}

DefaultFiles is the built-in list of glob patterns used for file discovery when no file arguments are given on the command line.

View Source
var ValidCategories = []string{
	"accessibility",
	"code",
	"directive",
	"heading",
	"line",
	"link",
	"list",
	"prose",
	"structural",
	"table",
	"whitespace",
}

ValidCategories lists the recognized rule category names.

Functions

func ApplyCategories

func ApplyCategories(
	rules map[string]RuleCfg,
	categories map[string]bool,
	ruleCategory func(ruleName string) string,
	explicit map[string]bool,
) map[string]RuleCfg

ApplyCategories disables rules whose category is disabled, unless the rule has been explicitly configured (present in the explicit rules map). ruleCategory maps a rule name to its category string. The explicit map contains rule names that were explicitly set in config (not just inherited from defaults).

func Discover

func Discover(startDir string) (string, error)

Discover walks up the directory tree from startDir looking for a .mdsmith.yml config file. It stops searching when it encounters a .git directory (the repository root) or reaches the filesystem root. Returns the path to the config file, or "" if none was found.

func Effective

func Effective(cfg *Config, filePath string, fmKinds []string, fmFields map[string]any) map[string]RuleCfg

Effective returns the effective rule configuration for a given file path. It starts with the top-level rules, applies kinds in effective-list order (fmKinds from front matter first, then kind-assignment matches), and finally applies glob overrides. Later entries take precedence.

func EffectiveAll added in v0.7.0

func EffectiveAll(
	cfg *Config, filePath string, fmKinds []string, fmFields map[string]any,
) (map[string]RuleCfg, map[string]bool, map[string]bool)

EffectiveAll returns the effective rule config, category settings, and explicit rule set for a file path while resolving effective kinds once and reusing that result across all three computations.

func EffectiveCategories

func EffectiveCategories(cfg *Config, filePath string, fmKinds []string, fmFields map[string]any) map[string]bool

EffectiveCategories returns the effective category settings for a given file path. It starts with the top-level categories, applies kinds in effective-list order, and then applies matching overrides. Categories not explicitly set default to true (enabled).

func EffectiveExplicitRules

func EffectiveExplicitRules(cfg *Config, filePath string, fmKinds []string, fmFields map[string]any) map[string]bool

EffectiveExplicitRules returns the set of rule names that were explicitly configured for a given file path. It includes rules from the top-level ExplicitRules, any rules set by matching kinds, and any rules set by matching overrides.

func EffectiveKinds added in v0.13.2

func EffectiveKinds(cfg *Config, filePath string, fmKinds []string, fmFields map[string]any) []string

EffectiveKinds returns the same list resolveEffectiveKinds computes internally — the front-matter kinds plus every config-driven kind-assignment match in order, deduplicated. Exposed for callers outside the config package (e.g. the LSP symbol index) that need effective-kind resolution without re-implementing the merge rules.

When cfg is nil there are no kind-assignment entries to apply, so the result is just fmKinds with duplicates dropped — preserving the dedup contract callers rely on.

fmFields, when non-nil, is the file's parsed front matter; it is consumed by entries that set `fields-present:`. Pass nil when the caller has no FM info — such entries simply won't match.

func InjectBuildConfig added in v0.10.0

func InjectBuildConfig(cfg *Config, cfgPath string)

InjectBuildConfig copies cfg.Build.Recipes into the recipe-safety and build rule settings. It is called after config loading in main so rules receive their inputs through the normal ApplySettings path. cfgPath is the path to the loaded .mdsmith.yml; it is set in the config-path setting so MDS040 can report diagnostics against the right file.

func IsIgnored

func IsIgnored(patterns []string, path string) bool

IsIgnored returns true if the file path matches any of the given ignore patterns. It checks the raw path, the cleaned path, and the base name. A pattern prefixed with "!" excludes a path even if another ignore pattern also matches, regardless of list order.

func NeedsFieldsForFile added in v0.14.0

func NeedsFieldsForFile(cfg *Config, filePath string) bool

NeedsFieldsForFile returns true when at least one kind-assignment entry could match the given file path under its `fields-present:` selector — either because the entry has no `glob:` (it considers every file) or because its glob matches this path. Callers use this to skip the full FM-mapping YAML decode for files no fields-present entry could ever assign a kind to.

func ParseSize added in v0.6.0

func ParseSize(s string) (int64, error)

ParseSize parses a human-readable size string into bytes. Accepted formats: "2MB", "500KB", "1GB", bare integer (bytes), "0" (unlimited). Case-insensitive. Uses binary units (1 KB = 1024, 1 MB = 1048576, 1 GB = 1073741824).

func ValidateBuildConfig added in v0.10.0

func ValidateBuildConfig(cfg *Config) error

ValidateBuildConfig returns an error if any recipe declares a reserved param name or if its command references an unknown or reserved placeholder. Recipe names are validated in sorted order for deterministic errors.

func ValidateFrontMatterKinds added in v0.7.0

func ValidateFrontMatterKinds(cfg *Config, filePath string, kinds []string) error

ValidateFrontMatterKinds returns an error if any of the supplied front-matter kind names is not declared in cfg.Kinds. filePath is used in the message.

func ValidateKinds added in v0.7.0

func ValidateKinds(cfg *Config) error

ValidateKinds returns an error if any kind named in a kind-assignment entry is not declared in cfg.Kinds, or if any declared kind sets a schema both inline (KindBody.Schema) and via the legacy rules.required-structure.schema: path. Front-matter kinds are validated at lint time via ValidateFrontMatterKinds (see engine).

Types

type BuildConfig added in v0.10.0

type BuildConfig struct {
	BaseURL string               `yaml:"base-url,omitempty"`
	Recipes map[string]RecipeCfg `yaml:"recipes,omitempty"`
}

BuildConfig is the top-level build: section.

type Config

type Config struct {
	Rules          map[string]RuleCfg    `yaml:"rules"`
	Ignore         []string              `yaml:"ignore"`
	Overrides      []Override            `yaml:"overrides"`
	FrontMatter    *bool                 `yaml:"front-matter"`
	Categories     map[string]bool       `yaml:"categories"`
	Files          []string              `yaml:"files"`
	FollowSymlinks bool                  `yaml:"follow-symlinks"`
	MaxInputSize   string                `yaml:"max-input-size"`
	Kinds          map[string]KindBody   `yaml:"kinds,omitempty"`
	KindAssignment []KindAssignmentEntry `yaml:"kind-assignment,omitempty"`
	Build          BuildConfig           `yaml:"build,omitempty"`

	// Convention names a Markdown convention bundle. Built-in
	// values: "portable", "github", "plain". User-defined
	// conventions may also be referenced here after being declared
	// under the top-level `conventions:` key. Empty means no
	// convention. See internal/convention/convention.go and
	// docs/reference/conventions.md.
	Convention string `yaml:"convention,omitempty"`

	// Conventions holds user-defined convention bundles declared
	// under the top-level `conventions:` key. Each entry is a
	// { flavor, rules } pair. Names must not collide with the
	// built-in conventions ("portable", "github", "plain").
	Conventions map[string]UserConvention `yaml:"conventions,omitempty"`

	// LegacyNoFollowSymlinks captures the removed `no-follow-symlinks`
	// key. Its presence surfaces a deprecation warning via
	// Deprecations; its contents are otherwise ignored now that
	// symlinks are skipped by default. The `omitempty` tag keeps
	// round-tripped configs from re-emitting the deprecated key
	// unless a user explicitly supplied it.
	LegacyNoFollowSymlinks []string `yaml:"no-follow-symlinks,omitempty"`

	// ExplicitRules tracks rule names that were explicitly set in
	// the user config (not just inherited from defaults). This is
	// used for category override resolution: an explicitly enabled
	// rule takes precedence over a disabled category.
	// Not serialized to YAML.
	ExplicitRules map[string]bool `yaml:"-"`

	// FilesExplicit tracks whether the files key was explicitly set
	// in the user config. This distinguishes between an omitted key
	// (use defaults) and an explicitly empty list (no files).
	// Not serialized to YAML.
	FilesExplicit bool `yaml:"-"`

	// Deprecations lists human-readable warnings about deprecated
	// keys found in the loaded config. Callers (cmd/mdsmith) print
	// them to stderr.
	// Not serialized to YAML.
	Deprecations []string `yaml:"-"`

	// ConventionPreset is the convention's rule preset table,
	// captured at config load time. It is applied as a base layer
	// beneath the user's top-level rules: in effective-rule
	// resolution, the preset is merged first, the user's cfg.Rules
	// wins via deep-merge, then kinds and overrides apply on top.
	// Empty when no convention is selected.
	// Not serialized to YAML.
	ConventionPreset map[string]RuleCfg `yaml:"-"`
}

Config is the top-level configuration.

func Defaults

func Defaults() *Config

Defaults returns a Config with all registered rules using each rule's default enabled state and no custom settings.

func DumpDefaults

func DumpDefaults() *Config

DumpDefaults returns a Config with all registered rules using each rule's default enabled state. Enabled rules that implement Configurable have their DefaultSettings() included in RuleCfg.Settings. Categories are included with all set to true (enabled). This is consumed by `mdsmith init` to generate a default config file.

func Load

func Load(path string) (*Config, error)

Load reads and parses a config file at the given path.

func Merge

func Merge(defaults, loaded *Config) *Config

Merge merges a loaded config on top of defaults. The loaded config's rules override the defaults; any rule not mentioned in loaded keeps its default value. Ignore and Overrides come from the loaded config only. Categories from the loaded config are merged on top of defaults; any category not mentioned in loaded keeps its default value (true).

type FileResolution added in v0.7.1

type FileResolution struct {
	File       string
	Kinds      []ResolvedKind
	Rules      map[string]RuleResolution
	Categories map[string]bool
}

FileResolution is the per-file resolution: kind list (with assignment sources) and per-rule resolution. Rules is keyed by rule name.

func ResolveFile added in v0.7.1

func ResolveFile(cfg *Config, filePath string, fmKinds []string, fmFields map[string]any) *FileResolution

ResolveFile builds the full provenance picture for a single file. fmKinds is the kinds: list parsed from the file's front matter; fmFields, when non-nil, is the parsed front matter and feeds the kind-assignment `fields-present:` selector.

type KindAssignmentEntry added in v0.7.0

type KindAssignmentEntry struct {
	// Glob is the canonical field for file patterns (doublestar syntax,
	// supports **, brace expansion, and !-prefix exclusion).
	Glob []string `yaml:"glob,omitempty"`
	// Files is a deprecated alias for Glob. Use Glob in new configs.
	Files []string `yaml:"files,omitempty"`
	// FieldsPresent lists front-matter keys that must all be present
	// with a non-null value for this entry to match. An empty list
	// disables the selector — only glob is considered.
	FieldsPresent []string `yaml:"fields-present,omitempty"`
	Kinds         []string `yaml:"kinds"`
}

KindAssignmentEntry assigns one or more kinds to files matching the configured selectors. Two selectors are available: a glob set (`glob:`) and a front-matter field-presence set (`fields-present:`). Within a single entry the selectors combine with AND — every set selector must match. Across entries the matches union (OR semantics).

func (KindAssignmentEntry) Patterns added in v0.12.0

func (e KindAssignmentEntry) Patterns() []string

Patterns returns the effective set of glob patterns for the entry. When Glob is set it takes precedence; Files is used only when Glob is absent (backward compatibility with the deprecated files: key).

type KindAssignmentSource added in v0.7.1

type KindAssignmentSource string

KindAssignmentSource describes how a kind ended up in the effective list. Either "front-matter" or "kind-assignment[<i>]".

type KindBody added in v0.7.0

type KindBody struct {
	Rules       map[string]RuleCfg `yaml:"rules"`
	Categories  map[string]bool    `yaml:"categories"`
	Schema      map[string]any     `yaml:"schema,omitempty"`
	PathPattern string             `yaml:"path-pattern,omitempty"`
}

KindBody is a named bundle of rule settings. It has the same shape as Override minus the Files field; files are bound to kinds separately via front-matter kinds: or kind-assignment:.

Schema, when set, declares the document-structure schema for files of this kind inline (rather than referencing a proto.md file via rules.required-structure.schema:). A kind that sets both Schema and rules.required-structure.schema: is a config error; see ValidateKinds.

PathPattern, when set, is a glob the workspace-relative path of every file assigned to this kind must match. The pattern uses the doublestar syntax shared by overrides:, ignore:, and kind-assignment:, anchored at the workspace root. A path mismatch surfaces as an MDS020 diagnostic. PathPattern is the kind-config counterpart to the per-schema `<?require filename:?>` directive and the two may coexist on the same kind — each runs through its own matcher (`<?require filename:?>` uses filepath.Match against the basename, PathPattern uses doublestar against the workspace- relative path) and emits a separate diagnostic when violated.

type LayerEntry added in v0.7.1

type LayerEntry struct {
	Source string
	Set    bool
	Value  RuleCfg
}

LayerEntry is one applicable merge layer for a single rule. Source identifies the layer; Set indicates whether this layer touched the rule; Value, when Set is true, is the rule's RuleCfg supplied by this layer.

type Leaf added in v0.7.1

type Leaf struct {
	Path  string
	Value any
	Chain []LeafChainEntry
}

Leaf bundles a leaf path (e.g., "enabled" or "settings.max"), its winning value, and the chain of layers that set it (oldest → newest).

func (Leaf) Source added in v0.7.1

func (l Leaf) Source() string

Source returns the winning layer source for this leaf — the source of the last entry in the chain. An empty string indicates the leaf has no source (which should not happen for leaves emitted by Resolve).

type LeafChainEntry added in v0.7.1

type LeafChainEntry struct {
	Source string
	Value  any
}

LeafChainEntry records a layer that set a single leaf, with the value the leaf had at that layer.

type Override

type Override struct {
	// Glob is the canonical field for file patterns (doublestar syntax,
	// supports **, brace expansion, and !-prefix exclusion).
	Glob []string `yaml:"glob,omitempty"`
	// Files is a deprecated alias for Glob. Use Glob in new configs.
	Files      []string           `yaml:"files,omitempty"`
	Rules      map[string]RuleCfg `yaml:"rules"`
	Categories map[string]bool    `yaml:"categories"`
}

Override applies rule settings to files matching glob patterns.

func (Override) Patterns added in v0.12.0

func (o Override) Patterns() []string

Patterns returns the effective set of glob patterns for the override. When Glob is set it takes precedence; Files is used only when Glob is absent (backward compatibility with the deprecated files: key).

type ParamCfg added in v0.10.0

type ParamCfg struct {
	Required []string `yaml:"required,omitempty"`
	Optional []string `yaml:"optional,omitempty"`
}

ParamCfg names the params a recipe accepts.

type RecipeCfg added in v0.10.0

type RecipeCfg struct {
	Command      string   `yaml:"command"`
	BodyTemplate string   `yaml:"body-template,omitempty"`
	Params       ParamCfg `yaml:"params,omitempty"`
}

RecipeCfg is a single user-defined recipe declaration.

type ResolvedKind added in v0.7.1

type ResolvedKind struct {
	Name     string
	Source   KindAssignmentSource
	Selector string
}

ResolvedKind names a kind in the effective list and how it was assigned. Selector, when non-empty, describes the selectors that fired for a kind-assignment match ("glob a,b AND fields-present x"). It is empty for kinds declared via front matter.

type RuleCfg

type RuleCfg struct {
	Enabled  bool
	Settings map[string]any
}

RuleCfg is a YAML union: can be bool (enable/disable) or map[string]any (settings).

func (RuleCfg) MarshalYAML

func (r RuleCfg) MarshalYAML() (any, error)

MarshalYAML implements custom YAML marshalling for RuleCfg. A disabled rule (Enabled=false, no Settings) serializes as `false`. An enabled rule with settings serializes as the settings mapping. An enabled rule with no settings serializes as `true`.

func (*RuleCfg) UnmarshalYAML

func (r *RuleCfg) UnmarshalYAML(value *yaml.Node) error

UnmarshalYAML implements custom YAML unmarshalling for RuleCfg. It handles three forms:

  • false -> Enabled=false, Settings=nil
  • true -> Enabled=true, Settings=nil
  • {key: val, ...} -> Enabled=true, Settings={key: val, ...}

type RuleResolution added in v0.7.1

type RuleResolution struct {
	Rule   string
	Final  RuleCfg
	Layers []LayerEntry
	Leaves []Leaf
}

RuleResolution describes the merge of one rule for one file.

func (*RuleResolution) LeafByPath added in v0.7.1

func (rr *RuleResolution) LeafByPath(path string) *Leaf

LeafByPath returns the Leaf with the given path, or nil if absent.

type UserConvention added in v0.14.0

type UserConvention struct {
	// Flavor is the Markdown flavor MDS034 should validate against
	// (e.g. "commonmark", "gfm", "goldmark").
	Flavor string `yaml:"flavor"`
	// Rules maps rule names to their presets, using the same schema
	// as the top-level `rules:` block.
	Rules map[string]RuleCfg `yaml:"rules,omitempty"`
}

UserConvention is a user-defined convention bundle declared in the top-level `conventions:` block in .mdsmith.yml. It has the same { flavor, rules } shape as the built-in convention table.

Jump to

Keyboard shortcuts

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