aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bug/bug.go21
-rw-r--r--entity/refs.go18
-rw-r--r--go.sum3
-rw-r--r--identity/identity.go64
-rw-r--r--identity/identity_test.go123
5 files changed, 173 insertions, 56 deletions
diff --git a/bug/bug.go b/bug/bug.go
index 6f5d0a7a..f6c35a2d 100644
--- a/bug/bug.go
+++ b/bug/bug.go
@@ -234,7 +234,7 @@ func RemoveBug(repo repository.ClockedRepo, id entity.Id) error {
return err
}
if len(refs) > 1 {
- return NewErrMultipleMatchBug(refsToIds(refs))
+ return NewErrMultipleMatchBug(entity.RefsToIds(refs))
}
if len(refs) == 1 {
// we have the bug locally
@@ -253,7 +253,7 @@ func RemoveBug(repo repository.ClockedRepo, id entity.Id) error {
return err
}
if len(remoteRefs) > 1 {
- return NewErrMultipleMatchBug(refsToIds(refs))
+ return NewErrMultipleMatchBug(entity.RefsToIds(refs))
}
if len(remoteRefs) == 1 {
// found the bug in a remote
@@ -337,22 +337,7 @@ func ListLocalIds(repo repository.Repo) ([]entity.Id, error) {
return nil, err
}
- return refsToIds(refs), nil
-}
-
-func refsToIds(refs []string) []entity.Id {
- ids := make([]entity.Id, len(refs))
-
- for i, ref := range refs {
- ids[i] = refToId(ref)
- }
-
- return ids
-}
-
-func refToId(ref string) entity.Id {
- split := strings.Split(ref, "/")
- return entity.Id(split[len(split)-1])
+ return entity.RefsToIds(refs), nil
}
// Validate check if the Bug data is valid
diff --git a/entity/refs.go b/entity/refs.go
new file mode 100644
index 00000000..82b1741b
--- /dev/null
+++ b/entity/refs.go
@@ -0,0 +1,18 @@
+package entity
+
+import "strings"
+
+func RefsToIds(refs []string) []Id {
+ ids := make([]Id, len(refs))
+
+ for i, ref := range refs {
+ ids[i] = refToId(ref)
+ }
+
+ return ids
+}
+
+func refToId(ref string) Id {
+ split := strings.Split(ref, "/")
+ return Id(split[len(split)-1])
+}
diff --git a/go.sum b/go.sum
index e2f6679f..f3f5f7c6 100644
--- a/go.sum
+++ b/go.sum
@@ -43,6 +43,7 @@ github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF0
github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA=
github.com/MichaelMure/go-term-text v0.2.9 h1:jUxInT3rDhl4WoJgLnmMS3hR79zigyJS1TqKFDTI6xE=
github.com/MichaelMure/go-term-text v0.2.9/go.mod h1:2QSU/Nn2u41Tqoar+90RlYuhjngJPYgod7evnsYwkWc=
+github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/agnivade/levenshtein v1.0.1 h1:3oJU7J3FGFmyhn8KHjmVaZCN5hxTr7GxgRue+sxIXdQ=
@@ -207,6 +208,7 @@ github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ=
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
@@ -379,6 +381,7 @@ github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJ
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
diff --git a/identity/identity.go b/identity/identity.go
index b7bf9e64..8182e263 100644
--- a/identity/identity.go
+++ b/identity/identity.go
@@ -27,6 +27,10 @@ var ErrNoIdentitySet = errors.New("No identity is set.\n" +
"\"git bug user create\"")
var ErrMultipleIdentitiesSet = errors.New("multiple user identities set")
+func NewErrMultipleMatchIdentity(matching []entity.Id) *entity.ErrMultipleMatch {
+ return entity.NewErrMultipleMatch("identity", matching)
+}
+
var _ Interface = &Identity{}
var _ entity.Interface = &Identity{}
@@ -175,6 +179,66 @@ func read(repo repository.Repo, ref string) (*Identity, error) {
return i, nil
}
+// ListLocalIds list all the available local identity ids
+func ListLocalIds(repo repository.Repo) ([]entity.Id, error) {
+ refs, err := repo.ListRefs(identityRefPattern)
+ if err != nil {
+ return nil, err
+ }
+
+ return entity.RefsToIds(refs), nil
+}
+
+// RemoveIdentity will remove a local identity from its entity.Id
+func RemoveIdentity(repo repository.ClockedRepo, id entity.Id) error {
+ var fullMatches []string
+
+ refs, err := repo.ListRefs(identityRefPattern + id.String())
+ if err != nil {
+ return err
+ }
+ if len(refs) > 1 {
+ return NewErrMultipleMatchIdentity(entity.RefsToIds(refs))
+ }
+ if len(refs) == 1 {
+ // we have the identity locally
+ fullMatches = append(fullMatches, refs[0])
+ }
+
+ remotes, err := repo.GetRemotes()
+ if err != nil {
+ return err
+ }
+
+ for remote := range remotes {
+ remotePrefix := fmt.Sprintf(identityRemoteRefPattern+id.String(), remote)
+ remoteRefs, err := repo.ListRefs(remotePrefix)
+ if err != nil {
+ return err
+ }
+ if len(remoteRefs) > 1 {
+ return NewErrMultipleMatchIdentity(entity.RefsToIds(refs))
+ }
+ if len(remoteRefs) == 1 {
+ // found the identity in a remote
+ fullMatches = append(fullMatches, remoteRefs[0])
+ }
+ }
+
+ if len(fullMatches) == 0 {
+ return ErrIdentityNotExist
+ }
+
+ for _, ref := range fullMatches {
+ err = repo.RemoveRef(ref)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
type StreamedIdentity struct {
Identity *Identity
Err error
diff --git a/identity/identity_test.go b/identity/identity_test.go
index f9091294..baf933c8 100644
--- a/identity/identity_test.go
+++ b/identity/identity_test.go
@@ -4,9 +4,10 @@ import (
"encoding/json"
"testing"
+ "github.com/stretchr/testify/require"
+
"github.com/MichaelMure/git-bug/entity"
"github.com/MichaelMure/git-bug/repository"
- "github.com/stretchr/testify/assert"
)
// Test the commit and load of an Identity with multiple versions
@@ -27,13 +28,13 @@ func TestIdentityCommitLoad(t *testing.T) {
err := identity.Commit(mockRepo)
- assert.Nil(t, err)
- assert.NotEmpty(t, identity.id)
+ require.NoError(t, err)
+ require.NotEmpty(t, identity.id)
loaded, err := ReadLocal(mockRepo, identity.id)
- assert.Nil(t, err)
+ require.NoError(t, err)
commitsAreSet(t, loaded)
- assert.Equal(t, identity, loaded)
+ require.Equal(t, identity, loaded)
// multiple version
@@ -69,13 +70,13 @@ func TestIdentityCommitLoad(t *testing.T) {
err = identity.Commit(mockRepo)
- assert.Nil(t, err)
- assert.NotEmpty(t, identity.id)
+ require.NoError(t, err)
+ require.NotEmpty(t, identity.id)
loaded, err = ReadLocal(mockRepo, identity.id)
- assert.Nil(t, err)
+ require.NoError(t, err)
commitsAreSet(t, loaded)
- assert.Equal(t, identity, loaded)
+ require.Equal(t, identity, loaded)
// add more version
@@ -99,19 +100,19 @@ func TestIdentityCommitLoad(t *testing.T) {
err = identity.Commit(mockRepo)
- assert.Nil(t, err)
- assert.NotEmpty(t, identity.id)
+ require.NoError(t, err)
+ require.NotEmpty(t, identity.id)
loaded, err = ReadLocal(mockRepo, identity.id)
- assert.Nil(t, err)
+ require.NoError(t, err)
commitsAreSet(t, loaded)
- assert.Equal(t, identity, loaded)
+ require.Equal(t, identity, loaded)
}
func TestIdentityMutate(t *testing.T) {
identity := NewIdentity("René Descartes", "rene.descartes@example.com")
- assert.Len(t, identity.versions, 1)
+ require.Len(t, identity.versions, 1)
identity.Mutate(func(orig Mutator) Mutator {
orig.Email = "rene@descartes.fr"
@@ -120,15 +121,15 @@ func TestIdentityMutate(t *testing.T) {
return orig
})
- assert.Len(t, identity.versions, 2)
- assert.Equal(t, identity.Email(), "rene@descartes.fr")
- assert.Equal(t, identity.Name(), "René")
- assert.Equal(t, identity.Login(), "rene")
+ require.Len(t, identity.versions, 2)
+ require.Equal(t, identity.Email(), "rene@descartes.fr")
+ require.Equal(t, identity.Name(), "René")
+ require.Equal(t, identity.Login(), "rene")
}
func commitsAreSet(t *testing.T, identity *Identity) {
for _, version := range identity.versions {
- assert.NotEmpty(t, version.commitHash)
+ require.NotEmpty(t, version.commitHash)
}
}
@@ -180,14 +181,14 @@ func TestIdentity_ValidKeysAtTime(t *testing.T) {
},
}
- assert.Nil(t, identity.ValidKeysAtTime(10))
- assert.Equal(t, identity.ValidKeysAtTime(100), []*Key{{PubKey: "pubkeyA"}})
- assert.Equal(t, identity.ValidKeysAtTime(140), []*Key{{PubKey: "pubkeyA"}})
- assert.Equal(t, identity.ValidKeysAtTime(200), []*Key{{PubKey: "pubkeyB"}})
- assert.Equal(t, identity.ValidKeysAtTime(201), []*Key{{PubKey: "pubkeyD"}})
- assert.Equal(t, identity.ValidKeysAtTime(202), []*Key{{PubKey: "pubkeyD"}})
- assert.Equal(t, identity.ValidKeysAtTime(300), []*Key{{PubKey: "pubkeyE"}})
- assert.Equal(t, identity.ValidKeysAtTime(3000), []*Key{{PubKey: "pubkeyE"}})
+ require.Nil(t, identity.ValidKeysAtTime(10))
+ require.Equal(t, identity.ValidKeysAtTime(100), []*Key{{PubKey: "pubkeyA"}})
+ require.Equal(t, identity.ValidKeysAtTime(140), []*Key{{PubKey: "pubkeyA"}})
+ require.Equal(t, identity.ValidKeysAtTime(200), []*Key{{PubKey: "pubkeyB"}})
+ require.Equal(t, identity.ValidKeysAtTime(201), []*Key{{PubKey: "pubkeyD"}})
+ require.Equal(t, identity.ValidKeysAtTime(202), []*Key{{PubKey: "pubkeyD"}})
+ require.Equal(t, identity.ValidKeysAtTime(300), []*Key{{PubKey: "pubkeyE"}})
+ require.Equal(t, identity.ValidKeysAtTime(3000), []*Key{{PubKey: "pubkeyE"}})
}
// Test the immutable or mutable metadata search
@@ -201,7 +202,7 @@ func TestMetadata(t *testing.T) {
assertHasKeyValue(t, identity.MutableMetadata(), "key1", "value1")
err := identity.Commit(mockRepo)
- assert.NoError(t, err)
+ require.NoError(t, err)
assertHasKeyValue(t, identity.ImmutableMetadata(), "key1", "value1")
assertHasKeyValue(t, identity.MutableMetadata(), "key1", "value1")
@@ -217,11 +218,11 @@ func TestMetadata(t *testing.T) {
assertHasKeyValue(t, identity.MutableMetadata(), "key1", "value2")
err = identity.Commit(mockRepo)
- assert.NoError(t, err)
+ require.NoError(t, err)
// reload
loaded, err := ReadLocal(mockRepo, identity.id)
- assert.Nil(t, err)
+ require.NoError(t, err)
assertHasKeyValue(t, loaded.ImmutableMetadata(), "key1", "value1")
assertHasKeyValue(t, loaded.MutableMetadata(), "key1", "value2")
@@ -229,8 +230,8 @@ func TestMetadata(t *testing.T) {
func assertHasKeyValue(t *testing.T, metadata map[string]string, key, value string) {
val, ok := metadata[key]
- assert.True(t, ok)
- assert.Equal(t, val, value)
+ require.True(t, ok)
+ require.Equal(t, val, value)
}
func TestJSON(t *testing.T) {
@@ -248,20 +249,66 @@ func TestJSON(t *testing.T) {
// commit to make sure we have an Id
err := identity.Commit(mockRepo)
- assert.Nil(t, err)
- assert.NotEmpty(t, identity.id)
+ require.NoError(t, err)
+ require.NotEmpty(t, identity.id)
// serialize
data, err := json.Marshal(identity)
- assert.NoError(t, err)
+ require.NoError(t, err)
// deserialize, got a IdentityStub with the same id
var i Interface
i, err = UnmarshalJSON(data)
- assert.NoError(t, err)
- assert.Equal(t, identity.id, i.Id())
+ require.NoError(t, err)
+ require.Equal(t, identity.id, i.Id())
// make sure we can load the identity properly
i, err = ReadLocal(mockRepo, i.Id())
- assert.NoError(t, err)
+ require.NoError(t, err)
+}
+
+func TestIdentityRemove(t *testing.T) {
+ repo := repository.CreateGoGitTestRepo(false)
+ remoteA := repository.CreateGoGitTestRepo(true)
+ remoteB := repository.CreateGoGitTestRepo(true)
+ defer repository.CleanupTestRepos(repo, remoteA, remoteB)
+
+ err := repo.AddRemote("remoteA", "file://"+remoteA.GetPath())
+ require.NoError(t, err)
+
+ err = repo.AddRemote("remoteB", "file://"+remoteB.GetPath())
+ require.NoError(t, err)
+
+ // generate an identity for testing
+ rene := NewIdentity("René Descartes", "rene@descartes.fr")
+ err = rene.Commit(repo)
+ require.NoError(t, err)
+
+ _, err = Push(repo, "remoteA")
+ require.NoError(t, err)
+
+ _, err = Push(repo, "remoteB")
+ require.NoError(t, err)
+
+ _, err = Fetch(repo, "remoteA")
+ require.NoError(t, err)
+
+ _, err = Fetch(repo, "remoteB")
+ require.NoError(t, err)
+
+ err = RemoveIdentity(repo, rene.Id())
+ require.NoError(t, err)
+
+ _, err = ReadLocal(repo, rene.Id())
+ require.Error(t, ErrIdentityNotExist, err)
+
+ _, err = ReadRemote(repo, "remoteA", string(rene.Id()))
+ require.Error(t, ErrIdentityNotExist, err)
+
+ _, err = ReadRemote(repo, "remoteB", string(rene.Id()))
+ require.Error(t, ErrIdentityNotExist, err)
+
+ ids, err := ListLocalIds(repo)
+ require.NoError(t, err)
+ require.Len(t, ids, 0)
}