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	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}