board_adddraft.go

  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}