controller-tools: Index | Files | Directories

package genall

import ""

Package genall defines entrypoints for generation tools to hook into and share the same set of parsing, typechecking, and marker information.


Each Generator knows how to register its markers into a central Registry, and then how to generate output using a Collector and some root packages. Each generator can be considered to be the output type of a marker, for easy command line parsing.

Output and Input

Generators output artifacts via an OutputRule. OutputRules know how to write output for different package-associated (code) files, as well as config files. Each OutputRule should also be considered to be the output type as a marker, for easy command-line parsing.

OutputRules groups together an OutputRule per generator, plus a default output rule for any not explicitly specified.

OutputRules are defined for stdout, file writing, and sending to /dev/null (useful for doing "type-checking" without actually saving the results).

InputRule defines custom input loading, but its shared across all Generators. There's currently only a filesystem implementation.

Runtime and Context

Runtime maps together Generators, and constructs "contexts" which provide the common collector and roots, plus the output rule for that generator, and a handle for reading files (like boilerplate headers).

It will run all associated generators, printing errors and automatically skipping type-checking errors (since those are commonly caused by the partial type-checking of loader.TypeChecker).


The FromOptions (and associated helpers) function makes it easy to use generators and output rules as markers that can be parsed from the command line, producing a registry from command line args.


Package Files

doc.go genall.go input.go options.go output.go zz_generated.markerhelp.go


var InputFromFileSystem = inputFromFileSystem{}

InputFromFileSystem reads from the filesystem as normal.

