package cmd import ( "axolotl/models" "axolotl/output" "axolotl/service" "fmt" "os" "slices" "github.com/spf13/cobra" ) var ( uTitle, uContent, uDue string uClearDue bool uAddTags, uRmTags, uAddRels, uRmRels []string ) var updateCmd = &cobra.Command{ Use: "update ", Short: "Update a node", Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { svc, err := service.GetNodeService(cfg) if err != nil { fmt.Fprintln(os.Stderr, err) return } node, err := svc.GetByID(args[0]) if err != nil { fmt.Fprintln(os.Stderr, "node not found:", args[0]) return } // parse relations addRels, rmRels := make(map[models.RelType][]string), make(map[models.RelType][]string) parseRel := func(src []string, dst map[models.RelType][]string) bool { for _, r := range src { rel, err := parseRelFlag(svc, r) if err != nil { fmt.Fprintln(os.Stderr, err) return false } dst[rel.Type] = append(dst[rel.Type], rel.Target) } return true } if !parseRel(uAddRels, addRels) || !parseRel(uRmRels, rmRels) { return } // enforce blocking of tasks //TODO: mabye part of the backend? if slices.Contains(uAddTags, "_status::done") { ok, blockers, err := svc.CanClose(args[0]) if err != nil { fmt.Fprintln(os.Stderr, "failed to check blockers:", err) return } if !ok { fmt.Fprintf(os.Stderr, "cannot close: blocked by %v\n", blockers) return } } // update main fields if cmd.Flags().Changed("title") { node.Title = uTitle } if cmd.Flags().Changed("content") { node.Content = uContent } if cmd.Flags().Changed("due") { node.DueDate = uDue } if uClearDue { node.DueDate = "" } // udpate tags for _, t := range uRmTags { if err := node.RemoveTag(t); err != nil { fmt.Fprintln(os.Stderr, "failed to remove tag:", err) return } } for _, t := range uAddTags { node.AddTag(t) } // update relations for rt, tgts := range rmRels { for _, tgt := range tgts { if err := node.RemoveRelation(rt, tgt); err != nil { fmt.Fprintln(os.Stderr, "failed to remove relation:", err) return } } } for rt, tgts := range addRels { for _, tgt := range tgts { node.AddRelation(rt, tgt) } } // persist update if err := svc.Update(node); err != nil { fmt.Fprintln(os.Stderr, "failed to update:", err) return } if n, err := svc.GetByID(args[0]); err == nil { output.PrintNode(cmd.OutOrStdout(), svc, n, jsonFlag) } else { fmt.Fprintln(os.Stderr, "failed to fetch node:", err) } }, } func init() { rootCmd.AddCommand(updateCmd) addPropertyFlags(updateCmd) f := updateCmd.Flags() f.StringVar(&uTitle, "title", "", "") f.StringVar(&uContent, "content", "", "") f.StringVar(&uDue, "due", "", "") f.BoolVar(&uClearDue, "clear-due", false, "") f.StringArrayVar(&uAddTags, "tag", nil, "") f.StringArrayVar(&uRmTags, "tag-remove", nil, "") f.StringArrayVar(&uAddRels, "rel", nil, "") f.StringArrayVar(&uRmRels, "rel-remove", nil, "") }