lint

package
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Jul 30, 2026 License: MPL-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package lint evaluates a repository's dependency graph against the coupling policy declared in the repo's .uda.yaml lint block. The policy is a lockfile: every internal edge is enumerated, new edges fail until a human moves them from pending to allowed, and forbid rules can never be accepted at all.

Index

Constants

This section is empty.

Variables

View Source
var ErrNoLintConfig = errors.New("no lint configuration")

ErrNoLintConfig distinguishes "no policy declared" from a read failure — the lint command turns it into a pointer at `uda lint init`.

Functions

func Accept

func Accept(rules Rules, violations []Violation, added, addedBy string) (Rules, []Violation)

Accept stages every unlisted violation as pending, attributed with the added/by metadata. Forbidden and stable-origin edges are never staged — they come back as skipped so the caller can surface why. Lint stays red until approval.

func Approve

func Approve(rules Rules) (Rules, []Violation)

Approve moves every pending edge into allowed. A pending entry that matches a forbid rule is dropped and reported — forbid wins over every path into the lockfile, including a hand-edited pending block.

func MatchGlob

func MatchGlob(pattern, name string) bool

MatchGlob matches a package path against a pattern with path semantics: "*" matches within one segment, "**" matches any number of segments (including zero), and a pattern without wildcards must match exactly.

func WriteRules

func WriteRules(path, language string, rules Rules) error

WriteRules replaces the allowed and pending lists of one language block in the config file at path, creating the file, the lint section, or the block as needed. Everything else in the file — other sections, roles, forbid, comments — is preserved byte-for-byte by operating on the yaml node tree instead of re-marshalling a struct.

Types

type Config

type Config struct {
	Exclude   []string
	Languages map[string]Rules // keyed by lowercase language name
}

Config is the parsed lint section of a repo's .uda.yaml.

func LoadConfig

func LoadConfig(path string) (Config, error)

LoadConfig reads the lint section from the config file at path. A missing file or missing lint section returns ErrNoLintConfig.

type Edge

type Edge struct {
	From string
	To   string
}

Edge is a directed dependency between two internal packages, identified by their repo-relative names.

func ParseEdge

func ParseEdge(s string) (Edge, error)

ParseEdge parses the yaml lockfile form produced by Edge.String.

func (Edge) String

func (e Edge) String() string

String renders the yaml lockfile form: "from -> to".

type ForbidRule

type ForbidRule struct {
	From string `mapstructure:"from" yaml:"from"`
	To   string `mapstructure:"to"   yaml:"to"`
}

ForbidRule bans edges matching a pair of glob patterns (see MatchGlob).

func (ForbidRule) Matches

func (r ForbidRule) Matches(e Edge) bool

Matches reports whether the rule bans the given edge.

type PendingEdge

type PendingEdge struct {
	Edge  string `mapstructure:"edge"  yaml:"edge"`
	Added string `mapstructure:"added" yaml:"added,omitempty"`
	By    string `mapstructure:"by"    yaml:"by,omitempty"`
}

PendingEdge is an edge staged by accept but not yet human-approved. Lint stays red while any exist — pending is a visible-in-diff staging area, not a bypass.

type Roles

type Roles struct {
	Stable []string `mapstructure:"stable" yaml:"stable,omitempty"`
}

Roles declares package intent. Stable packages expect dependents: their new outbound edges are never auto-acceptable — accept skips them so only a deliberate yaml edit can allow the coupling.

type Rules

type Rules struct {
	// Boundary overrides the package-boundary granularity for this
	// language's analyzer (e.g. "module" for Python so intra-package
	// imports aren't collapsed into one node). Empty means the analyzer
	// default ("package"). Only honored for languages whose analyzer
	// supports it (python, rust, typescript).
	Boundary string        `mapstructure:"boundary" yaml:"boundary,omitempty"`
	Roles    Roles         `mapstructure:"roles"    yaml:"roles,omitempty"`
	Forbid   []ForbidRule  `mapstructure:"forbid"   yaml:"forbid,omitempty"`
	Allowed  []string      `mapstructure:"allowed"  yaml:"allowed"`
	Pending  []PendingEdge `mapstructure:"pending"  yaml:"pending"`
}

Rules is one language's policy block from the .uda.yaml lint section.

func Init

func Init(edges []Edge) Rules

Init snapshots the current graph into a fresh allowed list — adopting lint on an existing repo starts green. Forbid/roles are authored by humans afterwards; Init never invents policy.

type Violation

type Violation struct {
	Kind ViolationKind `json:"kind"`
	Edge Edge          `json:"-"`
	Rule string        `json:"rule,omitempty"` // forbid pattern or stable package that fired
}

Violation is one gate failure.

func Evaluate

func Evaluate(edges []Edge, rules Rules) []Violation

Evaluate compares the current graph against the rules. Precedence per edge: forbid beats allowed beats pending beats unlisted; a stable origin upgrades unlisted. The result is sorted severity-first, then by edge.

type ViolationKind

type ViolationKind string

ViolationKind classifies why an edge fails the gate. Stable strings — they appear in JSON output.

const (
	// KindForbidden: the edge matches a forbid rule. Never acceptable.
	KindForbidden ViolationKind = "forbidden"
	// KindStable: the edge originates from a declared-stable package and
	// is not allowed. Accept refuses to stage it; allowing it is a
	// deliberate yaml edit.
	KindStable ViolationKind = "stable"
	// KindUnlisted: the edge exists in the graph but not in the lockfile.
	KindUnlisted ViolationKind = "unlisted"
	// KindPending: the edge is staged but awaiting approval.
	KindPending ViolationKind = "pending"
)

Violation kinds, ordered by severity.

Jump to

Keyboard shortcuts

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