Detailed changes
@@ -3,10 +3,10 @@ package cache
import (
"time"
- "github.com/MichaelMure/git-bug/entities/board"
- "github.com/MichaelMure/git-bug/entities/identity"
- "github.com/MichaelMure/git-bug/entity"
- "github.com/MichaelMure/git-bug/repository"
+ "github.com/git-bug/git-bug/entities/board"
+ "github.com/git-bug/git-bug/entities/identity"
+ "github.com/git-bug/git-bug/entity"
+ "github.com/git-bug/git-bug/repository"
)
// BoardCache is a wrapper around a Board. It provides multiple functions:
@@ -4,8 +4,8 @@ import (
"encoding/gob"
"time"
- "github.com/MichaelMure/git-bug/entity"
- "github.com/MichaelMure/git-bug/util/lamport"
+ "github.com/git-bug/git-bug/entity"
+ "github.com/git-bug/git-bug/util/lamport"
)
// Package initialisation used to register the type for (de)serialization
@@ -25,10 +25,10 @@ type BoardExcerpt struct {
CreateUnixTime int64
EditUnixTime int64
- Title string
- Description string
- ItemCount int
- Actors []entity.Id
+ Title string
+ Description string
+ ItemCount int
+ Participants []entity.Id
CreateMetadata map[string]string
}
@@ -36,9 +36,9 @@ type BoardExcerpt struct {
func NewBoardExcerpt(b *BoardCache) *BoardExcerpt {
snap := b.Snapshot()
- actorsIds := make([]entity.Id, 0, len(snap.Actors))
- for _, actor := range snap.Actors {
- actorsIds = append(actorsIds, actor.Id())
+ participantsIds := make([]entity.Id, 0, len(snap.Participants))
+ for _, participant := range snap.Participants {
+ participantsIds = append(participantsIds, participant.Id())
}
return &BoardExcerpt{
@@ -50,7 +50,7 @@ func NewBoardExcerpt(b *BoardCache) *BoardExcerpt {
Title: snap.Title,
Description: snap.Description,
ItemCount: snap.ItemCount(),
- Actors: actorsIds,
+ Participants: participantsIds,
CreateMetadata: b.FirstOp().AllMetadata(),
}
}
@@ -3,10 +3,10 @@ package cache
import (
"time"
- "github.com/MichaelMure/git-bug/entities/board"
- "github.com/MichaelMure/git-bug/entities/identity"
- "github.com/MichaelMure/git-bug/entity"
- "github.com/MichaelMure/git-bug/repository"
+ "github.com/git-bug/git-bug/entities/board"
+ "github.com/git-bug/git-bug/entities/identity"
+ "github.com/git-bug/git-bug/entity"
+ "github.com/git-bug/git-bug/repository"
)
type RepoCacheBoard struct {
@@ -0,0 +1,145 @@
+package boardcmd
+
+import (
+ "fmt"
+ "strings"
+
+ text "github.com/MichaelMure/go-term-text"
+ "github.com/spf13/cobra"
+
+ "github.com/git-bug/git-bug/cache"
+ "github.com/git-bug/git-bug/commands/cmdjson"
+ "github.com/git-bug/git-bug/commands/completion"
+ "github.com/git-bug/git-bug/commands/execenv"
+ "github.com/git-bug/git-bug/util/colors"
+)
+
+type boardOptions struct {
+ metadataQuery []string
+ actorQuery []string
+ titleQuery []string
+ outputFormat string
+}
+
+func NewBoardCommand() *cobra.Command {
+ env := execenv.NewEnv()
+ options := boardOptions{}
+
+ cmd := &cobra.Command{
+ Use: "board",
+ Short: "List boards",
+ PreRunE: execenv.LoadBackend(env),
+ RunE: execenv.CloseBackend(env, func(cmd *cobra.Command, args []string) error {
+ return runBoard(env, options, args)
+ }),
+ }
+
+ flags := cmd.Flags()
+ flags.SortFlags = false
+
+ flags.StringSliceVarP(&options.metadataQuery, "metadata", "m", nil,
+ "Filter by metadata. Example: github-url=URL")
+ cmd.RegisterFlagCompletionFunc("author", completion.UserForQuery(env))
+ flags.StringSliceVarP(&options.actorQuery, "actor", "A", nil,
+ "Filter by actor")
+ cmd.RegisterFlagCompletionFunc("actor", completion.UserForQuery(env))
+ flags.StringSliceVarP(&options.titleQuery, "title", "t", nil,
+ "Filter by title")
+ flags.StringVarP(&options.outputFormat, "format", "f", "default",
+ "Select the output formatting style. Valid values are [default,plain,compact,id,json,org-mode]")
+ cmd.RegisterFlagCompletionFunc("format",
+ completion.From([]string{"default", "id", "json"}))
+
+ const selectGroup = "select"
+ cmd.AddGroup(&cobra.Group{ID: selectGroup, Title: "Implicit selection"})
+
+ addCmdWithGroup := func(child *cobra.Command, groupID string) {
+ cmd.AddCommand(child)
+ child.GroupID = groupID
+ }
+
+ addCmdWithGroup(newBoardDeselectCommand(), selectGroup)
+ addCmdWithGroup(newBoardSelectCommand(), selectGroup)
+
+ cmd.AddCommand(newBoardNewCommand())
+ cmd.AddCommand(newBoardRmCommand())
+ cmd.AddCommand(newBoardShowCommand())
+ cmd.AddCommand(newBoardDescriptionCommand())
+ cmd.AddCommand(newBoardTitleCommand())
+ cmd.AddCommand(newBoardAddDraftCommand())
+
+ return cmd
+}
+
+func runBoard(env *execenv.Env, opts boardOptions, args []string) error {
+ // TODO: query
+
+ allIds := env.Backend.Boards().AllIds()
+
+ excerpts := make([]*cache.BoardExcerpt, len(allIds))
+ for i, id := range allIds {
+ b, err := env.Backend.Boards().ResolveExcerpt(id)
+ if err != nil {
+ return err
+ }
+ excerpts[i] = b
+ }
+
+ switch opts.outputFormat {
+ case "json":
+ return boardJsonFormatter(env, excerpts)
+ case "id":
+ return boardIDFormatter(env, excerpts)
+ case "default":
+ return boardDefaultFormatter(env, excerpts)
+ default:
+ return fmt.Errorf("unknown format %s", opts.outputFormat)
+ }
+}
+
+func boardIDFormatter(env *execenv.Env, excerpts []*cache.BoardExcerpt) error {
+ for _, b := range excerpts {
+ env.Out.Println(b.Id().String())
+ }
+
+ return nil
+}
+
+func boardDefaultFormatter(env *execenv.Env, excerpts []*cache.BoardExcerpt) error {
+ for _, b := range excerpts {
+ // truncate + pad if needed
+ titleFmt := text.LeftPadMaxLine(strings.TrimSpace(b.Title), 50, 0)
+ descFmt := text.LeftPadMaxLine(strings.TrimSpace(b.Description), 50, 0)
+
+ var itemFmt string
+ switch {
+ case b.ItemCount < 1:
+ itemFmt = "empty"
+ case b.ItemCount < 1000:
+ itemFmt = fmt.Sprintf("%3d 📝", b.ItemCount)
+ default:
+ itemFmt = " ∞ 📝"
+
+ }
+
+ env.Out.Printf("%s\t%s\t%s\t%s\n",
+ colors.Cyan(b.Id().Human()),
+ titleFmt,
+ descFmt,
+ itemFmt,
+ )
+ }
+ return nil
+}
+
+func boardJsonFormatter(env *execenv.Env, excerpts []*cache.BoardExcerpt) error {
+ res := make([]cmdjson.BoardExcerpt, len(excerpts))
+ for i, b := range excerpts {
+ jsonBoard, err := cmdjson.NewBoardExcerpt(env.Backend, b)
+ if err != nil {
+ return err
+ }
+ res[i] = jsonBoard
+ }
+ return env.Out.PrintJSON(res)
+}
@@ -0,0 +1,96 @@
+package boardcmd
+
+import (
+ "strconv"
+
+ "github.com/spf13/cobra"
+
+ buginput "github.com/git-bug/git-bug/commands/bug/input"
+ "github.com/git-bug/git-bug/commands/execenv"
+ "github.com/git-bug/git-bug/entity"
+)
+
+type boardAddDraftOptions struct {
+ title string
+ messageFile string
+ message string
+ column string
+ nonInteractive bool
+}
+
+func newBoardAddDraftCommand() *cobra.Command {
+ env := execenv.NewEnv()
+ options := boardAddDraftOptions{}
+
+ cmd := &cobra.Command{
+ Use: "add-draft [BOARD_ID]",
+ Short: "Add a draft item to a board",
+ PreRunE: execenv.LoadBackend(env),
+ RunE: execenv.CloseBackend(env, func(cmd *cobra.Command, args []string) error {
+ return runBoardAddDraft(env, options, args)
+ }),
+ ValidArgsFunction: BoardCompletion(env),
+ }
+
+ flags := cmd.Flags()
+ flags.SortFlags = false
+
+ flags.StringVarP(&options.title, "title", "t", "",
+ "Provide the title to describe the draft item")
+ flags.StringVarP(&options.message, "message", "m", "",
+ "Provide the message of the draft item")
+ flags.StringVarP(&options.messageFile, "file", "F", "",
+ "Take the message from the given file. Use - to read the message from the standard input")
+ flags.StringVarP(&options.column, "column", "c", "1",
+ "The column to add to. Either a column Id or prefix, or the column number starting from 1.")
+ // _ = cmd.MarkFlagRequired("column")
+ _ = cmd.RegisterFlagCompletionFunc("column", ColumnCompletion(env))
+ flags.BoolVar(&options.nonInteractive, "non-interactive", false, "Do not ask for user input")
+
+ return cmd
+}
+
+func runBoardAddDraft(env *execenv.Env, opts boardAddDraftOptions, args []string) error {
+ b, args, err := ResolveSelected(env.Backend, args)
+ if err != nil {
+ return err
+ }
+
+ var columnId entity.Id
+
+ index, err := strconv.Atoi(opts.column)
+ if err == nil && index-1 >= 0 && index-1 < len(b.Snapshot().Columns) {
+ columnId = b.Snapshot().Columns[index-1].Id
+ } else {
+ // TODO: ID or combined ID?
+ // TODO: resolve
+ }
+
+ if opts.messageFile != "" && opts.message == "" {
+ // Note: reuse the bug inputs
+ opts.title, opts.message, err = buginput.BugCreateFileInput(opts.messageFile)
+ if err != nil {
+ return err
+ }
+ }
+
+ if !opts.nonInteractive && opts.messageFile == "" && (opts.message == "" || opts.title == "") {
+ opts.title, opts.message, err = buginput.BugCreateEditorInput(env.Backend, opts.title, opts.message)
+ if err == buginput.ErrEmptyTitle {
+ env.Out.Println("Empty title, aborting.")
+ return nil
+ }
+ if err != nil {
+ return err
+ }
+ }
+
+ id, _, err := b.AddItemDraft(columnId, opts.title, opts.message, nil)
+ if err != nil {
+ return err
+ }
+
+ env.Out.Printf("%s created\n", id.Human())
+
+ return b.Commit()
+}
@@ -0,0 +1,38 @@
+package boardcmd
+
+import (
+ "github.com/spf13/cobra"
+
+ "github.com/git-bug/git-bug/commands/execenv"
+)
+
+func newBoardDescriptionCommand() *cobra.Command {
+ env := execenv.NewEnv()
+
+ cmd := &cobra.Command{
+ Use: "description [BOARD_ID]",
+ Short: "Display the description of a board",
+ PreRunE: execenv.LoadBackend(env),
+ RunE: execenv.CloseBackend(env, func(cmd *cobra.Command, args []string) error {
+ return runBoardDescription(env, args)
+ }),
+ ValidArgsFunction: BoardCompletion(env),
+ }
+
+ cmd.AddCommand(newBoardDescriptionEditCommand())
+
+ return cmd
+}
+
+func runBoardDescription(env *execenv.Env, args []string) error {
+ b, args, err := ResolveSelected(env.Backend, args)
+ if err != nil {
+ return err
+ }
+
+ snap := b.Snapshot()
+
+ env.Out.Println(snap.Description)
+
+ return nil
+}
@@ -0,0 +1,70 @@
+package boardcmd
+
+import (
+ "github.com/spf13/cobra"
+
+ "github.com/git-bug/git-bug/commands/execenv"
+ "github.com/git-bug/git-bug/commands/input"
+ "github.com/git-bug/git-bug/util/text"
+)
+
+type boardDescriptionEditOptions struct {
+ description string
+ nonInteractive bool
+}
+
+func newBoardDescriptionEditCommand() *cobra.Command {
+ env := execenv.NewEnv()
+ options := boardDescriptionEditOptions{}
+
+ cmd := &cobra.Command{
+ Use: "edit [BUG_ID]",
+ Short: "Edit a description of a board",
+ PreRunE: execenv.LoadBackendEnsureUser(env),
+ RunE: execenv.CloseBackend(env, func(cmd *cobra.Command, args []string) error {
+ return runBugDescriptionEdit(env, options, args)
+ }),
+ ValidArgsFunction: BoardCompletion(env),
+ }
+
+ flags := cmd.Flags()
+ flags.SortFlags = false
+
+ flags.StringVarP(&options.description, "description", "t", "",
+ "Provide a description for the board",
+ )
+ flags.BoolVar(&options.nonInteractive, "non-interactive", false, "Do not ask for user input")
+
+ return cmd
+}
+
+func runBugDescriptionEdit(env *execenv.Env, opts boardDescriptionEditOptions, args []string) error {
+ b, args, err := ResolveSelected(env.Backend, args)
+ if err != nil {
+ return err
+ }
+
+ snap := b.Snapshot()
+
+ if opts.description == "" {
+ if opts.nonInteractive {
+ env.Err.Println("No description given. Aborting.")
+ return nil
+ }
+ opts.description, err = input.PromptDefault("Board description", "description", snap.Description, input.Required)
+ if err != nil {
+ return err
+ }
+ }
+
+ if opts.description == snap.Description {
+ env.Err.Println("No change, aborting.")
+ }
+
+ _, err = b.SetDescription(text.CleanupOneLine(opts.description))
+ if err != nil {
+ return err
+ }
+
+ return b.Commit()
+}
@@ -0,0 +1,34 @@
+package boardcmd
+
+import (
+ "github.com/spf13/cobra"
+
+ "github.com/git-bug/git-bug/commands/execenv"
+ _select "github.com/git-bug/git-bug/commands/select"
+ "github.com/git-bug/git-bug/entities/board"
+)
+
+func newBoardDeselectCommand() *cobra.Command {
+ env := execenv.NewEnv()
+
+ cmd := &cobra.Command{
+ Use: "deselect",
+ Short: "Clear the implicitly selected board",
+
+ PreRunE: execenv.LoadBackend(env),
+ RunE: execenv.CloseBackend(env, func(cmd *cobra.Command, args []string) error {
+ return runBoardDeselect(env)
+ }),
+ }
+
+ return cmd
+}
+
+func runBoardDeselect(env *execenv.Env) error {
+ err := _select.Clear(env.Backend, board.Namespace)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
@@ -0,0 +1,83 @@
+package boardcmd
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/spf13/cobra"
+
+ "github.com/git-bug/git-bug/commands/execenv"
+ "github.com/git-bug/git-bug/commands/input"
+ "github.com/git-bug/git-bug/entities/board"
+ "github.com/git-bug/git-bug/util/text"
+)
+
+type boardNewOptions struct {
+ title string
+ description string
+ columns []string
+ nonInteractive bool
+}
+
+func newBoardNewCommand() *cobra.Command {
+ env := execenv.NewEnv()
+ options := boardNewOptions{}
+
+ cmd := &cobra.Command{
+ Use: "new",
+ Short: "Create a new board",
+ PreRunE: execenv.LoadBackendEnsureUser(env),
+ RunE: execenv.CloseBackend(env, func(cmd *cobra.Command, args []string) error {
+ return runBugNew(env, options)
+ }),
+ }
+
+ flags := cmd.Flags()
+ flags.SortFlags = false
+
+ flags.StringVarP(&options.title, "title", "t", "",
+ "Provide a title to describe the issue")
+ flags.StringVarP(&options.description, "description", "d", "",
+ "Provide a message to describe the board")
+ flags.StringArrayVarP(&options.columns, "columns", "c", board.DefaultColumns,
+ fmt.Sprintf("Define the columns of the board (default to %s)",
+ strings.Join(board.DefaultColumns, ",")))
+ flags.BoolVar(&options.nonInteractive, "non-interactive", false, "Do not ask for user input")
+
+ return cmd
+}
+
+func runBugNew(env *execenv.Env, opts boardNewOptions) error {
+ var err error
+
+ if !opts.nonInteractive && opts.title == "" {
+ opts.title, err = input.Prompt("Board title", "title", input.Required)
+ if err != nil {
+ return err
+ }
+ }
+
+ if !opts.nonInteractive && opts.description == "" {
+ opts.description, err = input.Prompt("Board description", "description")
+ if err != nil {
+ return err
+ }
+ }
+
+ for i, column := range opts.columns {
+ opts.columns[i] = text.Cleanup(column)
+ }
+
+ b, _, err := env.Backend.Boards().New(
+ text.CleanupOneLine(opts.title),
+ text.CleanupOneLine(opts.description),
+ opts.columns,
+ )
+ if err != nil {
+ return err
+ }
+
+ env.Out.Printf("%s created\n", b.Id().Human())
+
+ return nil
+}
@@ -0,0 +1,45 @@
+package boardcmd
+
+import (
+ "errors"
+
+ "github.com/spf13/cobra"
+
+ "github.com/git-bug/git-bug/commands/execenv"
+)
+
+func newBoardRmCommand() *cobra.Command {
+ env := execenv.NewEnv()
+
+ cmd := &cobra.Command{
+ Use: "rm BOARD_ID",
+ Short: "Remove an existing board",
+ Long: "Remove an existing board in the local repository.",
+ PreRunE: execenv.LoadBackendEnsureUser(env),
+ RunE: execenv.CloseBackend(env, func(cmd *cobra.Command, args []string) error {
+ return runBoardRm(env, args)
+ }),
+ ValidArgsFunction: BoardCompletion(env),
+ }
+
+ flags := cmd.Flags()
+ flags.SortFlags = false
+
+ return cmd
+}
+
+func runBoardRm(env *execenv.Env, args []string) (err error) {
+ if len(args) == 0 {
+ return errors.New("you must provide a board prefix to remove")
+ }
+
+ err = env.Backend.Boards().Remove(args[0])
+
+ if err != nil {
+ return
+ }
+
+ env.Out.Printf("board %s removed\n", args[0])
+
+ return
+}
@@ -0,0 +1,58 @@
+package boardcmd
+
+import (
+ "errors"
+
+ "github.com/spf13/cobra"
+
+ "github.com/git-bug/git-bug/cache"
+ "github.com/git-bug/git-bug/commands/execenv"
+ _select "github.com/git-bug/git-bug/commands/select"
+ "github.com/git-bug/git-bug/entities/board"
+)
+
+func ResolveSelected(repo *cache.RepoCache, args []string) (*cache.BoardCache, []string, error) {
+ return _select.Resolve[*cache.BoardCache](repo, board.Typename, board.Namespace, repo.Boards(), args)
+}
+
+func newBoardSelectCommand() *cobra.Command {
+ env := execenv.NewEnv()
+
+ cmd := &cobra.Command{
+ Use: "select BOARD_ID",
+ Short: "Select a board for implicit use in future commands",
+ Long: `Select a board for implicit use in future commands.
+
+The complementary command is "git board deselect" performing the opposite operation.
+`,
+ PreRunE: execenv.LoadBackend(env),
+ RunE: execenv.CloseBackend(env, func(cmd *cobra.Command, args []string) error {
+ return runBoardSelect(env, args)
+ }),
+ ValidArgsFunction: BoardCompletion(env),
+ }
+
+ return cmd
+}
+
+func runBoardSelect(env *execenv.Env, args []string) error {
+ if len(args) == 0 {
+ return errors.New("You must provide a board id")
+ }
+
+ prefix := args[0]
+
+ b, err := env.Backend.Boards().ResolvePrefix(prefix)
+ if err != nil {
+ return err
+ }
+
+ err = _select.Select(env.Backend, board.Namespace, b.Id())
+ if err != nil {
+ return err
+ }
+
+ env.Out.Printf("selected board %s: %s\n", b.Id().Human(), b.Snapshot().Title)
+
+ return nil
+}
@@ -0,0 +1,136 @@
+package boardcmd
+
+import (
+ "fmt"
+
+ "github.com/spf13/cobra"
+
+ "github.com/git-bug/git-bug/commands/cmdjson"
+ "github.com/git-bug/git-bug/commands/execenv"
+ "github.com/git-bug/git-bug/entities/board"
+)
+
+type boardShowOptions struct {
+ format string
+}
+
+func newBoardShowCommand() *cobra.Command {
+ env := execenv.NewEnv()
+ options := boardShowOptions{}
+
+ cmd := &cobra.Command{
+ Use: "show [BOARD_ID]",
+ Short: "Display a board",
+ PreRunE: execenv.LoadBackend(env),
+ RunE: execenv.CloseBackend(env, func(cmd *cobra.Command, args []string) error {
+ return runBoardShow(env, options, args)
+ }),
+ ValidArgsFunction: BoardCompletion(env),
+ }
+
+ flags := cmd.Flags()
+ flags.SortFlags = false
+
+ flags.StringVarP(&options.format, "format", "f", "default",
+ "Select the output formatting style. Valid values are [default,json,org-mode]")
+
+ return cmd
+}
+
+func runBoardShow(env *execenv.Env, opts boardShowOptions, args []string) error {
+ b, args, err := ResolveSelected(env.Backend, args)
+ if err != nil {
+ return err
+ }
+
+ snap := b.Snapshot()
+
+ switch opts.format {
+ case "json":
+ return showJsonFormatter(env, snap)
+ case "default":
+ return showDefaultFormatter(env, snap)
+ default:
+ return fmt.Errorf("unknown format %s", opts.format)
+ }
+}
+
+func showDefaultFormatter(env *execenv.Env, snapshot *board.Snapshot) error {
+ // // Header
+ // env.Out.Printf("%s [%s] %s\n\n",
+ // colors.Cyan(snapshot.Id().Human()),
+ // colors.Yellow(snapshot.Status),
+ // snapshot.Title,
+ // )
+ //
+ // env.Out.Printf("%s opened this issue %s\n",
+ // colors.Magenta(snapshot.Author.DisplayName()),
+ // snapshot.CreateTime.String(),
+ // )
+ //
+ // env.Out.Printf("This was last edited at %s\n\n",
+ // snapshot.EditTime().String(),
+ // )
+ //
+ // // Labels
+ // var labels = make([]string, len(snapshot.Labels))
+ // for i := range snapshot.Labels {
+ // labels[i] = string(snapshot.Labels[i])
+ // }
+ //
+ // env.Out.Printf("labels: %s\n",
+ // strings.Join(labels, ", "),
+ // )
+ //
+ // // Actors
+ // var actors = make([]string, len(snapshot.Actors))
+ // for i := range snapshot.Actors {
+ // actors[i] = snapshot.Actors[i].DisplayName()
+ // }
+ //
+ // env.Out.Printf("actors: %s\n",
+ // strings.Join(actors, ", "),
+ // )
+ //
+ // // Participants
+ // var participants = make([]string, len(snapshot.Participants))
+ // for i := range snapshot.Participants {
+ // participants[i] = snapshot.Participants[i].DisplayName()
+ // }
+ //
+ // env.Out.Printf("participants: %s\n\n",
+ // strings.Join(participants, ", "),
+ // )
+ //
+ // // Comments
+ // indent := " "
+ //
+ // for i, comment := range snapshot.Comments {
+ // var message string
+ // env.Out.Printf("%s%s #%d %s <%s>\n\n",
+ // indent,
+ // comment.CombinedId().Human(),
+ // i,
+ // comment.Author.DisplayName(),
+ // comment.Author.Email(),
+ // )
+ //
+ // if comment.Message == "" {
+ // message = colors.BlackBold(colors.WhiteBg("No description provided."))
+ // } else {
+ // message = comment.Message
+ // }
+ //
+ // env.Out.Printf("%s%s\n\n\n",
+ // indent,
+ // message,
+ // )
+ // }
+
+ return nil
+}
+
+func showJsonFormatter(env *execenv.Env, snap *board.Snapshot) error {
+ jsonBoard := cmdjson.NewBoardSnapshot(snap)
+ return env.Out.PrintJSON(jsonBoard)
+}
@@ -0,0 +1,38 @@
+package boardcmd
+
+import (
+ "github.com/spf13/cobra"
+
+ "github.com/git-bug/git-bug/commands/execenv"
+)
+
+func newBoardTitleCommand() *cobra.Command {
+ env := execenv.NewEnv()
+
+ cmd := &cobra.Command{
+ Use: "title [BOARD_ID]",
+ Short: "Display the title of a board",
+ PreRunE: execenv.LoadBackend(env),
+ RunE: execenv.CloseBackend(env, func(cmd *cobra.Command, args []string) error {
+ return runBoardTitle(env, args)
+ }),
+ ValidArgsFunction: BoardCompletion(env),
+ }
+
+ cmd.AddCommand(newBoardTitleEditCommand())
+
+ return cmd
+}
+
+func runBoardTitle(env *execenv.Env, args []string) error {
+ b, args, err := ResolveSelected(env.Backend, args)
+ if err != nil {
+ return err
+ }
+
+ snap := b.Snapshot()
+
+ env.Out.Println(snap.Title)
+
+ return nil
+}
@@ -0,0 +1,70 @@
+package boardcmd
+
+import (
+ "github.com/spf13/cobra"
+
+ "github.com/git-bug/git-bug/commands/execenv"
+ "github.com/git-bug/git-bug/commands/input"
+ "github.com/git-bug/git-bug/util/text"
+)
+
+type boardTitleEditOptions struct {
+ title string
+ nonInteractive bool
+}
+
+func newBoardTitleEditCommand() *cobra.Command {
+ env := execenv.NewEnv()
+ options := boardTitleEditOptions{}
+
+ cmd := &cobra.Command{
+ Use: "edit [BUG_ID]",
+ Short: "Edit a title of a board",
+ PreRunE: execenv.LoadBackendEnsureUser(env),
+ RunE: execenv.CloseBackend(env, func(cmd *cobra.Command, args []string) error {
+ return runBugTitleEdit(env, options, args)
+ }),
+ ValidArgsFunction: BoardCompletion(env),
+ }
+
+ flags := cmd.Flags()
+ flags.SortFlags = false
+
+ flags.StringVarP(&options.title, "title", "t", "",
+ "Provide a title to describe the board",
+ )
+ flags.BoolVar(&options.nonInteractive, "non-interactive", false, "Do not ask for user input")
+
+ return cmd
+}
+
+func runBugTitleEdit(env *execenv.Env, opts boardTitleEditOptions, args []string) error {
+ b, args, err := ResolveSelected(env.Backend, args)
+ if err != nil {
+ return err
+ }
+
+ snap := b.Snapshot()
+
+ if opts.title == "" {
+ if opts.nonInteractive {
+ env.Err.Println("No title given. Aborting.")
+ return nil
+ }
+ opts.title, err = input.PromptDefault("Board title", "title", snap.Title, input.Required)
+ if err != nil {
+ return err
+ }
+ }
+
+ if opts.title == snap.Title {
+ env.Err.Println("No change, aborting.")
+ }
+
+ _, err = b.SetTitle(text.CleanupOneLine(opts.title))
+ if err != nil {
+ return err
+ }
+
+ return b.Commit()
+}
@@ -0,0 +1,56 @@
+package boardcmd
+
+import (
+ "strings"
+
+ "github.com/spf13/cobra"
+
+ "github.com/git-bug/git-bug/commands/completion"
+ "github.com/git-bug/git-bug/commands/execenv"
+)
+
+// BoardCompletion complete a board id
+func BoardCompletion(env *execenv.Env) completion.ValidArgsFunction {
+ return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
+ if err := execenv.LoadBackend(env)(cmd, args); err != nil {
+ return completion.HandleError(err)
+ }
+ defer func() {
+ _ = env.Backend.Close()
+ }()
+
+ for _, id := range env.Backend.Boards().AllIds() {
+ if strings.Contains(id.String(), strings.TrimSpace(toComplete)) {
+ excerpt, err := env.Backend.Boards().ResolveExcerpt(id)
+ if err != nil {
+ return completion.HandleError(err)
+ }
+ completions = append(completions, id.Human()+"\t"+excerpt.Title)
+ }
+ }
+
+ return completions, cobra.ShellCompDirectiveNoFileComp
+ }
+}
+
+func ColumnCompletion(env *execenv.Env) completion.ValidArgsFunction {
+ return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
+ if err := execenv.LoadBackend(env)(cmd, args); err != nil {
+ return completion.HandleError(err)
+ }
+ defer func() {
+ _ = env.Backend.Close()
+ }()
+
+ b, _, err := ResolveSelected(env.Backend, args)
+ if err != nil {
+ return completion.HandleError(err)
+ }
+
+ for _, column := range b.Snapshot().Columns {
+ completions = append(completions, column.Id.Human()+"\t"+column.Name)
+ }
+
+ return completions, cobra.ShellCompDirectiveNoFileComp
+ }
+}
@@ -0,0 +1,123 @@
+package cmdjson
+
+import (
+ "github.com/git-bug/git-bug/cache"
+ "github.com/git-bug/git-bug/entities/board"
+)
+
+type BoardSnapshot struct {
+ Id string `json:"id"`
+ HumanId string `json:"human_id"`
+ CreateTime Time `json:"create_time"`
+ EditTime Time `json:"edit_time"`
+
+ Title string `json:"title"`
+ Description string `json:"description"`
+ Participants []Identity `json:"participants"`
+ Columns []BoardColumn `json:"columns"`
+}
+
+func NewBoardSnapshot(snapshot *board.Snapshot) BoardSnapshot {
+ jsonBoard := BoardSnapshot{
+ Id: snapshot.Id().String(),
+ HumanId: snapshot.Id().Human(),
+ CreateTime: NewTime(snapshot.CreateTime, 0),
+ EditTime: NewTime(snapshot.EditTime(), 0),
+ Title: snapshot.Title,
+ Description: snapshot.Description,
+ }
+
+ jsonBoard.Participants = make([]Identity, len(snapshot.Participants))
+ for i, element := range snapshot.Participants {
+ jsonBoard.Participants[i] = NewIdentity(element)
+ }
+
+ jsonBoard.Columns = make([]BoardColumn, len(snapshot.Columns))
+ for i, column := range snapshot.Columns {
+ jsonBoard.Columns[i] = NewBoardColumn(column)
+ }
+
+ return jsonBoard
+}
+
+type BoardColumn struct {
+ Id string `json:"id"`
+ HumanId string `json:"human_id"`
+ Name string `json:"name"`
+ Items []any `json:"items"`
+}
+
+func NewBoardColumn(column *board.Column) BoardColumn {
+ jsonColumn := BoardColumn{
+ Id: column.Id.String(),
+ HumanId: column.Id.Human(),
+ Name: column.Name,
+ }
+ jsonColumn.Items = make([]any, len(column.Items))
+ for j, item := range column.Items {
+ switch item := item.(type) {
+ case *board.Draft:
+ jsonColumn.Items[j] = NewBoardDraftItem(item)
+ case *board.BugItem:
+ jsonColumn.Items[j] = NewBugSnapshot(item.Bug.Compile())
+ default:
+ panic("unknown item type")
+ }
+ }
+ return jsonColumn
+}
+
+type BoardDraftItem struct {
+ Id string `json:"id"`
+ HumanId string `json:"human_id"`
+ Author Identity `json:"author"`
+ Title string `json:"title"`
+ Message string `json:"message"`
+}
+
+func NewBoardDraftItem(item *board.Draft) BoardDraftItem {
+ return BoardDraftItem{
+ Id: item.CombinedId().String(),
+ HumanId: item.CombinedId().Human(),
+ Author: NewIdentity(item.Author),
+ Title: item.Title,
+ Message: item.Message,
+ }
+}
+
+type BoardExcerpt struct {
+ Id string `json:"id"`
+ HumanId string `json:"human_id"`
+ CreateTime Time `json:"create_time"`
+ EditTime Time `json:"edit_time"`
+
+ Title string `json:"title"`
+ Description string `json:"description"`
+ Participants []Identity `json:"participants"`
+
+ Items int `json:"items"`
+ Metadata map[string]string `json:"metadata"`
+}
+
+func NewBoardExcerpt(backend *cache.RepoCache, b *cache.BoardExcerpt) (BoardExcerpt, error) {
+ jsonBoard := BoardExcerpt{
+ Id: b.Id().String(),
+ HumanId: b.Id().Human(),
+ CreateTime: NewTime(b.CreateTime(), b.CreateLamportTime),
+ EditTime: NewTime(b.EditTime(), b.EditLamportTime),
+ Title: b.Title,
+ Description: b.Description,
+ Items: b.ItemCount,
+ Metadata: b.CreateMetadata,
+ }
+
+ jsonBoard.Participants = make([]Identity, len(b.Participants))
+ for i, element := range b.Participants {
+ participant, err := backend.Identities().ResolveExcerpt(element)
+ if err != nil {
+ return BoardExcerpt{}, err
+ }
+ jsonBoard.Participants[i] = NewIdentityFromExcerpt(participant)
+ }
+ return jsonBoard, nil
+}
@@ -5,8 +5,9 @@ import (
"github.com/spf13/cobra"
- "github.com/git-bug/git-bug/commands/bridge"
- "github.com/git-bug/git-bug/commands/bug"
+ boardcmd "github.com/git-bug/git-bug/commands/board"
+ bridgecmd "github.com/git-bug/git-bug/commands/bridge"
+ bugcmd "github.com/git-bug/git-bug/commands/bug"
"github.com/git-bug/git-bug/commands/execenv"
"github.com/git-bug/git-bug/commands/user"
)
@@ -56,6 +57,7 @@ the same git remote you are already using to collaborate with other people.
env := execenv.NewEnv()
+ addCmdWithGroup(boardcmd.NewBoardCommand(), entityGroup)
addCmdWithGroup(bugcmd.NewBugCommand(env), entityGroup)
addCmdWithGroup(usercmd.NewUserCommand(env), entityGroup)
addCmdWithGroup(newLabelCommand(env), entityGroup)
@@ -0,0 +1,42 @@
+.nh
+.TH "GIT-BUG" "1" "Apr 2019" "Generated from git-bug's source code" ""
+
+.SH NAME
+git-bug-board-add-draft - Add a draft item to a board
+
+
+.SH SYNOPSIS
+\fBgit-bug board add-draft [BOARD_ID] [flags]\fP
+
+
+.SH DESCRIPTION
+Add a draft item to a board
+
+
+.SH OPTIONS
+\fB-t\fP, \fB--title\fP=""
+ Provide the title to describe the draft item
+
+.PP
+\fB-m\fP, \fB--message\fP=""
+ Provide the message of the draft item
+
+.PP
+\fB-F\fP, \fB--file\fP=""
+ Take the message from the given file. Use - to read the message from the standard input
+
+.PP
+\fB-c\fP, \fB--column\fP="1"
+ The column to add to. Either a column Id or prefix, or the column number starting from 1.
+
+.PP
+\fB--non-interactive\fP[=false]
+ Do not ask for user input
+
+.PP
+\fB-h\fP, \fB--help\fP[=false]
+ help for add-draft
+
+
+.SH SEE ALSO
+\fBgit-bug-board(1)\fP
@@ -0,0 +1,30 @@
+.nh
+.TH "GIT-BUG" "1" "Apr 2019" "Generated from git-bug's source code" ""
+
+.SH NAME
+git-bug-board-description-edit - Edit a description of a board
+
+
+.SH SYNOPSIS
+\fBgit-bug board description edit [BUG_ID] [flags]\fP
+
+
+.SH DESCRIPTION
+Edit a description of a board
+
+
+.SH OPTIONS
+\fB-t\fP, \fB--description\fP=""
+ Provide a description for the board
+
+.PP
+\fB--non-interactive\fP[=false]
+ Do not ask for user input
+
+.PP
+\fB-h\fP, \fB--help\fP[=false]
+ help for edit
+
+
+.SH SEE ALSO
+\fBgit-bug-board-description(1)\fP
@@ -0,0 +1,22 @@
+.nh
+.TH "GIT-BUG" "1" "Apr 2019" "Generated from git-bug's source code" ""
+
+.SH NAME
+git-bug-board-description - Display the description of a board
+
+
+.SH SYNOPSIS
+\fBgit-bug board description [BOARD_ID] [flags]\fP
+
+
+.SH DESCRIPTION
+Display the description of a board
+
+
+.SH OPTIONS
+\fB-h\fP, \fB--help\fP[=false]
+ help for description
+
+
+.SH SEE ALSO
+\fBgit-bug-board(1)\fP, \fBgit-bug-board-description-edit(1)\fP
@@ -0,0 +1,22 @@
+.nh
+.TH "GIT-BUG" "1" "Apr 2019" "Generated from git-bug's source code" ""
+
+.SH NAME
+git-bug-board-deselect - Clear the implicitly selected board
+
+
+.SH SYNOPSIS
+\fBgit-bug board deselect [flags]\fP
+
+
+.SH DESCRIPTION
+Clear the implicitly selected board
+
+
+.SH OPTIONS
+\fB-h\fP, \fB--help\fP[=false]
+ help for deselect
+
+
+.SH SEE ALSO
+\fBgit-bug-board(1)\fP
@@ -0,0 +1,38 @@
+.nh
+.TH "GIT-BUG" "1" "Apr 2019" "Generated from git-bug's source code" ""
+
+.SH NAME
+git-bug-board-new - Create a new board
+
+
+.SH SYNOPSIS
+\fBgit-bug board new [flags]\fP
+
+
+.SH DESCRIPTION
+Create a new board
+
+
+.SH OPTIONS
+\fB-t\fP, \fB--title\fP=""
+ Provide a title to describe the issue
+
+.PP
+\fB-d\fP, \fB--description\fP=""
+ Provide a message to describe the board
+
+.PP
+\fB-c\fP, \fB--columns\fP=[To Do,In Progress,Done]
+ Define the columns of the board (default to To Do,In Progress,Done)
+
+.PP
+\fB--non-interactive\fP[=false]
+ Do not ask for user input
+
+.PP
+\fB-h\fP, \fB--help\fP[=false]
+ help for new
+
+
+.SH SEE ALSO
+\fBgit-bug-board(1)\fP
@@ -0,0 +1,22 @@
+.nh
+.TH "GIT-BUG" "1" "Apr 2019" "Generated from git-bug's source code" ""
+
+.SH NAME
+git-bug-board-rm - Remove an existing board
+
+
+.SH SYNOPSIS
+\fBgit-bug board rm BOARD_ID [flags]\fP
+
+
+.SH DESCRIPTION
+Remove an existing board in the local repository.
+
+
+.SH OPTIONS
+\fB-h\fP, \fB--help\fP[=false]
+ help for rm
+
+
+.SH SEE ALSO
+\fBgit-bug-board(1)\fP
@@ -0,0 +1,25 @@
+.nh
+.TH "GIT-BUG" "1" "Apr 2019" "Generated from git-bug's source code" ""
+
+.SH NAME
+git-bug-board-select - Select a board for implicit use in future commands
+
+
+.SH SYNOPSIS
+\fBgit-bug board select BOARD_ID [flags]\fP
+
+
+.SH DESCRIPTION
+Select a board for implicit use in future commands.
+
+.PP
+The complementary command is "git board deselect" performing the opposite operation.
+
+
+.SH OPTIONS
+\fB-h\fP, \fB--help\fP[=false]
+ help for select
+
+
+.SH SEE ALSO
+\fBgit-bug-board(1)\fP
@@ -0,0 +1,26 @@
+.nh
+.TH "GIT-BUG" "1" "Apr 2019" "Generated from git-bug's source code" ""
+
+.SH NAME
+git-bug-board-show - Display a board
+
+
+.SH SYNOPSIS
+\fBgit-bug board show [BOARD_ID] [flags]\fP
+
+
+.SH DESCRIPTION
+Display a board
+
+
+.SH OPTIONS
+\fB-f\fP, \fB--format\fP="default"
+ Select the output formatting style. Valid values are [default,json,org-mode]
+
+.PP
+\fB-h\fP, \fB--help\fP[=false]
+ help for show
+
+
+.SH SEE ALSO
+\fBgit-bug-board(1)\fP
@@ -0,0 +1,30 @@
+.nh
+.TH "GIT-BUG" "1" "Apr 2019" "Generated from git-bug's source code" ""
+
+.SH NAME
+git-bug-board-title-edit - Edit a title of a board
+
+
+.SH SYNOPSIS
+\fBgit-bug board title edit [BUG_ID] [flags]\fP
+
+
+.SH DESCRIPTION
+Edit a title of a board
+
+
+.SH OPTIONS
+\fB-t\fP, \fB--title\fP=""
+ Provide a title to describe the board
+
+.PP
+\fB--non-interactive\fP[=false]
+ Do not ask for user input
+
+.PP
+\fB-h\fP, \fB--help\fP[=false]
+ help for edit
+
+
+.SH SEE ALSO
+\fBgit-bug-board-title(1)\fP
@@ -0,0 +1,22 @@
+.nh
+.TH "GIT-BUG" "1" "Apr 2019" "Generated from git-bug's source code" ""
+
+.SH NAME
+git-bug-board-title - Display the title of a board
+
+
+.SH SYNOPSIS
+\fBgit-bug board title [BOARD_ID] [flags]\fP
+
+
+.SH DESCRIPTION
+Display the title of a board
+
+
+.SH OPTIONS
+\fB-h\fP, \fB--help\fP[=false]
+ help for title
+
+
+.SH SEE ALSO
+\fBgit-bug-board(1)\fP, \fBgit-bug-board-title-edit(1)\fP
@@ -0,0 +1,38 @@
+.nh
+.TH "GIT-BUG" "1" "Apr 2019" "Generated from git-bug's source code" ""
+
+.SH NAME
+git-bug-board - List boards
+
+
+.SH SYNOPSIS
+\fBgit-bug board [flags]\fP
+
+
+.SH DESCRIPTION
+List boards
+
+
+.SH OPTIONS
+\fB-m\fP, \fB--metadata\fP=[]
+ Filter by metadata. Example: github-url=URL
+
+.PP
+\fB-A\fP, \fB--actor\fP=[]
+ Filter by actor
+
+.PP
+\fB-t\fP, \fB--title\fP=[]
+ Filter by title
+
+.PP
+\fB-f\fP, \fB--format\fP="default"
+ Select the output formatting style. Valid values are [default,plain,compact,id,json,org-mode]
+
+.PP
+\fB-h\fP, \fB--help\fP[=false]
+ help for board
+
+
+.SH SEE ALSO
+\fBgit-bug(1)\fP, \fBgit-bug-board-add-draft(1)\fP, \fBgit-bug-board-description(1)\fP, \fBgit-bug-board-deselect(1)\fP, \fBgit-bug-board-new(1)\fP, \fBgit-bug-board-rm(1)\fP, \fBgit-bug-board-select(1)\fP, \fBgit-bug-board-show(1)\fP, \fBgit-bug-board-title(1)\fP
@@ -24,4 +24,4 @@ the same git remote you are already using to collaborate with other people.
.SH SEE ALSO
-\fBgit-bug-bridge(1)\fP, \fBgit-bug-bug(1)\fP, \fBgit-bug-label(1)\fP, \fBgit-bug-pull(1)\fP, \fBgit-bug-push(1)\fP, \fBgit-bug-termui(1)\fP, \fBgit-bug-user(1)\fP, \fBgit-bug-version(1)\fP, \fBgit-bug-webui(1)\fP, \fBgit-bug-wipe(1)\fP
+\fBgit-bug-board(1)\fP, \fBgit-bug-bridge(1)\fP, \fBgit-bug-bug(1)\fP, \fBgit-bug-label(1)\fP, \fBgit-bug-pull(1)\fP, \fBgit-bug-push(1)\fP, \fBgit-bug-termui(1)\fP, \fBgit-bug-user(1)\fP, \fBgit-bug-version(1)\fP, \fBgit-bug-webui(1)\fP, \fBgit-bug-wipe(1)\fP
@@ -24,6 +24,7 @@ git-bug [flags]
### SEE ALSO
+* [git-bug board](git-bug_board.md) - List boards
* [git-bug bridge](git-bug_bridge.md) - List bridges to other bug trackers
* [git-bug bug](git-bug_bug.md) - List bugs
* [git-bug label](git-bug_label.md) - List valid labels
@@ -0,0 +1,30 @@
+## git-bug board
+
+List boards
+
+```
+git-bug board [flags]
+```
+
+### Options
+
+```
+ -m, --metadata strings Filter by metadata. Example: github-url=URL
+ -A, --actor strings Filter by actor
+ -t, --title strings Filter by title
+ -f, --format string Select the output formatting style. Valid values are [default,plain,compact,id,json,org-mode] (default "default")
+ -h, --help help for board
+```
+
+### SEE ALSO
+
+* [git-bug](git-bug.md) - A bug tracker embedded in Git
+* [git-bug board add-draft](git-bug_board_add-draft.md) - Add a draft item to a board
+* [git-bug board description](git-bug_board_description.md) - Display the description of a board
+* [git-bug board deselect](git-bug_board_deselect.md) - Clear the implicitly selected board
+* [git-bug board new](git-bug_board_new.md) - Create a new board
+* [git-bug board rm](git-bug_board_rm.md) - Remove an existing board
+* [git-bug board select](git-bug_board_select.md) - Select a board for implicit use in future commands
+* [git-bug board show](git-bug_board_show.md) - Display a board
+* [git-bug board title](git-bug_board_title.md) - Display the title of a board
+
@@ -0,0 +1,23 @@
+## git-bug board add-draft
+
+Add a draft item to a board
+
+```
+git-bug board add-draft [BOARD_ID] [flags]
+```
+
+### Options
+
+```
+ -t, --title string Provide the title to describe the draft item
+ -m, --message string Provide the message of the draft item
+ -F, --file string Take the message from the given file. Use - to read the message from the standard input
+ -c, --column string The column to add to. Either a column Id or prefix, or the column number starting from 1. (default "1")
+ --non-interactive Do not ask for user input
+ -h, --help help for add-draft
+```
+
+### SEE ALSO
+
+* [git-bug board](git-bug_board.md) - List boards
+
@@ -0,0 +1,19 @@
+## git-bug board description
+
+Display the description of a board
+
+```
+git-bug board description [BOARD_ID] [flags]
+```
+
+### Options
+
+```
+ -h, --help help for description
+```
+
+### SEE ALSO
+
+* [git-bug board](git-bug_board.md) - List boards
+* [git-bug board description edit](git-bug_board_description_edit.md) - Edit a description of a board
+
@@ -0,0 +1,20 @@
+## git-bug board description edit
+
+Edit a description of a board
+
+```
+git-bug board description edit [BUG_ID] [flags]
+```
+
+### Options
+
+```
+ -t, --description string Provide a description for the board
+ --non-interactive Do not ask for user input
+ -h, --help help for edit
+```
+
+### SEE ALSO
+
+* [git-bug board description](git-bug_board_description.md) - Display the description of a board
+
@@ -0,0 +1,18 @@
+## git-bug board deselect
+
+Clear the implicitly selected board
+
+```
+git-bug board deselect [flags]
+```
+
+### Options
+
+```
+ -h, --help help for deselect
+```
+
+### SEE ALSO
+
+* [git-bug board](git-bug_board.md) - List boards
+
@@ -0,0 +1,22 @@
+## git-bug board new
+
+Create a new board
+
+```
+git-bug board new [flags]
+```
+
+### Options
+
+```
+ -t, --title string Provide a title to describe the issue
+ -d, --description string Provide a message to describe the board
+ -c, --columns stringArray Define the columns of the board (default to To Do,In Progress,Done) (default [To Do,In Progress,Done])
+ --non-interactive Do not ask for user input
+ -h, --help help for new
+```
+
+### SEE ALSO
+
+* [git-bug board](git-bug_board.md) - List boards
+
@@ -0,0 +1,22 @@
+## git-bug board rm
+
+Remove an existing board
+
+### Synopsis
+
+Remove an existing board in the local repository.
+
+```
+git-bug board rm BOARD_ID [flags]
+```
+
+### Options
+
+```
+ -h, --help help for rm
+```
+
+### SEE ALSO
+
+* [git-bug board](git-bug_board.md) - List boards
+
@@ -0,0 +1,25 @@
+## git-bug board select
+
+Select a board for implicit use in future commands
+
+### Synopsis
+
+Select a board for implicit use in future commands.
+
+The complementary command is "git board deselect" performing the opposite operation.
+
+
+```
+git-bug board select BOARD_ID [flags]
+```
+
+### Options
+
+```
+ -h, --help help for select
+```
+
+### SEE ALSO
+
+* [git-bug board](git-bug_board.md) - List boards
+
@@ -0,0 +1,19 @@
+## git-bug board show
+
+Display a board
+
+```
+git-bug board show [BOARD_ID] [flags]
+```
+
+### Options
+
+```
+ -f, --format string Select the output formatting style. Valid values are [default,json,org-mode] (default "default")
+ -h, --help help for show
+```
+
+### SEE ALSO
+
+* [git-bug board](git-bug_board.md) - List boards
+
@@ -0,0 +1,19 @@
+## git-bug board title
+
+Display the title of a board
+
+```
+git-bug board title [BOARD_ID] [flags]
+```
+
+### Options
+
+```
+ -h, --help help for title
+```
+
+### SEE ALSO
+
+* [git-bug board](git-bug_board.md) - List boards
+* [git-bug board title edit](git-bug_board_title_edit.md) - Edit a title of a board
+
@@ -0,0 +1,20 @@
+## git-bug board title edit
+
+Edit a title of a board
+
+```
+git-bug board title edit [BUG_ID] [flags]
+```
+
+### Options
+
+```
+ -t, --title string Provide a title to describe the board
+ --non-interactive Do not ask for user input
+ -h, --help help for edit
+```
+
+### SEE ALSO
+
+* [git-bug board title](git-bug_board_title.md) - Display the title of a board
+
@@ -3,12 +3,12 @@ package board
import (
"fmt"
- "github.com/MichaelMure/git-bug/entities/bug"
- "github.com/MichaelMure/git-bug/entities/identity"
+ "github.com/git-bug/git-bug/entities/bug"
+ "github.com/git-bug/git-bug/entities/identity"
- "github.com/MichaelMure/git-bug/entity"
- "github.com/MichaelMure/git-bug/entity/dag"
- "github.com/MichaelMure/git-bug/repository"
+ "github.com/git-bug/git-bug/entity"
+ "github.com/git-bug/git-bug/entity/dag"
+ "github.com/git-bug/git-bug/repository"
)
var _ Interface = &Board{}
@@ -1,10 +1,10 @@
package board
import (
- "github.com/MichaelMure/git-bug/entities/identity"
- "github.com/MichaelMure/git-bug/entity"
- "github.com/MichaelMure/git-bug/entity/dag"
- "github.com/MichaelMure/git-bug/repository"
+ "github.com/git-bug/git-bug/entities/identity"
+ "github.com/git-bug/git-bug/entity"
+ "github.com/git-bug/git-bug/entity/dag"
+ "github.com/git-bug/git-bug/repository"
)
// Fetch retrieve updates from a remote
@@ -1,12 +1,12 @@
package board
import (
- "github.com/MichaelMure/git-bug/entities/identity"
- "github.com/MichaelMure/git-bug/entity"
"github.com/dustin/go-humanize"
- "github.com/MichaelMure/git-bug/entities/common"
- "github.com/MichaelMure/git-bug/util/timestamp"
+ "github.com/git-bug/git-bug/entities/identity"
+ "github.com/git-bug/git-bug/entity"
+
+ "github.com/git-bug/git-bug/util/timestamp"
)
var _ Item = &Draft{}
@@ -16,10 +16,9 @@ type Draft struct {
// of the Operation that created the Draft
combinedId entity.CombinedId
- author identity.Interface
- status common.Status
- title string
- message string
+ Author identity.Interface
+ Title string
+ Message string
// Creation time of the comment.
// Should be used only for human display, never for ordering as we can't rely on it in a distributed system.
@@ -34,11 +33,6 @@ func (d *Draft) CombinedId() entity.CombinedId {
return d.combinedId
}
-func (d *Draft) Status() common.Status {
- // TODO implement me
- panic("implement me")
-}
-
// FormatTimeRel format the UnixTime of the comment for human consumption
func (d *Draft) FormatTimeRel() string {
return humanize.Time(d.unixTime.Time())
@@ -1,15 +1,15 @@
package board
import (
- "github.com/MichaelMure/git-bug/entities/bug"
- "github.com/MichaelMure/git-bug/entity"
+ "github.com/git-bug/git-bug/entities/bug"
+ "github.com/git-bug/git-bug/entity"
)
var _ Item = &BugItem{}
type BugItem struct {
combinedId entity.CombinedId
- bug bug.Interface
+ Bug bug.Interface
}
func (e *BugItem) CombinedId() entity.CombinedId {
@@ -3,13 +3,12 @@ package board
import (
"fmt"
- "github.com/MichaelMure/git-bug/entities/common"
- "github.com/MichaelMure/git-bug/entities/identity"
- "github.com/MichaelMure/git-bug/entity"
- "github.com/MichaelMure/git-bug/entity/dag"
- "github.com/MichaelMure/git-bug/repository"
- "github.com/MichaelMure/git-bug/util/text"
- "github.com/MichaelMure/git-bug/util/timestamp"
+ "github.com/git-bug/git-bug/entities/identity"
+ "github.com/git-bug/git-bug/entity"
+ "github.com/git-bug/git-bug/entity/dag"
+ "github.com/git-bug/git-bug/repository"
+ "github.com/git-bug/git-bug/util/text"
+ "github.com/git-bug/git-bug/util/timestamp"
)
var _ Operation = &AddItemDraftOperation{}
@@ -60,16 +59,15 @@ func (op *AddItemDraftOperation) Validate() error {
}
func (op *AddItemDraftOperation) Apply(snapshot *Snapshot) {
- snapshot.addActor(op.Author())
+ snapshot.addParticipant(op.Author())
for _, column := range snapshot.Columns {
if column.Id == op.ColumnId {
column.Items = append(column.Items, &Draft{
combinedId: entity.CombineIds(snapshot.id, op.Id()),
- author: op.Author(),
- status: common.OpenStatus,
- title: op.Title,
- message: op.Message,
+ Author: op.Author(),
+ Title: op.Title,
+ Message: op.Message,
unixTime: timestamp.Timestamp(op.UnixTime),
})
return
@@ -3,10 +3,10 @@ package board
import (
"testing"
- "github.com/MichaelMure/git-bug/entities/identity"
- "github.com/MichaelMure/git-bug/entity"
- "github.com/MichaelMure/git-bug/entity/dag"
- "github.com/MichaelMure/git-bug/repository"
+ "github.com/git-bug/git-bug/entities/identity"
+ "github.com/git-bug/git-bug/entity"
+ "github.com/git-bug/git-bug/entity/dag"
+ "github.com/git-bug/git-bug/repository"
)
func TestAddItemDraftOpSerialize(t *testing.T) {
@@ -3,10 +3,10 @@ package board
import (
"fmt"
- "github.com/MichaelMure/git-bug/entities/bug"
- "github.com/MichaelMure/git-bug/entities/identity"
- "github.com/MichaelMure/git-bug/entity"
- "github.com/MichaelMure/git-bug/entity/dag"
+ "github.com/git-bug/git-bug/entities/bug"
+ "github.com/git-bug/git-bug/entities/identity"
+ "github.com/git-bug/git-bug/entity"
+ "github.com/git-bug/git-bug/entity/dag"
)
// itemEntityType indicate the type of entity board item
@@ -57,7 +57,7 @@ func (op *AddItemEntityOperation) Apply(snapshot *Snapshot) {
return
}
- snapshot.addActor(op.Author())
+ snapshot.addParticipant(op.Author())
for _, column := range snapshot.Columns {
if column.Id == op.ColumnId {
@@ -65,7 +65,7 @@ func (op *AddItemEntityOperation) Apply(snapshot *Snapshot) {
case bug.Interface:
column.Items = append(column.Items, &BugItem{
combinedId: entity.CombineIds(snapshot.Id(), e.Id()),
- bug: e,
+ Bug: e,
})
}
return
@@ -5,10 +5,10 @@ import (
"github.com/stretchr/testify/require"
- "github.com/MichaelMure/git-bug/entities/bug"
- "github.com/MichaelMure/git-bug/entities/identity"
- "github.com/MichaelMure/git-bug/entity"
- "github.com/MichaelMure/git-bug/entity/dag"
+ "github.com/git-bug/git-bug/entities/bug"
+ "github.com/git-bug/git-bug/entities/identity"
+ "github.com/git-bug/git-bug/entity"
+ "github.com/git-bug/git-bug/entity/dag"
)
func TestAddItemEntityOpSerialize(t *testing.T) {
@@ -3,11 +3,11 @@ package board
import (
"fmt"
- "github.com/MichaelMure/git-bug/entities/identity"
+ "github.com/git-bug/git-bug/entities/identity"
- "github.com/MichaelMure/git-bug/entity"
- "github.com/MichaelMure/git-bug/entity/dag"
- "github.com/MichaelMure/git-bug/util/text"
+ "github.com/git-bug/git-bug/entity"
+ "github.com/git-bug/git-bug/entity/dag"
+ "github.com/git-bug/git-bug/util/text"
)
var DefaultColumns = []string{"To Do", "In Progress", "Done"}
@@ -96,7 +96,7 @@ func (op *CreateOperation) Apply(snap *Snapshot) {
})
}
- snap.addActor(op.Author())
+ snap.addParticipant(op.Author())
}
// CreateDefaultColumns is a convenience function to create a board with the default columns
@@ -6,10 +6,10 @@ import (
"github.com/stretchr/testify/require"
- "github.com/MichaelMure/git-bug/entities/identity"
- "github.com/MichaelMure/git-bug/entity"
- "github.com/MichaelMure/git-bug/entity/dag"
- "github.com/MichaelMure/git-bug/repository"
+ "github.com/git-bug/git-bug/entities/identity"
+ "github.com/git-bug/git-bug/entity"
+ "github.com/git-bug/git-bug/entity/dag"
+ "github.com/git-bug/git-bug/repository"
)
func TestCreate(t *testing.T) {
@@ -3,10 +3,10 @@ package board
import (
"fmt"
- "github.com/MichaelMure/git-bug/entities/identity"
- "github.com/MichaelMure/git-bug/entity"
- "github.com/MichaelMure/git-bug/entity/dag"
- "github.com/MichaelMure/git-bug/util/text"
+ "github.com/git-bug/git-bug/entities/identity"
+ "github.com/git-bug/git-bug/entity"
+ "github.com/git-bug/git-bug/entity/dag"
+ "github.com/git-bug/git-bug/util/text"
)
var _ Operation = &SetDescriptionOperation{}
@@ -44,7 +44,7 @@ func (op *SetDescriptionOperation) Validate() error {
func (op *SetDescriptionOperation) Apply(snapshot *Snapshot) {
snapshot.Description = op.Description
- snapshot.addActor(op.Author())
+ snapshot.addParticipant(op.Author())
}
func NewSetDescriptionOp(author identity.Interface, unixTime int64, description string, was string) *SetDescriptionOperation {
@@ -3,9 +3,9 @@ package board
import (
"testing"
- "github.com/MichaelMure/git-bug/entities/identity"
- "github.com/MichaelMure/git-bug/entity"
- "github.com/MichaelMure/git-bug/entity/dag"
+ "github.com/git-bug/git-bug/entities/identity"
+ "github.com/git-bug/git-bug/entity"
+ "github.com/git-bug/git-bug/entity/dag"
)
func TestSetDescriptionSerialize(t *testing.T) {
@@ -3,10 +3,10 @@ package board
import (
"fmt"
- "github.com/MichaelMure/git-bug/entities/identity"
- "github.com/MichaelMure/git-bug/entity"
- "github.com/MichaelMure/git-bug/entity/dag"
- "github.com/MichaelMure/git-bug/util/text"
+ "github.com/git-bug/git-bug/entities/identity"
+ "github.com/git-bug/git-bug/entity"
+ "github.com/git-bug/git-bug/entity/dag"
+ "github.com/git-bug/git-bug/util/text"
)
var _ Operation = &SetTitleOperation{}
@@ -44,7 +44,7 @@ func (op *SetTitleOperation) Validate() error {
func (op *SetTitleOperation) Apply(snapshot *Snapshot) {
snapshot.Title = op.Title
- snapshot.addActor(op.Author())
+ snapshot.addParticipant(op.Author())
}
func NewSetTitleOp(author identity.Interface, unixTime int64, title string, was string) *SetTitleOperation {
@@ -3,9 +3,9 @@ package board
import (
"testing"
- "github.com/MichaelMure/git-bug/entities/identity"
- "github.com/MichaelMure/git-bug/entity"
- "github.com/MichaelMure/git-bug/entity/dag"
+ "github.com/git-bug/git-bug/entities/identity"
+ "github.com/git-bug/git-bug/entity"
+ "github.com/git-bug/git-bug/entity/dag"
)
func TestSetTitleSerialize(t *testing.T) {
@@ -4,9 +4,9 @@ import (
"encoding/json"
"fmt"
- "github.com/MichaelMure/git-bug/entities/bug"
- "github.com/MichaelMure/git-bug/entity"
- "github.com/MichaelMure/git-bug/entity/dag"
+ "github.com/git-bug/git-bug/entities/bug"
+ "github.com/git-bug/git-bug/entity"
+ "github.com/git-bug/git-bug/entity/dag"
)
// OperationType is an operation type identifier
@@ -3,9 +3,9 @@ package board
import (
"time"
- "github.com/MichaelMure/git-bug/entities/identity"
- "github.com/MichaelMure/git-bug/entity"
- "github.com/MichaelMure/git-bug/entity/dag"
+ "github.com/git-bug/git-bug/entities/identity"
+ "github.com/git-bug/git-bug/entity"
+ "github.com/git-bug/git-bug/entity/dag"
)
type Column struct {
@@ -16,6 +16,7 @@ type Column struct {
type Item interface {
CombinedId() entity.CombinedId
+ // TODO: all items have status?
// Status() common.Status
}
@@ -24,10 +25,10 @@ var _ dag.Snapshot = &Snapshot{}
type Snapshot struct {
id entity.Id
- Title string
- Description string
- Columns []*Column
- Actors []identity.Interface
+ Title string
+ Description string
+ Columns []*Column
+ Participants []identity.Interface
CreateTime time.Time
Operations []dag.Operation
@@ -59,20 +60,20 @@ func (snap *Snapshot) EditTime() time.Time {
return snap.Operations[len(snap.Operations)-1].Time()
}
-// append the operation author to the actors list
-func (snap *Snapshot) addActor(actor identity.Interface) {
- for _, a := range snap.Actors {
- if actor.Id() == a.Id() {
+// append the operation author to the participants list
+func (snap *Snapshot) addParticipant(participant identity.Interface) {
+ for _, p := range snap.Participants {
+ if participant.Id() == p.Id() {
return
}
}
- snap.Actors = append(snap.Actors, actor)
+ snap.Participants = append(snap.Participants, participant)
}
-// HasActor return true if the id is a actor
-func (snap *Snapshot) HasActor(id entity.Id) bool {
- for _, p := range snap.Actors {
+// HasParticipant return true if the id is a participant
+func (snap *Snapshot) HasParticipant(id entity.Id) bool {
+ for _, p := range snap.Participants {
if p.Id() == id {
return true
}
@@ -80,10 +81,10 @@ func (snap *Snapshot) HasActor(id entity.Id) bool {
return false
}
-// HasAnyActor return true if one of the ids is a actor
-func (snap *Snapshot) HasAnyActor(ids ...entity.Id) bool {
+// HasAnyParticipant return true if one of the ids is a participant
+func (snap *Snapshot) HasAnyParticipant(ids ...entity.Id) bool {
for _, id := range ids {
- if snap.HasActor(id) {
+ if snap.HasParticipant(id) {
return true
}
}