var (
    InputPathsMarker = markers.Must(markers.MakeDefinition("paths", markers.DescribesPackage, InputPaths(nil)))
var OutputToNothing = outputToNothing{}

OutputToNothing skips outputting anything.

var OutputToStdout = outputToStdout{}

OutputToStdout outputs everything to standard-out, with no separation.

Generally useful for single-artifact outputs.

func RegisterOptionsMarkers Uses

func RegisterOptionsMarkers(into *markers.Registry) error

RegisterOptionsMarkers registers "mandatory" options markers for FromOptions into the given registry. At this point, that's just InputPaths.

func RegistryFromOptions Uses

func RegistryFromOptions(optionsRegistry *markers.Registry, options []string) (*markers.Registry, error)

RegistryFromOptions produces just the marker registry that would be used by FromOptions, without attempting to produce a full Runtime. This can be useful if you want to display help without trying to load roots.

type GenerationContext Uses

type GenerationContext struct {
    // Collector is the shared marker collector.
    Collector *markers.Collector
    // Roots are the base packages to be processed.
    Roots []*loader.Package
    // Checker is the shared partial type-checker.
    Checker *loader.TypeChecker
    // OutputRule describes how to output artifacts.
    // InputRule describes how to load associated boilerplate artifacts.
    // It should *not* be used to load source files.

GenerationContext defines the common information needed for each Generator to run.

func (GenerationContext) ReadFile Uses

func (g GenerationContext) ReadFile(path string) ([]byte, error)

ReadFile reads the given boilerplate artifact using the context's InputRule.

func (GenerationContext) WriteYAML Uses

func (g GenerationContext) WriteYAML(itemPath string, objs ...interface{}) error

WriteYAML writes the given objects out, serialized as YAML, using the context's OutputRule. Objects are written as separate documents, separated from each other by `---` (as per the YAML spec).

type Generator Uses

type Generator interface {
    // RegisterMarkers registers all markers needed by this Generator
    // into the given registry.
    RegisterMarkers(into *markers.Registry) error
    // Generate generates artifacts produced by this marker.
    // It's called *after* RegisterMarkers has been called.
    Generate(*GenerationContext) error

Generator knows how to register some set of markers, and then produce output artifacts based on loaded code containing those markers, sharing common loaded data.

type Generators Uses

type Generators []*Generator

Generators are a list of Generators. NB(directxman12): this is a pointer so that we can uniquely identify each instance of a generator, even if it's not hashable. Different *instances* of a generator are treated differently.

func (Generators) ForRoots Uses

func (g Generators) ForRoots(rootPaths ...string) (*Runtime, error)

ForRoots produces a Runtime to run the given generators against the given packages. It outputs to /dev/null by default.

func (Generators) RegisterMarkers Uses

func (g Generators) RegisterMarkers(reg *markers.Registry) error

RegisterMarkers registers all markers defined by each of the Generators in this list into the given registry.

type HasHelp Uses

type HasHelp interface {
    // Help returns help for this generator.
    Help() *markers.DefinitionHelp

HasHelp is some Generator, OutputRule, etc with a help method.

type InputPaths Uses

type InputPaths []string

InputPaths represents paths and go-style path patterns to use as package roots.

func (InputPaths) Help Uses

func (InputPaths) Help() *markers.DefinitionHelp

type InputRule Uses

type InputRule interface {
    // OpenForRead opens the given non-code artifact for reading.
    OpenForRead(path string) (io.ReadCloser, error)

InputRule describes how to load non-code boilerplate artifacts. It's not used for loading code.

type OutputArtifacts Uses

type OutputArtifacts struct {
    // Config points to the directory to which to write configuration.
    Config OutputToDirectory
    // Code overrides the directory in which to write new code (defaults to where the existing code lives).
    Code OutputToDirectory `marker:",optional"`

OutputArtifacts outputs artifacts to different locations, depending on whether they're package-associated or not.

Non-package associated artifacts are output to the Config directory, while package-associated ones are output to their package's source files' directory, unless an alternate path is specified in Code.

func (OutputArtifacts) Help Uses

func (OutputArtifacts) Help() *markers.DefinitionHelp

func (OutputArtifacts) Open Uses

func (o OutputArtifacts) Open(pkg *loader.Package, itemPath string) (io.WriteCloser, error)

type OutputRule Uses

type OutputRule interface {
    // Open opens the given artifact path for writing.  If a package is passed,
    // the artifact is considered to be used as part of the package (e.g.
    // generated code), while a nil package indicates that the artifact is
    // config (or something else not involved in Go compilation).
    Open(pkg *loader.Package, path string) (io.WriteCloser, error)

OutputRule defines how to output artifacts from a generator.

type OutputRules Uses

type OutputRules struct {
    // Default is the output rule used when no specific per-generator overrides match.
    Default OutputRule
    // ByGenerator contains specific per-generator overrides.
    // NB(directxman12): this is a pointer to avoid issues if a given Generator becomes unhashable
    // (interface values compare by "dereferencing" their internal pointer first, whereas pointers
    // compare by the actual pointer itself).
    ByGenerator map[*Generator]OutputRule

OutputRules defines how to output artificats on a per-generator basis.

func DirectoryPerGenerator Uses

func DirectoryPerGenerator(base string, generators map[string]*Generator) OutputRules

DirectoryPerGenerator produces output rules mapping output to a different subdirectory of the given base directory for each generator (with each subdirectory specified as the key in the input map).

func (OutputRules) ForGenerator Uses

func (o OutputRules) ForGenerator(gen *Generator) OutputRule

ForGenerator returns the output rule that should be used by the given Generator.

type OutputToDirectory Uses

type OutputToDirectory string

OutputToDirectory outputs each artifact to the given directory, regardless of if it's package-associated or not.

func (OutputToDirectory) Help Uses

func (OutputToDirectory) Help() *markers.DefinitionHelp

func (OutputToDirectory) Open Uses

func (o OutputToDirectory) Open(_ *loader.Package, itemPath string) (io.WriteCloser, error)

type Runtime Uses

type Runtime struct {
    // Generators are the Generators to be run by this Runtime.
    Generators Generators
    // GenerationContext is the base generation context that's copied
    // to produce the context for each Generator.
    // OutputRules defines how to output artifacts for each Generator.
    OutputRules OutputRules

Runtime collects generators, loaded program data (Collector, root Packages), and I/O rules, running them together.

func FromOptions Uses

func FromOptions(optionsRegistry *markers.Registry, options []string) (*Runtime, error)

FromOptions parses the options from markers stored in the given registry out into a runtime. The markers in the registry must be either

a) Generators b) OutputRules c) InputPaths

The paths specified in InputPaths are loaded as package roots, and the combined with the generators and the specified output rules to produce a runtime that can be run or further modified. Not default generators are used if none are specified -- you can check the output and rerun for that.

func (*Runtime) Run Uses

func (r *Runtime) Run() bool

Run runs the Generators in this Runtime against its packages, printing errors (except type errors, which common result from using TypeChecker with filters), returning true if errors were found.


helpPackage help contains utilities for actually writing out marker help.
help/prettyPackage pretty contains utilities for formatting terminal help output, and a use of those to display marker help.

Package genall imports 10 packages (graph) and is imported by 15 packages. Updated 2019-11-15. Refresh now. Tools for package owners.