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 ¶
HasErrors reports whether any finding has SeverityError. Useful for callers picking an exit code.
func HasWarnings ¶
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 ¶
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.