stickler

package module
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Jun 29, 2026 License: MIT Imports: 13 Imported by: 0

README

stickler

The gomatic lint runner — a stickler for the rules. It executes a set of analyzer tools (the yze suite, golangci-lint, and others) to completion, normalizes their findings into one diagnostic schema, writes the report to stdout in the chosen format, prints a pass/fail status to stderr, and reports pass/fail via the process exit code. Any finding or any tool error is a stickler failure; every tool still runs to completion first.

stickler [--format human|json|github] [root]
  • Runner model — each tool is an executable plus an output adapter (Runner). yze is read via its native stickler-json (no adapter); golangci-lint's JSON is adapted. New tools are added as more Runners.
  • --formathuman (default, one line per finding), json (the normalized result), github (Actions annotations). SARIF output is planned.
  • Exit code0 only when every tool ran cleanly with zero findings; non-zero on any finding or tool error.

Configuration (layered merge)

stickler is a runner, so its configuration is about configuring the tools it runs. Two layers merge, global first then repo:

  • Global: $XDG_CONFIG_HOME/stickler/config.yaml (or ~/.config/stickler/config.yaml).
  • Repo: .stickler.yaml at the target (or --root).
runners: [yze, golangci-lint]   # which tools to run
format: human                   # default output (overridable by --format)
analyzers:                      # per-analyzer settings (forwarded to yze)
  ptrrecv:
    allow: [mypkg.MyMutexType]

A repo layer can replace, add, or remove relative to the global layer. A list written as a sequence replaces; a list written as a mapping adds/removes:

runners:
  add: [revive]
  remove: [golangci-lint]

Maps (the analyzers tree) deep-merge; each setting's list follows the same replace/add/remove rules. Precedence for output format is --format flag > config > human.

