Files
nib-v1/cmd/ls.go
lerko d715b053e7 refactor(db): thread context.Context through all Store methods
Enables request-scoped cancellation, timeouts, and graceful shutdown
for all database operations across API handlers, CLI commands, and TUI.
2026-05-20 20:51:51 -04:00

177 lines
3.6 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package cmd
import (
"fmt"
"strings"
"time"
"github.com/lerko/nib/internal/db"
"github.com/lerko/nib/internal/display"
"github.com/spf13/cobra"
)
var (
lsTag string
lsDate string
lsMonth string
lsFrom string
lsTo string
lsLimit int
lsAll bool
)
var lsCmd = &cobra.Command{
Use: "ls",
Short: "list entities in stream order",
RunE: runLs,
}
func init() {
lsCmd.Flags().StringVar(&lsTag, "tag", "", "filter by tag")
lsCmd.Flags().StringVar(&lsDate, "date", "", "filter by date (YYYY-MM-DD)")
lsCmd.Flags().StringVar(&lsMonth, "month", "", "filter by month (YYYY-MM)")
lsCmd.Flags().StringVar(&lsFrom, "from", "", "start date (YYYY-MM-DD)")
lsCmd.Flags().StringVar(&lsTo, "to", "", "end date (YYYY-MM-DD)")
lsCmd.Flags().IntVar(&lsLimit, "limit", 0, "max entities to show (default 50)")
lsCmd.Flags().BoolVar(&lsAll, "all", false, "include deleted entities")
}
func runLs(cmd *cobra.Command, _ []string) error {
store, err := openStore()
if err != nil {
return err
}
defer store.Close()
p := db.DefaultListParams()
p.IncludeDeleted = lsAll
if lsTag != "" {
p.Tag = &lsTag
}
if lsLimit > 0 {
p.Limit = lsLimit
}
hasDateFilter := false
if lsDate != "" {
p.Date = &lsDate
hasDateFilter = true
}
if lsMonth != "" {
t, err := time.Parse("2006-01", lsMonth)
if err != nil {
return fmt.Errorf("bad --month format, use YYYY-MM")
}
from := t.Format("2006-01-02")
to := t.AddDate(0, 1, -1).Format("2006-01-02")
p.From = &from
p.To = &to
hasDateFilter = true
}
if lsFrom != "" {
if _, err := time.Parse("2006-01-02", lsFrom); err != nil {
return fmt.Errorf("bad --from format, use YYYY-MM-DD")
}
p.From = &lsFrom
hasDateFilter = true
}
if lsTo != "" {
if _, err := time.Parse("2006-01-02", lsTo); err != nil {
return fmt.Errorf("bad --to format, use YYYY-MM-DD")
}
p.To = &lsTo
hasDateFilter = true
}
if !hasDateFilter {
since := time.Now().UTC().Add(-48 * time.Hour)
p.Since = &since
}
entities, err := store.List(cmd.Context(), p)
if err != nil {
return err
}
if len(entities) == 0 {
return nil
}
groups := groupByDate(entities)
for _, g := range groups {
fmt.Printf("── %s ──\n", g.label)
for _, e := range g.entities {
printEntity(e)
}
fmt.Println()
}
return nil
}
type dateGroup struct {
label string
entities []*db.Entity
}
func groupByDate(entities []*db.Entity) []dateGroup {
var groups []dateGroup
var current *dateGroup
for _, e := range entities {
label := formatDateLabel(e.CreatedAt)
if current == nil || current.label != label {
if current != nil {
groups = append(groups, *current)
}
current = &dateGroup{label: label}
}
current.entities = append(current.entities, e)
}
if current != nil {
groups = append(groups, *current)
}
return groups
}
func formatDateLabel(t time.Time) string {
return strings.ToLower(t.Format("Jan 2"))
}
func printEntity(e *db.Entity) {
glyph := display.DisplayGlyph(e.Glyph, e.CardType)
shortID := display.FormatID(e.ID)
label := e.Body
if e.Title != nil {
label = *e.Title
}
var line strings.Builder
fmt.Fprintf(&line, "%s %-40s", glyph, label)
if e.TimeAnchor != nil {
fmt.Fprintf(&line, " @%-5s", *e.TimeAnchor)
} else {
line.WriteString(" ")
}
var tagStr string
for _, tag := range e.Tags {
tagStr += " #" + tag
}
if tagStr != "" {
fmt.Fprintf(&line, " %-16s", strings.TrimSpace(tagStr))
} else {
line.WriteString(" ")
}
fmt.Fprintf(&line, " %s", shortID)
if e.UseCount > 0 {
fmt.Fprintf(&line, " (%d×)", e.UseCount)
}
fmt.Println(line.String())
}