From 864eae0d6bd0732260c0c56583bb77f9b25b60f6 Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Sun, 17 Feb 2019 16:12:06 +0100 Subject: identity: work on higher level now, cache, first two identity commands --- bridge/github/import.go | 4 +-- bridge/launchpad/import.go | 2 +- cache/bug_cache.go | 38 ++++++++++----------- cache/identity_cache.go | 26 ++++++++++++++ cache/repo_cache.go | 68 +++++++++++++++++++++++++++--------- commands/id.go | 49 -------------------------- commands/user.go | 56 ++++++++++++++++++++++++++++++ commands/user_create.go | 76 +++++++++++++++++++++++++++++++++++++++++ doc/man/git-bug-bridge-bridge.1 | 29 ---------------- doc/man/git-bug-id.1 | 29 ---------------- doc/man/git-bug-user-create.1 | 29 ++++++++++++++++ doc/man/git-bug-user.1 | 29 ++++++++++++++++ doc/man/git-bug.1 | 2 +- doc/md/git-bug.md | 2 +- doc/md/git-bug_bridge_bridge.md | 22 ------------ doc/md/git-bug_close.md | 22 ------------ doc/md/git-bug_id.md | 22 ------------ doc/md/git-bug_new.md | 25 -------------- doc/md/git-bug_open.md | 22 ------------ doc/md/git-bug_user.md | 23 +++++++++++++ doc/md/git-bug_user_create.md | 22 ++++++++++++ identity/identity.go | 16 ++++++++- input/prompt.go | 44 ++++++++++++++++++++++++ misc/bash_completion/git-bug | 63 ++++++++++++++++++++++------------ misc/zsh_completion/git-bug | 5 ++- 25 files changed, 441 insertions(+), 284 deletions(-) create mode 100644 cache/identity_cache.go delete mode 100644 commands/id.go create mode 100644 commands/user.go create mode 100644 commands/user_create.go delete mode 100644 doc/man/git-bug-bridge-bridge.1 delete mode 100644 doc/man/git-bug-id.1 create mode 100644 doc/man/git-bug-user-create.1 create mode 100644 doc/man/git-bug-user.1 delete mode 100644 doc/md/git-bug_bridge_bridge.md delete mode 100644 doc/md/git-bug_close.md delete mode 100644 doc/md/git-bug_id.md delete mode 100644 doc/md/git-bug_new.md delete mode 100644 doc/md/git-bug_open.md create mode 100644 doc/md/git-bug_user.md create mode 100644 doc/md/git-bug_user_create.md create mode 100644 input/prompt.go 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 []", - 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 []", + 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-id.1 b/doc/man/git-bug-id.1 deleted file mode 100644 index b3baf589..00000000 --- a/doc/man/git-bug-id.1 +++ /dev/null @@ -1,29 +0,0 @@ -.TH "GIT-BUG" "1" "Feb 2019" "Generated from git-bug's source code" "" -.nh -.ad l - - -.SH NAME -.PP -git\-bug\-id \- Display or change the user identity - - -.SH SYNOPSIS -.PP -\fBgit\-bug id [] [flags]\fP - - -.SH DESCRIPTION -.PP -Display or change the user identity - - -.SH OPTIONS -.PP -\fB\-h\fP, \fB\-\-help\fP[=false] - help for id - - -.SH SEE ALSO -.PP -\fBgit\-bug(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-user.1 b/doc/man/git-bug-user.1 new file mode 100644 index 00000000..eb074973 --- /dev/null +++ b/doc/man/git-bug-user.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 \- Display or change the user identity + + +.SH SYNOPSIS +.PP +\fBgit\-bug user [] [flags]\fP + + +.SH DESCRIPTION +.PP +Display or change the user identity + + +.SH OPTIONS +.PP +\fB\-h\fP, \fB\-\-help\fP[=false] + help for user + + +.SH SEE ALSO +.PP +\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 [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_id.md b/doc/md/git-bug_id.md deleted file mode 100644 index 09f8f276..00000000 --- a/doc/md/git-bug_id.md +++ /dev/null @@ -1,22 +0,0 @@ -## git-bug id - -Display or change the user identity - -### Synopsis - -Display or change the user identity - -``` -git-bug id [] [flags] -``` - -### Options - -``` - -h, --help help for id -``` - -### SEE ALSO - -* [git-bug](git-bug.md) - A bug tracker 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 [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_user.md b/doc/md/git-bug_user.md new file mode 100644 index 00000000..5692b40a --- /dev/null +++ b/doc/md/git-bug_user.md @@ -0,0 +1,23 @@ +## git-bug user + +Display or change the user identity + +### Synopsis + +Display or change the user identity + +``` +git-bug user [] [flags] +``` + +### Options + +``` + -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' ;; -- cgit