package cmd import ( "fmt" "os" "sort" "git.jnss.me/joakim/opal/internal/engine" "github.com/spf13/cobra" ) // CreateReportCommands generates commands for all reports dynamically func CreateReportCommands() []*cobra.Command { reports := engine.AllReports() commands := make([]*cobra.Command, 0, len(reports)) // Create a command for each report for name, report := range reports { // Capture in closure reportName := name reportObj := report cmd := &cobra.Command{ Use: reportName + " [filter...]", Short: reportObj.Description, Long: fmt.Sprintf("%s\n\nThis is a report that shows: %s", reportObj.Description, reportObj.Description), Run: func(cmd *cobra.Command, args []string) { parsed := getParsedArgs(cmd) if err := runReport(reportName, parsed.Filters); err != nil { fmt.Fprintf(os.Stderr, "Error: %v\n", err) os.Exit(1) } }, } commands = append(commands, cmd) } return commands } // runReport executes a report by name with optional filters func runReport(reportName string, filters []string) error { // Get the report report, err := engine.GetReport(reportName) if err != nil { return err } // Execute the report tasks, err := report.Execute(filters) if err != nil { return fmt.Errorf("failed to execute report: %w", err) } // Build working set for display IDs ws, err := engine.BuildWorkingSet(report.BaseFilter) if err != nil { return fmt.Errorf("failed to build working set: %w", err) } // Display tasks based on format var output string if report.DisplayFormat == engine.DisplayFormatMinimal { output = engine.FormatTaskListWithFormat(tasks, ws, "minimal") } else { output = engine.FormatTaskListWithFormat(tasks, ws, "table") } fmt.Println(output) return nil } // reportsCmd shows all available reports var reportsCmd = &cobra.Command{ Use: "reports", Short: "List all available reports", Long: `Display a list of all available task reports with their descriptions.`, Run: func(cmd *cobra.Command, args []string) { reports := engine.AllReports() // Sort by name names := make([]string, 0, len(reports)) for name := range reports { names = append(names, name) } sort.Strings(names) fmt.Println("Available reports:\n") for _, name := range names { report := reports[name] fmt.Printf(" %-12s %s\n", name, report.Description) } fmt.Println("\nUsage: opal [filters...]") fmt.Println("Example: opal ready +home") }, }