blueprint

package
v0.1.1 Latest Latest
Warning

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

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

Documentation

Overview

Package blueprint defines the blueprint.yaml schema and its parser.

Index

Constants

View Source
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.

View Source
const Filename = "blueprint.yaml"

Filename is the conventional name of a blueprint file.

View Source
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

func CheckRelative(p string) error

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.

func Locate

func Locate(dir string) (string, bool)

Locate finds a blueprint within a directory, preferring the .rig layout and falling back to one at the root.

Both are supported rather than only the new one: a project generated before the move should not stop working because rig tidied up.

func ParseMode

func ParseMode(s string) (os.FileMode, error)

ParseMode reads an octal file mode such as "0755".

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.

func Load

func Load(path string) (*Blueprint, error)

Load reads and validates a blueprint from a file or from a directory containing one.

func Parse

func Parse(data []byte) (*Blueprint, error)

Parse decodes and validates blueprint bytes.

func (*Blueprint) Validate

func (b *Blueprint) Validate() error

Validate reports the first structural problem with a blueprint. It is deliberately strict: a blueprint runs shell commands and writes files, so failing loudly at parse time beats failing halfway through generation.

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

func (f File) ShouldRender() bool

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

func (t Template) DelimiterPair() (left, right string)

DelimiterPair returns the template delimiters, defaulted.

type VarType

type VarType string

VarType is the kind of answer a variable accepts.

const (
	VarString VarType = "string"
	VarBool   VarType = "bool"
	VarChoice VarType = "choice"
)

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

func (v Variable) EffectiveType() VarType

EffectiveType fills in the type a variable behaves as when unset.

Jump to

Keyboard shortcuts

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