// Package cli defines the ocdsgen command tree using Cobra. The commands are // thin wrappers around internal/generator. package cli import ( "fmt" "io" "time" "github.com/spf13/cobra" "git.avsdev.uk/Go/go-ocds/internal/generator" ) // options are the flags shared by every subcommand. type options struct { config string timeout time.Duration strict bool quiet bool } // NewRootCmd builds the command tree. It returns a fresh tree on each call so // tests can run commands in isolation. func NewRootCmd() *cobra.Command { opts := &options{} root := &cobra.Command{ Use: "ocdsgen", Short: "Generate Go types for OCDS releases with chosen extensions", Long: `ocdsgen reads an extensions.json config listing the OCDS core schemas and extension URLs, resolves extension dependencies, applies each extension's schema patch in order, and generates Go structs from the result.`, SilenceUsage: true, // don't print usage on runtime errors SilenceErrors: true, // main prints the error once } pf := root.PersistentFlags() pf.StringVarP(&opts.config, "config", "c", "extensions.json", "path to the extensions config file") pf.DurationVar(&opts.timeout, "timeout", 60*time.Second, "timeout for each HTTP request") pf.BoolVar(&opts.strict, "strict", false, "fail if the generator reports any warnings") pf.BoolVarP(&opts.quiet, "quiet", "q", false, "don't print notes and warnings") root.AddCommand( newGenerateCmd(opts), newResolveCmd(opts), newSchemaCmd(opts), ) return root } // setup loads the config and creates a Generator that logs to the command's // stderr (or nowhere, with --quiet). func (o *options) setup(cmd *cobra.Command) (*generator.Config, *generator.Generator, error) { cfg, err := generator.LoadConfig(o.config) if err != nil { return nil, nil, err } var log io.Writer = cmd.ErrOrStderr() if o.quiet { log = io.Discard } return cfg, generator.New(log, o.timeout), nil } // finish enforces --strict once a command's work is done. func (o *options) finish(g *generator.Generator) error { if n := g.Warnings(); o.strict && n > 0 { return fmt.Errorf("%d warning(s) reported and --strict is set", n) } return nil }