...
1 package cmd
2
3 import (
4 "bufio"
5 "bytes"
6 "context"
7 "fmt"
8 "os"
9 "path/filepath"
10 "strings"
11 "time"
12
13 "edge-infra.dev/pkg/lib/cli/rags"
14 "edge-infra.dev/pkg/lib/cli/sink"
15 "edge-infra.dev/pkg/tools/dlog"
16 )
17
18
19
20
21 func newCreateCmd() *sink.Command {
22 var (
23 dir, template string
24 tags []string
25 )
26
27 cmd := &sink.Command{
28 Use: "create [flags] <file>",
29 Short: "Create decision logs from a template.",
30 Flags: []*rags.Rag{
31 dirFlag(&dir),
32 templateFlag(&template),
33 {
34 Name: "tags",
35 Usage: "Comma separated list of tags to apply to new dlog. Can be provided multiple times",
36 Value: &rags.StringSet{Var: &tags},
37 },
38 },
39 Exec: func(_ context.Context, r sink.Run) error {
40 if len(r.Args()) != 1 {
41 return fmt.Errorf("a name for the decision log file is required")
42 }
43
44 p := filepath.Join(dir, r.Args()[0])
45 _, err := os.Stat(p)
46 if err == nil {
47 return fmt.Errorf("%s already exists", p)
48 }
49
50 t, err := os.Open(template)
51 if err != nil {
52 return fmt.Errorf("failed to open template %s: %w", template, err)
53 }
54
55 return createDLog(p, t, time.Now(), tags)
56 },
57 }
58
59 return cmd
60 }
61
62 func createDLog(path string, t *os.File, d time.Time, tags []string) error {
63 buf := new(bytes.Buffer)
64 scanner := bufio.NewScanner(t)
65 for scanner.Scan() {
66 text := scanner.Text()
67
68
69
70 if strings.HasPrefix(text, "date:") {
71 buf.WriteString(fmt.Sprintf("date: %s", dlog.Time{Time: d}))
72 buf.WriteString("\n")
73 continue
74 }
75 if len(tags) > 0 && strings.HasPrefix(text, "tags:") {
76 buf.WriteString(fmt.Sprintf(
77 "tags: [%s]",
78
79 strings.Join(tags, ", ")),
80 )
81 buf.WriteString("\n")
82 continue
83 }
84
85 buf.WriteString(text)
86 buf.WriteString("\n")
87 }
88 if scanner.Err() != nil {
89 return fmt.Errorf("failed to read template %s: %w", t.Name(), scanner.Err())
90 }
91
92 f, err := os.Create(path)
93 if err != nil {
94 return fmt.Errorf("failed to create %s: %w", path, err)
95 }
96 if _, err := buf.WriteTo(f); err != nil {
97 return fmt.Errorf("failed to write %s: %w", path, err)
98 }
99 return nil
100 }
101
View as plain text