validate

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: May 4, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package validate runs a fixed set of static checks against a monorel.toml + the surrounding repo state and reports findings.

Unlike the other commands' single-error fail-fast loaders (config.Load returns the first violation; changeset.LoadAll bails on the first malformed file), validate is fault-tolerant by design: it surfaces every issue in one pass so authors fix them in one round-trip.

Checks fall into four buckets:

  • Schema: provider fields, package fields, no duplicate tag prefixes. Delegated to config.Config.Validate().
  • Filesystem: every package's Path exists, no two packages share a Path, every Changelog's parent directory exists.
  • Changesets: every .changeset/*.md parses cleanly and only names packages that exist in monorel.toml.
  • Tags (opt-in): the latest tag matching each package's prefix parses as valid semver. Non-semver tags surface as warnings.

validate intentionally does no network I/O and no mutation; it does not compute the release plan (that's monorel plan).

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func HasErrors

func HasErrors(findings []Finding) bool

HasErrors reports whether any finding has SeverityError. Useful for callers picking an exit code.

func HasWarnings

func HasWarnings(findings []Finding) bool

HasWarnings reports whether any finding has SeverityWarning.

Types

type Finding

type Finding struct {
	Severity Severity `json:"severity"`
	Code     string   `json:"code"`
	Message  string   `json:"message"`
	// Path is the file path the finding refers to, when applicable
	// (e.g. the changeset that failed to parse). Relative to the
	// repository root for changeset findings; absolute for config
	// findings.
	Path string `json:"path,omitempty"`
	// Package is the monorel.toml package key the finding refers to,
	// when applicable.
	Package string `json:"package,omitempty"`
}

Finding is a single validation issue. The Code is a stable identifier (used by tests, CI integrations, and the JSON output); the Message is the human-readable rendering.

func Run

func Run(in Inputs) []Finding

Run executes every applicable check in order and returns the aggregated findings. Findings are returned in a stable order: schema first, then filesystem (per package, lex order), then changesets (per file, lex order), then tags (per package, lex order).

Run never panics on bad inputs; every error path produces a Finding instead. An empty return slice means the run is clean.

Example

ExampleRun walks a monorel.toml + the changeset directory and reports every issue in one pass. Unlike the rest of monorel's loaders (which fail-fast on the first error), Run is fault-tolerant by design: it keeps going so authors fix every issue in one round-trip.

The example sets up a deliberately-broken layout (a typo in a changeset's package key) so the output has a finding to show.

package main

import (
	"fmt"
	"os"
	"path/filepath"

	"monorel.disaresta.com/validate"
)

func main() {
	dir, _ := os.MkdirTemp("", "monorel-validate")
	defer os.RemoveAll(dir)

	_ = os.WriteFile(filepath.Join(dir, "monorel.toml"), []byte(`
[provider]
owner = "acme"
repo = "widget"

[packages."widget"]
tag_prefix = ""
path = "."
changelog = "CHANGELOG.md"
`), 0o644)

	csDir := filepath.Join(dir, ".changeset")
	_ = os.MkdirAll(csDir, 0o755)
	_ = os.WriteFile(filepath.Join(csDir, "typo.md"), []byte(`---
"widgett": patch
---

Typo: widget vs widgett.
`), 0o644)

	findings := validate.Run(validate.Inputs{
		ConfigPath: filepath.Join(dir, "monorel.toml"),
	})
	for _, f := range findings {
		fmt.Printf("%s [%s] %s\n", f.Severity, f.Code, f.Package)
	}
	fmt.Println("has errors:", validate.HasErrors(findings))
}
Output:
error [changeset_unknown_package] widgett
has errors: true
Example (Clean)

ExampleRun_clean shows the success case: a well-formed monorel.toml with no pending changesets returns no findings.

package main

import (
	"fmt"
	"os"
	"path/filepath"

	"monorel.disaresta.com/validate"
)

func main() {
	dir, _ := os.MkdirTemp("", "monorel-validate-clean")
	defer os.RemoveAll(dir)

	_ = os.WriteFile(filepath.Join(dir, "monorel.toml"), []byte(`
[provider]
owner = "acme"
repo = "widget"

[packages."widget"]
tag_prefix = ""
path = "."
changelog = "CHANGELOG.md"
`), 0o644)

	findings := validate.Run(validate.Inputs{
		ConfigPath: filepath.Join(dir, "monorel.toml"),
	})
	fmt.Println("findings:", len(findings))
	fmt.Println("has errors:", validate.HasErrors(findings))
}
Output:
findings: 0
has errors: false

type Inputs

type Inputs struct {
	// ConfigPath is the path to monorel.toml. Need not be absolute;
	// validate resolves it.
	ConfigPath string

	// ChangesetDir is the directory containing .changeset/*.md files.
	// Empty defaults to <ConfigPath dir>/.changeset.
	ChangesetDir string

	// CheckTags enables the opt-in semver-validation pass over each
	// package's tag namespace.
	CheckTags bool

	// ListTags supplies the tag list for a given prefix when
	// CheckTags is true. The prefix is the value returned by
	// PackageConfig.FullTagPrefix() (e.g. "transports/zerolog/" or
	// "" for bare-tag root). A well-behaved implementation should
	// return only tags whose names begin with the prefix; validate
	// re-filters defensively so a misbehaving callback that returns
	// extra tags will not cross-pollinate findings.
	//
	// Stays a callback so the validate package doesn't pull in
	// internal/git. When CheckTags is true and ListTags is nil,
	// validate emits a single error finding and skips the tag pass.
	ListTags func(prefix string) ([]string, error)
}

Inputs bundle the validate run's parameters. ConfigPath is required; everything else is optional with sensible defaults.

type Severity

type Severity string

Severity classifies a finding. Errors fail the run; warnings only fail when the caller passes Strict=true.

const (
	SeverityError   Severity = "error"
	SeverityWarning Severity = "warning"
)

Jump to

Keyboard shortcuts

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