1package boardcmd
2
3import (
4 "fmt"
5 "strconv"
6
7 "github.com/spf13/cobra"
8
9 "github.com/git-bug/git-bug/cache"
10 buginput "github.com/git-bug/git-bug/commands/bug/input"
11 "github.com/git-bug/git-bug/commands/execenv"
12 _select "github.com/git-bug/git-bug/commands/select"
13 "github.com/git-bug/git-bug/entity"
14)
15
16type boardAddDraftOptions struct {
17 title string
18 messageFile string
19 message string
20 column string
21 nonInteractive bool
22}
23
24func newBoardAddDraftCommand() *cobra.Command {
25 env := execenv.NewEnv()
26 options := boardAddDraftOptions{}
27
28 cmd := &cobra.Command{
29 Use: "add-draft [BOARD_ID]",
30 Short: "Add a draft item to a board",
31 PreRunE: execenv.LoadBackend(env),
32 RunE: execenv.CloseBackend(env, func(cmd *cobra.Command, args []string) error {
33 return runBoardAddDraft(env, options, args)
34 }),
35 ValidArgsFunction: BoardCompletion(env),
36 }
37
38 flags := cmd.Flags()
39 flags.SortFlags = false
40
41 flags.StringVarP(&options.title, "title", "t", "",
42 "Provide the title to describe the draft item")
43 flags.StringVarP(&options.message, "message", "m", "",
44 "Provide the message of the draft item")
45 flags.StringVarP(&options.messageFile, "file", "F", "",
46 "Take the message from the given file. Use - to read the message from the standard input")
47 flags.StringVarP(&options.column, "column", "c", "1",
48 "The column to add to. Either a column Id or prefix, or the column number starting from 1.")
49 _ = cmd.RegisterFlagCompletionFunc("column", ColumnCompletion(env))
50 flags.BoolVar(&options.nonInteractive, "non-interactive", false, "Do not ask for user input")
51
52 return cmd
53}
54
55func runBoardAddDraft(env *execenv.Env, opts boardAddDraftOptions, args []string) error {
56 b, columnId, err := resolveColumnId(env, opts.column, args)
57 if err != nil {
58 return err
59 }
60
61 if opts.messageFile != "" && opts.message == "" {
62 // Note: reuse the bug inputs
63 opts.title, opts.message, err = buginput.BugCreateFileInput(opts.messageFile)
64 if err != nil {
65 return err
66 }
67 }
68
69 if !opts.nonInteractive && opts.messageFile == "" && (opts.message == "" || opts.title == "") {
70 opts.title, opts.message, err = buginput.BugCreateEditorInput(env.Backend, opts.title, opts.message)
71 if err == buginput.ErrEmptyTitle {
72 env.Out.Println("Empty title, aborting.")
73 return nil
74 }
75 if err != nil {
76 return err
77 }
78 }
79
80 id, _, err := b.AddItemDraft(columnId, opts.title, opts.message, nil)
81 if err != nil {
82 return err
83 }
84
85 env.Out.Printf("%s created\n", id.Human())
86
87 return b.Commit()
88}
89
90func resolveColumnId(env *execenv.Env, column string, args []string) (*cache.BoardCache, entity.CombinedId, error) {
91 if column == "" {
92 return nil, entity.UnsetCombinedId, fmt.Errorf("flag --column is required")
93 }
94
95 b, args, err := ResolveSelected(env.Backend, args)
96
97 switch {
98 case err == nil:
99 // we have a pre-selected board, try to parse as column number
100 index, err := strconv.Atoi(column)
101 if err == nil && index-1 >= 0 && index-1 < len(b.Snapshot().Columns) {
102 return b, b.Snapshot().Columns[index-1].CombinedId, nil
103 }
104 fallthrough // could be an Id
105 case _select.IsErrNoValidId(err):
106 return env.Backend.Boards().ResolveColumn(column)
107
108 default:
109 // actual error
110 return nil, entity.UnsetCombinedId, err
111 }
112}