summaryrefslogtreecommitdiff
path: root/internal/cli/report.go
blob: 7f95c8043ca88b173e0695eea884238f1a5eb15c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package cli

import (
	"fmt"
	"os"
	"time"

	"github.com/spf13/cobra"
	"github.com/thepeterstone/claudomator/internal/reporter"
	"github.com/thepeterstone/claudomator/internal/storage"
)

func newReportCmd() *cobra.Command {
	var format string
	var limit int
	var taskID string

	cmd := &cobra.Command{
		Use:   "report",
		Short: "Report execution history",
		RunE: func(cmd *cobra.Command, args []string) error {
			return runReport(format, limit, taskID)
		},
	}

	cmd.Flags().StringVar(&format, "format", "table", "output format: table, json, html")
	cmd.Flags().IntVar(&limit, "limit", 50, "maximum number of executions to show")
	cmd.Flags().StringVar(&taskID, "task", "", "filter by task ID")

	return cmd
}

func runReport(format string, limit int, taskID string) error {
	var rep reporter.Reporter
	switch format {
	case "table", "":
		rep = &reporter.ConsoleReporter{}
	case "json":
		rep = &reporter.JSONReporter{Pretty: true}
	case "html":
		rep = &reporter.HTMLReporter{}
	default:
		return fmt.Errorf("invalid format %q: must be table, json, or html", format)
	}

	store, err := storage.Open(cfg.DBPath)
	if err != nil {
		return fmt.Errorf("opening db: %w", err)
	}
	defer store.Close()

	recent, err := store.ListRecentExecutions(time.Time{}, limit, taskID)
	if err != nil {
		return fmt.Errorf("listing executions: %w", err)
	}

	execs := make([]*storage.Execution, len(recent))
	for i, r := range recent {
		e := &storage.Execution{
			ID:        r.ID,
			TaskID:    r.TaskID,
			Status:    r.State,
			StartTime: r.StartedAt,
			ExitCode:  r.ExitCode,
			CostUSD:   r.CostUSD,
		}
		if r.FinishedAt != nil {
			e.EndTime = *r.FinishedAt
		}
		execs[i] = e
	}

	return rep.Generate(os.Stdout, execs)
}