aboutsummaryrefslogtreecommitdiffstats
path: root/commands
diff options
context:
space:
mode:
Diffstat (limited to 'commands')
-rw-r--r--commands/add.go2
-rw-r--r--commands/bridge.go2
-rw-r--r--commands/bridge_configure.go2
-rw-r--r--commands/bridge_pull.go2
-rw-r--r--commands/bridge_rm.go2
-rw-r--r--commands/commands.go2
-rw-r--r--commands/comment.go2
-rw-r--r--commands/comment_add.go4
-rw-r--r--commands/deselect.go2
-rw-r--r--commands/label.go2
-rw-r--r--commands/label_add.go4
-rw-r--r--commands/label_rm.go4
-rw-r--r--commands/ls-labels.go2
-rw-r--r--commands/ls.go6
-rw-r--r--commands/pull.go2
-rw-r--r--commands/push.go2
-rw-r--r--commands/root.go25
-rw-r--r--commands/select.go2
-rw-r--r--commands/select/select_test.go129
-rw-r--r--commands/show.go6
-rw-r--r--commands/status.go2
-rw-r--r--commands/status_close.go4
-rw-r--r--commands/status_open.go4
-rw-r--r--commands/termui.go4
-rw-r--r--commands/title.go2
-rw-r--r--commands/title_edit.go4
-rw-r--r--commands/user.go61
-rw-r--r--commands/user_adopt.go48
-rw-r--r--commands/user_create.go81
-rw-r--r--commands/user_ls.go45
-rw-r--r--commands/version.go2
-rw-r--r--commands/webui.go2
32 files changed, 344 insertions, 119 deletions
diff --git a/commands/add.go b/commands/add.go
index 54ede126..ea40227c 100644
--- a/commands/add.go
+++ b/commands/add.go
@@ -56,7 +56,7 @@ func runAddBug(cmd *cobra.Command, args []string) error {
var addCmd = &cobra.Command{
Use: "add",
- Short: "Create a new bug",
+ Short: "Create a new bug.",
PreRunE: loadRepo,
RunE: runAddBug,
}
diff --git a/commands/bridge.go b/commands/bridge.go
index a473776d..2566fd06 100644
--- a/commands/bridge.go
+++ b/commands/bridge.go
@@ -31,7 +31,7 @@ func runBridge(cmd *cobra.Command, args []string) error {
var bridgeCmd = &cobra.Command{
Use: "bridge",
- Short: "Configure and use bridges to other bug trackers",
+ Short: "Configure and use bridges to other bug trackers.",
PreRunE: loadRepo,
RunE: runBridge,
Args: cobra.NoArgs,
diff --git a/commands/bridge_configure.go b/commands/bridge_configure.go
index ef499f1f..ce10d9af 100644
--- a/commands/bridge_configure.go
+++ b/commands/bridge_configure.go
@@ -91,7 +91,7 @@ func promptName() (string, error) {
var bridgeConfigureCmd = &cobra.Command{
Use: "configure",
- Short: "Configure a new bridge",
+ Short: "Configure a new bridge.",
PreRunE: loadRepo,
RunE: runBridgeConfigure,
}
diff --git a/commands/bridge_pull.go b/commands/bridge_pull.go
index 669a6713..9b251479 100644
--- a/commands/bridge_pull.go
+++ b/commands/bridge_pull.go
@@ -38,7 +38,7 @@ func runBridgePull(cmd *cobra.Command, args []string) error {
var bridgePullCmd = &cobra.Command{
Use: "pull [<name>]",
- Short: "Pull updates",
+ Short: "Pull updates.",
PreRunE: loadRepo,
RunE: runBridgePull,
}
diff --git a/commands/bridge_rm.go b/commands/bridge_rm.go
index 172fc0d8..80a831ff 100644
--- a/commands/bridge_rm.go
+++ b/commands/bridge_rm.go
@@ -25,7 +25,7 @@ func runBridgeRm(cmd *cobra.Command, args []string) error {
var bridgeRmCmd = &cobra.Command{
Use: "rm name <name>",
- Short: "Delete a configured bridge",
+ Short: "Delete a configured bridge.",
PreRunE: loadRepo,
RunE: runBridgeRm,
Args: cobra.ExactArgs(1),
diff --git a/commands/commands.go b/commands/commands.go
index e48cd542..a30c38a5 100644
--- a/commands/commands.go
+++ b/commands/commands.go
@@ -61,7 +61,7 @@ func runCommands(cmd *cobra.Command, args []string) error {
var commandsCmd = &cobra.Command{
Use: "commands [<option>...]",
- Short: "Display available commands",
+ Short: "Display available commands.",
RunE: runCommands,
}
diff --git a/commands/comment.go b/commands/comment.go
index 89378da3..3d5fe4eb 100644
--- a/commands/comment.go
+++ b/commands/comment.go
@@ -46,7 +46,7 @@ func commentsTextOutput(comments []bug.Comment) {
var commentCmd = &cobra.Command{
Use: "comment [<id>]",
- Short: "Display or add comments",
+ Short: "Display or add comments.",
PreRunE: loadRepo,
RunE: runComment,
}
diff --git a/commands/comment_add.go b/commands/comment_add.go
index 58408bc5..9bb24086 100644
--- a/commands/comment_add.go
+++ b/commands/comment_add.go
@@ -46,7 +46,7 @@ func runCommentAdd(cmd *cobra.Command, args []string) error {
}
}
- err = b.AddComment(commentAddMessage)
+ _, err = b.AddComment(commentAddMessage)
if err != nil {
return err
}
@@ -56,7 +56,7 @@ func runCommentAdd(cmd *cobra.Command, args []string) error {
var commentAddCmd = &cobra.Command{
Use: "add [<id>]",
- Short: "Add a new comment",
+ Short: "Add a new comment.",
PreRunE: loadRepo,
RunE: runCommentAdd,
}
diff --git a/commands/deselect.go b/commands/deselect.go
index 210f158c..f92c81fd 100644
--- a/commands/deselect.go
+++ b/commands/deselect.go
@@ -25,7 +25,7 @@ func runDeselect(cmd *cobra.Command, args []string) error {
var deselectCmd = &cobra.Command{
Use: "deselect",
- Short: "Clear the implicitly selected bug",
+ Short: "Clear the implicitly selected bug.",
Example: `git bug select 2f15
git bug comment
git bug status
diff --git a/commands/label.go b/commands/label.go
index 58ccc299..4f15c893 100644
--- a/commands/label.go
+++ b/commands/label.go
@@ -33,7 +33,7 @@ func runLabel(cmd *cobra.Command, args []string) error {
var labelCmd = &cobra.Command{
Use: "label [<id>]",
- Short: "Display, add or remove labels",
+ Short: "Display, add or remove labels.",
PreRunE: loadRepo,
RunE: runLabel,
}
diff --git a/commands/label_add.go b/commands/label_add.go
index f04ed7d6..b936bc37 100644
--- a/commands/label_add.go
+++ b/commands/label_add.go
@@ -22,7 +22,7 @@ func runLabelAdd(cmd *cobra.Command, args []string) error {
return err
}
- changes, err := b.ChangeLabels(args, nil)
+ changes, _, err := b.ChangeLabels(args, nil)
for _, change := range changes {
fmt.Println(change)
@@ -37,7 +37,7 @@ func runLabelAdd(cmd *cobra.Command, args []string) error {
var labelAddCmd = &cobra.Command{
Use: "add [<id>] <label>[...]",
- Short: "Add a label",
+ Short: "Add a label.",
PreRunE: loadRepo,
RunE: runLabelAdd,
}
diff --git a/commands/label_rm.go b/commands/label_rm.go
index 36051ba1..c03a20d9 100644
--- a/commands/label_rm.go
+++ b/commands/label_rm.go
@@ -22,7 +22,7 @@ func runLabelRm(cmd *cobra.Command, args []string) error {
return err
}
- changes, err := b.ChangeLabels(nil, args)
+ changes, _, err := b.ChangeLabels(nil, args)
for _, change := range changes {
fmt.Println(change)
@@ -37,7 +37,7 @@ func runLabelRm(cmd *cobra.Command, args []string) error {
var labelRmCmd = &cobra.Command{
Use: "rm [<id>] <label>[...]",
- Short: "Remove a label",
+ Short: "Remove a label.",
PreRunE: loadRepo,
RunE: runLabelRm,
}
diff --git a/commands/ls-labels.go b/commands/ls-labels.go
index ef2c95bc..5610fb56 100644
--- a/commands/ls-labels.go
+++ b/commands/ls-labels.go
@@ -27,7 +27,7 @@ func runLsLabel(cmd *cobra.Command, args []string) error {
var lsLabelCmd = &cobra.Command{
Use: "ls-label",
- Short: "List valid labels",
+ Short: "List valid labels.",
Long: `List valid labels.
Note: in the future, a proper label policy could be implemented where valid labels are defined in a configuration file. Until that, the default behavior is to return the list of labels already used.`,
diff --git a/commands/ls.go b/commands/ls.go
index 2f621bc5..75b7ceaf 100644
--- a/commands/ls.go
+++ b/commands/ls.go
@@ -4,8 +4,8 @@ import (
"fmt"
"strings"
- "github.com/MichaelMure/git-bug/bug"
"github.com/MichaelMure/git-bug/cache"
+ "github.com/MichaelMure/git-bug/identity"
"github.com/MichaelMure/git-bug/util/colors"
"github.com/MichaelMure/git-bug/util/interrupt"
"github.com/spf13/cobra"
@@ -52,7 +52,7 @@ func runLsBug(cmd *cobra.Command, args []string) error {
snapshot := b.Snapshot()
- var author bug.Person
+ var author identity.Interface
if len(snapshot.Comments) > 0 {
create := snapshot.Comments[0]
@@ -131,7 +131,7 @@ func lsQueryFromFlags() (*cache.Query, error) {
var lsCmd = &cobra.Command{
Use: "ls [<query>]",
- Short: "List bugs",
+ Short: "List bugs.",
Long: `Display a summary of each bugs.
You can pass an additional query to filter and order the list. This query can be expressed either with a simple query language or with flags.`,
diff --git a/commands/pull.go b/commands/pull.go
index 67c2a339..d2d75f3f 100644
--- a/commands/pull.go
+++ b/commands/pull.go
@@ -54,7 +54,7 @@ func runPull(cmd *cobra.Command, args []string) error {
// showCmd defines the "push" subcommand.
var pullCmd = &cobra.Command{
Use: "pull [<remote>]",
- Short: "Pull bugs update from a git remote",
+ Short: "Pull bugs update from a git remote.",
PreRunE: loadRepo,
RunE: runPull,
}
diff --git a/commands/push.go b/commands/push.go
index 0477be60..8f67d3c0 100644
--- a/commands/push.go
+++ b/commands/push.go
@@ -39,7 +39,7 @@ func runPush(cmd *cobra.Command, args []string) error {
// showCmd defines the "push" subcommand.
var pushCmd = &cobra.Command{
Use: "push [<remote>]",
- Short: "Push bugs update to a git remote",
+ Short: "Push bugs update to a git remote.",
PreRunE: loadRepo,
RunE: runPush,
}
diff --git a/commands/root.go b/commands/root.go
index 797ae949..adbf51d9 100644
--- a/commands/root.go
+++ b/commands/root.go
@@ -6,6 +6,7 @@ import (
"os"
"github.com/MichaelMure/git-bug/bug"
+ "github.com/MichaelMure/git-bug/identity"
"github.com/MichaelMure/git-bug/repository"
"github.com/spf13/cobra"
)
@@ -18,7 +19,7 @@ var repo repository.ClockedRepo
// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
Use: rootCommandName,
- Short: "A bug tracker embedded in Git",
+ Short: "A bug tracker embedded in Git.",
Long: `git-bug is a bug tracker embedded in git.
git-bug use git objects to store the bug tracking separated from the files
@@ -53,6 +54,7 @@ func Execute() {
}
}
+// loadRepo is a pre-run function that load the repository for use in a command
func loadRepo(cmd *cobra.Command, args []string) error {
cwd, err := os.Getwd()
if err != nil {
@@ -70,3 +72,24 @@ func loadRepo(cmd *cobra.Command, args []string) error {
return nil
}
+
+// loadRepoEnsureUser is the same as loadRepo, but also ensure that the user has configured
+// an identity. Use this pre-run function when an error after using the configured user won't
+// do.
+func loadRepoEnsureUser(cmd *cobra.Command, args []string) error {
+ err := loadRepo(cmd, args)
+ if err != nil {
+ return err
+ }
+
+ set, err := identity.IsUserIdentitySet(repo)
+ if err != nil {
+ return err
+ }
+
+ if !set {
+ return identity.ErrNoIdentitySet
+ }
+
+ return nil
+}
diff --git a/commands/select.go b/commands/select.go
index cc688354..6b214961 100644
--- a/commands/select.go
+++ b/commands/select.go
@@ -41,7 +41,7 @@ func runSelect(cmd *cobra.Command, args []string) error {
var selectCmd = &cobra.Command{
Use: "select <id>",
- Short: "Select a bug for implicit use in future commands",
+ Short: "Select a bug for implicit use in future commands.",
Example: `git bug select 2f15
git bug comment
git bug status
diff --git a/commands/select/select_test.go b/commands/select/select_test.go
index fe501d76..29fdb3b8 100644
--- a/commands/select/select_test.go
+++ b/commands/select/select_test.go
@@ -1,113 +1,80 @@
package _select
import (
- "io/ioutil"
- "log"
"testing"
+ "time"
"github.com/MichaelMure/git-bug/cache"
- "github.com/MichaelMure/git-bug/repository"
+ "github.com/MichaelMure/git-bug/util/test"
+ "github.com/stretchr/testify/require"
)
func TestSelect(t *testing.T) {
- repo, err := cache.NewRepoCache(createRepo())
- checkErr(t, err)
+ repo := test.CreateRepo(false)
- _, _, err = ResolveBug(repo, []string{})
- if err != ErrNoValidId {
- t.Fatal("expected no valid id error, got", err)
- }
+ repoCache, err := cache.NewRepoCache(repo)
+ require.NoError(t, err)
- err = Select(repo, "invalid")
- checkErr(t, err)
+ _, _, err = ResolveBug(repoCache, []string{})
+ require.Equal(t, ErrNoValidId, err)
- _, _, err = ResolveBug(repo, []string{})
- if err == nil {
- t.Fatal("expected invalid bug error")
- }
+ err = Select(repoCache, "invalid")
+ require.NoError(t, err)
+
+ // Resolve without a pattern should fail when no bug is selected
+ _, _, err = ResolveBug(repoCache, []string{})
+ require.Error(t, err)
// generate a bunch of bugs
+
+ rene, err := repoCache.NewIdentity("René Descartes", "rene@descartes.fr")
+ require.NoError(t, err)
+
for i := 0; i < 10; i++ {
- _, err := repo.NewBug("title", "message")
- checkErr(t, err)
+ _, err := repoCache.NewBugRaw(rene, time.Now().Unix(), "title", "message", nil, nil)
+ require.NoError(t, err)
}
- // two more for testing
- b1, err := repo.NewBug("title", "message")
- checkErr(t, err)
- b2, err := repo.NewBug("title", "message")
- checkErr(t, err)
+ // and two more for testing
+ b1, err := repoCache.NewBugRaw(rene, time.Now().Unix(), "title", "message", nil, nil)
+ require.NoError(t, err)
+ b2, err := repoCache.NewBugRaw(rene, time.Now().Unix(), "title", "message", nil, nil)
+ require.NoError(t, err)
- err = Select(repo, b1.Id())
- checkErr(t, err)
+ err = Select(repoCache, b1.Id())
+ require.NoError(t, err)
// normal select without args
- b3, _, err := ResolveBug(repo, []string{})
- checkErr(t, err)
- if b3.Id() != b1.Id() {
- t.Fatal("incorrect bug returned")
- }
+ b3, _, err := ResolveBug(repoCache, []string{})
+ require.NoError(t, err)
+ require.Equal(t, b1.Id(), b3.Id())
// override selection with same id
- b4, _, err := ResolveBug(repo, []string{b1.Id()})
- checkErr(t, err)
- if b4.Id() != b1.Id() {
- t.Fatal("incorrect bug returned")
- }
+ b4, _, err := ResolveBug(repoCache, []string{b1.Id()})
+ require.NoError(t, err)
+ require.Equal(t, b1.Id(), b4.Id())
// override selection with a prefix
- b5, _, err := ResolveBug(repo, []string{b1.HumanId()})
- checkErr(t, err)
- if b5.Id() != b1.Id() {
- t.Fatal("incorrect bug returned")
- }
+ b5, _, err := ResolveBug(repoCache, []string{b1.HumanId()})
+ require.NoError(t, err)
+ require.Equal(t, b1.Id(), b5.Id())
// args that shouldn't override
- b6, _, err := ResolveBug(repo, []string{"arg"})
- checkErr(t, err)
- if b6.Id() != b1.Id() {
- t.Fatal("incorrect bug returned")
- }
+ b6, _, err := ResolveBug(repoCache, []string{"arg"})
+ require.NoError(t, err)
+ require.Equal(t, b1.Id(), b6.Id())
// override with a different id
- b7, _, err := ResolveBug(repo, []string{b2.Id()})
- checkErr(t, err)
- if b7.Id() != b2.Id() {
- t.Fatal("incorrect bug returned")
- }
-
- err = Clear(repo)
- checkErr(t, err)
+ b7, _, err := ResolveBug(repoCache, []string{b2.Id()})
+ require.NoError(t, err)
+ require.Equal(t, b2.Id(), b7.Id())
- _, _, err = ResolveBug(repo, []string{})
- if err == nil {
- t.Fatal("expected invalid bug error")
- }
-}
-
-func createRepo() *repository.GitRepo {
- dir, err := ioutil.TempDir("", "")
- if err != nil {
- log.Fatal(err)
- }
+ err = Clear(repoCache)
+ require.NoError(t, err)
- repo, err := repository.InitGitRepo(dir)
- if err != nil {
- log.Fatal(err)
- }
+ // Resolve without a pattern should error again after clearing the selected bug
+ _, _, err = ResolveBug(repoCache, []string{})
+ require.Error(t, err)
- if err := repo.StoreConfig("user.name", "testuser"); err != nil {
- log.Fatal("failed to set user.name for test repository: ", err)
- }
- if err := repo.StoreConfig("user.email", "testuser@example.com"); err != nil {
- log.Fatal("failed to set user.email for test repository: ", err)
- }
-
- return repo
-}
-
-func checkErr(t testing.TB, err error) {
- if err != nil {
- t.Fatal(err)
- }
+ require.NoError(t, test.CleanupRepo(repo))
}
diff --git a/commands/show.go b/commands/show.go
index 56717b3b..c62db1a1 100644
--- a/commands/show.go
+++ b/commands/show.go
@@ -42,7 +42,7 @@ func runShowBug(cmd *cobra.Command, args []string) error {
case "author":
fmt.Printf("%s\n", firstComment.Author.DisplayName())
case "authorEmail":
- fmt.Printf("%s\n", firstComment.Author.Email)
+ fmt.Printf("%s\n", firstComment.Author.Email())
case "createTime":
fmt.Printf("%s\n", firstComment.FormatTime())
case "id":
@@ -93,7 +93,7 @@ func runShowBug(cmd *cobra.Command, args []string) error {
indent,
i,
comment.Author.DisplayName(),
- comment.Author.Email,
+ comment.Author.Email(),
)
if comment.Message == "" {
@@ -113,7 +113,7 @@ func runShowBug(cmd *cobra.Command, args []string) error {
var showCmd = &cobra.Command{
Use: "show [<id>]",
- Short: "Display the details of a bug",
+ Short: "Display the details of a bug.",
PreRunE: loadRepo,
RunE: runShowBug,
}
diff --git a/commands/status.go b/commands/status.go
index 7928628a..4675195d 100644
--- a/commands/status.go
+++ b/commands/status.go
@@ -31,7 +31,7 @@ func runStatus(cmd *cobra.Command, args []string) error {
var statusCmd = &cobra.Command{
Use: "status [<id>]",
- Short: "Display or change a bug status",
+ Short: "Display or change a bug status.",
PreRunE: loadRepo,
RunE: runStatus,
}
diff --git a/commands/status_close.go b/commands/status_close.go
index 2b4f9602..94d05ddf 100644
--- a/commands/status_close.go
+++ b/commands/status_close.go
@@ -20,7 +20,7 @@ func runStatusClose(cmd *cobra.Command, args []string) error {
return err
}
- err = b.Close()
+ _, err = b.Close()
if err != nil {
return err
}
@@ -30,7 +30,7 @@ func runStatusClose(cmd *cobra.Command, args []string) error {
var closeCmd = &cobra.Command{
Use: "close [<id>]",
- Short: "Mark a bug as closed",
+ Short: "Mark a bug as closed.",
PreRunE: loadRepo,
RunE: runStatusClose,
}
diff --git a/commands/status_open.go b/commands/status_open.go
index 5e3029e2..9a2b76ab 100644
--- a/commands/status_open.go
+++ b/commands/status_open.go
@@ -20,7 +20,7 @@ func runStatusOpen(cmd *cobra.Command, args []string) error {
return err
}
- err = b.Open()
+ _, err = b.Open()
if err != nil {
return err
}
@@ -30,7 +30,7 @@ func runStatusOpen(cmd *cobra.Command, args []string) error {
var openCmd = &cobra.Command{
Use: "open [<id>]",
- Short: "Mark a bug as open",
+ Short: "Mark a bug as open.",
PreRunE: loadRepo,
RunE: runStatusOpen,
}
diff --git a/commands/termui.go b/commands/termui.go
index 4a029d6c..19a1397a 100644
--- a/commands/termui.go
+++ b/commands/termui.go
@@ -20,8 +20,8 @@ func runTermUI(cmd *cobra.Command, args []string) error {
var termUICmd = &cobra.Command{
Use: "termui",
- Short: "Launch the terminal UI",
- PreRunE: loadRepo,
+ Short: "Launch the terminal UI.",
+ PreRunE: loadRepoEnsureUser,
RunE: runTermUI,
}
diff --git a/commands/title.go b/commands/title.go
index c9157a70..f9b7542b 100644
--- a/commands/title.go
+++ b/commands/title.go
@@ -31,7 +31,7 @@ func runTitle(cmd *cobra.Command, args []string) error {
var titleCmd = &cobra.Command{
Use: "title [<id>]",
- Short: "Display or change a title",
+ Short: "Display or change a title.",
PreRunE: loadRepo,
RunE: runTitle,
}
diff --git a/commands/title_edit.go b/commands/title_edit.go
index 6bbd1b0a..e95c77d0 100644
--- a/commands/title_edit.go
+++ b/commands/title_edit.go
@@ -44,7 +44,7 @@ func runTitleEdit(cmd *cobra.Command, args []string) error {
fmt.Println("No change, aborting.")
}
- err = b.SetTitle(titleEditTitle)
+ _, err = b.SetTitle(titleEditTitle)
if err != nil {
return err
}
@@ -54,7 +54,7 @@ func runTitleEdit(cmd *cobra.Command, args []string) error {
var titleEditCmd = &cobra.Command{
Use: "edit [<id>]",
- Short: "Edit a title",
+ Short: "Edit a title.",
PreRunE: loadRepo,
RunE: runTitleEdit,
}
diff --git a/commands/user.go b/commands/user.go
new file mode 100644
index 00000000..12180321
--- /dev/null
+++ b/commands/user.go
@@ -0,0 +1,61 @@
+package commands
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/MichaelMure/git-bug/cache"
+ "github.com/MichaelMure/git-bug/util/interrupt"
+ "github.com/spf13/cobra"
+)
+
+func runUser(cmd *cobra.Command, args []string) error {
+ backend, err := cache.NewRepoCache(repo)
+ if err != nil {
+ return err
+ }
+ defer backend.Close()
+ interrupt.RegisterCleaner(backend.Close)
+
+ if len(args) > 1 {
+ return errors.New("only one identity can be displayed at a time")
+ }
+
+ var id *cache.IdentityCache
+ if len(args) == 1 {
+ id, err = backend.ResolveIdentityPrefix(args[0])
+ } else {
+ id, err = backend.GetUserIdentity()
+ }
+
+ if err != nil {
+ return err
+ }
+
+ fmt.Printf("Id: %s\n", id.Id())
+ fmt.Printf("Name: %s\n", id.Name())
+ fmt.Printf("Login: %s\n", id.Login())
+ fmt.Printf("Email: %s\n", id.Email())
+ fmt.Printf("Last modification: %s (lamport %d)\n",
+ id.LastModification().Time().Format("Mon Jan 2 15:04:05 2006 +0200"),
+ id.LastModificationLamport())
+ fmt.Println("Metadata:")
+ for key, value := range id.ImmutableMetadata() {
+ fmt.Printf(" %s --> %s\n", key, value)
+ }
+ // fmt.Printf("Protected: %v\n", id.IsProtected())
+
+ return nil
+}
+
+var userCmd = &cobra.Command{
+ Use: "user [<id>]",
+ Short: "Display or change the user identity.",
+ PreRunE: loadRepo,
+ RunE: runUser,
+}
+
+func init() {
+ RootCmd.AddCommand(userCmd)
+ userCmd.Flags().SortFlags = false
+}
diff --git a/commands/user_adopt.go b/commands/user_adopt.go
new file mode 100644
index 00000000..5313e366
--- /dev/null
+++ b/commands/user_adopt.go
@@ -0,0 +1,48 @@
+package commands
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/MichaelMure/git-bug/cache"
+ "github.com/MichaelMure/git-bug/util/interrupt"
+ "github.com/spf13/cobra"
+)
+
+func runUserAdopt(cmd *cobra.Command, args []string) error {
+ backend, err := cache.NewRepoCache(repo)
+ if err != nil {
+ return err
+ }
+ defer backend.Close()
+ interrupt.RegisterCleaner(backend.Close)
+
+ prefix := args[0]
+
+ i, err := backend.ResolveIdentityPrefix(prefix)
+ if err != nil {
+ return err
+ }
+
+ err = backend.SetUserIdentity(i)
+ if err != nil {
+ return err
+ }
+
+ _, _ = fmt.Fprintf(os.Stderr, "Your identity is now: %s\n", i.DisplayName())
+
+ return nil
+}
+
+var userAdoptCmd = &cobra.Command{
+ Use: "adopt <id>",
+ Short: "Adopt an existing identity as your own.",
+ PreRunE: loadRepo,
+ RunE: runUserAdopt,
+ Args: cobra.ExactArgs(1),
+}
+
+func init() {
+ userCmd.AddCommand(userAdoptCmd)
+ userAdoptCmd.Flags().SortFlags = false
+}
diff --git a/commands/user_create.go b/commands/user_create.go
new file mode 100644
index 00000000..037d79b2
--- /dev/null
+++ b/commands/user_create.go
@@ -0,0 +1,81 @@
+package commands
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/MichaelMure/git-bug/cache"
+ "github.com/MichaelMure/git-bug/input"
+ "github.com/MichaelMure/git-bug/util/interrupt"
+ "github.com/spf13/cobra"
+)
+
+func runUserCreate(cmd *cobra.Command, args []string) error {
+ backend, err := cache.NewRepoCache(repo)
+ if err != nil {
+ return err
+ }
+ defer backend.Close()
+ interrupt.RegisterCleaner(backend.Close)
+
+ _, _ = fmt.Fprintf(os.Stderr, "Before creating a new identity, please be aware that "+
+ "you can also use an already existing one using \"git bug user adopt\". As an example, "+
+ "you can do that if your identity has already been created by an importer.\n\n")
+
+ preName, err := backend.GetUserName()
+ if err != nil {
+ return err
+ }
+
+ name, err := input.PromptValueRequired("Name", preName)
+ if err != nil {
+ return err
+ }
+
+ preEmail, err := backend.GetUserEmail()
+ if err != nil {
+ return err
+ }
+
+ email, err := input.PromptValueRequired("Email", preEmail)
+ if err != nil {
+ return err
+ }
+
+ login, err := input.PromptValue("Avatar URL", "")
+ if err != nil {
+ return err
+ }
+
+ id, err := backend.NewIdentityRaw(name, email, "", login, nil)
+ if err != nil {
+ return err
+ }
+
+ err = id.CommitAsNeeded()
+ if err != nil {
+ return err
+ }
+
+ err = backend.SetUserIdentity(id)
+ if err != nil {
+ return err
+ }
+
+ _, _ = fmt.Fprintln(os.Stderr)
+ fmt.Println(id.Id())
+
+ return nil
+}
+
+var userCreateCmd = &cobra.Command{
+ Use: "create",
+ Short: "Create a new identity.",
+ PreRunE: loadRepo,
+ RunE: runUserCreate,
+}
+
+func init() {
+ userCmd.AddCommand(userCreateCmd)
+ userCreateCmd.Flags().SortFlags = false
+}
diff --git a/commands/user_ls.go b/commands/user_ls.go
new file mode 100644
index 00000000..23ecea73
--- /dev/null
+++ b/commands/user_ls.go
@@ -0,0 +1,45 @@
+package commands
+
+import (
+ "fmt"
+
+ "github.com/MichaelMure/git-bug/cache"
+ "github.com/MichaelMure/git-bug/util/colors"
+ "github.com/MichaelMure/git-bug/util/interrupt"
+ "github.com/spf13/cobra"
+)
+
+func runUserLs(cmd *cobra.Command, args []string) error {
+ backend, err := cache.NewRepoCache(repo)
+ if err != nil {
+ return err
+ }
+ defer backend.Close()
+ interrupt.RegisterCleaner(backend.Close)
+
+ for _, id := range backend.AllIdentityIds() {
+ i, err := backend.ResolveIdentityExcerpt(id)
+ if err != nil {
+ return err
+ }
+
+ fmt.Printf("%s %s\n",
+ colors.Cyan(i.HumanId()),
+ i.DisplayName(),
+ )
+ }
+
+ return nil
+}
+
+var userLsCmd = &cobra.Command{
+ Use: "ls",
+ Short: "List identities.",
+ PreRunE: loadRepo,
+ RunE: runUserLs,
+}
+
+func init() {
+ userCmd.AddCommand(userLsCmd)
+ userLsCmd.Flags().SortFlags = false
+}
diff --git a/commands/version.go b/commands/version.go
index b4dc008e..05016a0b 100644
--- a/commands/version.go
+++ b/commands/version.go
@@ -41,7 +41,7 @@ func runVersionCmd(cmd *cobra.Command, args []string) {
var versionCmd = &cobra.Command{
Use: "version",
- Short: "Show git-bug version information",
+ Short: "Show git-bug version information.",
Run: runVersionCmd,
}
diff --git a/commands/webui.go b/commands/webui.go
index e2a3265c..f86616d5 100644
--- a/commands/webui.go
+++ b/commands/webui.go
@@ -224,7 +224,7 @@ func (gufh *gitUploadFileHandler) ServeHTTP(rw http.ResponseWriter, r *http.Requ
var webUICmd = &cobra.Command{
Use: "webui",
- Short: "Launch the web UI",
+ Short: "Launch the web UI.",
PreRunE: loadRepo,
RunE: runWebUI,
}