Built on the go-yze diagnostic schema. Forwarding the merged analyzers settings to yze --config, and --fix (delegating to each tool's fixer), are the next steps; today stickler selects runners and output format from the merged config.

Documentation

Overview

Package stickler is the gomatic lint runner: it executes a set of analyzer tools (the yze suite, golangci-lint, and others) to completion, normalizes their findings into one diagnostic schema, and reports pass/fail via the process exit code. Any finding or any tool error is a stickler failure.

Index

Constants

View Source
const (
	// ErrConfig reports a stickler config file that cannot be parsed.
	ErrConfig errs.Const = "cannot load stickler config"
	// ErrBadListSetting reports a list setting that is neither a sequence nor an
	// add/remove/replace mapping.
	ErrBadListSetting errs.Const = "list setting must be a sequence or an add/remove/replace mapping"
)

Configuration errors.

View Source
const (
	// ErrYzeFailed reports that the yze aggregator could not be run or parsed.
	ErrYzeFailed errs.Const = "yze runner failed"
	// ErrGolangciFailed reports that golangci-lint could not be run or parsed.
	ErrGolangciFailed errs.Const = "golangci-lint runner failed"
	// ErrExec reports that a subprocess could not be started or exited non-zero;
	// it carries the captured stderr so the failure's real reason is reported.
	ErrExec errs.Const = "command execution failed"
)

Runner failures.

View Source
const ErrRunner errs.Const = "lint runner failed"

ErrRunner wraps a failure from one tool runner, tagged with the runner name.

View Source
const ErrUnknownOutput errs.Const = "unknown output format"

ErrUnknownOutput reports an output format stickler does not support.

Variables

This section is empty.

Functions

func ConfigPaths added in v0.2.0

func ConfigPaths(getenv func(string) string, home HomeDir, repoRoot RepoRoot) []string

ConfigPaths returns the ordered config layer paths: the global config, then the repository's .stickler.yaml.

func ExecCommand

func ExecCommand(ctx context.Context, name RunnerName, args ...Arg) ([]byte, error)

ExecCommand is the default Command, executing a real subprocess. On failure the returned error wraps ErrExec with the captured stderr so the underlying reason (config error, panic, load failure) reaches the caller's message.

func Format

func Format(w io.Writer, format OutputFormat, result Result) error

Format writes the result to w in the named format.

Types

type Arg added in v0.2.1

type Arg string

Arg is one command-line argument passed to a runner's binary.

type Command

type Command func(ctx context.Context, name RunnerName, args ...Arg) ([]byte, error)

Command runs an external tool and returns its stdout. A non-nil error includes a non-zero exit; callers that can still parse the stdout (linters exit non-zero when they report findings) treat the output as authoritative.

type Config added in v0.2.0

type Config struct {
	Analyzers map[string]map[string]StringList `yaml:"analyzers"`
	Format    string                           `yaml:"format"`
	Runners   StringList                       `yaml:"runners"`
}

Config is one configuration layer (global or repo).

func LoadLayers added in v0.2.0

func LoadLayers(read func(path string) ([]byte, error), paths ...string) ([]Config, error)

LoadLayers reads and parses each existing config path into a layer. A path the reader cannot open is treated as an absent layer and skipped; a path that parses badly is an error.

type HomeDir added in v0.2.1

type HomeDir string

HomeDir is the current user's home directory, the base for the default global config location.

type OutputFormat

type OutputFormat string

OutputFormat names how a Result is rendered.

const (
	OutputHuman  OutputFormat = "human"
	OutputJSON   OutputFormat = "json"
	OutputGitHub OutputFormat = "github"
)

The output formats stickler supports.

type RepoRoot added in v0.2.1

type RepoRoot string

RepoRoot is the directory whose .stickler.yaml supplies the repository configuration layer.

type Resolved added in v0.2.0

type Resolved struct {
	Analyzers map[string]map[string][]string
	Format    string
	Runners   []string
}

Resolved is the concrete configuration after all layers are folded.

func Resolve added in v0.2.0

func Resolve(layers ...Config) Resolved

Resolve folds the layers in order (global first, repo last), applying each layer's add/remove/replace directives onto the accumulated result.

type Result

type Result struct {
	Diagnostics []goyze.Diagnostic
	Errors      []error
}

Result aggregates every runner's findings and failures from one stickler pass.

func Orchestrate

func Orchestrate(ctx context.Context, root Root, runners []Runner) Result

Orchestrate runs every runner to completion over root, collecting all diagnostics and wrapping any runner error with its name. One runner's failure never prevents the others from running.

func (Result) Failed

func (r Result) Failed() bool

Failed reports whether the pass should fail the build: any diagnostic or any runner error.

type Root added in v0.2.1

type Root string

Root is the directory or package pattern a runner analyzes (e.g. "./..." or a path); it is the target every Runner operates over.

type Runner

type Runner interface {
	Name() string
	Run(ctx context.Context, root Root) ([]goyze.Diagnostic, error)
}

Runner executes one analyzer tool over a root directory and returns its findings as normalized diagnostics.

func BuildRunners added in v0.2.0

func BuildRunners(command Command, names []string) []Runner

BuildRunners constructs the runners named in the resolved configuration, defaulting to the full set when none are configured. Unknown runner names are ignored.

func NewGolangciRunner

func NewGolangciRunner(command Command) Runner

NewGolangciRunner builds a Runner that invokes golangci-lint.

func NewYzeRunner

func NewYzeRunner(command Command) Runner

NewYzeRunner builds a Runner that invokes the yze aggregator.

type RunnerName added in v0.2.1

type RunnerName string

RunnerName identifies a runner in configuration, selection, and as the binary name stickler executes.

const (
	RunnerYze      RunnerName = "yze"
	RunnerGolangci RunnerName = "golangci-lint"
)

Runner names, used in configuration and selection.

type StringList added in v0.2.0

type StringList struct {
	// contains filtered or unexported fields
}

StringList is a list-valued setting in one configuration layer. It merges onto the value accumulated from lower layers either by replacing it (when written as a YAML sequence) or by adding and removing entries (when written as a mapping with add/remove/replace keys). An absent setting leaves the lower value intact.

func (*StringList) UnmarshalYAML added in v0.2.0

func (l *StringList) UnmarshalYAML(node *yaml.Node) error

UnmarshalYAML accepts a sequence (replace) or an add/remove/replace mapping, rejecting any unknown mapping key (a config typo such as `addd`). The pointer receiver and *yaml.Node parameter are dictated by the yaml.Unmarshaler interface, which a polymorphic (sequence-or-mapping) setting must implement.

Directories

Path Synopsis
cmd
stickler command
Command stickler is the gomatic lint runner: it executes the yze suite and golangci-lint to completion, normalizes their findings, writes them to stderr in the chosen format, and exits non-zero if any finding or tool error occurred.
Command stickler is the gomatic lint runner: it executes the yze suite and golangci-lint to completion, normalizes their findings, writes them to stderr in the chosen format, and exits non-zero if any finding or tool error occurred.

Jump to

Keyboard shortcuts

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