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 // TODO: editor with single line, no message
62
63 if opts.messageFile != "" && opts.message == "" {
64 // Note: reuse the bug inputs
65 opts.title, opts.message, err = buginput.BugCreateFileInput(opts.messageFile)
66 if err != nil {
67 return err
68 }
69 }
70
71 if !opts.nonInteractive && opts.messageFile == "" && (opts.message == "" || opts.title == "") {
72 opts.title, opts.message, err = buginput.BugCreateEditorInput(env.Backend, opts.title, opts.message)
73 if err == buginput.ErrEmptyTitle {
74 env.Out.Println("Empty title, aborting.")
75 return nil
76 }
77 if err != nil {
78 return err
79 }
80 }
81
82 id, _, err := b.AddItemDraft(columnId, opts.title)
83 if err != nil {
84 return err
85 }
86
87 env.Out.Printf("%s created\n", id.Human())
88
89 return b.Commit()
90}
91
92func resolveColumnId(env *execenv.Env, column string, args []string) (*cache.BoardCache, entity.CombinedId, error) {
93 if column == "" {
94 return nil, entity.UnsetCombinedId, fmt.Errorf("flag --column is required")
95 }
96
97 b, args, err := ResolveSelected(env.Backend, args)
98
99 switch {
100 case err == nil:
101 // we have a pre-selected board, try to parse as column number
102 index, err := strconv.Atoi(column)
103 if err == nil && index-1 >= 0 && index-1 < len(b.Snapshot().Columns) {
104 return b, b.Snapshot().Columns[index-1].CombinedId, nil
105 }
106 fallthrough // could be an Id
107 case _select.IsErrNoValidId(err):
108 return env.Backend.Boards().ResolveColumn(column)
109
110 default:
111 // actual error
112 return nil, entity.UnsetCombinedId, err
113 }
114}