aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/graphql/models/lazy_identity.go49
-rw-r--r--bridge/github/import.go2
-rw-r--r--bridge/github/import_test.go64
-rw-r--r--bridge/gitlab/import.go1
-rw-r--r--bridge/gitlab/import_test.go72
-rw-r--r--bridge/jira/import.go1
-rw-r--r--bridge/launchpad/import.go1
-rw-r--r--cache/identity_cache.go8
-rw-r--r--cache/repo_cache.go3
-rw-r--r--cache/repo_cache_identity.go13
-rw-r--r--commands/user.go14
-rw-r--r--commands/user_create.go2
-rw-r--r--doc/man/git-bug-user.12
-rw-r--r--doc/md/git-bug_user.md2
-rw-r--r--entity/id.go6
-rw-r--r--entity/interface.go6
-rw-r--r--go.sum1
-rw-r--r--misc/powershell_completion/git-bug4
-rw-r--r--misc/random_bugs/create_random_bugs.go11
19 files changed, 124 insertions, 138 deletions
diff --git a/api/graphql/models/lazy_identity.go b/api/graphql/models/lazy_identity.go
index 344bb5f0..002c38e4 100644
--- a/api/graphql/models/lazy_identity.go
+++ b/api/graphql/models/lazy_identity.go
@@ -7,8 +7,6 @@ import (
"github.com/MichaelMure/git-bug/cache"
"github.com/MichaelMure/git-bug/entity"
"github.com/MichaelMure/git-bug/identity"
- "github.com/MichaelMure/git-bug/util/lamport"
- "github.com/MichaelMure/git-bug/util/timestamp"
)
// IdentityWrapper is an interface used by the GraphQL resolvers to handle an identity.
@@ -21,11 +19,8 @@ type IdentityWrapper interface {
Login() (string, error)
AvatarUrl() (string, error)
Keys() ([]*identity.Key, error)
- ValidKeysAtTime(time lamport.Time) ([]*identity.Key, error)
DisplayName() string
IsProtected() (bool, error)
- LastModificationLamport() (lamport.Time, error)
- LastModification() (timestamp.Timestamp, error)
}
var _ IdentityWrapper = &lazyIdentity{}
@@ -69,6 +64,10 @@ func (li *lazyIdentity) Name() string {
return li.excerpt.Name
}
+func (li *lazyIdentity) DisplayName() string {
+ return li.excerpt.DisplayName()
+}
+
func (li *lazyIdentity) Email() (string, error) {
id, err := li.load()
if err != nil {
@@ -101,18 +100,6 @@ func (li *lazyIdentity) Keys() ([]*identity.Key, error) {
return id.Keys(), nil
}
-func (li *lazyIdentity) ValidKeysAtTime(time lamport.Time) ([]*identity.Key, error) {
- id, err := li.load()
- if err != nil {
- return nil, err
- }
- return id.ValidKeysAtTime(time), nil
-}
-
-func (li *lazyIdentity) DisplayName() string {
- return li.excerpt.DisplayName()
-}
-
func (li *lazyIdentity) IsProtected() (bool, error) {
id, err := li.load()
if err != nil {
@@ -121,22 +108,6 @@ func (li *lazyIdentity) IsProtected() (bool, error) {
return id.IsProtected(), nil
}
-func (li *lazyIdentity) LastModificationLamport() (lamport.Time, error) {
- id, err := li.load()
- if err != nil {
- return 0, err
- }
- return id.LastModificationLamport(), nil
-}
-
-func (li *lazyIdentity) LastModification() (timestamp.Timestamp, error) {
- id, err := li.load()
- if err != nil {
- return 0, err
- }
- return id.LastModification(), nil
-}
-
var _ IdentityWrapper = &loadedIdentity{}
type loadedIdentity struct {
@@ -163,18 +134,6 @@ func (l loadedIdentity) Keys() ([]*identity.Key, error) {
return l.Interface.Keys(), nil
}
-func (l loadedIdentity) ValidKeysAtTime(time lamport.Time) ([]*identity.Key, error) {
- return l.Interface.ValidKeysAtTime(time), nil
-}
-
func (l loadedIdentity) IsProtected() (bool, error) {
return l.Interface.IsProtected(), nil
}
-
-func (l loadedIdentity) LastModificationLamport() (lamport.Time, error) {
- return l.Interface.LastModificationLamport(), nil
-}
-
-func (l loadedIdentity) LastModification() (timestamp.Timestamp, error) {
- return l.Interface.LastModification(), nil
-}
diff --git a/bridge/github/import.go b/bridge/github/import.go
index e8a4d3cb..af62746f 100644
--- a/bridge/github/import.go
+++ b/bridge/github/import.go
@@ -551,6 +551,7 @@ func (gi *githubImporter) ensurePerson(repo *cache.RepoCache, actor *actor) (*ca
email,
string(actor.Login),
string(actor.AvatarUrl),
+ nil,
map[string]string{
metaKeyGithubLogin: string(actor.Login),
},
@@ -598,6 +599,7 @@ func (gi *githubImporter) getGhost(repo *cache.RepoCache) (*cache.IdentityCache,
"",
string(q.User.Login),
string(q.User.AvatarUrl),
+ nil,
map[string]string{
metaKeyGithubLogin: string(q.User.Login),
},
diff --git a/bridge/github/import_test.go b/bridge/github/import_test.go
index 2295806f..3d0004c1 100644
--- a/bridge/github/import_test.go
+++ b/bridge/github/import_test.go
@@ -7,7 +7,6 @@ import (
"testing"
"time"
- "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/MichaelMure/git-bug/bridge/core"
@@ -20,7 +19,22 @@ import (
)
func Test_Importer(t *testing.T) {
- author := identity.NewIdentity("Michael Muré", "batolettre@gmail.com")
+ envToken := os.Getenv("GITHUB_TOKEN_PRIVATE")
+ if envToken == "" {
+ t.Skip("Env var GITHUB_TOKEN_PRIVATE missing")
+ }
+
+ repo := repository.CreateGoGitTestRepo(false)
+ defer repository.CleanupTestRepos(repo)
+
+ backend, err := cache.NewRepoCache(repo)
+ require.NoError(t, err)
+
+ defer backend.Close()
+ interrupt.RegisterCleaner(backend.Close)
+
+ author, err := identity.NewIdentity(repo, "Michael Muré", "batolettre@gmail.com")
+ require.NoError(t, err)
tests := []struct {
name string
@@ -127,20 +141,6 @@ func Test_Importer(t *testing.T) {
},
}
- repo := repository.CreateGoGitTestRepo(false)
- defer repository.CleanupTestRepos(repo)
-
- backend, err := cache.NewRepoCache(repo)
- require.NoError(t, err)
-
- defer backend.Close()
- interrupt.RegisterCleaner(backend.Close)
-
- envToken := os.Getenv("GITHUB_TOKEN_PRIVATE")
- if envToken == "" {
- t.Skip("Env var GITHUB_TOKEN_PRIVATE missing")
- }
-
login := "test-identity"
author.SetMetadata(metaKeyGithubLogin, login)
@@ -178,33 +178,33 @@ func Test_Importer(t *testing.T) {
require.NoError(t, err)
ops := b.Snapshot().Operations
- assert.Len(t, tt.bug.Operations, len(b.Snapshot().Operations))
+ require.Len(t, tt.bug.Operations, len(b.Snapshot().Operations))
for i, op := range tt.bug.Operations {
require.IsType(t, ops[i], op)
switch op.(type) {
case *bug.CreateOperation:
- assert.Equal(t, op.(*bug.CreateOperation).Title, ops[i].(*bug.CreateOperation).Title)
- assert.Equal(t, op.(*bug.CreateOperation).Message, ops[i].(*bug.CreateOperation).Message)
- assert.Equal(t, op.(*bug.CreateOperation).Author.Name(), ops[i].(*bug.CreateOperation).Author.Name())
+ require.Equal(t, op.(*bug.CreateOperation).Title, ops[i].(*bug.CreateOperation).Title)
+ require.Equal(t, op.(*bug.CreateOperation).Message, ops[i].(*bug.CreateOperation).Message)
+ require.Equal(t, op.(*bug.CreateOperation).Author.Name(), ops[i].(*bug.CreateOperation).Author.Name())
case *bug.SetStatusOperation:
- assert.Equal(t, op.(*bug.SetStatusOperation).Status, ops[i].(*bug.SetStatusOperation).Status)
- assert.Equal(t, op.(*bug.SetStatusOperation).Author.Name(), ops[i].(*bug.SetStatusOperation).Author.Name())
+ require.Equal(t, op.(*bug.SetStatusOperation).Status, ops[i].(*bug.SetStatusOperation).Status)
+ require.Equal(t, op.(*bug.SetStatusOperation).Author.Name(), ops[i].(*bug.SetStatusOperation).Author.Name())
case *bug.SetTitleOperation:
- assert.Equal(t, op.(*bug.SetTitleOperation).Was, ops[i].(*bug.SetTitleOperation).Was)
- assert.Equal(t, op.(*bug.SetTitleOperation).Title, ops[i].(*bug.SetTitleOperation).Title)
- assert.Equal(t, op.(*bug.SetTitleOperation).Author.Name(), ops[i].(*bug.SetTitleOperation).Author.Name())
+ require.Equal(t, op.(*bug.SetTitleOperation).Was, ops[i].(*bug.SetTitleOperation).Was)
+ require.Equal(t, op.(*bug.SetTitleOperation).Title, ops[i].(*bug.SetTitleOperation).Title)
+ require.Equal(t, op.(*bug.SetTitleOperation).Author.Name(), ops[i].(*bug.SetTitleOperation).Author.Name())
case *bug.LabelChangeOperation:
- assert.ElementsMatch(t, op.(*bug.LabelChangeOperation).Added, ops[i].(*bug.LabelChangeOperation).Added)
- assert.ElementsMatch(t, op.(*bug.LabelChangeOperation).Removed, ops[i].(*bug.LabelChangeOperation).Removed)
- assert.Equal(t, op.(*bug.LabelChangeOperation).Author.Name(), ops[i].(*bug.LabelChangeOperation).Author.Name())
+ require.ElementsMatch(t, op.(*bug.LabelChangeOperation).Added, ops[i].(*bug.LabelChangeOperation).Added)
+ require.ElementsMatch(t, op.(*bug.LabelChangeOperation).Removed, ops[i].(*bug.LabelChangeOperation).Removed)
+ require.Equal(t, op.(*bug.LabelChangeOperation).Author.Name(), ops[i].(*bug.LabelChangeOperation).Author.Name())
case *bug.AddCommentOperation:
- assert.Equal(t, op.(*bug.AddCommentOperation).Message, ops[i].(*bug.AddCommentOperation).Message)
- assert.Equal(t, op.(*bug.AddCommentOperation).Author.Name(), ops[i].(*bug.AddCommentOperation).Author.Name())
+ require.Equal(t, op.(*bug.AddCommentOperation).Message, ops[i].(*bug.AddCommentOperation).Message)
+ require.Equal(t, op.(*bug.AddCommentOperation).Author.Name(), ops[i].(*bug.AddCommentOperation).Author.Name())
case *bug.EditCommentOperation:
- assert.Equal(t, op.(*bug.EditCommentOperation).Message, ops[i].(*bug.EditCommentOperation).Message)
- assert.Equal(t, op.(*bug.EditCommentOperation).Author.Name(), ops[i].(*bug.EditCommentOperation).Author.Name())
+ require.Equal(t, op.(*bug.EditCommentOperation).Message, ops[i].(*bug.EditCommentOperation).Message)
+ require.Equal(t, op.(*bug.EditCommentOperation).Author.Name(), ops[i].(*bug.EditCommentOperation).Author.Name())
default:
panic("unknown operation type")
diff --git a/bridge/gitlab/import.go b/bridge/gitlab/import.go
index cf4f0039..7939f4e4 100644
--- a/bridge/gitlab/import.go
+++ b/bridge/gitlab/import.go
@@ -406,6 +406,7 @@ func (gi *gitlabImporter) ensurePerson(repo *cache.RepoCache, id int) (*cache.Id
user.PublicEmail,
user.Username,
user.AvatarURL,
+ nil,
map[string]string{
// because Gitlab
metaKeyGitlabId: strconv.Itoa(id),
diff --git a/bridge/gitlab/import_test.go b/bridge/gitlab/import_test.go
index db550f08..7e47e149 100644
--- a/bridge/gitlab/import_test.go
+++ b/bridge/gitlab/import_test.go
@@ -7,7 +7,6 @@ import (
"testing"
"time"
- "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/MichaelMure/git-bug/bridge/core"
@@ -20,7 +19,27 @@ import (
)
func TestImport(t *testing.T) {
- author := identity.NewIdentity("Amine Hilaly", "hilalyamine@gmail.com")
+ envToken := os.Getenv("GITLAB_API_TOKEN")
+ if envToken == "" {
+ t.Skip("Env var GITLAB_API_TOKEN missing")
+ }
+
+ projectID := os.Getenv("GITLAB_PROJECT_ID")
+ if projectID == "" {
+ t.Skip("Env var GITLAB_PROJECT_ID missing")
+ }
+
+ repo := repository.CreateGoGitTestRepo(false)
+ defer repository.CleanupTestRepos(repo)
+
+ backend, err := cache.NewRepoCache(repo)
+ require.NoError(t, err)
+
+ defer backend.Close()
+ interrupt.RegisterCleaner(backend.Close)
+
+ author, err := identity.NewIdentity(repo, "Amine Hilaly", "hilalyamine@gmail.com")
+ require.NoError(t, err)
tests := []struct {
name string
@@ -76,25 +95,6 @@ func TestImport(t *testing.T) {
},
}
- repo := repository.CreateGoGitTestRepo(false)
- defer repository.CleanupTestRepos(repo)
-
- backend, err := cache.NewRepoCache(repo)
- require.NoError(t, err)
-
- defer backend.Close()
- interrupt.RegisterCleaner(backend.Close)
-
- envToken := os.Getenv("GITLAB_API_TOKEN")
- if envToken == "" {
- t.Skip("Env var GITLAB_API_TOKEN missing")
- }
-
- projectID := os.Getenv("GITLAB_PROJECT_ID")
- if projectID == "" {
- t.Skip("Env var GITLAB_PROJECT_ID missing")
- }
-
login := "test-identity"
author.SetMetadata(metaKeyGitlabLogin, login)
@@ -141,26 +141,26 @@ func TestImport(t *testing.T) {
switch op.(type) {
case *bug.CreateOperation:
- assert.Equal(t, op.(*bug.CreateOperation).Title, ops[i].(*bug.CreateOperation).Title)
- assert.Equal(t, op.(*bug.CreateOperation).Message, ops[i].(*bug.CreateOperation).Message)
- assert.Equal(t, op.(*bug.CreateOperation).Author.Name(), ops[i].(*bug.CreateOperation).Author.Name())
+ require.Equal(t, op.(*bug.CreateOperation).Title, ops[i].(*bug.CreateOperation).Title)
+ require.Equal(t, op.(*bug.CreateOperation).Message, ops[i].(*bug.CreateOperation).Message)
+ require.Equal(t, op.(*bug.CreateOperation).Author.Name(), ops[i].(*bug.CreateOperation).Author.Name())
case *bug.SetStatusOperation:
- assert.Equal(t, op.(*bug.SetStatusOperation).Status, ops[i].(*bug.SetStatusOperation).Status)
- assert.Equal(t, op.(*bug.SetStatusOperation).Author.Name(), ops[i].(*bug.SetStatusOperation).Author.Name())
+ require.Equal(t, op.(*bug.SetStatusOperation).Status, ops[i].(*bug.SetStatusOperation).Status)
+ require.Equal(t, op.(*bug.SetStatusOperation).Author.Name(), ops[i].(*bug.SetStatusOperation).Author.Name())
case *bug.SetTitleOperation:
- assert.Equal(t, op.(*bug.SetTitleOperation).Was, ops[i].(*bug.SetTitleOperation).Was)
- assert.Equal(t, op.(*bug.SetTitleOperation).Title, ops[i].(*bug.SetTitleOperation).Title)
- assert.Equal(t, op.(*bug.SetTitleOperation).Author.Name(), ops[i].(*bug.SetTitleOperation).Author.Name())
+ require.Equal(t, op.(*bug.SetTitleOperation).Was, ops[i].(*bug.SetTitleOperation).Was)
+ require.Equal(t, op.(*bug.SetTitleOperation).Title, ops[i].(*bug.SetTitleOperation).Title)
+ require.Equal(t, op.(*bug.SetTitleOperation).Author.Name(), ops[i].(*bug.SetTitleOperation).Author.Name())
case *bug.LabelChangeOperation:
- assert.ElementsMatch(t, op.(*bug.LabelChangeOperation).Added, ops[i].(*bug.LabelChangeOperation).Added)
- assert.ElementsMatch(t, op.(*bug.LabelChangeOperation).Removed, ops[i].(*bug.LabelChangeOperation).Removed)
- assert.Equal(t, op.(*bug.LabelChangeOperation).Author.Name(), ops[i].(*bug.LabelChangeOperation).Author.Name())
+ require.ElementsMatch(t, op.(*bug.LabelChangeOperation).Added, ops[i].(*bug.LabelChangeOperation).Added)
+ require.ElementsMatch(t, op.(*bug.LabelChangeOperation).Removed, ops[i].(*bug.LabelChangeOperation).Removed)
+ require.Equal(t, op.(*bug.LabelChangeOperation).Author.Name(), ops[i].(*bug.LabelChangeOperation).Author.Name())
case *bug.AddCommentOperation:
- assert.Equal(t, op.(*bug.AddCommentOperation).Message, ops[i].(*bug.AddCommentOperation).Message)
- assert.Equal(t, op.(*bug.AddCommentOperation).Author.Name(), ops[i].(*bug.AddCommentOperation).Author.Name())
+ require.Equal(t, op.(*bug.AddCommentOperation).Message, ops[i].(*bug.AddCommentOperation).Message)
+ require.Equal(t, op.(*bug.AddCommentOperation).Author.Name(), ops[i].(*bug.AddCommentOperation).Author.Name())
case *bug.EditCommentOperation:
- assert.Equal(t, op.(*bug.EditCommentOperation).Message, ops[i].(*bug.EditCommentOperation).Message)
- assert.Equal(t, op.(*bug.EditCommentOperation).Author.Name(), ops[i].(*bug.EditCommentOperation).Author.Name())
+ require.Equal(t, op.(*bug.EditCommentOperation).Message, ops[i].(*bug.EditCommentOperation).Message)
+ require.Equal(t, op.(*bug.EditCommentOperation).Author.Name(), ops[i].(*bug.EditCommentOperation).Author.Name())
default:
panic("unknown operation type")
diff --git a/bridge/jira/import.go b/bridge/jira/import.go
index b66b0fa3..00148bb6 100644
--- a/bridge/jira/import.go
+++ b/bridge/jira/import.go
@@ -196,6 +196,7 @@ func (ji *jiraImporter) ensurePerson(repo *cache.RepoCache, user User) (*cache.I
user.EmailAddress,
user.Key,
"",
+ nil,
map[string]string{
metaKeyJiraUser: user.Key,
},
diff --git a/bridge/launchpad/import.go b/bridge/launchpad/import.go
index ce50828b..6b5667ba 100644
--- a/bridge/launchpad/import.go
+++ b/bridge/launchpad/import.go
@@ -35,6 +35,7 @@ func (li *launchpadImporter) ensurePerson(repo *cache.RepoCache, owner LPPerson)
"",
owner.Login,
"",
+ nil,
map[string]string{
metaKeyLaunchpadLogin: owner.Login,
},
diff --git a/cache/identity_cache.go b/cache/identity_cache.go
index 25e273b9..e419387f 100644
--- a/cache/identity_cache.go
+++ b/cache/identity_cache.go
@@ -2,6 +2,7 @@ package cache
import (
"github.com/MichaelMure/git-bug/identity"
+ "github.com/MichaelMure/git-bug/repository"
)
var _ identity.Interface = &IdentityCache{}
@@ -23,8 +24,11 @@ func (i *IdentityCache) notifyUpdated() error {
return i.repoCache.identityUpdated(i.Identity.Id())
}
-func (i *IdentityCache) Mutate(f func(identity.Mutator) identity.Mutator) error {
- i.Identity.Mutate(f)
+func (i *IdentityCache) Mutate(repo repository.RepoClock, f func(*identity.Mutator)) error {
+ err := i.Identity.Mutate(repo, f)
+ if err != nil {
+ return err
+ }
return i.notifyUpdated()
}
diff --git a/cache/repo_cache.go b/cache/repo_cache.go
index b5b9ee54..ab3e1bcb 100644
--- a/cache/repo_cache.go
+++ b/cache/repo_cache.go
@@ -18,7 +18,8 @@ import (
// 1: original format
// 2: added cache for identities with a reference in the bug cache
// 3: no more legacy identity
-const formatVersion = 3
+// 4: entities make their IDs from data, not git commit
+const formatVersion = 4
// The maximum number of bugs loaded in memory. After that, eviction will be done.
const defaultMaxLoadedBugs = 1000
diff --git a/cache/repo_cache_identity.go b/cache/repo_cache_identity.go
index 8df5b810..75453cb8 100644
--- a/cache/repo_cache_identity.go
+++ b/cache/repo_cache_identity.go
@@ -225,17 +225,20 @@ func (c *RepoCache) NewIdentityFromGitUserRaw(metadata map[string]string) (*Iden
// NewIdentity create a new identity
// The new identity is written in the repository (commit)
func (c *RepoCache) NewIdentity(name string, email string) (*IdentityCache, error) {
- return c.NewIdentityRaw(name, email, "", "", nil)
+ return c.NewIdentityRaw(name, email, "", "", nil, 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) (*IdentityCache, error) {
- return c.NewIdentityRaw(name, email, login, avatarUrl, nil)
+func (c *RepoCache) NewIdentityFull(name string, email string, login string, avatarUrl string, keys []*identity.Key) (*IdentityCache, error) {
+ return c.NewIdentityRaw(name, email, login, avatarUrl, keys, nil)
}
-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)
+func (c *RepoCache) NewIdentityRaw(name string, email string, login string, avatarUrl string, keys []*identity.Key, metadata map[string]string) (*IdentityCache, error) {
+ i, err := identity.NewIdentityFull(c.repo, name, email, login, avatarUrl, keys)
+ if err != nil {
+ return nil, err
+ }
return c.finishIdentity(i, metadata)
}
diff --git a/commands/user.go b/commands/user.go
index d4d3fecd..29c4e932 100644
--- a/commands/user.go
+++ b/commands/user.go
@@ -35,7 +35,7 @@ func newUserCommand() *cobra.Command {
flags.SortFlags = false
flags.StringVarP(&options.fields, "field", "f", "",
- "Select field to display. Valid values are [email,humanId,id,lastModification,lastModificationLamport,login,metadata,name]")
+ "Select field to display. Valid values are [email,humanId,id,lastModification,lastModificationLamports,login,metadata,name]")
return cmd
}
@@ -71,7 +71,9 @@ func runUser(env *Env, opts userOptions, args []string) error {
env.out.Printf("%s\n", id.LastModification().
Time().Format("Mon Jan 2 15:04:05 2006 +0200"))
case "lastModificationLamport":
- env.out.Printf("%d\n", id.LastModificationLamport())
+ for name, t := range id.LastModificationLamports() {
+ env.out.Printf("%s\n%d\n", name, t)
+ }
case "metadata":
for key, value := range id.ImmutableMetadata() {
env.out.Printf("%s\n%s\n", key, value)
@@ -90,9 +92,11 @@ func runUser(env *Env, opts userOptions, args []string) error {
env.out.Printf("Name: %s\n", id.Name())
env.out.Printf("Email: %s\n", id.Email())
env.out.Printf("Login: %s\n", id.Login())
- env.out.Printf("Last modification: %s (lamport %d)\n",
- id.LastModification().Time().Format("Mon Jan 2 15:04:05 2006 +0200"),
- id.LastModificationLamport())
+ env.out.Printf("Last modification: %s\n", id.LastModification().Time().Format("Mon Jan 2 15:04:05 2006 +0200"))
+ env.out.Printf("Last moditication (lamport):\n")
+ for name, t := range id.LastModificationLamports() {
+ env.out.Printf("\t%s: %d", name, t)
+ }
env.out.Println("Metadata:")
for key, value := range id.ImmutableMetadata() {
env.out.Printf(" %s --> %s\n", key, value)
diff --git a/commands/user_create.go b/commands/user_create.go
index 3da712f3..5203d11c 100644
--- a/commands/user_create.go
+++ b/commands/user_create.go
@@ -48,7 +48,7 @@ func runUserCreate(env *Env) error {
return err
}
- id, err := env.backend.NewIdentityRaw(name, email, "", avatarURL, nil)
+ id, err := env.backend.NewIdentityRaw(name, email, "", avatarURL, nil, nil)
if err != nil {
return err
}
diff --git a/doc/man/git-bug-user.1 b/doc/man/git-bug-user.1
index 39925433..c4ca0e54 100644
--- a/doc/man/git-bug-user.1
+++ b/doc/man/git-bug-user.1
@@ -19,7 +19,7 @@ Display or change the user identity.
.SH OPTIONS
.PP
\fB\-f\fP, \fB\-\-field\fP=""
- Select field to display. Valid values are [email,humanId,id,lastModification,lastModificationLamport,login,metadata,name]
+ Select field to display. Valid values are [email,humanId,id,lastModification,lastModificationLamports,login,metadata,name]
.PP
\fB\-h\fP, \fB\-\-help\fP[=false]
diff --git a/doc/md/git-bug_user.md b/doc/md/git-bug_user.md
index d9388def..302a1eda 100644
--- a/doc/md/git-bug_user.md
+++ b/doc/md/git-bug_user.md
@@ -9,7 +9,7 @@ git-bug user [USER-ID] [flags]
### Options
```
- -f, --field string Select field to display. Valid values are [email,humanId,id,lastModification,lastModificationLamport,login,metadata,name]
+ -f, --field string Select field to display. Valid values are [email,humanId,id,lastModification,lastModificationLamports,login,metadata,name]
-h, --help help for user
```
diff --git a/entity/id.go b/entity/id.go
index 1b78aacd..08916987 100644
--- a/entity/id.go
+++ b/entity/id.go
@@ -8,8 +8,8 @@ import (
"github.com/pkg/errors"
)
-const IdLengthSHA1 = 40
-const IdLengthSHA256 = 64
+// sha-256
+const idLength = 64
const humanIdLength = 7
const UnsetId = Id("unset")
@@ -55,7 +55,7 @@ func (i Id) MarshalGQL(w io.Writer) {
// IsValid tell if the Id is valid
func (i Id) Validate() error {
- if len(i) != IdLengthSHA1 && len(i) != IdLengthSHA256 {
+ if len(i) != idLength {
return fmt.Errorf("invalid length")
}
for _, r := range i {
diff --git a/entity/interface.go b/entity/interface.go
index dd5d69b1..fb4735e4 100644
--- a/entity/interface.go
+++ b/entity/interface.go
@@ -2,5 +2,11 @@ package entity
type Interface interface {
// Id return the Entity identifier
+ //
+ // This Id need to be immutable without having to store the entity somewhere (ie, an entity only in memory
+ // should have a valid Id, and it should not change if further edit are done on this entity).
+ // How to achieve that is up to the entity itself. A common way would be to take a hash of an immutable data at
+ // the root of the entity.
+ // It is acceptable to use such a hash and keep mutating that data as long as Id() is not called.
Id() Id
}
diff --git a/go.sum b/go.sum
index c6875b9a..9d0a8c82 100644
--- a/go.sum
+++ b/go.sum
@@ -727,6 +727,7 @@ golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200825202427-b303f430e36d h1:W07d4xkoAUSNOkOzdzXCdFGxT7o2rW4q8M34tB2i//k=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/misc/powershell_completion/git-bug b/misc/powershell_completion/git-bug
index c2aa0adf..29c28237 100644
--- a/misc/powershell_completion/git-bug
+++ b/misc/powershell_completion/git-bug
@@ -212,8 +212,8 @@ Register-ArgumentCompleter -Native -CommandName 'git-bug' -ScriptBlock {
break
}
'git-bug;user' {
- [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'Select field to display. Valid values are [email,humanId,id,lastModification,lastModificationLamport,login,metadata,name]')
- [CompletionResult]::new('--field', 'field', [CompletionResultType]::ParameterName, 'Select field to display. Valid values are [email,humanId,id,lastModification,lastModificationLamport,login,metadata,name]')
+ [CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'Select field to display. Valid values are [email,humanId,id,lastModification,lastModificationLamports,login,metadata,name]')
+ [CompletionResult]::new('--field', 'field', [CompletionResultType]::ParameterName, 'Select field to display. Valid values are [email,humanId,id,lastModification,lastModificationLamports,login,metadata,name]')
[CompletionResult]::new('adopt', 'adopt', [CompletionResultType]::ParameterValue, 'Adopt an existing identity as your own.')
[CompletionResult]::new('create', 'create', [CompletionResultType]::ParameterValue, 'Create a new identity.')
[CompletionResult]::new('ls', 'ls', [CompletionResultType]::ParameterValue, 'List identities.')
diff --git a/misc/random_bugs/create_random_bugs.go b/misc/random_bugs/create_random_bugs.go
index 2de77722..3d93135e 100644
--- a/misc/random_bugs/create_random_bugs.go
+++ b/misc/random_bugs/create_random_bugs.go
@@ -157,8 +157,8 @@ func GenerateRandomOperationPacksWithSeed(packNumber int, opNumber int, seed int
return result
}
-func person() *identity.Identity {
- return identity.NewIdentity(fake.FullName(), fake.EmailAddress())
+func person(repo repository.RepoClock) (*identity.Identity, error) {
+ return identity.NewIdentity(repo, fake.FullName(), fake.EmailAddress())
}
var persons []*identity.Identity
@@ -166,8 +166,11 @@ var persons []*identity.Identity
func generateRandomPersons(repo repository.ClockedRepo, n int) {
persons = make([]*identity.Identity, n)
for i := range persons {
- p := person()
- err := p.Commit(repo)
+ p, err := person(repo)
+ if err != nil {
+ panic(err)
+ }
+ err = p.Commit(repo)
if err != nil {
panic(err)
}