aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Muré <batolettre@gmail.com>2019-02-17 16:12:06 +0100
committerMichael Muré <batolettre@gmail.com>2019-03-01 22:40:25 +0100
commit864eae0d6bd0732260c0c56583bb77f9b25b60f6 (patch)
treeb1a0384f2fdb0af0c8aaf0f1b0fbc1c445c418f3
parentda558b05ef79f4c80df10c6969a9ae5f4f764f96 (diff)
downloadgit-bug-864eae0d6bd0732260c0c56583bb77f9b25b60f6.tar.gz
identity: work on higher level now, cache, first two identity commands
-rw-r--r--bridge/github/import.go4
-rw-r--r--bridge/launchpad/import.go2
-rw-r--r--cache/bug_cache.go38
-rw-r--r--cache/identity_cache.go26
-rw-r--r--cache/repo_cache.go68
-rw-r--r--commands/id.go49
-rw-r--r--commands/user.go56
-rw-r--r--commands/user_create.go76
-rw-r--r--doc/man/git-bug-bridge-bridge.129
-rw-r--r--doc/man/git-bug-user-create.129
-rw-r--r--doc/man/git-bug-user.1 (renamed from doc/man/git-bug-id.1)8
-rw-r--r--doc/man/git-bug.12
-rw-r--r--doc/md/git-bug.md2
-rw-r--r--doc/md/git-bug_bridge_bridge.md22
-rw-r--r--doc/md/git-bug_close.md22
-rw-r--r--doc/md/git-bug_new.md25
-rw-r--r--doc/md/git-bug_open.md22
-rw-r--r--doc/md/git-bug_user.md (renamed from doc/md/git-bug_id.md)7
-rw-r--r--doc/md/git-bug_user_create.md22
-rw-r--r--identity/identity.go16
-rw-r--r--input/prompt.go44
-rw-r--r--misc/bash_completion/git-bug63
-rw-r--r--misc/zsh_completion/git-bug5
23 files changed, 397 insertions, 240 deletions
diff --git a/bridge/github/import.go b/bridge/github/import.go
index 43a8e3b5..38278911 100644
--- a/bridge/github/import.go
+++ b/bridge/github/import.go
@@ -599,7 +599,7 @@ func (gi *githubImporter) ensureCommentEdit(repo *cache.RepoCache, b *cache.BugC
}
// makePerson create a bug.Person from the Github data
-func (gi *githubImporter) makePerson(repo *cache.RepoCache, actor *actor) (*identity.Identity, error) {
+func (gi *githubImporter) makePerson(repo *cache.RepoCache, actor *actor) (*cache.IdentityCache, error) {
// When a user has been deleted, Github return a null actor, while displaying a profile named "ghost"
// in it's UI. So we need a special case to get it.
if actor == nil {
@@ -645,7 +645,7 @@ func (gi *githubImporter) makePerson(repo *cache.RepoCache, actor *actor) (*iden
)
}
-func (gi *githubImporter) getGhost(repo *cache.RepoCache) (*identity.Identity, error) {
+func (gi *githubImporter) getGhost(repo *cache.RepoCache) (*cache.IdentityCache, error) {
// Look first in the cache
i, err := repo.ResolveIdentityImmutableMetadata(keyGithubLogin, "ghost")
if err == nil {
diff --git a/bridge/launchpad/import.go b/bridge/launchpad/import.go
index e65186ed..b70d34f0 100644
--- a/bridge/launchpad/import.go
+++ b/bridge/launchpad/import.go
@@ -23,7 +23,7 @@ func (li *launchpadImporter) Init(conf core.Configuration) error {
const keyLaunchpadID = "launchpad-id"
const keyLaunchpadLogin = "launchpad-login"
-func (li *launchpadImporter) makePerson(repo *cache.RepoCache, owner LPPerson) (*identity.Identity, error) {
+func (li *launchpadImporter) makePerson(repo *cache.RepoCache, owner LPPerson) (*cache.IdentityCache, error) {
// Look first in the cache
i, err := repo.ResolveIdentityImmutableMetadata(keyLaunchpadLogin, owner.Login)
if err == nil {
diff --git a/cache/bug_cache.go b/cache/bug_cache.go
index 2a570667..ce46837a 100644
--- a/cache/bug_cache.go
+++ b/cache/bug_cache.go
@@ -5,8 +5,6 @@ import (
"strings"
"time"
- "github.com/MichaelMure/git-bug/identity"
-
"github.com/MichaelMure/git-bug/bug"
"github.com/MichaelMure/git-bug/util/git"
)
@@ -93,7 +91,7 @@ func (c *BugCache) AddComment(message string) error {
}
func (c *BugCache) AddCommentWithFiles(message string, files []git.Hash) error {
- author, err := identity.GetUserIdentity(c.repoCache.repo)
+ author, err := c.repoCache.GetUserIdentity()
if err != nil {
return err
}
@@ -101,8 +99,8 @@ func (c *BugCache) AddCommentWithFiles(message string, files []git.Hash) error {
return c.AddCommentRaw(author, time.Now().Unix(), message, files, nil)
}
-func (c *BugCache) AddCommentRaw(author identity.Interface, unixTime int64, message string, files []git.Hash, metadata map[string]string) error {
- op, err := bug.AddCommentWithFiles(c.bug, author, unixTime, message, files)
+func (c *BugCache) AddCommentRaw(author *IdentityCache, unixTime int64, message string, files []git.Hash, metadata map[string]string) error {
+ op, err := bug.AddCommentWithFiles(c.bug, author.Identity, unixTime, message, files)
if err != nil {
return err
}
@@ -115,7 +113,7 @@ func (c *BugCache) AddCommentRaw(author identity.Interface, unixTime int64, mess
}
func (c *BugCache) ChangeLabels(added []string, removed []string) ([]bug.LabelChangeResult, error) {
- author, err := identity.GetUserIdentity(c.repoCache.repo)
+ author, err := c.repoCache.GetUserIdentity()
if err != nil {
return nil, err
}
@@ -123,8 +121,8 @@ func (c *BugCache) ChangeLabels(added []string, removed []string) ([]bug.LabelCh
return c.ChangeLabelsRaw(author, time.Now().Unix(), added, removed, nil)
}
-func (c *BugCache) ChangeLabelsRaw(author identity.Interface, unixTime int64, added []string, removed []string, metadata map[string]string) ([]bug.LabelChangeResult, error) {
- changes, op, err := bug.ChangeLabels(c.bug, author, unixTime, added, removed)
+func (c *BugCache) ChangeLabelsRaw(author *IdentityCache, unixTime int64, added []string, removed []string, metadata map[string]string) ([]bug.LabelChangeResult, error) {
+ changes, op, err := bug.ChangeLabels(c.bug, author.Identity, unixTime, added, removed)
if err != nil {
return changes, err
}
@@ -142,7 +140,7 @@ func (c *BugCache) ChangeLabelsRaw(author identity.Interface, unixTime int64, ad
}
func (c *BugCache) Open() error {
- author, err := identity.GetUserIdentity(c.repoCache.repo)
+ author, err := c.repoCache.GetUserIdentity()
if err != nil {
return err
}
@@ -150,8 +148,8 @@ func (c *BugCache) Open() error {
return c.OpenRaw(author, time.Now().Unix(), nil)
}
-func (c *BugCache) OpenRaw(author identity.Interface, unixTime int64, metadata map[string]string) error {
- op, err := bug.Open(c.bug, author, unixTime)
+func (c *BugCache) OpenRaw(author *IdentityCache, unixTime int64, metadata map[string]string) error {
+ op, err := bug.Open(c.bug, author.Identity, unixTime)
if err != nil {
return err
}
@@ -164,7 +162,7 @@ func (c *BugCache) OpenRaw(author identity.Interface, unixTime int64, metadata m
}
func (c *BugCache) Close() error {
- author, err := identity.GetUserIdentity(c.repoCache.repo)
+ author, err := c.repoCache.GetUserIdentity()
if err != nil {
return err
}
@@ -172,8 +170,8 @@ func (c *BugCache) Close() error {
return c.CloseRaw(author, time.Now().Unix(), nil)
}
-func (c *BugCache) CloseRaw(author identity.Interface, unixTime int64, metadata map[string]string) error {
- op, err := bug.Close(c.bug, author, unixTime)
+func (c *BugCache) CloseRaw(author *IdentityCache, unixTime int64, metadata map[string]string) error {
+ op, err := bug.Close(c.bug, author.Identity, unixTime)
if err != nil {
return err
}
@@ -186,7 +184,7 @@ func (c *BugCache) CloseRaw(author identity.Interface, unixTime int64, metadata
}
func (c *BugCache) SetTitle(title string) error {
- author, err := identity.GetUserIdentity(c.repoCache.repo)
+ author, err := c.repoCache.GetUserIdentity()
if err != nil {
return err
}
@@ -194,8 +192,8 @@ func (c *BugCache) SetTitle(title string) error {
return c.SetTitleRaw(author, time.Now().Unix(), title, nil)
}
-func (c *BugCache) SetTitleRaw(author identity.Interface, unixTime int64, title string, metadata map[string]string) error {
- op, err := bug.SetTitle(c.bug, author, unixTime, title)
+func (c *BugCache) SetTitleRaw(author *IdentityCache, unixTime int64, title string, metadata map[string]string) error {
+ op, err := bug.SetTitle(c.bug, author.Identity, unixTime, title)
if err != nil {
return err
}
@@ -208,7 +206,7 @@ func (c *BugCache) SetTitleRaw(author identity.Interface, unixTime int64, title
}
func (c *BugCache) EditComment(target git.Hash, message string) error {
- author, err := identity.GetUserIdentity(c.repoCache.repo)
+ author, err := c.repoCache.GetUserIdentity()
if err != nil {
return err
}
@@ -216,8 +214,8 @@ func (c *BugCache) EditComment(target git.Hash, message string) error {
return c.EditCommentRaw(author, time.Now().Unix(), target, message, nil)
}
-func (c *BugCache) EditCommentRaw(author identity.Interface, unixTime int64, target git.Hash, message string, metadata map[string]string) error {
- op, err := bug.EditComment(c.bug, author, unixTime, target, message)
+func (c *BugCache) EditCommentRaw(author *IdentityCache, unixTime int64, target git.Hash, message string, metadata map[string]string) error {
+ op, err := bug.EditComment(c.bug, author.Identity, unixTime, target, message)
if err != nil {
return err
}
diff --git a/cache/identity_cache.go b/cache/identity_cache.go
new file mode 100644
index 00000000..93b2dc4b
--- /dev/null
+++ b/cache/identity_cache.go
@@ -0,0 +1,26 @@
+package cache
+
+import (
+ "github.com/MichaelMure/git-bug/identity"
+)
+
+// IdentityCache is a wrapper around an Identity. It provide multiple functions:
+type IdentityCache struct {
+ *identity.Identity
+ repoCache *RepoCache
+}
+
+func NewIdentityCache(repoCache *RepoCache, id *identity.Identity) *IdentityCache {
+ return &IdentityCache{
+ Identity: id,
+ repoCache: repoCache,
+ }
+}
+
+func (i *IdentityCache) Commit() error {
+ return i.Identity.Commit(i.repoCache.repo)
+}
+
+func (i *IdentityCache) CommitAsNeeded() error {
+ return i.Identity.CommitAsNeeded(i.repoCache.repo)
+}
diff --git a/cache/repo_cache.go b/cache/repo_cache.go
index 74f04e11..f64a1b76 100644
--- a/cache/repo_cache.go
+++ b/cache/repo_cache.go
@@ -45,13 +45,16 @@ type RepoCache struct {
// bug loaded in memory
bugs map[string]*BugCache
// identities loaded in memory
- identities map[string]*identity.Identity
+ identities map[string]*IdentityCache
+ // the user identity's id, if known
+ userIdentityId string
}
func NewRepoCache(r repository.ClockedRepo) (*RepoCache, error) {
c := &RepoCache{
- repo: r,
- bugs: make(map[string]*BugCache),
+ repo: r,
+ bugs: make(map[string]*BugCache),
+ identities: make(map[string]*IdentityCache),
}
err := c.lock()
@@ -394,7 +397,7 @@ func (c *RepoCache) NewBug(title string, message string) (*BugCache, error) {
// NewBugWithFiles create a new bug with attached files for the message
// The new bug is written in the repository (commit)
func (c *RepoCache) NewBugWithFiles(title string, message string, files []git.Hash) (*BugCache, error) {
- author, err := identity.GetUserIdentity(c.repo)
+ author, err := c.GetUserIdentity()
if err != nil {
return nil, err
}
@@ -405,8 +408,8 @@ func (c *RepoCache) NewBugWithFiles(title string, message string, files []git.Ha
// NewBugWithFilesMeta create a new bug with attached files for the message, as
// well as metadata for the Create operation.
// The new bug is written in the repository (commit)
-func (c *RepoCache) NewBugRaw(author identity.Interface, unixTime int64, title string, message string, files []git.Hash, metadata map[string]string) (*BugCache, error) {
- b, op, err := bug.CreateWithFiles(author, unixTime, title, message, files)
+func (c *RepoCache) NewBugRaw(author *IdentityCache, unixTime int64, title string, message string, files []git.Hash, metadata map[string]string) (*BugCache, error) {
+ b, op, err := bug.CreateWithFiles(author.Identity, unixTime, title, message, files)
if err != nil {
return nil, err
}
@@ -549,7 +552,7 @@ func repoIsAvailable(repo repository.Repo) error {
}
// ResolveIdentity retrieve an identity matching the exact given id
-func (c *RepoCache) ResolveIdentity(id string) (*identity.Identity, error) {
+func (c *RepoCache) ResolveIdentity(id string) (*IdentityCache, error) {
cached, ok := c.identities[id]
if ok {
return cached, nil
@@ -560,14 +563,15 @@ func (c *RepoCache) ResolveIdentity(id string) (*identity.Identity, error) {
return nil, err
}
- c.identities[id] = i
+ cached = NewIdentityCache(c, i)
+ c.identities[id] = cached
- return i, nil
+ return cached, nil
}
// ResolveIdentityPrefix retrieve an Identity matching an id prefix.
// It fails if multiple identities match.
-func (c *RepoCache) ResolveIdentityPrefix(prefix string) (*identity.Identity, error) {
+func (c *RepoCache) ResolveIdentityPrefix(prefix string) (*IdentityCache, error) {
// preallocate but empty
matching := make([]string, 0, 5)
@@ -590,7 +594,7 @@ func (c *RepoCache) ResolveIdentityPrefix(prefix string) (*identity.Identity, er
// ResolveIdentityImmutableMetadata retrieve an Identity that has the exact given metadata on
// one of it's version. If multiple version have the same key, the first defined take precedence.
-func (c *RepoCache) ResolveIdentityImmutableMetadata(key string, value string) (*identity.Identity, error) {
+func (c *RepoCache) ResolveIdentityImmutableMetadata(key string, value string) (*IdentityCache, error) {
// preallocate but empty
matching := make([]string, 0, 5)
@@ -611,19 +615,50 @@ func (c *RepoCache) ResolveIdentityImmutableMetadata(key string, value string) (
return c.ResolveIdentity(matching[0])
}
+func (c *RepoCache) SetUserIdentity(i *IdentityCache) error {
+ err := identity.SetUserIdentity(c.repo, i.Identity)
+ if err != nil {
+ return err
+ }
+
+ c.userIdentityId = i.Id()
+
+ return nil
+}
+
+func (c *RepoCache) GetUserIdentity() (*IdentityCache, error) {
+ if c.userIdentityId != "" {
+ i, ok := c.identities[c.userIdentityId]
+ if ok {
+ return i, nil
+ }
+ }
+
+ i, err := identity.GetUserIdentity(c.repo)
+ if err != nil {
+ return nil, err
+ }
+
+ cached := NewIdentityCache(c, i)
+ c.identities[i.Id()] = cached
+ c.userIdentityId = i.Id()
+
+ return cached, nil
+}
+
// NewIdentity create a new identity
// The new identity is written in the repository (commit)
-func (c *RepoCache) NewIdentity(name string, email string) (*identity.Identity, error) {
+func (c *RepoCache) NewIdentity(name string, email string) (*IdentityCache, error) {
return c.NewIdentityRaw(name, email, "", "", nil)
}
// NewIdentityFull create a new identity
// The new identity is written in the repository (commit)
-func (c *RepoCache) NewIdentityFull(name string, email string, login string, avatarUrl string) (*identity.Identity, error) {
+func (c *RepoCache) NewIdentityFull(name string, email string, login string, avatarUrl string) (*IdentityCache, error) {
return c.NewIdentityRaw(name, email, login, avatarUrl, nil)
}
-func (c *RepoCache) NewIdentityRaw(name string, email string, login string, avatarUrl string, metadata map[string]string) (*identity.Identity, error) {
+func (c *RepoCache) NewIdentityRaw(name string, email string, login string, avatarUrl string, metadata map[string]string) (*IdentityCache, error) {
i := identity.NewIdentityFull(name, email, login, avatarUrl)
for key, value := range metadata {
@@ -639,7 +674,8 @@ func (c *RepoCache) NewIdentityRaw(name string, email string, login string, avat
return nil, fmt.Errorf("identity %s already exist in the cache", i.Id())
}
- c.identities[i.Id()] = i
+ cached := NewIdentityCache(c, i)
+ c.identities[i.Id()] = cached
- return i, nil
+ return cached, nil
}
diff --git a/commands/id.go b/commands/id.go
deleted file mode 100644
index 7eacd986..00000000
--- a/commands/id.go
+++ /dev/null
@@ -1,49 +0,0 @@
-package commands
-
-import (
- "errors"
- "fmt"
-
- "github.com/MichaelMure/git-bug/identity"
- "github.com/spf13/cobra"
-)
-
-func runId(cmd *cobra.Command, args []string) error {
- if len(args) > 1 {
- return errors.New("only one identity can be displayed at a time")
- }
-
- var id *identity.Identity
- var err error
-
- if len(args) == 1 {
- id, err = identity.ReadLocal(repo, args[0])
- } else {
- id, err = identity.GetUserIdentity(repo)
- }
-
- if err != nil {
- return err
- }
-
- fmt.Printf("Id: %s\n", id.Id())
- fmt.Printf("Identity: %s\n", id.DisplayName())
- fmt.Printf("Name: %s\n", id.Name())
- fmt.Printf("Login: %s\n", id.Login())
- fmt.Printf("Email: %s\n", id.Email())
- fmt.Printf("Protected: %v\n", id.IsProtected())
-
- return nil
-}
-
-var idCmd = &cobra.Command{
- Use: "id [<id>]",
- Short: "Display or change the user identity",
- PreRunE: loadRepo,
- RunE: runId,
-}
-
-func init() {
- RootCmd.AddCommand(idCmd)
- selectCmd.Flags().SortFlags = false
-}
diff --git a/commands/user.go b/commands/user.go
new file mode 100644
index 00000000..55ad813c
--- /dev/null
+++ b/commands/user.go
@@ -0,0 +1,56 @@
+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 {
+ // TODO
+ return errors.New("this is not working yet, cache need to be hacked on")
+ 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("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_create.go b/commands/user_create.go
new file mode 100644
index 00000000..50acac3e
--- /dev/null
+++ b/commands/user_create.go
@@ -0,0 +1,76 @@
+package commands
+
+import (
+ "fmt"
+
+ "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)
+
+ 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.Println()
+ 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/doc/man/git-bug-bridge-bridge.1 b/doc/man/git-bug-bridge-bridge.1
deleted file mode 100644
index edd0a5d3..00000000
--- a/doc/man/git-bug-bridge-bridge.1
+++ /dev/null
@@ -1,29 +0,0 @@
-.TH "GIT-BUG" "1" "Sep 2018" "Generated from git-bug's source code" ""
-.nh
-.ad l
-
-
-.SH NAME
-.PP
-git\-bug\-bridge\-bridge \- Configure and use bridges to other bug trackers
-
-
-.SH SYNOPSIS
-.PP
-\fBgit\-bug bridge bridge [flags]\fP
-
-
-.SH DESCRIPTION
-.PP
-Configure and use bridges to other bug trackers
-
-
-.SH OPTIONS
-.PP
-\fB\-h\fP, \fB\-\-help\fP[=false]
- help for bridge
-
-
-.SH SEE ALSO
-.PP
-\fBgit\-bug\-bridge(1)\fP
diff --git a/doc/man/git-bug-user-create.1 b/doc/man/git-bug-user-create.1
new file mode 100644
index 00000000..a54adca4
--- /dev/null
+++ b/doc/man/git-bug-user-create.1
@@ -0,0 +1,29 @@
+.TH "GIT-BUG" "1" "Feb 2019" "Generated from git-bug's source code" ""
+.nh
+.ad l
+
+
+.SH NAME
+.PP
+git\-bug\-user\-create \- Create a new identity
+
+
+.SH SYNOPSIS
+.PP
+\fBgit\-bug user create [flags]\fP
+
+
+.SH DESCRIPTION
+.PP
+Create a new identity
+
+
+.SH OPTIONS
+.PP
+\fB\-h\fP, \fB\-\-help\fP[=false]
+ help for create
+
+
+.SH SEE ALSO
+.PP
+\fBgit\-bug\-user(1)\fP
diff --git a/doc/man/git-bug-id.1 b/doc/man/git-bug-user.1
index b3baf589..eb074973 100644
--- a/doc/man/git-bug-id.1
+++ b/doc/man/git-bug-user.1
@@ -5,12 +5,12 @@
.SH NAME
.PP
-git\-bug\-id \- Display or change the user identity
+git\-bug\-user \- Display or change the user identity
.SH SYNOPSIS
.PP
-\fBgit\-bug id [<id>] [flags]\fP
+\fBgit\-bug user [<id>] [flags]\fP
.SH DESCRIPTION
@@ -21,9 +21,9 @@ Display or change the user identity
.SH OPTIONS
.PP
\fB\-h\fP, \fB\-\-help\fP[=false]
- help for id
+ help for user
.SH SEE ALSO
.PP
-\fBgit\-bug(1)\fP
+\fBgit\-bug(1)\fP, \fBgit\-bug\-user\-create(1)\fP
diff --git a/doc/man/git-bug.1 b/doc/man/git-bug.1
index f3ad4729..523dafe5 100644
--- a/doc/man/git-bug.1
+++ b/doc/man/git-bug.1
@@ -31,4 +31,4 @@ the same git remote your are already using to collaborate with other peoples.
.SH SEE ALSO
.PP
-\fBgit\-bug\-add(1)\fP, \fBgit\-bug\-bridge(1)\fP, \fBgit\-bug\-commands(1)\fP, \fBgit\-bug\-comment(1)\fP, \fBgit\-bug\-deselect(1)\fP, \fBgit\-bug\-id(1)\fP, \fBgit\-bug\-label(1)\fP, \fBgit\-bug\-ls(1)\fP, \fBgit\-bug\-ls\-label(1)\fP, \fBgit\-bug\-pull(1)\fP, \fBgit\-bug\-push(1)\fP, \fBgit\-bug\-select(1)\fP, \fBgit\-bug\-show(1)\fP, \fBgit\-bug\-status(1)\fP, \fBgit\-bug\-termui(1)\fP, \fBgit\-bug\-title(1)\fP, \fBgit\-bug\-version(1)\fP, \fBgit\-bug\-webui(1)\fP
+\fBgit\-bug\-add(1)\fP, \fBgit\-bug\-bridge(1)\fP, \fBgit\-bug\-commands(1)\fP, \fBgit\-bug\-comment(1)\fP, \fBgit\-bug\-deselect(1)\fP, \fBgit\-bug\-label(1)\fP, \fBgit\-bug\-ls(1)\fP, \fBgit\-bug\-ls\-label(1)\fP, \fBgit\-bug\-pull(1)\fP, \fBgit\-bug\-push(1)\fP, \fBgit\-bug\-select(1)\fP, \fBgit\-bug\-show(1)\fP, \fBgit\-bug\-status(1)\fP, \fBgit\-bug\-termui(1)\fP, \fBgit\-bug\-title(1)\fP, \fBgit\-bug\-user(1)\fP, \fBgit\-bug\-version(1)\fP, \fBgit\-bug\-webui(1)\fP
diff --git a/doc/md/git-bug.md b/doc/md/git-bug.md
index 7183dd76..a5f61032 100644
--- a/doc/md/git-bug.md
+++ b/doc/md/git-bug.md
@@ -29,7 +29,6 @@ git-bug [flags]
* [git-bug commands](git-bug_commands.md) - Display available commands
* [git-bug comment](git-bug_comment.md) - Display or add comments
* [git-bug deselect](git-bug_deselect.md) - Clear the implicitly selected bug
-* [git-bug id](git-bug_id.md) - Display or change the user identity
* [git-bug label](git-bug_label.md) - Display, add or remove labels
* [git-bug ls](git-bug_ls.md) - List bugs
* [git-bug ls-id](git-bug_ls-id.md) - List Bug Id
@@ -41,6 +40,7 @@ git-bug [flags]
* [git-bug status](git-bug_status.md) - Display or change a bug status
* [git-bug termui](git-bug_termui.md) - Launch the terminal UI
* [git-bug title](git-bug_title.md) - Display or change a title
+* [git-bug user](git-bug_user.md) - Display or change the user identity
* [git-bug version](git-bug_version.md) - Show git-bug version information
* [git-bug webui](git-bug_webui.md) - Launch the web UI
diff --git a/doc/md/git-bug_bridge_bridge.md b/doc/md/git-bug_bridge_bridge.md
deleted file mode 100644
index d5803190..00000000
--- a/doc/md/git-bug_bridge_bridge.md
+++ /dev/null
@@ -1,22 +0,0 @@
-## git-bug bridge bridge
-
-Configure and use bridges to other bug trackers
-
-### Synopsis
-
-Configure and use bridges to other bug trackers
-
-```
-git-bug bridge bridge [flags]
-```
-
-### Options
-
-```
- -h, --help help for bridge
-```
-
-### SEE ALSO
-
-* [git-bug bridge](git-bug_bridge.md) - Configure and use bridges to other bug trackers
-
diff --git a/doc/md/git-bug_close.md b/doc/md/git-bug_close.md
deleted file mode 100644
index ab95706d..00000000
--- a/doc/md/git-bug_close.md
+++ /dev/null
@@ -1,22 +0,0 @@
-## git-bug close
-
-Mark the bug as closed
-
-### Synopsis
-
-Mark the bug as closed
-
-```
-git-bug close <id> [flags]
-```
-
-### Options
-
-```
- -h, --help help for close
-```
-
-### SEE ALSO
-
-* [git-bug](git-bug.md) - A bugtracker embedded in Git
-
diff --git a/doc/md/git-bug_new.md b/doc/md/git-bug_new.md
deleted file mode 100644
index de6cffbf..00000000
--- a/doc/md/git-bug_new.md
+++ /dev/null
@@ -1,25 +0,0 @@
-## git-bug new
-
-Create a new bug
-
-### Synopsis
-
-Create a new bug
-
-```
-git-bug new [flags]
-```
-
-### Options
-
-```
- -t, --title string Provide a title to describe the issue
- -m, --message string Provide a message to describe the issue
- -F, --file string Take the message from the given file. Use - to read the message from the standard input
- -h, --help help for new
-```
-
-### SEE ALSO
-
-* [git-bug](git-bug.md) - A bugtracker embedded in Git
-
diff --git a/doc/md/git-bug_open.md b/doc/md/git-bug_open.md
deleted file mode 100644
index 38c6d6fa..00000000
--- a/doc/md/git-bug_open.md
+++ /dev/null
@@ -1,22 +0,0 @@
-## git-bug open
-
-Mark the bug as open
-
-### Synopsis
-
-Mark the bug as open
-
-```
-git-bug open <id> [flags]
-```
-
-### Options
-
-```
- -h, --help help for open
-```
-
-### SEE ALSO
-
-* [git-bug](git-bug.md) - A bugtracker embedded in Git
-
diff --git a/doc/md/git-bug_id.md b/doc/md/git-bug_user.md
index 09f8f276..5692b40a 100644
--- a/doc/md/git-bug_id.md
+++ b/doc/md/git-bug_user.md
@@ -1,4 +1,4 @@
-## git-bug id
+## git-bug user
Display or change the user identity
@@ -7,16 +7,17 @@ Display or change the user identity
Display or change the user identity
```
-git-bug id [<id>] [flags]
+git-bug user [<id>] [flags]
```
### Options
```
- -h, --help help for id
+ -h, --help help for user
```
### SEE ALSO
* [git-bug](git-bug.md) - A bug tracker embedded in Git
+* [git-bug user create](git-bug_user_create.md) - Create a new identity
diff --git a/doc/md/git-bug_user_create.md b/doc/md/git-bug_user_create.md
new file mode 100644
index 00000000..55a1159c
--- /dev/null
+++ b/doc/md/git-bug_user_create.md
@@ -0,0 +1,22 @@
+## git-bug user create
+
+Create a new identity
+
+### Synopsis
+
+Create a new identity
+
+```
+git-bug user create [flags]
+```
+
+### Options
+
+```
+ -h, --help help for create
+```
+
+### SEE ALSO
+
+* [git-bug user](git-bug_user.md) - Display or change the user identity
+
diff --git a/identity/identity.go b/identity/identity.go
index a0800bcd..35edca18 100644
--- a/identity/identity.go
+++ b/identity/identity.go
@@ -204,8 +204,22 @@ func NewFromGitUser(repo repository.Repo) (*Identity, error) {
return NewIdentity(name, email), nil
}
+// IsUserIdentitySet tell if the user identity is correctly set.
+func IsUserIdentitySet(repo repository.RepoCommon) (bool, error) {
+ configs, err := repo.ReadConfigs(identityConfigKey)
+ if err != nil {
+ return false, err
+ }
+
+ if len(configs) > 1 {
+ return false, fmt.Errorf("multiple identity config exist")
+ }
+
+ return len(configs) == 1, nil
+}
+
// SetUserIdentity store the user identity's id in the git config
-func SetUserIdentity(repo repository.RepoCommon, identity Identity) error {
+func SetUserIdentity(repo repository.RepoCommon, identity *Identity) error {
return repo.StoreConfig(identityConfigKey, identity.Id())
}
diff --git a/input/prompt.go b/input/prompt.go
new file mode 100644
index 00000000..7a059b1a
--- /dev/null
+++ b/input/prompt.go
@@ -0,0 +1,44 @@
+package input
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+ "strings"
+)
+
+func PromptValue(name string, preValue string) (string, error) {
+ return promptValue(name, preValue, false)
+}
+
+func PromptValueRequired(name string, preValue string) (string, error) {
+ return promptValue(name, preValue, true)
+}
+
+func promptValue(name string, preValue string, required bool) (string, error) {
+ for {
+ if preValue != "" {
+ fmt.Printf("%s [%s]: ", name, preValue)
+ } else {
+ fmt.Printf("%s: ", name)
+ }
+
+ line, err := bufio.NewReader(os.Stdin).ReadString('\n')
+ if err != nil {
+ return "", err
+ }
+
+ line = strings.TrimSpace(line)
+
+ if preValue != "" && line == "" {
+ return preValue, nil
+ }
+
+ if required && line == "" {
+ fmt.Printf("%s is empty\n", name)
+ continue
+ }
+
+ return line, nil
+ }
+}
diff --git a/misc/bash_completion/git-bug b/misc/bash_completion/git-bug
index 98d94a35..4ec1e472 100644
--- a/misc/bash_completion/git-bug
+++ b/misc/bash_completion/git-bug
@@ -450,26 +450,6 @@ _git-bug_deselect()
noun_aliases=()
}
-_git-bug_id()
-{
- last_command="git-bug_id"
-
- command_aliases=()
-
- commands=()
-
- flags=()
- two_word_flags=()
- local_nonpersistent_flags=()
- flags_with_completion=()
- flags_completion=()
-
-
- must_have_one_flag=()
- must_have_one_noun=()
- noun_aliases=()
-}
-
_git-bug_label_add()
{
last_command="git-bug_label_add"
@@ -819,6 +799,47 @@ _git-bug_title()
noun_aliases=()
}
+_git-bug_user_create()
+{
+ last_command="git-bug_user_create"
+
+ command_aliases=()
+
+ commands=()
+
+ flags=()
+ two_word_flags=()
+ local_nonpersistent_flags=()
+ flags_with_completion=()
+ flags_completion=()
+
+
+ must_have_one_flag=()
+ must_have_one_noun=()
+ noun_aliases=()
+}
+
+_git-bug_user()
+{
+ last_command="git-bug_user"
+
+ command_aliases=()
+
+ commands=()
+ commands+=("create")
+
+ flags=()
+ two_word_flags=()
+ local_nonpersistent_flags=()
+ flags_with_completion=()
+ flags_completion=()
+
+
+ must_have_one_flag=()
+ must_have_one_noun=()
+ noun_aliases=()
+}
+
_git-bug_version()
{
last_command="git-bug_version"
@@ -883,7 +904,6 @@ _git-bug_root_command()
commands+=("commands")
commands+=("comment")
commands+=("deselect")
- commands+=("id")
commands+=("label")
commands+=("ls")
commands+=("ls-id")
@@ -895,6 +915,7 @@ _git-bug_root_command()
commands+=("status")
commands+=("termui")
commands+=("title")
+ commands+=("user")
commands+=("version")
commands+=("webui")
diff --git a/misc/zsh_completion/git-bug b/misc/zsh_completion/git-bug
index d966b9be..1a705f7d 100644
--- a/misc/zsh_completion/git-bug
+++ b/misc/zsh_completion/git-bug
@@ -8,7 +8,7 @@ case $state in
level1)
case $words[1] in
git-bug)
- _arguments '1: :(add bridge commands comment deselect id label ls ls-label pull push select show status termui title version webui)'
+ _arguments '1: :(add bridge commands comment deselect label ls ls-label pull push select show status termui title user version webui)'
;;
*)
_arguments '*: :_files'
@@ -32,6 +32,9 @@ case $state in
title)
_arguments '2: :(edit)'
;;
+ user)
+ _arguments '2: :(create)'
+ ;;
*)
_arguments '*: :_files'
;;