archcheck

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Aug 28, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package archcheck enforces Kram's architectural layer boundaries — the project's single most valuable and hardest-to-retrofit property — so a stray import can't silently breach a layer in a future PR and still compile and pass every other test.

The boundaries it locks (all verified to hold when this was written):

  • internal/cli/** never imports internal/daemon/**, internal/gateway, or internal/router. The CLI talks to the daemon and gateway only over HTTP, via the client packages under internal/cli — never by reaching into server-side internals.
  • internal/daemon/** never imports internal/gateway. The daemon reaches the gateway only over HTTP, via internal/daemon/gatewayclient — the gateway's own server/router internals stay off-limits.

The rule-evaluation logic (Analyze) is a pure function, unit-tested with synthetic import graphs; Load feeds it the real graph via `go list`, swept across every platform Kram ships (so a breach hidden behind an OS build tag can't slip past a single-OS CI runner — see buildTargets), and the package's own integration test asserts the real module has zero violations. See DECISIONS.md.

Index

Constants

View Source
const Module = "github.com/codexmark/kram"

Module is Kram's module path — the prefix stripped to turn a full import path into the module-relative path the rules are written against.

Variables

This section is empty.

Functions

This section is empty.

Types

type PackageImports

type PackageImports struct {
	Path    string
	Imports []string
}

PackageImports is one package's full import path and the full import paths it directly depends on (production and test imports both — a test file breaching a layer is still a breach).

func Load

func Load(ctx context.Context, pattern string) ([]PackageImports, error)

Load builds the real import graph for pattern (e.g. Module+"/...") by shelling out to `go list` once per build target and unioning the results. It collects each package's production and test imports, since a boundary breach in a _test.go file is still a breach worth catching.

type Rule

type Rule struct {
	From   string
	To     string
	Except []string // module-relative prefixes under To that are allowed anyway
	Why    string   // printed when the rule is violated, so the failure explains itself
}

Rule forbids packages under From from importing packages under To. From, To, and each Except entry are module-relative package-path prefixes (e.g. "internal/cli"), matched on whole path segments: "internal/gateway" matches "internal/gateway" and "internal/gateway/x" but NOT "internal/gatewayclient" or "internal/gatewayconfig".

func DefaultRules

func DefaultRules() []Rule

DefaultRules is Kram's layer policy — the single source of truth shared by the integration test and any external runner.

type Violation

type Violation struct {
	Package string
	Import  string
	Rule    Rule
}

Violation is one forbidden edge: Package (full import path) imports Import (full import path) in breach of Rule.

func Analyze

func Analyze(pkgs []PackageImports, rules []Rule) []Violation

Analyze returns every rule violation in pkgs, deterministically ordered (by package, then import, then rule). It's pure: no I/O, no globals — the import graph is entirely supplied by the caller.

func (Violation) String

func (v Violation) String() string

Jump to

Keyboard shortcuts

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