list.go

 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}