1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
2//
3// SPDX-License-Identifier: AGPL-3.0-or-later
4
5package habit
6
7import (
8 "encoding/json"
9 "fmt"
10
11 "git.secluded.site/lune/internal/config"
12 "git.secluded.site/lune/internal/ui"
13 "github.com/charmbracelet/lipgloss"
14 "github.com/charmbracelet/lipgloss/table"
15 "github.com/spf13/cobra"
16)
17
18// ListCmd lists configured habits.
19var ListCmd = &cobra.Command{
20 Use: "list",
21 Short: "List configured habits",
22 Long: `List habits configured in lune.
23
24Habits are copied from the Lunatask desktop app during 'lune init'.`,
25 RunE: runList,
26}
27
28func init() {
29 ListCmd.Flags().Bool("json", false, "Output as JSON")
30}
31
32func runList(cmd *cobra.Command, _ []string) error {
33 cfg, err := config.Load()
34 if err != nil {
35 return err
36 }
37
38 if len(cfg.Habits) == 0 {
39 fmt.Fprintln(cmd.OutOrStdout(), "No habits configured")
40
41 return nil
42 }
43
44 jsonFlag, _ := cmd.Flags().GetBool("json")
45 if jsonFlag {
46 return outputJSON(cmd, cfg.Habits)
47 }
48
49 return outputTable(cmd, cfg.Habits)
50}
51
52func outputJSON(cmd *cobra.Command, habits []config.Habit) error {
53 enc := json.NewEncoder(cmd.OutOrStdout())
54 enc.SetIndent("", " ")
55
56 if err := enc.Encode(habits); err != nil {
57 return fmt.Errorf("encoding JSON: %w", err)
58 }
59
60 return nil
61}
62
63func outputTable(cmd *cobra.Command, habits []config.Habit) error {
64 rows := make([][]string, 0, len(habits))
65
66 for _, habit := range habits {
67 rows = append(rows, []string{habit.Key, habit.Name})
68 }
69
70 tbl := table.New().
71 Headers("KEY", "NAME").
72 Rows(rows...).
73 StyleFunc(func(row, col int) lipgloss.Style {
74 if row == table.HeaderRow {
75 return ui.TableHeaderStyle()
76 }
77
78 return lipgloss.NewStyle()
79 }).
80 Border(ui.TableBorder())
81
82 fmt.Fprintln(cmd.OutOrStdout(), tbl.Render())
83
84 return nil
85}