Skip to content

cli: simple

Back to gallery

Exhibit path: docs/examples/codegen/cli/simple/

A single command with one string flag and one positional argument. This is the minimal working case: one annotated struct, one generated file.

Input (in.go)

go
//go:build glacier_codegen_fixture

// Package main is the entry point for the myapp CLI.
package main

import (
	"context"
)

// MyApp is the root command.
//
// +glacier:command name=myapp
// +glacier:root
type MyApp struct{}

// Run is a no-op; subcommands do the work.
func (MyApp) Run(_ context.Context) error { return nil }

// ServeCmd starts the HTTP server.
//
// +glacier:command name=serve parent=myapp
type ServeCmd struct {
	// Port is the TCP port to listen on.
	//
	// +glacier:default 8080
	Port int

	// Config is the path to the config file.
	//
	// +glacier:positional
	Config string
}

// Run starts the server on the configured port.
func (c *ServeCmd) Run(_ context.Context) error {
	// implementation goes here
	return nil
}

Output (out.go)

go
//go:build glacier_codegen_fixture

// Code generated by glaciergen. DO NOT EDIT.
// Source: in.go
package main

import (
	"github.com/nathanbrophy/glacier/cli"
)

func init() {
	cli.Default.Register(
		cli.WithName("myapp"),
		cli.WithRoot(),
		cli.WithRunner(func() cli.Runner { return &MyApp{} }),
	)
	cli.Default.Register(
		cli.WithName("serve"),
		cli.WithParent("myapp"),
		cli.WithRunner(func() cli.Runner { return &ServeCmd{} }),
		cli.WithFlagDefault("Port", 8080),
		cli.WithPositional("Config"),
	)
}

What the generator did

  • Read the +glacier:command name=serve parent=myapp marker and registered ServeCmd as a subcommand of the root myapp command.
  • Emitted cli.WithFlagDefault("Port", 8080) from the +glacier:default 8080 marker on the Port field.
  • Emitted cli.WithPositional("Config") from the +glacier:positional marker on the Config field.
  • Wired the struct into the generated registry so cli.Default dispatches serve to ServeCmd.Run.

nested all-markers glacier generate

Apache-2.0