CLI
The craftgo binary drives codegen and project commands. Run craftgo help for the up-to-date list, or craftgo <command> -h for one command's usage. A bad flag or argument is reported once, followed by the command's usage.
craftgo init [path]
Scaffolds a design folder with a starter craftgo.design.yaml.
craftgo init # creates ./design
craftgo init api/spec # creates ./api/specThe path is the design folder; the manifest (craftgo.design.yaml) lands flat inside it. The Go module path is read from go.mod at gen time, so init itself does not need a -package flag.
After init, you write .craftgo files inside the design folder, then run craftgo gen.
craftgo gen [path]
Generates types, validators, handlers, routes, and an OpenAPI spec from .craftgo files, and - from the .proto files in the same folder - the pb code, the gRPC server layer, its logic stubs and wiring. The protoc plugins run through go tool; pin them once with go get -tool google.golang.org/protobuf/cmd/protoc-gen-go@latest google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest (see gRPC).
craftgo gen # walk up from cwd for craftgo.design.yaml
craftgo gen design # explicit path
craftgo gen -f design # skip walk-up; use the given folder
craftgo gen -f design -c . # set the project root for output pathsFlags:
| Flag | Effect |
|---|---|
-f, --folder <path> | Path to the folder holding craftgo.design.yaml. Skips the walk-up. |
-c, --context <path> | Project root the output.* paths resolve against, an existing directory. Defaults to the parent of the design folder. |
--target <name> | Generate only the named target (go, docs); repeatable, default all. A narrowed run leaves the other targets' output untouched. An empty name is an error. |
-h, --help | Show help. |
Without -f, craftgo gen walks upward from <path> (or cwd) for a craftgo.design.yaml, probing the direct subdirectories at each level - links to directories included, hidden ones, vendor and node_modules not. Two matches at one level ask for -f. The walk stops at the first directory that holds go.mod or is a repository root (.git, .hg, .svn), so it never picks up the design of an enclosing module; a manifest that is a symbolic link to nothing is an error, not a missing manifest. With -f, a path is an error. The Go module path comes from go.mod, walking up from the project root - run go mod init <module> first if go.mod does not exist yet.
Every run first names the design folder it reads and the project root it writes under:
craftgo: design /path/to/app/design, project root /path/to/appA key the manifest does not declare - a misspelling, say - is ignored, and craftgo gen names it on stderr before generating:
craftgo: warning: output.typs is not a manifest key and is ignoredA warning of the design's analysis - the ones the editor underlines without blocking - is printed on stderr with its position, and the run goes on:
/path/to/app/design/api.craftgo:4:12: warning: @default on non-optional field "limit": ...craftgo fmt [-l] [-w] [path]
Canonical-format design files (.craftgo, .cg): every one under a directory, or the one file the path names. Default action: write back in place.
craftgo fmt # format every design file under cwd
craftgo fmt design # format files under design/
craftgo fmt -l # list files that would change (no write)
craftgo fmt -w design # explicit write mode
craftgo fmt -w=false x.cg # print the formatted file insteadFlags go before the path; a flag after it, or a second path, is an error. A design folder without design files, one of protos alone, has nothing to format.
| Flag | Effect |
|---|---|
-l | List files that need formatting; do not modify. Exits 1 if any do. |
-w | Write the formatted result back (default; with -l, list and write). An explicit -w=false prints the formatted text to stdout instead, as gofmt does. |
-h, --help | Show help. |
Use -l in CI to fail when files are not formatted. Use the default in local pre-commit hooks.
A directory is walked as craftgo gen reads a design folder: links to directories are followed, and hidden directories, vendor, node_modules and files whose name starts with . or _ are passed over. A directory fmt cannot read is named in a warning on stderr and skipped. A file named on its own is formatted whatever its extension, except one that is plainly something else - Go source, a .proto, YAML such as the manifest, go.mod, go.sum or go.work - which is refused.
Each file is written through a temporary file renamed into place, keeping its mode, so an interrupted run never leaves half a file. A file fmt cannot read or write is reported on stderr and passed over; the other files are still formatted, and the command exits 1 at the end. Every path fmt prints - a listed file, a diagnostic's position - is spelled as the walk reached it.
A file is formatted only when it has no errors, parse or semantic: a mistake the parser tolerates (a stray word read as a mixin, for example) must never be rearranged into something else. Such a file is reported on stderr with its diagnostics and left untouched, and the command exits 1. A file inside a design folder is checked with its whole project, so cross-package references resolve; any other file is checked on its own. A file whose formatted text would not parse, or would drop, duplicate, add or move a comment, is reported and left untouched the same way.
craftgo version
Prints the CLI version alone, without a leading v. --version and -v do the same.
craftgo version
1.9.0craftgo help [command]
Top-level help. Same content as running craftgo with no arguments. craftgo help <command> prints that command's usage, as craftgo <command> -h does.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Any failure: parse or semantic errors, a generation error, fmt left a file with errors unformatted or could not read or write one, fmt -l listed a file, or a bad flag or argument to a command (printed with the command's usage) |
| 2 | Usage error: no command, or an unknown one |
CI scripts can rely on these to fail builds.
Project structure expected
craftgo gen expects:
- A
craftgo.design.yamlsomewhere (walked up from cwd, or provided via-f) - A
go.modat or above the project root (so the Go module path can be resolved) .craftgofiles under the design folder
Output paths are configured in craftgo.design.yaml and resolved against the project root: the parent of the design folder, unless overridden with -c.