package api_gen import ( "bytes" "go/format" "os" "path/filepath" "text/template" ) // generateCLI emits a dispatch table over the generated Client: a list of // command names and an Invoke function that decodes a JSON request body into // the typed request and calls the matching client method. The hand-written CLI // binary (apps/demo/cmd/atlas9api) wraps this with credential handling. func generateCLI(outputDir string, pkg *APIPackage) error { tmpl := `// Code generated by api_gen. DO NOT EDIT. package client import ( "context" "encoding/json" "fmt" "{{ .PkgPath }}" ) // CommandNames lists every endpoint the CLI can invoke, in registration order. var CommandNames = []string{ {{- range .Endpoints }} "{{ .Name }}", {{- end }} } // Invoke decodes body into the request type for the named command, calls the // corresponding client method, and returns the typed response. An unknown name // returns an error. func Invoke(ctx context.Context, c *Client, name string, body []byte) (any, error) { switch name { {{- range .Endpoints }} case "{{ .Name }}": var req {{ $.PkgName }}.{{ .ReqType }} if len(body) > 0 { if err := json.Unmarshal(body, &req); err != nil { return nil, fmt.Errorf("decoding request: %w", err) } } return c.{{ .Name }}(ctx, &req) {{- end }} default: return nil, fmt.Errorf("unknown command: %s", name) } } ` tmplObj := template.Must(template.New("cli").Parse(tmpl)) var buf bytes.Buffer if err := tmplObj.Execute(&buf, pkg); err != nil { return err } formatted, err := format.Source(buf.Bytes()) if err != nil { return err } return os.WriteFile(filepath.Join(outputDir, "cli_gen.go"), formatted, 0644) }