Documentation
¶
Overview ¶
Package blueprint defines the blueprint.yaml schema and its parser.
Index ¶
Constants ¶
const Dir = ".rig"
Dir is where rig keeps its own machinery, in both a template repository and a generated project.
Everything rig needs lives under it — the blueprint, its partials, the lockfile — so a template repository reads as the skeleton it is rather than as a skeleton with a scaffolder's paperwork mixed in. It is dot-prefixed so that tooling which already ignores dot directories ignores this one too.
const Filename = "blueprint.yaml"
Filename is the conventional name of a blueprint file.
const SchemaVersion = "1"
SchemaVersion is the only schema version this build understands. The field is required in every blueprint so that a future incompatible schema can be rejected with a clear message rather than misparsed into zero values.
Variables ¶
This section is empty.
Functions ¶
func CheckRelative ¶
CheckRelative is the exported form used by the renderer, which has to make the same guarantee about paths that came out of a template rather than out of the blueprint file.
Types ¶
type Blueprint ¶
type Blueprint struct {
Version string `yaml:"version"`
Name string `yaml:"name"`
Description string `yaml:"description"`
// Source is optional. When omitted the directory containing the
// blueprint is itself the template, which is the common case: a template
// repository drops a blueprint.yaml at its root and becomes usable.
// Setting it lets a standalone blueprint wrap a template it does not own.
Source *Source `yaml:"source"`
Requirements Requirements `yaml:"requirements"`
Variables []Variable `yaml:"variables"`
Template Template `yaml:"template"`
Files []File `yaml:"files"`
Hooks Hooks `yaml:"hooks"`
// Dir is the directory holding blueprint.yaml, and the anchor for `from`
// partials. Not part of the file.
Dir string `yaml:"-"`
// Root is the project root: the parent of Dir when the blueprint lives in
// a .rig directory, and equal to Dir otherwise.
//
// The two differ for a reason worth stating. When a blueprint is its own
// template, the template is the whole repository — not the .rig directory
// the blueprint happens to sit in. Rendering from Dir would produce an
// empty project.
Root string `yaml:"-"`
}
Blueprint is a parsed blueprint.yaml.
type File ¶
type File struct {
// Path is where the file lands in the generated project.
Path string `yaml:"path"`
// Content is the file body, written inline. Fine for a few lines.
Content string `yaml:"content"`
// From is a path to a partial holding the body instead, resolved against
// the directory containing blueprint.yaml.
//
// Anything longer than a handful of lines wants this. An inline body gets
// no syntax highlighting, cannot be linted or formatted by the tools that
// understand it, and has to be indented to suit YAML rather than itself.
//
// A partial is never also copied into the generated project, even when the
// blueprint is its own template and the partial therefore sits inside the
// template tree.
From string `yaml:"from"`
// Render controls whether the body is treated as a template. Defaults to
// true; set it false to write the body byte for byte.
//
// This is the same opt-in principle the template tree already follows,
// applied to the one place it was missing. Without it a partial could
// never hold a file whose own language uses `{{ }}` — a Blade fragment, a
// Helm chart, a GitHub Actions workflow.
//
// A pointer so that an absent key is distinguishable from an explicit
// false, which a plain bool's zero value would swallow.
Render *bool `yaml:"render"`
Mode string `yaml:"mode"`
When string `yaml:"when"`
}
File is a stub the blueprint supplies itself, rather than one coming from the template repository. It is always rendered.
func (File) ShouldRender ¶
ShouldRender reports whether this file's body goes through the template engine. Its path and `when` always do, since those belong to the blueprint rather than to the file's contents.
type Hooks ¶
type Hooks struct {
PreInstall []string `yaml:"pre_install"`
PostInstall []string `yaml:"post_install"`
}
Hooks are shell commands run in the generated project. They are arbitrary code from whoever wrote the blueprint, so the runner shows them and asks before executing.
type Requirement ¶
type Requirement struct {
Name string `yaml:"name"`
Version string `yaml:"version"`
// Reason is shown when the check fails, so a blueprint can explain why
// it needs the thing rather than leaving the user to guess.
Reason string `yaml:"reason"`
}
Requirement is one binary that must be present, optionally at a minimum version. Tools carry no version because probing an arbitrary binary's version string is not something we can do reliably.
type Requirements ¶
type Requirements struct {
Runtimes []Requirement `yaml:"runtimes"`
Tools []Requirement `yaml:"tools"`
}
Requirements are checked before anything is downloaded or written.
type Source ¶
type Source struct {
Type SourceType `yaml:"type"`
// Repository is an "owner/name" pair, used by the github type.
Repository string `yaml:"repository"`
// URL is the clone URL for git, or the archive URL for zip.
URL string `yaml:"url"`
// Path is a filesystem path, used by the local type. Relative paths
// resolve against the blueprint's own directory.
Path string `yaml:"path"`
// Ref is a branch, tag or commit SHA. Defaults to the remote's default
// branch. Pinning to a SHA is the safe choice for a shared blueprint.
Ref string `yaml:"ref"`
// Subdir narrows the template to one directory inside the source, for
// monorepos that hold several templates.
Subdir string `yaml:"subdir"`
}
Source describes where the template skeleton comes from.
type SourceType ¶
type SourceType string
SourceType identifies how a template is fetched.
const ( SourceGitHub SourceType = "github" SourceGit SourceType = "git" SourceZip SourceType = "zip" SourceLocal SourceType = "local" )
type Template ¶
type Template struct {
// Include are globs, relative to the template root, that get rendered.
// Empty means nothing is rendered as a template.
Include []string `yaml:"include"`
// Exclude wins over Include.
Exclude []string `yaml:"exclude"`
// Copy are globs that are copied verbatim and never rendered, evaluated
// before Include. Use for binary assets or files with hostile syntax.
Copy []string `yaml:"copy"`
// StripSuffix is removed from a rendered file's name, so a template repo
// can hold `main.go.tmpl` and produce `main.go`.
StripSuffix string `yaml:"strip_suffix"`
// Delimiters overrides the default {{ }} pair, as a two-element list.
Delimiters []string `yaml:"delimiters"`
// RenderPaths also runs file and directory names through the template
// engine, so a repo can hold `{{ .module }}/main.go`.
RenderPaths bool `yaml:"render_paths"`
}
Template controls which of the fetched files are treated as templates. Rendering everything by default would corrupt any template repository that legitimately contains {{ }} — Blade views, Go templates, Helm charts and GitHub Actions expressions all collide with the default delimiters.
func (Template) DelimiterPair ¶
DelimiterPair returns the template delimiters, defaulted.
type Variable ¶
type Variable struct {
Name string `yaml:"name"`
Prompt string `yaml:"prompt"`
Type VarType `yaml:"type"`
Help string `yaml:"help"`
Options []string `yaml:"options"`
// Default is itself rendered as a template, against the builtins and any
// variable answered before this one. That ordering is why Variables is a
// list rather than a map.
Default string `yaml:"default"`
// Validate is a regular expression the answer must match. String vars only.
Validate string `yaml:"validate"`
// When gates the question. It is a template expression evaluated for
// truthiness, e.g. `{{ eq .database "postgres" }}`. A skipped variable
// takes its rendered default so downstream templates still resolve.
When string `yaml:"when"`
}
Variable is one question asked before rendering. Answers are recorded in the lockfile so that `rig apply` can re-render without re-asking.
func (Variable) EffectiveType ¶
EffectiveType fills in the type a variable behaves as when unset.