diff options
| author | Paul Buetow <paul@buetow.org> | 2026-03-03 20:07:43 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-03-03 20:07:43 +0200 |
| commit | 81e89f8e67a2eef0c8815f9d3ac79ee67530e9d3 (patch) | |
| tree | cbf3d672eafe7bef799a1b3f2d224e407b0a8837 | |
| parent | aa7495388de82446a78b4f767a62728de9f777ed (diff) | |
refactor(cli): move main orchestration into internal cli package (task 332)
| -rw-r--r-- | cmd/goprecords/main.go | 131 | ||||
| -rw-r--r-- | internal/cli/cli.go | 120 |
2 files changed, 123 insertions, 128 deletions
diff --git a/cmd/goprecords/main.go b/cmd/goprecords/main.go index ad75949..88ce727 100644 --- a/cmd/goprecords/main.go +++ b/cmd/goprecords/main.go @@ -1,139 +1,14 @@ -// Program goprecords generates uptime reports from uptimed record files or a SQLite database. package main import ( - "context" - "flag" - "fmt" "os" - "github.com/goprecords/internal/goprecords" - "github.com/goprecords/internal/version" + "github.com/goprecords/internal/cli" ) -const defaultDB = "goprecords.db" - func main() { - if len(os.Args) > 1 && (os.Args[1] == "-version" || os.Args[1] == "--version") { - fmt.Println(version.Version) - return - } - - if len(os.Args) < 2 { - runReportFromFiles(nil) - return - } - - switch os.Args[1] { - case "import": - runImport(os.Args[2:]) - case "query": - runQuery(os.Args[2:]) - case "test": - runTests() - default: - runReportFromFiles(os.Args[1:]) - } -} - -func runImport(args []string) { - fs := flag.NewFlagSet("import", flag.ExitOnError) - statsDir := fs.String("stats-dir", "", "Directory containing .records files (required)") - dbPath := fs.String("db", defaultDB, "SQLite database path") - fs.Parse(args) - - if *statsDir == "" { - fmt.Fprintln(os.Stderr, "import: missing required flag: -stats-dir") - fs.Usage() - os.Exit(1) - } - db, err := goprecords.OpenDB(*dbPath) - if err != nil { - fmt.Fprintln(os.Stderr, "open db:", err) - os.Exit(1) - } - defer db.Close() - ctx := context.Background() - if err := goprecords.CreateSchema(ctx, db); err != nil { - fmt.Fprintln(os.Stderr, "schema:", err) - os.Exit(1) - } - if err := goprecords.ImportFromDir(ctx, db, *statsDir); err != nil { - fmt.Fprintln(os.Stderr, "import:", err) - os.Exit(1) - } - fmt.Fprintf(os.Stderr, "imported %s into %s\n", *statsDir, *dbPath) -} - -func runQuery(args []string) { - fs := flag.NewFlagSet("query", flag.ExitOnError) - dbPath := fs.String("db", defaultDB, "SQLite database path") - rf := goprecords.RegisterReportFlags(fs) - fs.Parse(args) - - db, err := goprecords.OpenDB(*dbPath) - if err != nil { - fmt.Fprintln(os.Stderr, "open db:", err) - os.Exit(1) - } - defer db.Close() - - ctx := context.Background() - aggregates, err := goprecords.LoadAggregates(ctx, db) - if err != nil { - fmt.Fprintln(os.Stderr, "load:", err) - os.Exit(1) - } - - cfg, err := rf.Parse() - if err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } - if err := goprecords.WriteReports(os.Stdout, aggregates, cfg); err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } -} - -func runReportFromFiles(args []string) { - if args == nil { - args = []string{} - } - fs := flag.NewFlagSet("goprecords", flag.ExitOnError) - statsDir := fs.String("stats-dir", "", "The uptimed raw record input dir (required)") - rf := goprecords.RegisterReportFlags(fs) - fs.Parse(args) - - if *statsDir == "" { - fmt.Fprintln(os.Stderr, "missing required flag: -stats-dir") - fs.Usage() - os.Exit(1) - } - - cfg, err := rf.Parse() - if err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } - - ctx := context.Background() - aggr := goprecords.NewAggregator(*statsDir) - aggregates, err := aggr.Aggregate(ctx) - if err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } - - if err := goprecords.WriteReports(os.Stdout, aggregates, cfg); err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } -} - -func runTests() { - if err := goprecords.RunIntegrationTests("./fixtures"); err != nil { - fmt.Fprintln(os.Stderr, err) + if err := cli.Execute(os.Args[1:]); err != nil { + _, _ = os.Stderr.WriteString(err.Error() + "\n") os.Exit(1) } } diff --git a/internal/cli/cli.go b/internal/cli/cli.go new file mode 100644 index 0000000..1085ea3 --- /dev/null +++ b/internal/cli/cli.go @@ -0,0 +1,120 @@ +package cli + +import ( + "context" + "flag" + "fmt" + "os" + + "github.com/goprecords/internal/goprecords" + "github.com/goprecords/internal/version" +) + +// Execute parses command‑line arguments and runs the appropriate sub‑command. +func Execute(args []string) error { + // Handle version flag early. + if len(args) > 0 && (args[0] == "-version" || args[0] == "--version") { + fmt.Println(version.Version) + return nil + } + + // No subcommand – treat args as flags for a direct report from files. + if len(args) == 0 { + return runReportFromFiles(nil) + } + + switch args[0] { + case "import": + return runImport(args[1:]) + case "query": + return runQuery(args[1:]) + case "test": + return runTests() + default: + return runReportFromFiles(args) + } +} + +func runImport(args []string) error { + fs := flag.NewFlagSet("import", flag.ExitOnError) + statsDir := fs.String("stats-dir", "", "Directory containing .records files (required)") + dbPath := fs.String("db", "goprecords.db", "SQLite database path") + if err := fs.Parse(args); err != nil { + return err + } + if *statsDir == "" { + fmt.Fprintln(os.Stderr, "import: missing required flag: -stats-dir") + fs.Usage() + return fmt.Errorf("missing -stats-dir") + } + db, err := goprecords.OpenDB(*dbPath) + if err != nil { + return fmt.Errorf("open db: %w", err) + } + defer db.Close() + ctx := context.Background() + if err := goprecords.CreateSchema(ctx, db); err != nil { + return fmt.Errorf("schema: %w", err) + } + if err := goprecords.ImportFromDir(ctx, db, *statsDir); err != nil { + return fmt.Errorf("import: %w", err) + } + fmt.Fprintf(os.Stderr, "imported %s into %s\n", *statsDir, *dbPath) + return nil +} + +func runQuery(args []string) error { + fs := flag.NewFlagSet("query", flag.ExitOnError) + dbPath := fs.String("db", "goprecords.db", "SQLite database path") + rf := goprecords.RegisterReportFlags(fs) + if err := fs.Parse(args); err != nil { + return err + } + db, err := goprecords.OpenDB(*dbPath) + if err != nil { + return fmt.Errorf("open db: %w", err) + } + defer db.Close() + ctx := context.Background() + aggregates, err := goprecords.LoadAggregates(ctx, db) + if err != nil { + return fmt.Errorf("load: %w", err) + } + cfg, err := rf.Parse() + if err != nil { + return err + } + return goprecords.WriteReports(os.Stdout, aggregates, cfg) +} + +func runReportFromFiles(args []string) error { + if args == nil { + args = []string{} + } + fs := flag.NewFlagSet("goprecords", flag.ExitOnError) + statsDir := fs.String("stats-dir", "", "The uptimed raw record input dir (required)") + rf := goprecords.RegisterReportFlags(fs) + if err := fs.Parse(args); err != nil { + return err + } + if *statsDir == "" { + fmt.Fprintln(os.Stderr, "missing required flag: -stats-dir") + fs.Usage() + return fmt.Errorf("missing -stats-dir") + } + cfg, err := rf.Parse() + if err != nil { + return err + } + ctx := context.Background() + aggr := goprecords.NewAggregator(*statsDir) + aggregates, err := aggr.Aggregate(ctx) + if err != nil { + return err + } + return goprecords.WriteReports(os.Stdout, aggregates, cfg) +} + +func runTests() error { + return goprecords.RunIntegrationTests("./fixtures") +} |
