Add comparison command request parsing
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"gitea.maximumdirect.net/eric/weatherreporter/internal/app"
|
||||
"gitea.maximumdirect.net/eric/weatherreporter/internal/buildinfo"
|
||||
"gitea.maximumdirect.net/eric/weatherreporter/internal/comparison"
|
||||
"gitea.maximumdirect.net/eric/weatherreporter/internal/config"
|
||||
"gitea.maximumdirect.net/eric/weatherreporter/internal/report"
|
||||
"gitea.maximumdirect.net/eric/weatherreporter/internal/timeutil"
|
||||
@@ -45,6 +46,7 @@ type Runner struct {
|
||||
Version string
|
||||
WorkingDir string
|
||||
runBatchDetailed func(context.Context, app.BatchRequest) (*app.BatchResult, error)
|
||||
compareDetailed func(context.Context, app.ComparisonRequest) (*app.ComparisonResult, error)
|
||||
}
|
||||
|
||||
func Run(ctx context.Context, args []string, stdout io.Writer, stderr io.Writer) error {
|
||||
@@ -127,6 +129,24 @@ type generateOptions struct {
|
||||
Date string
|
||||
}
|
||||
|
||||
type comparisonOptions struct {
|
||||
commonOptions
|
||||
Date string
|
||||
ProfileIDs profileValues
|
||||
Replace bool
|
||||
}
|
||||
|
||||
type profileValues []string
|
||||
|
||||
func (values *profileValues) String() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (values *profileValues) Set(value string) error {
|
||||
*values = append(*values, value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r Runner) resolveGenerate(args []string) (app.GenerateRequest, error) {
|
||||
req, _, err := r.resolveGenerateAction(args)
|
||||
return req, err
|
||||
@@ -212,6 +232,93 @@ func (r Runner) resolveRun(args []string) (app.BatchRequest, error) {
|
||||
return req, err
|
||||
}
|
||||
|
||||
func (r Runner) resolveComparison(args []string) (app.ComparisonRequest, error) {
|
||||
req, _, err := r.resolveComparisonAction(args)
|
||||
return req, err
|
||||
}
|
||||
|
||||
func (r Runner) executeComparison(ctx context.Context, args []string) (*app.ComparisonResult, error) {
|
||||
req, _, err := r.resolveComparisonAction(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
compareDetailed := r.compareDetailed
|
||||
if compareDetailed == nil {
|
||||
compareDetailed = app.CompareDetailed
|
||||
}
|
||||
return compareDetailed(ctx, req)
|
||||
}
|
||||
|
||||
func (r Runner) resolveComparisonAction(args []string) (app.ComparisonRequest, commonOptions, error) {
|
||||
if r.Clock == nil {
|
||||
r.Clock = timeutil.SystemClock{}
|
||||
}
|
||||
if len(args) == 0 {
|
||||
return app.ComparisonRequest{}, commonOptions{}, fmt.Errorf("compare requires a report name")
|
||||
}
|
||||
if _, err := report.IDForCommandName(args[0]); err != nil {
|
||||
return app.ComparisonRequest{}, commonOptions{}, fmt.Errorf("unknown compare report %q", args[0])
|
||||
}
|
||||
reportKind := app.ReportKind(args[0])
|
||||
opts, err := parseComparisonFlags(reportKind, args[1:])
|
||||
if err != nil {
|
||||
return app.ComparisonRequest{}, commonOptions{}, err
|
||||
}
|
||||
if err := comparison.ValidateProfileIDs(opts.ProfileIDs); err != nil {
|
||||
return app.ComparisonRequest{}, commonOptions{}, err
|
||||
}
|
||||
cfg, err := config.Load(config.LoadOptions{
|
||||
Path: opts.ConfigPath,
|
||||
Units: opts.Units,
|
||||
Timezone: opts.Timezone,
|
||||
})
|
||||
if err != nil {
|
||||
return app.ComparisonRequest{}, commonOptions{}, err
|
||||
}
|
||||
location, err := timeutil.LoadLocation(cfg.WeatherAPI.Timezone)
|
||||
if err != nil {
|
||||
return app.ComparisonRequest{}, commonOptions{}, err
|
||||
}
|
||||
workingDir, err := r.workingDir()
|
||||
if err != nil {
|
||||
return app.ComparisonRequest{}, commonOptions{}, err
|
||||
}
|
||||
outputDir, err := resolveOutputOverride(workingDir, opts.OutputDir)
|
||||
if err != nil {
|
||||
return app.ComparisonRequest{}, commonOptions{}, err
|
||||
}
|
||||
|
||||
req := app.ComparisonRequest{
|
||||
Config: cfg, Report: reportKind, ProfileIDs: append([]string(nil), opts.ProfileIDs...),
|
||||
WorkingDir: workingDir, OutputDir: outputDir, Replace: opts.Replace, LLMDebugDir: opts.LLMDebugDir, Clock: r.Clock,
|
||||
}
|
||||
switch reportKind {
|
||||
case app.ReportDaily:
|
||||
if opts.Date == "" {
|
||||
return app.ComparisonRequest{}, commonOptions{}, fmt.Errorf("compare daily requires --date YYYY-MM-DD")
|
||||
}
|
||||
req.Date, err = timeutil.ParseLocalDate(opts.Date, location)
|
||||
case app.ReportToday:
|
||||
if opts.Date == "" {
|
||||
req.Date = timeutil.LocalDate(r.Clock.Now(), location)
|
||||
} else {
|
||||
req.Date, err = timeutil.ParseLocalDate(opts.Date, location)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return app.ComparisonRequest{}, commonOptions{}, err
|
||||
}
|
||||
|
||||
promptkitConfig := cfg.Promptkit
|
||||
promptkitConfig.Profile = ""
|
||||
executor, err := r.promptExecutor(promptkitConfig)
|
||||
if err != nil {
|
||||
return app.ComparisonRequest{}, commonOptions{}, err
|
||||
}
|
||||
req.Executor = executor
|
||||
return req, opts.commonOptions, nil
|
||||
}
|
||||
|
||||
func (r Runner) resolveRunAction(args []string) (app.BatchRequest, commonOptions, error) {
|
||||
if r.Clock == nil {
|
||||
r.Clock = timeutil.SystemClock{}
|
||||
@@ -288,6 +395,27 @@ func parseRunFlags(args []string) (commonOptions, error) {
|
||||
return opts, nil
|
||||
}
|
||||
|
||||
func parseComparisonFlags(report app.ReportKind, args []string) (comparisonOptions, error) {
|
||||
fs := flag.NewFlagSet("compare "+string(report), flag.ContinueOnError)
|
||||
fs.SetOutput(io.Discard)
|
||||
opts := comparisonOptions{}
|
||||
addCommonFlags(fs, &opts.commonOptions, false)
|
||||
fs.StringVar(&opts.OutputDir, "out-dir", "", "comparison bundle directory")
|
||||
fs.BoolVar(&opts.Replace, "replace", false, "replace a recognized comparison bundle")
|
||||
fs.BoolVar(&opts.Quiet, "quiet", false, "suppress successful action output")
|
||||
fs.Var(&opts.ProfileIDs, "profile", "prompt profile ID")
|
||||
if report == app.ReportDaily || report == app.ReportToday {
|
||||
fs.StringVar(&opts.Date, "date", "", "report date in YYYY-MM-DD")
|
||||
}
|
||||
if err := fs.Parse(args); err != nil {
|
||||
return comparisonOptions{}, err
|
||||
}
|
||||
if fs.NArg() > 0 {
|
||||
return comparisonOptions{}, fmt.Errorf("unexpected argument %q", fs.Arg(0))
|
||||
}
|
||||
return opts, nil
|
||||
}
|
||||
|
||||
func addCommonFlags(fs *flag.FlagSet, opts *commonOptions, includeOutput bool) {
|
||||
fs.StringVar(&opts.ConfigPath, "config", "", "configuration file path")
|
||||
fs.StringVar(&opts.Units, "units", "", "weather API units")
|
||||
|
||||
Reference in New Issue
Block a user