aboutsummaryrefslogtreecommitdiffstats
path: root/commands
diff options
context:
space:
mode:
authorMichael Muré <batolettre@gmail.com>2018-07-19 12:30:25 +0200
committerMichael Muré <batolettre@gmail.com>2018-07-19 12:36:01 +0200
commit7f5922f905831a85ffee4c9226b65715899ba758 (patch)
treed18a29a2ec13706efa7f5e9efc9515a92cf4513d /commands
parent459bb8747d9e84493b8d04a3172e6758452a75b9 (diff)
downloadgit-bug-7f5922f905831a85ffee4c9226b65715899ba758.tar.gz
rework all the commands to use cobra as a parser
Diffstat (limited to 'commands')
-rw-r--r--commands/close.go16
-rw-r--r--commands/command.go59
-rw-r--r--commands/commands.go60
-rw-r--r--commands/comment.go45
-rw-r--r--commands/label.go33
-rw-r--r--commands/ls.go16
-rw-r--r--commands/new.go52
-rw-r--r--commands/open.go16
-rw-r--r--commands/pull.go16
-rw-r--r--commands/push.go16
-rw-r--r--commands/root.go59
-rw-r--r--commands/show.go16
-rw-r--r--commands/webui.go17
13 files changed, 228 insertions, 193 deletions
diff --git a/commands/close.go b/commands/close.go
index 15f50926..66c2b84d 100644
--- a/commands/close.go
+++ b/commands/close.go
@@ -4,10 +4,10 @@ import (
"errors"
"github.com/MichaelMure/git-bug/bug"
"github.com/MichaelMure/git-bug/bug/operations"
- "github.com/MichaelMure/git-bug/repository"
+ "github.com/spf13/cobra"
)
-func runCloseBug(repo repository.Repo, args []string) error {
+func runCloseBug(cmd *cobra.Command, args []string) error {
if len(args) > 1 {
return errors.New("Only closing one bug at a time is supported")
}
@@ -37,8 +37,12 @@ func runCloseBug(repo repository.Repo, args []string) error {
return err
}
-var closeCmd = &Command{
- Description: "Mark the bug as closed",
- Usage: "<id>",
- RunMethod: runCloseBug,
+var closeCmd = &cobra.Command{
+ Use: "close <id>",
+ Short: "Mark the bug as closed",
+ RunE: runCloseBug,
+}
+
+func init() {
+ rootCmd.AddCommand(closeCmd)
}
diff --git a/commands/command.go b/commands/command.go
deleted file mode 100644
index 89420b46..00000000
--- a/commands/command.go
+++ /dev/null
@@ -1,59 +0,0 @@
-// Package commands contains the assorted sub commands supported by the git-bug tool.
-package commands
-
-import (
- "flag"
- "fmt"
- "github.com/MichaelMure/git-bug/repository"
-)
-
-const messageFilename = "BUG_MESSAGE_EDITMSG"
-
-// Command represents the definition of a single command.
-type Command struct {
- // Short description of the command
- Description string
- // Command line usage
- Usage string
- // Flag set of the command
- flagSet *flag.FlagSet
- // Execute the command
- RunMethod func(repository.Repo, []string) error
-}
-
-// Run executes a command, given its arguments.
-//
-// The args parameter is all of the command line args that followed the
-// subcommand.
-func (cmd *Command) Run(repo repository.Repo, args []string) error {
- return cmd.RunMethod(repo, args)
-}
-
-func (cmd *Command) PrintUsage(rootCommand string, cmdName string) {
- fmt.Printf("Usage: %s %s %s\n", rootCommand, cmdName, cmd.Usage)
-
- if cmd.flagSet != nil {
- fmt.Printf("\nOptions:\n")
- cmd.flagSet.PrintDefaults()
- }
-}
-
-// CommandMap defines all of the available (sub)commands.
-var CommandMap map[string]*Command
-
-// We use init() to avoid a cycle in the data initialization because of the "commands" command
-func init() {
- CommandMap = map[string]*Command{
- "close": closeCmd,
- "commands": commandsCmd,
- "comment": commentCmd,
- "label": labelCmd,
- "ls": lsCmd,
- "new": newCmd,
- "open": openCmd,
- "pull": pullCmd,
- "push": pushCmd,
- "show": showCmd,
- "webui": webUICmd,
- }
-}
diff --git a/commands/commands.go b/commands/commands.go
index 1e8e9e19..f06d1ce8 100644
--- a/commands/commands.go
+++ b/commands/commands.go
@@ -1,55 +1,55 @@
package commands
import (
- "flag"
"fmt"
- "github.com/MichaelMure/git-bug/repository"
- "sort"
+ "github.com/spf13/cobra"
)
-var commandsFlagSet = flag.NewFlagSet("commands", flag.ExitOnError)
-
-var (
- commandsDesc = commandsFlagSet.Bool("pretty", false, "Output the command description as well as Markdown compatible comment")
-)
-
-func runCommands(repo repository.Repo, args []string) error {
- commandsFlagSet.Parse(args)
- args = commandsFlagSet.Args()
+var commandsDesc bool
+func runCommands(cmd *cobra.Command, args []string) error {
first := true
- keys := make([]string, 0, len(CommandMap))
+ allCmds := cmd.Root().Commands()
- for key := range CommandMap {
- keys = append(keys, key)
- }
-
- sort.Strings(keys)
-
- for _, key := range keys {
+ for _, cmd := range allCmds {
if !first {
fmt.Println()
}
first = false
- cmd := CommandMap[key]
+ if commandsDesc {
+ fmt.Printf("# %s\n", cmd.Short)
+ }
- if *commandsDesc {
- fmt.Printf("# %s\n", cmd.Description)
+ fmt.Printf("%s %s",
+ rootCommandName,
+ cmd.Use,
+ )
+
+ if commandsDesc {
+ fmt.Println()
}
+ }
- // TODO: the root name command ("git bug") should be passed from git-bug.go but well ...
- fmt.Printf("%s %s %s\n", "git bug", key, cmd.Usage)
+ if !commandsDesc {
+ fmt.Println()
}
return nil
}
-var commandsCmd = &Command{
- Description: "Display available commands",
- Usage: "[<option>...]",
- flagSet: commandsFlagSet,
- RunMethod: runCommands,
+var commandsCmd = &cobra.Command{
+ Use: "commands [<option>...]",
+ Short: "Display available commands",
+ RunE: runCommands,
+}
+
+func init() {
+ rootCmd.AddCommand(commandsCmd)
+
+ commandsCmd.Flags().BoolVarP(&commandsDesc, "pretty", "p", false,
+ "Output the command description as well as Markdown compatible comment",
+ )
}
diff --git a/commands/comment.go b/commands/comment.go
index 9815dac4..ce40d2e3 100644
--- a/commands/comment.go
+++ b/commands/comment.go
@@ -2,24 +2,18 @@ package commands
import (
"errors"
- "flag"
"github.com/MichaelMure/git-bug/bug"
"github.com/MichaelMure/git-bug/bug/operations"
"github.com/MichaelMure/git-bug/commands/input"
- "github.com/MichaelMure/git-bug/repository"
+ "github.com/spf13/cobra"
)
-var commentFlagSet = flag.NewFlagSet("comment", flag.ExitOnError)
-
var (
- commentMessageFile = commentFlagSet.String("F", "", "Take the message from the given file. Use - to read the message from the standard input")
- commentMessage = commentFlagSet.String("m", "", "Provide the new message from the command line")
+ commentMessageFile string
+ commentMessage string
)
-func runComment(repo repository.Repo, args []string) error {
- commentFlagSet.Parse(args)
- args = commentFlagSet.Args()
-
+func runComment(cmd *cobra.Command, args []string) error {
var err error
if len(args) > 1 {
@@ -32,14 +26,14 @@ func runComment(repo repository.Repo, args []string) error {
prefix := args[0]
- if *commentMessageFile != "" && *commentMessage == "" {
- *commentMessage, err = input.FromFile(*commentMessageFile)
+ if commentMessageFile != "" && commentMessage == "" {
+ commentMessage, err = input.FromFile(commentMessageFile)
if err != nil {
return err
}
}
- if *commentMessageFile == "" && *commentMessage == "" {
- *commentMessage, err = input.LaunchEditor(repo, messageFilename)
+ if commentMessageFile == "" && commentMessage == "" {
+ commentMessage, err = input.LaunchEditor(repo, messageFilename)
if err != nil {
return err
}
@@ -55,7 +49,7 @@ func runComment(repo repository.Repo, args []string) error {
return err
}
- addCommentOp := operations.NewAddCommentOp(author, *commentMessage)
+ addCommentOp := operations.NewAddCommentOp(author, commentMessage)
b.Append(addCommentOp)
@@ -64,9 +58,20 @@ func runComment(repo repository.Repo, args []string) error {
return err
}
-var commentCmd = &Command{
- Description: "Add a new comment to a bug",
- Usage: "[<options>...] <id>",
- flagSet: commentFlagSet,
- RunMethod: runComment,
+var commentCmd = &cobra.Command{
+ Use: "comment <id> [<options>...]",
+ Short: "Add a new comment to a bug",
+ RunE: runComment,
+}
+
+func init() {
+ rootCmd.AddCommand(commentCmd)
+
+ commentCmd.Flags().StringVarP(&commentMessageFile, "file", "F", "",
+ "Take the message from the given file. Use - to read the message from the standard input",
+ )
+
+ commentCmd.Flags().StringVarP(&commentMessage, "message", "m", "",
+ "Provide the new message from the command line",
+ )
}
diff --git a/commands/label.go b/commands/label.go
index ad3a388b..07dabfe8 100644
--- a/commands/label.go
+++ b/commands/label.go
@@ -2,23 +2,15 @@ package commands
import (
"errors"
- "flag"
"fmt"
"github.com/MichaelMure/git-bug/bug"
"github.com/MichaelMure/git-bug/bug/operations"
- "github.com/MichaelMure/git-bug/repository"
+ "github.com/spf13/cobra"
)
-var labelFlagSet = flag.NewFlagSet("label", flag.ExitOnError)
-
-var (
- labelRemove = newFlagSet.Bool("r", false, "Remove a label")
-)
-
-func runLabel(repo repository.Repo, args []string) error {
- labelFlagSet.Parse(args)
- args = labelFlagSet.Args()
+var labelRemove bool
+func runLabel(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return errors.New("You must provide a bug id")
}
@@ -46,7 +38,7 @@ func runLabel(repo repository.Repo, args []string) error {
for _, arg := range args[1:] {
label := bug.Label(arg)
- if *labelRemove {
+ if labelRemove {
// check for duplicate
if labelExist(removed, label) {
fmt.Printf("label \"%s\" is a duplicate\n", arg)
@@ -100,9 +92,16 @@ func labelExist(labels []bug.Label, label bug.Label) bool {
return false
}
-var labelCmd = &Command{
- Description: "Manipulate bug's label",
- Usage: "<id> [<option>...] [<label>...]",
- flagSet: labelFlagSet,
- RunMethod: runLabel,
+var labelCmd = &cobra.Command{
+ Use: "label [<option>...] <id> [<label>...]",
+ Short: "Manipulate bug's label",
+ RunE: runLabel,
+}
+
+func init() {
+ rootCmd.AddCommand(labelCmd)
+
+ labelCmd.Flags().BoolVarP(&labelRemove, "remove", "r", false,
+ "Remove a label",
+ )
}
diff --git a/commands/ls.go b/commands/ls.go
index 0d188833..fe3f9288 100644
--- a/commands/ls.go
+++ b/commands/ls.go
@@ -3,11 +3,11 @@ package commands
import (
"fmt"
b "github.com/MichaelMure/git-bug/bug"
- "github.com/MichaelMure/git-bug/repository"
"github.com/MichaelMure/git-bug/util"
+ "github.com/spf13/cobra"
)
-func runLsBug(repo repository.Repo, args []string) error {
+func runLsBug(cmd *cobra.Command, args []string) error {
ids, err := repo.ListRefs(b.BugsRefPattern)
if err != nil {
@@ -46,8 +46,12 @@ func runLsBug(repo repository.Repo, args []string) error {
return nil
}
-var lsCmd = &Command{
- Description: "Display a summary of all bugs",
- Usage: "",
- RunMethod: runLsBug,
+var lsCmd = &cobra.Command{
+ Use: "ls",
+ Short: "Display a summary of all bugs",
+ RunE: runLsBug,
+}
+
+func init() {
+ rootCmd.AddCommand(lsCmd)
}
diff --git a/commands/new.go b/commands/new.go
index 4f6008cf..fde944e9 100644
--- a/commands/new.go
+++ b/commands/new.go
@@ -2,25 +2,19 @@ package commands
import (
"errors"
- "flag"
"fmt"
"github.com/MichaelMure/git-bug/bug"
"github.com/MichaelMure/git-bug/bug/operations"
"github.com/MichaelMure/git-bug/commands/input"
- "github.com/MichaelMure/git-bug/repository"
+ "github.com/spf13/cobra"
)
-var newFlagSet = flag.NewFlagSet("new", flag.ExitOnError)
-
var (
- newMessageFile = newFlagSet.String("F", "", "Take the message from the given file. Use - to read the message from the standard input")
- newMessage = newFlagSet.String("m", "", "Provide a message to describe the issue")
+ newMessageFile string
+ newMessage string
)
-func runNewBug(repo repository.Repo, args []string) error {
- newFlagSet.Parse(args)
- args = newFlagSet.Args()
-
+func runNewBug(cmd *cobra.Command, args []string) error {
var err error
if len(args) == 0 {
@@ -32,14 +26,14 @@ func runNewBug(repo repository.Repo, args []string) error {
title := args[0]
- if *newMessageFile != "" && *newMessage == "" {
- *newMessage, err = input.FromFile(*newMessageFile)
+ if newMessageFile != "" && newMessage == "" {
+ newMessage, err = input.FromFile(newMessageFile)
if err != nil {
return err
}
}
- if *newMessageFile == "" && *newMessage == "" {
- *newMessage, err = input.LaunchEditor(repo, messageFilename)
+ if newMessageFile == "" && newMessage == "" {
+ newMessage, err = input.LaunchEditor(repo, messageFilename)
if err != nil {
return err
}
@@ -50,26 +44,36 @@ func runNewBug(repo repository.Repo, args []string) error {
return err
}
- newbug, err := bug.NewBug()
+ newBug, err := bug.NewBug()
if err != nil {
return err
}
- createOp := operations.NewCreateOp(author, title, *newMessage)
+ createOp := operations.NewCreateOp(author, title, newMessage)
- newbug.Append(createOp)
+ newBug.Append(createOp)
- err = newbug.Commit(repo)
+ err = newBug.Commit(repo)
- fmt.Println(newbug.HumanId())
+ fmt.Println(newBug.HumanId())
return err
}
-var newCmd = &Command{
- Description: "Create a new bug",
- Usage: "[<option>...] <title>",
- flagSet: newFlagSet,
- RunMethod: runNewBug,
+var newCmd = &cobra.Command{
+ Use: "new <title> [<option>...]",
+ Short: "Create a new bug",
+ RunE: runNewBug,
+}
+
+func init() {
+ rootCmd.AddCommand(newCmd)
+
+ newCmd.Flags().StringVarP(&newMessageFile, "file", "F", "",
+ "Take the message from the given file. Use - to read the message from the standard input",
+ )
+ newCmd.Flags().StringVarP(&newMessage, "message", "m", "",
+ "Provide a message to describe the issue",
+ )
}
diff --git a/commands/open.go b/commands/open.go
index 56416931..83e20a4a 100644
--- a/commands/open.go
+++ b/commands/open.go
@@ -4,10 +4,10 @@ import (
"errors"
"github.com/MichaelMure/git-bug/bug"
"github.com/MichaelMure/git-bug/bug/operations"
- "github.com/MichaelMure/git-bug/repository"
+ "github.com/spf13/cobra"
)
-func runOpenBug(repo repository.Repo, args []string) error {
+func runOpenBug(cmd *cobra.Command, args []string) error {
if len(args) > 1 {
return errors.New("Only opening one bug at a time is supported")
}
@@ -37,8 +37,12 @@ func runOpenBug(repo repository.Repo, args []string) error {
return err
}
-var openCmd = &Command{
- Description: "Mark the bug as open",
- Usage: "<id>",
- RunMethod: runOpenBug,
+var openCmd = &cobra.Command{
+ Use: "open <id>",
+ Short: "Mark the bug as open",
+ RunE: runOpenBug,
+}
+
+func init() {
+ rootCmd.AddCommand(openCmd)
}
diff --git a/commands/pull.go b/commands/pull.go
index 15d832fe..6e8acf50 100644
--- a/commands/pull.go
+++ b/commands/pull.go
@@ -4,10 +4,10 @@ import (
"errors"
"fmt"
"github.com/MichaelMure/git-bug/bug"
- "github.com/MichaelMure/git-bug/repository"
+ "github.com/spf13/cobra"
)
-func runPull(repo repository.Repo, args []string) error {
+func runPull(cmd *cobra.Command, args []string) error {
if len(args) > 1 {
return errors.New("Only pulling from one remote at a time is supported")
}
@@ -82,8 +82,12 @@ func runPull(repo repository.Repo, args []string) error {
}
// showCmd defines the "push" subcommand.
-var pullCmd = &Command{
- Description: "Pull bugs update from a git remote",
- Usage: "[<remote>]",
- RunMethod: runPull,
+var pullCmd = &cobra.Command{
+ Use: "pull [<remote>]",
+ Short: "Pull bugs update from a git remote",
+ RunE: runPull,
+}
+
+func init() {
+ rootCmd.AddCommand(pullCmd)
}
diff --git a/commands/push.go b/commands/push.go
index 2f7d9b29..5965e898 100644
--- a/commands/push.go
+++ b/commands/push.go
@@ -3,10 +3,10 @@ package commands
import (
"errors"
"github.com/MichaelMure/git-bug/bug"
- "github.com/MichaelMure/git-bug/repository"
+ "github.com/spf13/cobra"
)
-func runPush(repo repository.Repo, args []string) error {
+func runPush(cmd *cobra.Command, args []string) error {
if len(args) > 1 {
return errors.New("Only pushing to one remote at a time is supported")
}
@@ -23,8 +23,12 @@ func runPush(repo repository.Repo, args []string) error {
}
// showCmd defines the "push" subcommand.
-var pushCmd = &Command{
- Description: "Push bugs update to a git remote",
- Usage: "[<remote>]",
- RunMethod: runPush,
+var pushCmd = &cobra.Command{
+ Use: "push [<remote>]",
+ Short: "Push bugs update to a git remote",
+ RunE: runPush,
+}
+
+func init() {
+ rootCmd.AddCommand(pushCmd)
}
diff --git a/commands/root.go b/commands/root.go
new file mode 100644
index 00000000..31aa6bad
--- /dev/null
+++ b/commands/root.go
@@ -0,0 +1,59 @@
+package commands
+
+import (
+ "fmt"
+ "github.com/MichaelMure/git-bug/repository"
+ "github.com/spf13/cobra"
+ "os"
+)
+
+// Will display "git bug"
+// \u00A0 is a non-breaking space
+// It's used to avoid cobra to split the Use string at the first space to get the root command name
+const rootCommandName = "git\u00A0bug"
+const messageFilename = "BUG_MESSAGE_EDITMSG"
+
+// package scoped var to hold the repo after the PreRun execution
+var repo repository.Repo
+
+// rootCmd represents the base command when called without any subcommands
+var rootCmd = &cobra.Command{
+ Use: rootCommandName,
+ Short: "A bugtracker embedded in Git",
+ Long: `git-bug is a bugtracker embedded in git.
+
+It use the same internal storage so it doesn't pollute your project. As you would do with commits and branches, you can push your bugs to the same git remote your are already using to collaborate with other peoples.`,
+
+ // Force the execution of the PreRun while still displaying the help
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Help()
+ },
+
+ // Load the repo before any command execution
+ // Note, this concern only commands that actually has a Run function
+ PersistentPreRunE: loadRepo,
+}
+
+func Execute() {
+ if err := rootCmd.Execute(); err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+}
+
+func loadRepo(cmd *cobra.Command, args []string) error {
+ //fmt.Println("PersistentPreRun")
+
+ cwd, err := os.Getwd()
+ if err != nil {
+ return fmt.Errorf("Unable to get the current working directory: %q\n", err)
+ }
+
+ repo, err = repository.NewGitRepo(cwd)
+ if err != nil {
+ return fmt.Errorf("%s must be run from within a git repo.\n", rootCommandName)
+
+ }
+
+ return nil
+}
diff --git a/commands/show.go b/commands/show.go
index c5a043c7..8db3ed39 100644
--- a/commands/show.go
+++ b/commands/show.go
@@ -4,12 +4,12 @@ import (
"errors"
"fmt"
"github.com/MichaelMure/git-bug/bug"
- "github.com/MichaelMure/git-bug/repository"
"github.com/MichaelMure/git-bug/util"
+ "github.com/spf13/cobra"
"strings"
)
-func runShowBug(repo repository.Repo, args []string) error {
+func runShowBug(cmd *cobra.Command, args []string) error {
if len(args) > 1 {
return errors.New("Only showing one bug at a time is supported")
}
@@ -74,8 +74,12 @@ func runShowBug(repo repository.Repo, args []string) error {
return nil
}
-var showCmd = &Command{
- Description: "Display the details of a bug",
- Usage: "<id>",
- RunMethod: runShowBug,
+var showCmd = &cobra.Command{
+ Use: "show <id>",
+ Short: "Display the details of a bug",
+ RunE: runShowBug,
+}
+
+func init() {
+ rootCmd.AddCommand(showCmd)
}
diff --git a/commands/webui.go b/commands/webui.go
index df18d3b9..737632c3 100644
--- a/commands/webui.go
+++ b/commands/webui.go
@@ -2,16 +2,16 @@ package commands
import (
"fmt"
- "github.com/MichaelMure/git-bug/repository"
"github.com/MichaelMure/git-bug/webui"
"github.com/gorilla/mux"
"github.com/phayes/freeport"
"github.com/skratchdot/open-golang/open"
+ "github.com/spf13/cobra"
"log"
"net/http"
)
-func runWebUI(repo repository.Repo, args []string) error {
+func runWebUI(cmd *cobra.Command, args []string) error {
port, err := freeport.GetFreePort()
if err != nil {
log.Fatal(err)
@@ -29,9 +29,12 @@ func runWebUI(repo repository.Repo, args []string) error {
return nil
}
-var webUICmd = &Command{
- Description: "Launch the web UI",
- Usage: "",
- flagSet: nil,
- RunMethod: runWebUI,
+var webUICmd = &cobra.Command{
+ Use: "webui",
+ Short: "Launch the web UI",
+ RunE: runWebUI,
+}
+
+func init() {
+ rootCmd.AddCommand(webUICmd)
}