Generate
anvil generate writes the Go file that wires the application.
anvil generate .The command accepts the scan directory as its first positional argument. It
loads anvil.yaml or anvil.yml from that directory when one exists. Missing
configuration is valid; Anvil falls back to command defaults.
Arguments
Section titled “Arguments”anvil generate [project-dir] [output-file] [package-pattern...][project-dir]is where Anvil looks foranvil.yamloranvil.yml.[output-file]overrides configured output for this run. If it ends with.go, it is used as the generated file. Otherwise it is treated as a directory and Anvil writesanvil_autogenerated.goinside it.[package-pattern...]overrides configured scan patterns for this run.--profile <name>appliesprofiles.<name>fromanvil.yaml.--profile=<name>is accepted as the equals form.-p <name>is the short profile flag.
ANVIL_PROFILE selects a profile for commands that load project config. A CLI
profile flag overrides the environment variable.
Deterministic Execution Order
Section titled “Deterministic Execution Order”Generation runs in this exact order:
- Parse CLI flags and positional arguments.
- Load
anvil.yamloranvil.yml. - Apply the selected profile when
--profile,-p, orANVIL_PROFILEis provided. - Resolve configured relative paths against the config file directory.
- Determine scan package patterns from
scan.patterns,scan.dirs, or generator defaults. - Create the output directory.
- Create an overlay for the generated output file so scanning does not fail before the file exists.
- Load and type-check the configured Go packages.
- Run parser scanners for supported SDK markers.
- Stop if the parser produced any diagnostic.
- Compile the manifest from parser output.
- Run built-in compiler rules and configured Starlark rules.
- Stop if any compiler rule returns an
ERRORdiagnostic. - Compile HTTP, gRPC, GraphQL, and queue plans.
- Emit generated Go source.
- Write the generated file to disk.
The command has no hidden shortcuts. A protocol compiler can produce an empty plan when the project has no routes for that protocol, but the pipeline order stays the same.
Output Path
Section titled “Output Path”The output path is chosen in this order:
- second positional CLI argument
generator.outputgenerate.outputgenerator.output_dirgenerate.output_dir- Anvil’s default generated file path
The default generated file path is
<project-dir>/anvilgen/anvil_autogenerated.go.
The output package name is chosen in this order:
generator.packagegenerate.package- package name derived from the output directory
Derived package names are sanitized from the output directory. Characters that
are not letters, digits, or _ become _, and names starting with a digit are
prefixed with anvilgen_.
Rule Files
Section titled “Rule Files”Rule files come from:
compiler.rules- every configured stage’s
rules, sorted by stage name
anvil lint also accepts additional --rule <file> flags. anvil generate
uses rules from project configuration.
Rule warnings are reserved for anvil lint; generate continues after warning
diagnostics and writes generated output when no errors exist.
Parser warnings are different. They come from the source scanner before a
manifest exists, so generate stops on them the same way it stops on parser
errors. Run anvil scan when you want parser warnings printed without writing
generated output.
Failure Behavior
Section titled “Failure Behavior”Generation fails before writing output when:
- The project config cannot be parsed
- Package loading or type-checking fails
- The parser produced any diagnostic, including warnings
- Manifest compilation fails
- Built-in rules return
ERROR - Starlark scripts fail to load or return invalid diagnostics
- Configured Starlark rules return
ERROR - Protocol compilation fails
- The output directory or file cannot be written
Diagnostics include a level, code or rule name, message, file, line, and hint whenever Anvil can derive one.
Generated Registration
Section titled “Generated Registration”Generated code can be consumed explicitly:
import "example.com/portal/internal/anvilgen"
app := anvil.New(driver)app.Wire(anvilgen.Wiring())Generated code can also register itself through init when the generated
package is imported for side effects:
import _ "example.com/portal/internal/anvilgen"
app := anvil.New(driver)app.Wire()Use explicit wiring in tests when you want the package dependency visible in the file. Use blank imports when an application shell wants generated modules to self-register.