Files

74 lines
2.2 KiB
Go

// 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(
newVersionCmd(),
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
}