mirror of
https://github.com/MichaelMure/git-bug.git
synced 2024-12-14 17:51:44 +03:00
identity: remove support for legacy identity
This commit is contained in:
parent
5d1fc3ff39
commit
499dbc0a03
@ -6,12 +6,18 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/MichaelMure/git-bug/identity"
|
||||
"github.com/MichaelMure/git-bug/repository"
|
||||
)
|
||||
|
||||
func TestAddCommentSerialize(t *testing.T) {
|
||||
var rene = identity.NewBare("René Descartes", "rene@descartes.fr")
|
||||
repo := repository.NewMockRepoForTest()
|
||||
rene := identity.NewIdentity("René Descartes", "rene@descartes.fr")
|
||||
err := rene.Commit(repo)
|
||||
require.NoError(t, err)
|
||||
|
||||
unix := time.Now().Unix()
|
||||
before := NewAddCommentOp(rene, unix, "message", nil)
|
||||
|
||||
@ -22,9 +28,12 @@ func TestAddCommentSerialize(t *testing.T) {
|
||||
err = json.Unmarshal(data, &after)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// enforce creating the IDs
|
||||
// enforce creating the ID
|
||||
before.Id()
|
||||
rene.Id()
|
||||
|
||||
// Replace the identity stub with the real thing
|
||||
assert.Equal(t, rene.Id(), after.base().Author.Id())
|
||||
after.Author = rene
|
||||
|
||||
assert.Equal(t, before, &after)
|
||||
}
|
||||
|
@ -6,14 +6,16 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/MichaelMure/git-bug/identity"
|
||||
"github.com/MichaelMure/git-bug/repository"
|
||||
"github.com/MichaelMure/git-bug/util/timestamp"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
snapshot := Snapshot{}
|
||||
|
||||
rene := identity.NewBare("René Descartes", "rene@descartes.fr")
|
||||
rene := identity.NewIdentity("René Descartes", "rene@descartes.fr")
|
||||
unix := time.Now().Unix()
|
||||
|
||||
create := NewCreateOp(rene, unix, "title", "message", nil)
|
||||
@ -50,7 +52,11 @@ func TestCreate(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCreateSerialize(t *testing.T) {
|
||||
var rene = identity.NewBare("René Descartes", "rene@descartes.fr")
|
||||
repo := repository.NewMockRepoForTest()
|
||||
rene := identity.NewIdentity("René Descartes", "rene@descartes.fr")
|
||||
err := rene.Commit(repo)
|
||||
require.NoError(t, err)
|
||||
|
||||
unix := time.Now().Unix()
|
||||
before := NewCreateOp(rene, unix, "title", "message", nil)
|
||||
|
||||
@ -61,9 +67,12 @@ func TestCreateSerialize(t *testing.T) {
|
||||
err = json.Unmarshal(data, &after)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// enforce creating the IDs
|
||||
// enforce creating the ID
|
||||
before.Id()
|
||||
rene.Id()
|
||||
|
||||
// Replace the identity stub with the real thing
|
||||
assert.Equal(t, rene.Id(), after.base().Author.Id())
|
||||
after.Author = rene
|
||||
|
||||
assert.Equal(t, before, &after)
|
||||
}
|
||||
|
@ -9,12 +9,17 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/MichaelMure/git-bug/identity"
|
||||
"github.com/MichaelMure/git-bug/repository"
|
||||
)
|
||||
|
||||
func TestEdit(t *testing.T) {
|
||||
snapshot := Snapshot{}
|
||||
|
||||
rene := identity.NewBare("René Descartes", "rene@descartes.fr")
|
||||
repo := repository.NewMockRepoForTest()
|
||||
rene := identity.NewIdentity("René Descartes", "rene@descartes.fr")
|
||||
err := rene.Commit(repo)
|
||||
require.NoError(t, err)
|
||||
|
||||
unix := time.Now().Unix()
|
||||
|
||||
create := NewCreateOp(rene, unix, "title", "create", nil)
|
||||
@ -74,7 +79,11 @@ func TestEdit(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEditCommentSerialize(t *testing.T) {
|
||||
var rene = identity.NewBare("René Descartes", "rene@descartes.fr")
|
||||
repo := repository.NewMockRepoForTest()
|
||||
rene := identity.NewIdentity("René Descartes", "rene@descartes.fr")
|
||||
err := rene.Commit(repo)
|
||||
require.NoError(t, err)
|
||||
|
||||
unix := time.Now().Unix()
|
||||
before := NewEditCommentOp(rene, unix, "target", "message", nil)
|
||||
|
||||
@ -85,9 +94,12 @@ func TestEditCommentSerialize(t *testing.T) {
|
||||
err = json.Unmarshal(data, &after)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// enforce creating the IDs
|
||||
// enforce creating the ID
|
||||
before.Id()
|
||||
rene.Id()
|
||||
|
||||
// Replace the identity stub with the real thing
|
||||
assert.Equal(t, rene.Id(), after.base().Author.Id())
|
||||
after.Author = rene
|
||||
|
||||
assert.Equal(t, before, &after)
|
||||
}
|
||||
|
@ -5,12 +5,20 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/MichaelMure/git-bug/identity"
|
||||
"github.com/MichaelMure/git-bug/repository"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestLabelChangeSerialize(t *testing.T) {
|
||||
var rene = identity.NewBare("René Descartes", "rene@descartes.fr")
|
||||
repo := repository.NewMockRepoForTest()
|
||||
rene := identity.NewIdentity("René Descartes", "rene@descartes.fr")
|
||||
err := rene.Commit(repo)
|
||||
require.NoError(t, err)
|
||||
|
||||
unix := time.Now().Unix()
|
||||
before := NewLabelChangeOperation(rene, unix, []Label{"added"}, []Label{"removed"})
|
||||
|
||||
@ -21,9 +29,12 @@ func TestLabelChangeSerialize(t *testing.T) {
|
||||
err = json.Unmarshal(data, &after)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// enforce creating the IDs
|
||||
// enforce creating the ID
|
||||
before.Id()
|
||||
rene.Id()
|
||||
|
||||
// Replace the identity stub with the real thing
|
||||
assert.Equal(t, rene.Id(), after.base().Author.Id())
|
||||
after.Author = rene
|
||||
|
||||
assert.Equal(t, before, &after)
|
||||
}
|
||||
|
@ -5,12 +5,20 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/MichaelMure/git-bug/identity"
|
||||
"github.com/MichaelMure/git-bug/repository"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNoopSerialize(t *testing.T) {
|
||||
var rene = identity.NewBare("René Descartes", "rene@descartes.fr")
|
||||
repo := repository.NewMockRepoForTest()
|
||||
rene := identity.NewIdentity("René Descartes", "rene@descartes.fr")
|
||||
err := rene.Commit(repo)
|
||||
require.NoError(t, err)
|
||||
|
||||
unix := time.Now().Unix()
|
||||
before := NewNoOpOp(rene, unix)
|
||||
|
||||
@ -21,9 +29,12 @@ func TestNoopSerialize(t *testing.T) {
|
||||
err = json.Unmarshal(data, &after)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// enforce creating the IDs
|
||||
// enforce creating the ID
|
||||
before.Id()
|
||||
rene.Id()
|
||||
|
||||
// Replace the identity stub with the real thing
|
||||
assert.Equal(t, rene.Id(), after.base().Author.Id())
|
||||
after.Author = rene
|
||||
|
||||
assert.Equal(t, before, &after)
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/MichaelMure/git-bug/identity"
|
||||
"github.com/MichaelMure/git-bug/repository"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@ -13,7 +15,11 @@ import (
|
||||
func TestSetMetadata(t *testing.T) {
|
||||
snapshot := Snapshot{}
|
||||
|
||||
rene := identity.NewBare("René Descartes", "rene@descartes.fr")
|
||||
repo := repository.NewMockRepoForTest()
|
||||
rene := identity.NewIdentity("René Descartes", "rene@descartes.fr")
|
||||
err := rene.Commit(repo)
|
||||
require.NoError(t, err)
|
||||
|
||||
unix := time.Now().Unix()
|
||||
|
||||
create := NewCreateOp(rene, unix, "title", "create", nil)
|
||||
@ -93,7 +99,11 @@ func TestSetMetadata(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSetMetadataSerialize(t *testing.T) {
|
||||
var rene = identity.NewBare("René Descartes", "rene@descartes.fr")
|
||||
repo := repository.NewMockRepoForTest()
|
||||
rene := identity.NewIdentity("René Descartes", "rene@descartes.fr")
|
||||
err := rene.Commit(repo)
|
||||
require.NoError(t, err)
|
||||
|
||||
unix := time.Now().Unix()
|
||||
before := NewSetMetadataOp(rene, unix, "message", map[string]string{
|
||||
"key1": "value1",
|
||||
@ -107,9 +117,12 @@ func TestSetMetadataSerialize(t *testing.T) {
|
||||
err = json.Unmarshal(data, &after)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// enforce creating the IDs
|
||||
// enforce creating the ID
|
||||
before.Id()
|
||||
rene.Id()
|
||||
|
||||
// Replace the identity stub with the real thing
|
||||
assert.Equal(t, rene.Id(), after.base().Author.Id())
|
||||
after.Author = rene
|
||||
|
||||
assert.Equal(t, before, &after)
|
||||
}
|
||||
|
@ -5,12 +5,20 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/MichaelMure/git-bug/identity"
|
||||
"github.com/MichaelMure/git-bug/repository"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSetStatusSerialize(t *testing.T) {
|
||||
var rene = identity.NewBare("René Descartes", "rene@descartes.fr")
|
||||
repo := repository.NewMockRepoForTest()
|
||||
rene := identity.NewIdentity("René Descartes", "rene@descartes.fr")
|
||||
err := rene.Commit(repo)
|
||||
require.NoError(t, err)
|
||||
|
||||
unix := time.Now().Unix()
|
||||
before := NewSetStatusOp(rene, unix, ClosedStatus)
|
||||
|
||||
@ -21,9 +29,12 @@ func TestSetStatusSerialize(t *testing.T) {
|
||||
err = json.Unmarshal(data, &after)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// enforce creating the IDs
|
||||
// enforce creating the ID
|
||||
before.Id()
|
||||
rene.Id()
|
||||
|
||||
// Replace the identity stub with the real thing
|
||||
assert.Equal(t, rene.Id(), after.base().Author.Id())
|
||||
after.Author = rene
|
||||
|
||||
assert.Equal(t, before, &after)
|
||||
}
|
||||
|
@ -5,12 +5,20 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/MichaelMure/git-bug/identity"
|
||||
"github.com/MichaelMure/git-bug/repository"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSetTitleSerialize(t *testing.T) {
|
||||
var rene = identity.NewBare("René Descartes", "rene@descartes.fr")
|
||||
repo := repository.NewMockRepoForTest()
|
||||
rene := identity.NewIdentity("René Descartes", "rene@descartes.fr")
|
||||
err := rene.Commit(repo)
|
||||
require.NoError(t, err)
|
||||
|
||||
unix := time.Now().Unix()
|
||||
before := NewSetTitleOp(rene, unix, "title", "was")
|
||||
|
||||
@ -21,9 +29,12 @@ func TestSetTitleSerialize(t *testing.T) {
|
||||
err = json.Unmarshal(data, &after)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// enforce creating the IDs
|
||||
// enforce creating the ID
|
||||
before.Id()
|
||||
rene.Id()
|
||||
|
||||
// Replace the identity stub with the real thing
|
||||
assert.Equal(t, rene.Id(), after.base().Author.Id())
|
||||
after.Author = rene
|
||||
|
||||
assert.Equal(t, before, &after)
|
||||
}
|
||||
|
@ -9,7 +9,9 @@ import (
|
||||
"github.com/MichaelMure/git-bug/repository"
|
||||
)
|
||||
|
||||
const formatVersion = 1
|
||||
// 1: original format
|
||||
// 2: no more legacy identities
|
||||
const formatVersion = 2
|
||||
|
||||
// OperationPack represent an ordered set of operation to apply
|
||||
// to a Bug. These operations are stored in a single Git commit.
|
||||
@ -44,8 +46,11 @@ func (opp *OperationPack) UnmarshalJSON(data []byte) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if aux.Version != formatVersion {
|
||||
return fmt.Errorf("unknown format version %v", aux.Version)
|
||||
if aux.Version < formatVersion {
|
||||
return fmt.Errorf("outdated repository format, please use https://github.com/MichaelMure/git-bug-migration to upgrade")
|
||||
}
|
||||
if aux.Version > formatVersion {
|
||||
return fmt.Errorf("your version of git-bug is too old for this repository (version %v), please upgrade to the latest version", aux.Version)
|
||||
}
|
||||
|
||||
for _, raw := range aux.Operations {
|
||||
|
@ -15,7 +15,11 @@ import (
|
||||
func TestOperationPackSerialize(t *testing.T) {
|
||||
opp := &OperationPack{}
|
||||
|
||||
rene := identity.NewBare("René Descartes", "rene@descartes.fr")
|
||||
repo := repository.NewMockRepoForTest()
|
||||
rene := identity.NewIdentity("René Descartes", "rene@descartes.fr")
|
||||
err := rene.Commit(repo)
|
||||
require.NoError(t, err)
|
||||
|
||||
createOp := NewCreateOp(rene, time.Now().Unix(), "title", "message", nil)
|
||||
setTitleOp := NewSetTitleOp(rene, time.Now().Unix(), "title2", "title1")
|
||||
addCommentOp := NewAddCommentOp(rene, time.Now().Unix(), "message2", nil)
|
||||
@ -49,16 +53,27 @@ func TestOperationPackSerialize(t *testing.T) {
|
||||
err = json.Unmarshal(data, &opp2)
|
||||
assert.NoError(t, err)
|
||||
|
||||
ensureIDs(t, opp)
|
||||
ensureIds(opp)
|
||||
ensureAuthors(t, opp, opp2)
|
||||
|
||||
assert.Equal(t, opp, opp2)
|
||||
}
|
||||
|
||||
func ensureIDs(t *testing.T, opp *OperationPack) {
|
||||
func ensureIds(opp *OperationPack) {
|
||||
for _, op := range opp.Operations {
|
||||
id := op.Id()
|
||||
require.NoError(t, id.Validate())
|
||||
id = op.GetAuthor().Id()
|
||||
require.NoError(t, id.Validate())
|
||||
op.Id()
|
||||
}
|
||||
}
|
||||
|
||||
func ensureAuthors(t *testing.T, opp1 *OperationPack, opp2 *OperationPack) {
|
||||
require.Equal(t, len(opp1.Operations), len(opp2.Operations))
|
||||
for i := 0; i < len(opp1.Operations); i++ {
|
||||
op1 := opp1.Operations[i]
|
||||
op2 := opp2.Operations[i]
|
||||
|
||||
// ensure we have equivalent authors (IdentityStub vs Identity) then
|
||||
// enforce equality
|
||||
require.Equal(t, op1.base().Author.Id(), op2.base().Author.Id())
|
||||
op1.base().Author = op2.base().Author
|
||||
}
|
||||
}
|
||||
|
@ -88,32 +88,32 @@ func TestID(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, repo := range repos {
|
||||
rene := identity.NewBare("René Descartes", "rene@descartes.fr")
|
||||
rene := identity.NewIdentity("René Descartes", "rene@descartes.fr")
|
||||
err := rene.Commit(repo)
|
||||
require.NoError(t, err)
|
||||
|
||||
b, op, err := Create(rene, time.Now().Unix(), "title", "message")
|
||||
require.Nil(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
id1 := op.Id()
|
||||
require.NoError(t, id1.Validate())
|
||||
|
||||
err = b.Commit(repo)
|
||||
require.Nil(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
op2 := b.FirstOp()
|
||||
|
||||
id2 := op2.Id()
|
||||
require.NoError(t, id2.Validate())
|
||||
|
||||
require.Equal(t, id1, id2)
|
||||
|
||||
b2, err := ReadLocal(repo, b.Id())
|
||||
require.Nil(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
op3 := b2.FirstOp()
|
||||
|
||||
id3 := op3.Id()
|
||||
require.NoError(t, id3.Validate())
|
||||
|
||||
require.Equal(t, id1, id3)
|
||||
}
|
||||
}
|
||||
|
12
cache/bug_excerpt.go
vendored
12
cache/bug_excerpt.go
vendored
@ -26,6 +26,7 @@ type BugExcerpt struct {
|
||||
CreateUnixTime int64
|
||||
EditUnixTime int64
|
||||
|
||||
AuthorId entity.Id
|
||||
Status bug.Status
|
||||
Labels []bug.Label
|
||||
Title string
|
||||
@ -33,12 +34,6 @@ type BugExcerpt struct {
|
||||
Actors []entity.Id
|
||||
Participants []entity.Id
|
||||
|
||||
// If author is identity.Bare, LegacyAuthor is set
|
||||
// If author is identity.Identity, AuthorId is set and data is deported
|
||||
// in a IdentityExcerpt
|
||||
LegacyAuthor LegacyAuthorExcerpt
|
||||
AuthorId entity.Id
|
||||
|
||||
CreateMetadata map[string]string
|
||||
}
|
||||
|
||||
@ -94,11 +89,6 @@ func NewBugExcerpt(b bug.Interface, snap *bug.Snapshot) *BugExcerpt {
|
||||
switch snap.Author.(type) {
|
||||
case *identity.Identity, *IdentityCache:
|
||||
e.AuthorId = snap.Author.Id()
|
||||
case *identity.Bare:
|
||||
e.LegacyAuthor = LegacyAuthorExcerpt{
|
||||
Login: snap.Author.Login(),
|
||||
Name: snap.Author.Name(),
|
||||
}
|
||||
default:
|
||||
panic("unhandled identity type")
|
||||
}
|
||||
|
15
cache/filter.go
vendored
15
cache/filter.go
vendored
@ -29,19 +29,12 @@ func AuthorFilter(query string) Filter {
|
||||
return func(excerpt *BugExcerpt, resolver resolver) bool {
|
||||
query = strings.ToLower(query)
|
||||
|
||||
// Normal identity
|
||||
if excerpt.AuthorId != "" {
|
||||
author, err := resolver.ResolveIdentityExcerpt(excerpt.AuthorId)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return author.Match(query)
|
||||
author, err := resolver.ResolveIdentityExcerpt(excerpt.AuthorId)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Legacy identity support
|
||||
return strings.Contains(strings.ToLower(excerpt.LegacyAuthor.Name), query) ||
|
||||
strings.Contains(strings.ToLower(excerpt.LegacyAuthor.Login), query)
|
||||
return author.Match(query)
|
||||
}
|
||||
}
|
||||
|
||||
|
3
cache/repo_cache.go
vendored
3
cache/repo_cache.go
vendored
@ -19,7 +19,8 @@ import (
|
||||
|
||||
// 1: original format
|
||||
// 2: added cache for identities with a reference in the bug cache
|
||||
const formatVersion = 2
|
||||
// 3: no more legacy identity
|
||||
const formatVersion = 3
|
||||
|
||||
// The maximum number of bugs loaded in memory. After that, eviction will be done.
|
||||
const defaultMaxLoadedBugs = 1000
|
||||
|
@ -151,15 +151,11 @@ func lsJsonFormatter(env *Env, bugExcerpts []*cache.BugExcerpt) error {
|
||||
Metadata: b.CreateMetadata,
|
||||
}
|
||||
|
||||
if b.AuthorId != "" {
|
||||
author, err := env.backend.ResolveIdentityExcerpt(b.AuthorId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
jsonBug.Author = NewJSONIdentityFromExcerpt(author)
|
||||
} else {
|
||||
jsonBug.Author = NewJSONIdentityFromLegacyExcerpt(&b.LegacyAuthor)
|
||||
author, err := env.backend.ResolveIdentityExcerpt(b.AuthorId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
jsonBug.Author = NewJSONIdentityFromExcerpt(author)
|
||||
|
||||
jsonBug.Actors = make([]JSONIdentity, len(b.Actors))
|
||||
for i, element := range b.Actors {
|
||||
@ -188,15 +184,9 @@ func lsJsonFormatter(env *Env, bugExcerpts []*cache.BugExcerpt) error {
|
||||
|
||||
func lsDefaultFormatter(env *Env, bugExcerpts []*cache.BugExcerpt) error {
|
||||
for _, b := range bugExcerpts {
|
||||
var name string
|
||||
if b.AuthorId != "" {
|
||||
author, err := env.backend.ResolveIdentityExcerpt(b.AuthorId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name = author.DisplayName()
|
||||
} else {
|
||||
name = b.LegacyAuthor.DisplayName()
|
||||
author, err := env.backend.ResolveIdentityExcerpt(b.AuthorId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var labelsTxt strings.Builder
|
||||
@ -210,7 +200,7 @@ func lsDefaultFormatter(env *Env, bugExcerpts []*cache.BugExcerpt) error {
|
||||
// truncate + pad if needed
|
||||
labelsFmt := text.TruncateMax(labelsTxt.String(), 10)
|
||||
titleFmt := text.LeftPadMaxLine(strings.TrimSpace(b.Title), 50-text.Len(labelsFmt), 0)
|
||||
authorFmt := text.LeftPadMaxLine(name, 15, 0)
|
||||
authorFmt := text.LeftPadMaxLine(author.DisplayName(), 15, 0)
|
||||
|
||||
comments := fmt.Sprintf("%3d 💬", b.LenComments-1)
|
||||
if b.LenComments-1 <= 0 {
|
||||
@ -261,15 +251,9 @@ func lsOrgmodeFormatter(env *Env, bugExcerpts []*cache.BugExcerpt) error {
|
||||
title = b.Title
|
||||
}
|
||||
|
||||
var name string
|
||||
if b.AuthorId != "" {
|
||||
author, err := env.backend.ResolveIdentityExcerpt(b.AuthorId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name = author.DisplayName()
|
||||
} else {
|
||||
name = b.LegacyAuthor.DisplayName()
|
||||
author, err := env.backend.ResolveIdentityExcerpt(b.AuthorId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var labels strings.Builder
|
||||
@ -286,7 +270,7 @@ func lsOrgmodeFormatter(env *Env, bugExcerpts []*cache.BugExcerpt) error {
|
||||
status,
|
||||
b.Id.Human(),
|
||||
formatTime(b.CreateTime()),
|
||||
name,
|
||||
author.DisplayName(),
|
||||
title,
|
||||
labels.String(),
|
||||
)
|
||||
|
218
identity/bare.go
218
identity/bare.go
@ -1,218 +0,0 @@
|
||||
package identity
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/MichaelMure/git-bug/entity"
|
||||
"github.com/MichaelMure/git-bug/repository"
|
||||
"github.com/MichaelMure/git-bug/util/lamport"
|
||||
"github.com/MichaelMure/git-bug/util/text"
|
||||
"github.com/MichaelMure/git-bug/util/timestamp"
|
||||
)
|
||||
|
||||
var _ Interface = &Bare{}
|
||||
var _ entity.Interface = &Bare{}
|
||||
|
||||
// Bare is a very minimal identity, designed to be fully embedded directly along
|
||||
// other data.
|
||||
//
|
||||
// in particular, this identity is designed to be compatible with the handling of
|
||||
// identities in the early version of git-bug.
|
||||
// Deprecated: legacy identity for compat, might make sense to ditch entirely for
|
||||
// simplicity but that would be a breaking change.
|
||||
type Bare struct {
|
||||
id entity.Id
|
||||
name string
|
||||
email string
|
||||
login string
|
||||
avatarUrl string
|
||||
}
|
||||
|
||||
func NewBare(name string, email string) *Bare {
|
||||
return &Bare{id: entity.UnsetId, name: name, email: email}
|
||||
}
|
||||
|
||||
func NewBareFull(name string, email string, login string, avatarUrl string) *Bare {
|
||||
return &Bare{id: entity.UnsetId, name: name, email: email, login: login, avatarUrl: avatarUrl}
|
||||
}
|
||||
|
||||
func deriveId(data []byte) entity.Id {
|
||||
sum := sha256.Sum256(data)
|
||||
return entity.Id(fmt.Sprintf("%x", sum))
|
||||
}
|
||||
|
||||
type bareIdentityJSON struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Login string `json:"login,omitempty"`
|
||||
AvatarUrl string `json:"avatar_url,omitempty"`
|
||||
}
|
||||
|
||||
func (i *Bare) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(bareIdentityJSON{
|
||||
Name: i.name,
|
||||
Email: i.email,
|
||||
Login: i.login,
|
||||
AvatarUrl: i.avatarUrl,
|
||||
})
|
||||
}
|
||||
|
||||
func (i *Bare) UnmarshalJSON(data []byte) error {
|
||||
// Compute the Id when loading the op from disk.
|
||||
i.id = deriveId(data)
|
||||
|
||||
aux := bareIdentityJSON{}
|
||||
|
||||
if err := json.Unmarshal(data, &aux); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.name = aux.Name
|
||||
i.email = aux.Email
|
||||
i.login = aux.Login
|
||||
i.avatarUrl = aux.AvatarUrl
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Id return the Identity identifier
|
||||
func (i *Bare) Id() entity.Id {
|
||||
// We don't have a proper Id at hand, so let's hash all the data to get one.
|
||||
|
||||
if i.id == "" {
|
||||
// something went really wrong
|
||||
panic("identity's id not set")
|
||||
}
|
||||
if i.id == entity.UnsetId {
|
||||
// This means we are trying to get the identity identifier *before* it has been stored
|
||||
// As the Id is computed based on the actual bytes written on the disk, we are going to predict
|
||||
// those and then get the Id. This is safe as it will be the exact same code writing on disk later.
|
||||
|
||||
data, err := json.Marshal(i)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
i.id = deriveId(data)
|
||||
}
|
||||
return i.id
|
||||
}
|
||||
|
||||
// Name return the last version of the name
|
||||
func (i *Bare) Name() string {
|
||||
return i.name
|
||||
}
|
||||
|
||||
// Email return the last version of the email
|
||||
func (i *Bare) Email() string {
|
||||
return i.email
|
||||
}
|
||||
|
||||
// Login return the last version of the login
|
||||
func (i *Bare) Login() string {
|
||||
return i.login
|
||||
}
|
||||
|
||||
// AvatarUrl return the last version of the Avatar URL
|
||||
func (i *Bare) AvatarUrl() string {
|
||||
return i.avatarUrl
|
||||
}
|
||||
|
||||
// Keys return the last version of the valid keys
|
||||
func (i *Bare) Keys() []*Key {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidKeysAtTime return the set of keys valid at a given lamport time
|
||||
func (i *Bare) ValidKeysAtTime(_ lamport.Time) []*Key {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DisplayName return a non-empty string to display, representing the
|
||||
// identity, based on the non-empty values.
|
||||
func (i *Bare) DisplayName() string {
|
||||
switch {
|
||||
case i.name == "" && i.login != "":
|
||||
return i.login
|
||||
case i.name != "" && i.login == "":
|
||||
return i.name
|
||||
case i.name != "" && i.login != "":
|
||||
return fmt.Sprintf("%s (%s)", i.name, i.login)
|
||||
}
|
||||
|
||||
panic("invalid person data")
|
||||
}
|
||||
|
||||
// Validate check if the Identity data is valid
|
||||
func (i *Bare) Validate() error {
|
||||
if text.Empty(i.name) && text.Empty(i.login) {
|
||||
return fmt.Errorf("either name or login should be set")
|
||||
}
|
||||
|
||||
if strings.Contains(i.name, "\n") {
|
||||
return fmt.Errorf("name should be a single line")
|
||||
}
|
||||
|
||||
if !text.Safe(i.name) {
|
||||
return fmt.Errorf("name is not fully printable")
|
||||
}
|
||||
|
||||
if strings.Contains(i.login, "\n") {
|
||||
return fmt.Errorf("login should be a single line")
|
||||
}
|
||||
|
||||
if !text.Safe(i.login) {
|
||||
return fmt.Errorf("login is not fully printable")
|
||||
}
|
||||
|
||||
if strings.Contains(i.email, "\n") {
|
||||
return fmt.Errorf("email should be a single line")
|
||||
}
|
||||
|
||||
if !text.Safe(i.email) {
|
||||
return fmt.Errorf("email is not fully printable")
|
||||
}
|
||||
|
||||
if i.avatarUrl != "" && !text.ValidUrl(i.avatarUrl) {
|
||||
return fmt.Errorf("avatarUrl is not a valid URL")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Write the identity into the Repository. In particular, this ensure that
|
||||
// the Id is properly set.
|
||||
func (i *Bare) CommitWithRepo(repo repository.ClockedRepo) error {
|
||||
// Nothing to do, everything is directly embedded
|
||||
return nil
|
||||
}
|
||||
|
||||
// If needed, write the identity into the Repository. In particular, this
|
||||
// ensure that the Id is properly set.
|
||||
func (i *Bare) CommitAsNeededWithRepo(repo repository.ClockedRepo) error {
|
||||
// Nothing to do, everything is directly embedded
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsProtected return true if the chain of git commits started to be signed.
|
||||
// If that's the case, only signed commit with a valid key for this identity can be added.
|
||||
func (i *Bare) IsProtected() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// LastModificationLamportTime return the Lamport time at which the last version of the identity became valid.
|
||||
func (i *Bare) LastModificationLamport() lamport.Time {
|
||||
return 0
|
||||
}
|
||||
|
||||
// LastModification return the timestamp at which the last version of the identity became valid.
|
||||
func (i *Bare) LastModification() timestamp.Timestamp {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (i *Bare) NeedCommit() bool {
|
||||
return false
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package identity
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/MichaelMure/git-bug/entity"
|
||||
)
|
||||
|
||||
func TestBare_Id(t *testing.T) {
|
||||
i := NewBare("name", "email")
|
||||
id := i.Id()
|
||||
expected := entity.Id("e18b853fbd89d5d40ca24811539c9a800c705abd9232f396954e8ca8bb63fa8a")
|
||||
assert.Equal(t, expected, id)
|
||||
}
|
||||
|
||||
func TestBareSerialize(t *testing.T) {
|
||||
before := &Bare{
|
||||
login: "login",
|
||||
email: "email",
|
||||
name: "name",
|
||||
avatarUrl: "avatar",
|
||||
}
|
||||
|
||||
data, err := json.Marshal(before)
|
||||
assert.NoError(t, err)
|
||||
|
||||
var after Bare
|
||||
err = json.Unmarshal(data, &after)
|
||||
assert.NoError(t, err)
|
||||
|
||||
before.id = after.id
|
||||
|
||||
assert.Equal(t, before, &after)
|
||||
}
|
@ -33,18 +33,5 @@ func UnmarshalJSON(raw json.RawMessage) (Interface, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Fallback on a legacy Bare identity
|
||||
b := &Bare{}
|
||||
|
||||
err = json.Unmarshal(raw, b)
|
||||
if err == nil && (b.name != "" || b.login != "") {
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// abort if we have an error other than the wrong type
|
||||
if _, ok := err.(*json.UnmarshalTypeError); err != nil && !ok {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unknown identity type")
|
||||
}
|
||||
|
@ -441,7 +441,7 @@ func (i *Identity) lastVersion() *Version {
|
||||
|
||||
// Id return the Identity identifier
|
||||
func (i *Identity) Id() entity.Id {
|
||||
if i.id == "" {
|
||||
if i.id == "" || i.id == entity.UnsetId {
|
||||
// simply panic as it would be a coding error
|
||||
// (using an id of an identity not stored yet)
|
||||
panic("no id yet")
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"github.com/MichaelMure/git-bug/util/text"
|
||||
)
|
||||
|
||||
// 1: original format
|
||||
const formatVersion = 1
|
||||
|
||||
// Version is a complete set of information about an Identity at a point in time.
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/MichaelMure/go-term-text"
|
||||
text "github.com/MichaelMure/go-term-text"
|
||||
"github.com/awesome-gocui/gocui"
|
||||
"github.com/dustin/go-humanize"
|
||||
|
||||
@ -314,33 +314,25 @@ func (bt *bugTable) render(v *gocui.View, maxX int) {
|
||||
labelsTxt.WriteString(lc256.Unescape())
|
||||
}
|
||||
|
||||
var authorDisplayName string
|
||||
if excerpt.AuthorId != "" {
|
||||
author, err := bt.repo.ResolveIdentityExcerpt(excerpt.AuthorId)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
authorDisplayName = author.DisplayName()
|
||||
} else {
|
||||
authorDisplayName = excerpt.LegacyAuthor.DisplayName()
|
||||
author, err := bt.repo.ResolveIdentityExcerpt(excerpt.AuthorId)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
lastEditTime := excerpt.EditTime()
|
||||
|
||||
id := text.LeftPadMaxLine(excerpt.Id.Human(), columnWidths["id"], 0)
|
||||
status := text.LeftPadMaxLine(excerpt.Status.String(), columnWidths["status"], 0)
|
||||
labels := text.TruncateMax(labelsTxt.String(), minInt(columnWidths["title"]-2, 10))
|
||||
title := text.LeftPadMaxLine(strings.TrimSpace(excerpt.Title), columnWidths["title"]-text.Len(labels), 0)
|
||||
author := text.LeftPadMaxLine(authorDisplayName, columnWidths["author"], 0)
|
||||
authorTxt := text.LeftPadMaxLine(author.DisplayName(), columnWidths["author"], 0)
|
||||
comments := text.LeftPadMaxLine(summaryTxt, columnWidths["comments"], 0)
|
||||
lastEdit := text.LeftPadMaxLine(humanize.Time(lastEditTime), columnWidths["lastEdit"], 1)
|
||||
lastEdit := text.LeftPadMaxLine(humanize.Time(excerpt.EditTime()), columnWidths["lastEdit"], 1)
|
||||
|
||||
_, _ = fmt.Fprintf(v, "%s %s %s%s %s %s %s\n",
|
||||
colors.Cyan(id),
|
||||
colors.Yellow(status),
|
||||
title,
|
||||
labels,
|
||||
colors.Magenta(author),
|
||||
colors.Magenta(authorTxt),
|
||||
comments,
|
||||
lastEdit,
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user