add.go

 1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
 2//
 3// SPDX-License-Identifier: AGPL-3.0-or-later
 4
 5package journal
 6
 7import (
 8	"fmt"
 9	"os"
10	"strings"
11
12	"git.secluded.site/lune/internal/client"
13	"git.secluded.site/lune/internal/dateutil"
14	"git.secluded.site/lune/internal/ui"
15	"github.com/spf13/cobra"
16)
17
18// AddCmd creates a journal entry. Exported for use by the jrnl shortcut.
19var AddCmd = &cobra.Command{
20	Use:   "add [CONTENT]",
21	Short: "Create a journal entry",
22	Long: `Create a journal entry in Lunatask.
23
24Creates an entry for today by default. Use --date to specify another date
25using natural language (e.g., "yesterday", "last friday", "2024-01-15").
26
27Content supports Markdown formatting for rich text entries.
28Use "-" as CONTENT to read from stdin (useful for piping or multi-line input).`,
29	RunE: runAdd,
30}
31
32func init() {
33	AddCmd.Flags().StringP("date", "d", "", "Entry date (natural language, default: today)")
34	AddCmd.Flags().StringP("name", "n", "", "Entry title (omit to use weekday name)")
35}
36
37func runAdd(cmd *cobra.Command, args []string) error {
38	date, err := dateutil.Parse(cmd.Flag("date").Value.String())
39	if err != nil {
40		return err
41	}
42
43	content, err := resolveContent(args)
44	if err != nil {
45		return err
46	}
47
48	apiClient, err := client.New()
49	if err != nil {
50		return err
51	}
52
53	builder := apiClient.NewJournalEntry(date)
54
55	if content != "" {
56		builder.WithContent(content)
57	}
58
59	if name := cmd.Flag("name").Value.String(); name != "" {
60		builder.WithName(name)
61	}
62
63	entry, err := builder.Create(cmd.Context())
64	if err != nil {
65		return err
66	}
67
68	fmt.Fprintln(cmd.OutOrStdout(), ui.Success.Render("Created journal entry: "+entry.ID))
69
70	return nil
71}
72
73func resolveContent(args []string) (string, error) {
74	if len(args) == 0 {
75		return "", nil
76	}
77
78	if args[0] != "-" {
79		return strings.Join(args, " "), nil
80	}
81
82	data, err := os.ReadFile("/dev/stdin")
83	if err != nil {
84		return "", fmt.Errorf("reading stdin: %w", err)
85	}
86
87	return strings.TrimSpace(string(data)), nil
88}