aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bug/bug.go14
-rw-r--r--identity/bare.go9
-rw-r--r--identity/identity.go109
-rw-r--r--identity/interface.go6
-rw-r--r--identity/version.go2
5 files changed, 120 insertions, 20 deletions
diff --git a/bug/bug.go b/bug/bug.go
index b6d09c50..be3e2661 100644
--- a/bug/bug.go
+++ b/bug/bug.go
@@ -113,13 +113,6 @@ func ReadRemoteBug(repo repository.ClockedRepo, remote string, id string) (*Bug,
// readBug will read and parse a Bug from git
func readBug(repo repository.ClockedRepo, ref string) (*Bug, error) {
- hashes, err := repo.ListCommits(ref)
-
- // TODO: this is not perfect, it might be a command invoke error
- if err != nil {
- return nil, ErrBugNotExist
- }
-
refSplit := strings.Split(ref, "/")
id := refSplit[len(refSplit)-1]
@@ -127,6 +120,13 @@ func readBug(repo repository.ClockedRepo, ref string) (*Bug, error) {
return nil, fmt.Errorf("invalid ref length")
}
+ hashes, err := repo.ListCommits(ref)
+
+ // TODO: this is not perfect, it might be a command invoke error
+ if err != nil {
+ return nil, ErrBugNotExist
+ }
+
bug := Bug{
id: id,
}
diff --git a/identity/bare.go b/identity/bare.go
index eec00e19..24f30f9f 100644
--- a/identity/bare.go
+++ b/identity/bare.go
@@ -9,6 +9,11 @@ import (
"github.com/MichaelMure/git-bug/util/text"
)
+// 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.
type Bare struct {
name string
email string
@@ -71,10 +76,12 @@ func (i Bare) AvatarUrl() string {
return i.avatarUrl
}
+// Keys return the last version of the valid keys
func (i Bare) Keys() []Key {
return []Key{}
}
+// ValidKeysAtTime return the set of keys valid at a given lamport time
func (i Bare) ValidKeysAtTime(time lamport.Time) []Key {
return []Key{}
}
@@ -139,6 +146,8 @@ func (i Bare) Validate() error {
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
}
diff --git a/identity/identity.go b/identity/identity.go
index f65e2a86..0fe13d21 100644
--- a/identity/identity.go
+++ b/identity/identity.go
@@ -2,18 +2,22 @@
package identity
import (
+ "encoding/json"
"fmt"
"strings"
"github.com/MichaelMure/git-bug/repository"
"github.com/MichaelMure/git-bug/util/git"
"github.com/MichaelMure/git-bug/util/lamport"
+ "github.com/pkg/errors"
)
const identityRefPattern = "refs/identities/"
const versionEntryName = "version"
const identityConfigKey = "git-bug.identity"
+var ErrIdentityNotExist = errors.New("identity doesn't exist")
+
type Identity struct {
id string
Versions []Version
@@ -35,22 +39,106 @@ type identityJson struct {
Id string `json:"id"`
}
-// TODO: marshal/unmarshal identity + load/write from OpBase
+// MarshalJSON will only serialize the id
+func (i *Identity) MarshalJSON() ([]byte, error) {
+ return json.Marshal(identityJson{
+ Id: i.Id(),
+ })
+}
+
+// UnmarshalJSON will only read the id
+// Users of this package are expected to run Load() to load
+// the remaining data from the identities data in git.
+func (i *Identity) UnmarshalJSON(data []byte) error {
+ aux := identityJson{}
+
+ if err := json.Unmarshal(data, &aux); err != nil {
+ return err
+ }
+
+ i.id = aux.Id
+ return nil
+}
+
+// TODO: load/write from OpBase
+
+// Read load an Identity from the identities data available in git
func Read(repo repository.Repo, id string) (*Identity, error) {
- // Todo
- return &Identity{}, nil
+ i := &Identity{
+ id: id,
+ }
+
+ err := i.Load(repo)
+ if err != nil {
+ return nil, err
+ }
+
+ return i, nil
+}
+
+// Load will read the corresponding identity data from git and replace any
+// data already loaded if any.
+func (i *Identity) Load(repo repository.Repo) error {
+ ref := fmt.Sprintf("%s%s", identityRefPattern, i.Id())
+
+ hashes, err := repo.ListCommits(ref)
+
+ var versions []Version
+
+ // TODO: this is not perfect, it might be a command invoke error
+ if err != nil {
+ return ErrIdentityNotExist
+ }
+
+ for _, hash := range hashes {
+ entries, err := repo.ListEntries(hash)
+ if err != nil {
+ return errors.Wrap(err, "can't list git tree entries")
+ }
+
+ if len(entries) != 1 {
+ return fmt.Errorf("invalid identity data at hash %s", hash)
+ }
+
+ entry := entries[0]
+
+ if entry.Name != versionEntryName {
+ return fmt.Errorf("invalid identity data at hash %s", hash)
+ }
+
+ data, err := repo.ReadData(entry.Hash)
+ if err != nil {
+ return errors.Wrap(err, "failed to read git blob data")
+ }
+
+ var version Version
+ err = json.Unmarshal(data, &version)
+
+ if err != nil {
+ return errors.Wrapf(err, "failed to decode Identity version json %s", hash)
+ }
+
+ // tag the version with the commit hash
+ version.commitHash = hash
+
+ versions = append(versions, version)
+ }
+
+ i.Versions = versions
+
+ return nil
}
// NewFromGitUser will query the repository for user detail and
// build the corresponding Identity
-/*func NewFromGitUser(repo repository.Repo) (*Identity, error) {
+func NewFromGitUser(repo repository.Repo) (*Identity, error) {
name, err := repo.GetUserName()
if err != nil {
return nil, err
}
if name == "" {
- return nil, errors.New("User name is not configured in git yet. Please use `git config --global user.name \"John Doe\"`")
+ return nil, errors.New("user name is not configured in git yet. Please use `git config --global user.name \"John Doe\"`")
}
email, err := repo.GetUserEmail()
@@ -58,14 +146,15 @@ func Read(repo repository.Repo, id string) (*Identity, error) {
return nil, err
}
if email == "" {
- return nil, errors.New("User name is not configured in git yet. Please use `git config --global user.email johndoe@example.com`")
+ return nil, errors.New("user name is not configured in git yet. Please use `git config --global user.email johndoe@example.com`")
}
return NewIdentity(name, email)
-}*/
+}
-//
-func BuildFromGit(repo repository.Repo) *Identity {
+// BuildFromGit will query the repository for user detail and
+// build the corresponding Identity
+/*func BuildFromGit(repo repository.Repo) *Identity {
version := Version{}
name, err := repo.GetUserName()
@@ -83,7 +172,7 @@ func BuildFromGit(repo repository.Repo) *Identity {
version,
},
}
-}
+}*/
// SetIdentity store the user identity's id in the git config
func SetIdentity(repo repository.RepoCommon, identity Identity) error {
diff --git a/identity/interface.go b/identity/interface.go
index 14287655..058e6ec6 100644
--- a/identity/interface.go
+++ b/identity/interface.go
@@ -1,6 +1,8 @@
package identity
-import "github.com/MichaelMure/git-bug/util/lamport"
+import (
+ "github.com/MichaelMure/git-bug/util/lamport"
+)
type Interface interface {
Name() string
@@ -8,7 +10,7 @@ type Interface interface {
Login() string
AvatarUrl() string
- // Login return the last version of the valid keys
+ // Keys return the last version of the valid keys
Keys() []Key
// ValidKeysAtTime return the set of keys valid at a given lamport time
diff --git a/identity/version.go b/identity/version.go
index f76ec4c5..3e84ece3 100644
--- a/identity/version.go
+++ b/identity/version.go
@@ -8,11 +8,11 @@ import (
"github.com/MichaelMure/git-bug/repository"
"github.com/MichaelMure/git-bug/util/git"
-
"github.com/MichaelMure/git-bug/util/lamport"
"github.com/MichaelMure/git-bug/util/text"
)
+// Version is a complete set of informations about an Identity at a point in time.
type Version struct {
// Private field so not serialized
commitHash git.Hash