list.go

  1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
  2//
  3// SPDX-License-Identifier: AGPL-3.0-or-later
  4
  5package area
  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 areas and their goals.
 19var ListCmd = &cobra.Command{
 20	Use:   "list",
 21	Short: "List configured areas",
 22	Long: `List areas configured in lune.
 23
 24Areas are copied from the Lunatask desktop app during 'lune init'.
 25Each area may have goals associated with it.`,
 26	RunE: runList,
 27}
 28
 29func init() {
 30	ListCmd.Flags().Bool("json", false, "Output as JSON")
 31}
 32
 33func runList(cmd *cobra.Command, _ []string) error {
 34	cfg, err := config.Load()
 35	if err != nil {
 36		return err
 37	}
 38
 39	if len(cfg.Areas) == 0 {
 40		fmt.Fprintln(cmd.OutOrStdout(), "No areas configured")
 41
 42		return nil
 43	}
 44
 45	jsonFlag, _ := cmd.Flags().GetBool("json")
 46	if jsonFlag {
 47		return outputJSON(cmd, cfg.Areas)
 48	}
 49
 50	return outputTable(cmd, cfg.Areas)
 51}
 52
 53func outputJSON(cmd *cobra.Command, areas []config.Area) error {
 54	enc := json.NewEncoder(cmd.OutOrStdout())
 55	enc.SetIndent("", "  ")
 56
 57	if err := enc.Encode(areas); err != nil {
 58		return fmt.Errorf("encoding JSON: %w", err)
 59	}
 60
 61	return nil
 62}
 63
 64func outputTable(cmd *cobra.Command, areas []config.Area) error {
 65	rows := make([][]string, 0, len(areas))
 66
 67	for _, area := range areas {
 68		goals := formatGoals(area.Goals)
 69		rows = append(rows, []string{area.Key, area.Name, goals})
 70	}
 71
 72	tbl := table.New().
 73		Headers("KEY", "NAME", "GOALS").
 74		Rows(rows...).
 75		StyleFunc(func(row, col int) lipgloss.Style {
 76			if row == table.HeaderRow {
 77				return ui.TableHeaderStyle()
 78			}
 79
 80			return lipgloss.NewStyle()
 81		}).
 82		Border(ui.TableBorder())
 83
 84	fmt.Fprintln(cmd.OutOrStdout(), tbl.Render())
 85
 86	return nil
 87}
 88
 89func formatGoals(goals []config.Goal) string {
 90	if len(goals) == 0 {
 91		return "-"
 92	}
 93
 94	keys := make([]string, len(goals))
 95	for i, g := range goals {
 96		keys[i] = g.Key
 97	}
 98
 99	if len(keys) <= 3 {
100		return joinKeys(keys)
101	}
102
103	return joinKeys(keys[:3]) + fmt.Sprintf(" (+%d)", len(keys)-3)
104}
105
106func joinKeys(keys []string) string {
107	result := ""
108
109	for i, k := range keys {
110		if i > 0 {
111			result += ", "
112		}
113
114		result += k
115	}
116
117	return result
118}