package cmd import ( "context" "fmt" "path/filepath" "slices" "time" "edge-infra.dev/pkg/lib/cli/rags" "edge-infra.dev/pkg/lib/cli/sink" "edge-infra.dev/pkg/tools/dlog" ) func newEditCmd() *sink.Command { var ( dir, template, status string addTags, removeTags []string ) cmd := &sink.Command{ Use: "edit [flags] ", Short: "Edit decision logs.", Flags: []*rags.Rag{ dirFlag(&dir), templateFlag(&template), { Name: "add-tags", Value: &rags.StringSet{Var: &addTags}, Usage: "Comma separated list of tags to apply to dlog. Can be provided multiple times.", }, { Name: "remove-tags", Value: &rags.StringSet{Var: &removeTags}, Usage: "Comma separated list of tags to remove from dlog. Can be provided multiple times.", }, { Name: "status", Value: &rags.String{Var: &status}, Usage: "New dlog status", }, }, Exec: func(_ context.Context, r sink.Run) error { if len(r.Args()) != 1 { return fmt.Errorf("a name for the decision log file is required") } if len(addTags) == 0 && status == "" && len(removeTags) == 0 { return fmt.Errorf("at least one edit is required") } p := filepath.Join(dir, r.Args()[0]) d, err := dlog.FromMarkdown(p) if err != nil { return err } if len(removeTags) > 0 { n := 0 for _, t := range d.Tags { if !slices.Contains(removeTags, t) { d.Tags[n] = t n++ } } d.Tags = d.Tags[:n] } if len(addTags) > 0 { d.Tags = append(d.Tags, addTags...) slices.Sort(d.Tags) d.Tags = slices.Compact(d.Tags) } if status != "" { d.Status = status } // Always update date since we modified the log. d.Date.Time = time.Now() return dlog.ToMarkdown(d, dir) }, } return cmd }