diff options
Diffstat (limited to 'entities')
-rw-r--r-- | entities/bug/bug.go | 57 | ||||
-rw-r--r-- | entities/bug/bug_actions.go | 23 | ||||
-rw-r--r-- | entities/bug/err.go | 17 | ||||
-rw-r--r-- | entities/bug/operation.go | 7 | ||||
-rw-r--r-- | entities/bug/resolver.go | 2 | ||||
-rw-r--r-- | entities/bug/snapshot.go | 4 | ||||
-rw-r--r-- | entities/bug/with_snapshot.go | 53 | ||||
-rw-r--r-- | entities/identity/common.go | 9 | ||||
-rw-r--r-- | entities/identity/identity.go | 38 | ||||
-rw-r--r-- | entities/identity/identity_actions.go | 4 | ||||
-rw-r--r-- | entities/identity/identity_actions_test.go | 5 | ||||
-rw-r--r-- | entities/identity/identity_test.go | 7 | ||||
-rw-r--r-- | entities/identity/identity_user.go | 2 | ||||
-rw-r--r-- | entities/identity/resolver.go | 15 |
14 files changed, 50 insertions, 193 deletions
diff --git a/entities/bug/bug.go b/entities/bug/bug.go index b0f46c0b..deb00c7c 100644 --- a/entities/bug/bug.go +++ b/entities/bug/bug.go @@ -20,9 +20,12 @@ var _ entity.Interface = &Bug{} // 4: with DAG entity framework const formatVersion = 4 +const Typename = "bug" +const Namespace = "bugs" + var def = dag.Definition{ - Typename: "bug", - Namespace: "bugs", + Typename: Typename, + Namespace: Namespace, OperationUnmarshaler: operationUnmarshaler, FormatVersion: formatVersion, } @@ -42,9 +45,11 @@ type Bug struct { // NewBug create a new Bug func NewBug() *Bug { - return &Bug{ - Entity: dag.New(def), - } + return wrapper(dag.New(def)) +} + +func wrapper(e *dag.Entity) *Bug { + return &Bug{Entity: e} } func simpleResolvers(repo repository.ClockedRepo) entity.Resolvers { @@ -60,49 +65,17 @@ func Read(repo repository.ClockedRepo, id entity.Id) (*Bug, error) { // ReadWithResolver will read a bug from its Id, with custom resolvers func ReadWithResolver(repo repository.ClockedRepo, resolvers entity.Resolvers, id entity.Id) (*Bug, error) { - e, err := dag.Read(def, repo, resolvers, id) - if err != nil { - return nil, err - } - return &Bug{Entity: e}, nil -} - -type StreamedBug struct { - Bug *Bug - Err error + return dag.Read(def, wrapper, repo, resolvers, id) } // ReadAll read and parse all local bugs -func ReadAll(repo repository.ClockedRepo) <-chan StreamedBug { - return readAll(repo, simpleResolvers(repo)) +func ReadAll(repo repository.ClockedRepo) <-chan entity.StreamedEntity[*Bug] { + return dag.ReadAll(def, wrapper, repo, simpleResolvers(repo)) } // ReadAllWithResolver read and parse all local bugs -func ReadAllWithResolver(repo repository.ClockedRepo, resolvers entity.Resolvers) <-chan StreamedBug { - return readAll(repo, resolvers) -} - -// Read and parse all available bug with a given ref prefix -func readAll(repo repository.ClockedRepo, resolvers entity.Resolvers) <-chan StreamedBug { - out := make(chan StreamedBug) - - go func() { - defer close(out) - - for streamedEntity := range dag.ReadAll(def, repo, resolvers) { - if streamedEntity.Err != nil { - out <- StreamedBug{ - Err: streamedEntity.Err, - } - } else { - out <- StreamedBug{ - Bug: &Bug{Entity: streamedEntity.Entity}, - } - } - } - }() - - return out +func ReadAllWithResolver(repo repository.ClockedRepo, resolvers entity.Resolvers) <-chan entity.StreamedEntity[*Bug] { + return dag.ReadAll(def, wrapper, repo, resolvers) } // ListLocalIds list all the available local bug ids diff --git a/entities/bug/bug_actions.go b/entities/bug/bug_actions.go index c25b9243..198e4ed0 100644 --- a/entities/bug/bug_actions.go +++ b/entities/bug/bug_actions.go @@ -23,33 +23,14 @@ func Push(repo repository.Repo, remote string) (string, error) { // Note: an author is necessary for the case where a merge commit is created, as this commit will // have an author and may be signed if a signing key is available. func Pull(repo repository.ClockedRepo, resolvers entity.Resolvers, remote string, mergeAuthor identity.Interface) error { - return dag.Pull(def, repo, resolvers, remote, mergeAuthor) + return dag.Pull(def, wrapper, repo, resolvers, remote, mergeAuthor) } // MergeAll will merge all the available remote bug // Note: an author is necessary for the case where a merge commit is created, as this commit will // have an author and may be signed if a signing key is available. func MergeAll(repo repository.ClockedRepo, resolvers entity.Resolvers, remote string, mergeAuthor identity.Interface) <-chan entity.MergeResult { - out := make(chan entity.MergeResult) - - go func() { - defer close(out) - - results := dag.MergeAll(def, repo, resolvers, remote, mergeAuthor) - - // wrap the dag.Entity into a complete Bug - for result := range results { - result := result - if result.Entity != nil { - result.Entity = &Bug{ - Entity: result.Entity.(*dag.Entity), - } - } - out <- result - } - }() - - return out + return dag.MergeAll(def, wrapper, repo, resolvers, remote, mergeAuthor) } // Remove will remove a local bug from its entity.Id diff --git a/entities/bug/err.go b/entities/bug/err.go deleted file mode 100644 index 1bd174bb..00000000 --- a/entities/bug/err.go +++ /dev/null @@ -1,17 +0,0 @@ -package bug - -import ( - "errors" - - "github.com/MichaelMure/git-bug/entity" -) - -var ErrBugNotExist = errors.New("bug doesn't exist") - -func NewErrMultipleMatchBug(matching []entity.Id) *entity.ErrMultipleMatch { - return entity.NewErrMultipleMatch("bug", matching) -} - -func NewErrMultipleMatchOp(matching []entity.Id) *entity.ErrMultipleMatch { - return entity.NewErrMultipleMatch("operation", matching) -} diff --git a/entities/bug/operation.go b/entities/bug/operation.go index 41d80700..04365046 100644 --- a/entities/bug/operation.go +++ b/entities/bug/operation.go @@ -21,12 +21,7 @@ const ( ) // Operation define the interface to fulfill for an edit operation of a Bug -type Operation interface { - dag.Operation - - // Apply the operation to a Snapshot to create the final state - Apply(snapshot *Snapshot) -} +type Operation = dag.OperationWithApply[*Snapshot] // make sure that package external operations do conform to our interface var _ Operation = &dag.NoOpOperation[*Snapshot]{} diff --git a/entities/bug/resolver.go b/entities/bug/resolver.go index e7beb0e4..b0a05917 100644 --- a/entities/bug/resolver.go +++ b/entities/bug/resolver.go @@ -16,6 +16,6 @@ func NewSimpleResolver(repo repository.ClockedRepo) *SimpleResolver { return &SimpleResolver{repo: repo} } -func (r *SimpleResolver) Resolve(id entity.Id) (entity.Interface, error) { +func (r *SimpleResolver) Resolve(id entity.Id) (entity.Resolved, error) { return Read(r.repo, id) } diff --git a/entities/bug/snapshot.go b/entities/bug/snapshot.go index 333fe207..5c260d85 100644 --- a/entities/bug/snapshot.go +++ b/entities/bug/snapshot.go @@ -43,6 +43,10 @@ func (snap *Snapshot) AllOperations() []dag.Operation { return snap.Operations } +func (snap *Snapshot) AppendOperation(op dag.Operation) { + snap.Operations = append(snap.Operations, op) +} + // EditTime returns the last time a bug was modified func (snap *Snapshot) EditTime() time.Time { if len(snap.Operations) == 0 { diff --git a/entities/bug/with_snapshot.go b/entities/bug/with_snapshot.go deleted file mode 100644 index 0474cac7..00000000 --- a/entities/bug/with_snapshot.go +++ /dev/null @@ -1,53 +0,0 @@ -package bug - -import ( - "github.com/MichaelMure/git-bug/repository" -) - -var _ Interface = &WithSnapshot{} - -// WithSnapshot encapsulate a Bug and maintain the corresponding Snapshot efficiently -type WithSnapshot struct { - *Bug - snap *Snapshot -} - -func (b *WithSnapshot) Compile() *Snapshot { - if b.snap == nil { - snap := b.Bug.Compile() - b.snap = snap - } - return b.snap -} - -// Append intercept Bug.Append() to update the snapshot efficiently -func (b *WithSnapshot) Append(op Operation) { - b.Bug.Append(op) - - if b.snap == nil { - return - } - - op.Apply(b.snap) - b.snap.Operations = append(b.snap.Operations, op) -} - -// Commit intercept Bug.Commit() to update the snapshot efficiently -func (b *WithSnapshot) Commit(repo repository.ClockedRepo) error { - err := b.Bug.Commit(repo) - - if err != nil { - b.snap = nil - return err - } - - // Commit() shouldn't change anything of the bug state apart from the - // initial ID set - - if b.snap == nil { - return nil - } - - b.snap.id = b.Bug.Id() - return nil -} diff --git a/entities/identity/common.go b/entities/identity/common.go index 5c6445e9..88e30e33 100644 --- a/entities/identity/common.go +++ b/entities/identity/common.go @@ -2,18 +2,9 @@ package identity import ( "encoding/json" - "errors" "fmt" - - "github.com/MichaelMure/git-bug/entity" ) -var ErrIdentityNotExist = errors.New("identity doesn't exist") - -func NewErrMultipleMatch(matching []entity.Id) *entity.ErrMultipleMatch { - return entity.NewErrMultipleMatch("identity", matching) -} - // Custom unmarshaling function to allow package user to delegate // the decoding of an Identity and distinguish between an Identity // and a Bare. diff --git a/entities/identity/identity.go b/entities/identity/identity.go index d497dbcc..b0cee43b 100644 --- a/entities/identity/identity.go +++ b/entities/identity/identity.go @@ -19,16 +19,15 @@ const identityRemoteRefPattern = "refs/remotes/%s/identities/" const versionEntryName = "version" const identityConfigKey = "git-bug.identity" +const Typename = "identity" +const Namespace = "identities" + var ErrNonFastForwardMerge = errors.New("non fast-forward identity merge") var ErrNoIdentitySet = errors.New("No identity is set.\n" + "To interact with bugs, an identity first needs to be created using " + "\"git bug user new\" or adopted with \"git bug user adopt\"") 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{} @@ -109,7 +108,7 @@ func read(repo repository.Repo, ref string) (*Identity, error) { hashes, err := repo.ListCommits(ref) if err != nil { - return nil, ErrIdentityNotExist + return nil, entity.NewErrNotFound(Typename) } if len(hashes) == 0 { return nil, fmt.Errorf("empty identity") @@ -174,7 +173,7 @@ func RemoveIdentity(repo repository.ClockedRepo, id entity.Id) error { return err } if len(refs) > 1 { - return NewErrMultipleMatchIdentity(entity.RefsToIds(refs)) + return entity.NewErrMultipleMatch(Typename, entity.RefsToIds(refs)) } if len(refs) == 1 { // we have the identity locally @@ -193,7 +192,7 @@ func RemoveIdentity(repo repository.ClockedRepo, id entity.Id) error { return err } if len(remoteRefs) > 1 { - return NewErrMultipleMatchIdentity(entity.RefsToIds(refs)) + return entity.NewErrMultipleMatch(Typename, entity.RefsToIds(refs)) } if len(remoteRefs) == 1 { // found the identity in a remote @@ -202,7 +201,7 @@ func RemoveIdentity(repo repository.ClockedRepo, id entity.Id) error { } if len(fullMatches) == 0 { - return ErrIdentityNotExist + return entity.NewErrNotFound(Typename) } for _, ref := range fullMatches { @@ -215,44 +214,39 @@ func RemoveIdentity(repo repository.ClockedRepo, id entity.Id) error { return nil } -type StreamedIdentity struct { - Identity *Identity - Err error -} - // ReadAllLocal read and parse all local Identity -func ReadAllLocal(repo repository.ClockedRepo) <-chan StreamedIdentity { +func ReadAllLocal(repo repository.ClockedRepo) <-chan entity.StreamedEntity[*Identity] { return readAll(repo, identityRefPattern) } // ReadAllRemote read and parse all remote Identity for a given remote -func ReadAllRemote(repo repository.ClockedRepo, remote string) <-chan StreamedIdentity { +func ReadAllRemote(repo repository.ClockedRepo, remote string) <-chan entity.StreamedEntity[*Identity] { refPrefix := fmt.Sprintf(identityRemoteRefPattern, remote) return readAll(repo, refPrefix) } // readAll read and parse all available bug with a given ref prefix -func readAll(repo repository.ClockedRepo, refPrefix string) <-chan StreamedIdentity { - out := make(chan StreamedIdentity) +func readAll(repo repository.ClockedRepo, refPrefix string) <-chan entity.StreamedEntity[*Identity] { + out := make(chan entity.StreamedEntity[*Identity]) go func() { defer close(out) refs, err := repo.ListRefs(refPrefix) if err != nil { - out <- StreamedIdentity{Err: err} + out <- entity.StreamedEntity[*Identity]{Err: err} return } for _, ref := range refs { - b, err := read(repo, ref) + i, err := read(repo, ref) if err != nil { - out <- StreamedIdentity{Err: err} + out <- entity.StreamedEntity[*Identity]{Err: err} return } - out <- StreamedIdentity{Identity: b} + out <- entity.StreamedEntity[*Identity]{Entity: i} } }() @@ -308,7 +302,7 @@ func (i *Identity) Mutate(repo repository.RepoClock, f func(orig *Mutator)) erro return nil } -// Write the identity into the Repository. In particular, this ensure that +// Commit write the identity into the Repository. In particular, this ensures that // the Id is properly set. func (i *Identity) Commit(repo repository.ClockedRepo) error { if !i.NeedCommit() { diff --git a/entities/identity/identity_actions.go b/entities/identity/identity_actions.go index b58bb2d9..13776078 100644 --- a/entities/identity/identity_actions.go +++ b/entities/identity/identity_actions.go @@ -13,12 +13,12 @@ import ( // Fetch retrieve updates from a remote // This does not change the local identities state func Fetch(repo repository.Repo, remote string) (string, error) { - return repo.FetchRefs(remote, "identities") + return repo.FetchRefs(remote, Namespace) } // Push update a remote with the local changes func Push(repo repository.Repo, remote string) (string, error) { - return repo.PushRefs(remote, "identities") + return repo.PushRefs(remote, Namespace) } // Pull will do a Fetch + MergeAll diff --git a/entities/identity/identity_actions_test.go b/entities/identity/identity_actions_test.go index 351fb7a4..e9626cb9 100644 --- a/entities/identity/identity_actions_test.go +++ b/entities/identity/identity_actions_test.go @@ -5,6 +5,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/MichaelMure/git-bug/entity" "github.com/MichaelMure/git-bug/repository" ) @@ -145,13 +146,13 @@ func TestIdentityPushPull(t *testing.T) { } } -func allIdentities(t testing.TB, identities <-chan StreamedIdentity) []*Identity { +func allIdentities(t testing.TB, identities <-chan entity.StreamedEntity[*Identity]) []*Identity { var result []*Identity for streamed := range identities { if streamed.Err != nil { t.Fatal(streamed.Err) } - result = append(result, streamed.Identity) + result = append(result, streamed.Entity) } return result } diff --git a/entities/identity/identity_test.go b/entities/identity/identity_test.go index f0c3bbe9..0ecc8058 100644 --- a/entities/identity/identity_test.go +++ b/entities/identity/identity_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/MichaelMure/git-bug/entity" "github.com/MichaelMure/git-bug/repository" "github.com/MichaelMure/git-bug/util/lamport" ) @@ -278,13 +279,13 @@ func TestIdentityRemove(t *testing.T) { require.NoError(t, err) _, err = ReadLocal(repo, rene.Id()) - require.Error(t, ErrIdentityNotExist, err) + require.ErrorAs(t, entity.ErrNotFound{}, err) _, err = ReadRemote(repo, "remoteA", string(rene.Id())) - require.Error(t, ErrIdentityNotExist, err) + require.ErrorAs(t, entity.ErrNotFound{}, err) _, err = ReadRemote(repo, "remoteB", string(rene.Id())) - require.Error(t, ErrIdentityNotExist, err) + require.ErrorAs(t, entity.ErrNotFound{}, err) ids, err := ListLocalIds(repo) require.NoError(t, err) diff --git a/entities/identity/identity_user.go b/entities/identity/identity_user.go index cd67459e..e671e662 100644 --- a/entities/identity/identity_user.go +++ b/entities/identity/identity_user.go @@ -23,7 +23,7 @@ func GetUserIdentity(repo repository.Repo) (*Identity, error) { } i, err := ReadLocal(repo, id) - if err == ErrIdentityNotExist { + if entity.IsErrNotFound(err) { innerErr := repo.LocalConfig().RemoveAll(identityConfigKey) if innerErr != nil { _, _ = fmt.Fprintln(os.Stderr, errors.Wrap(innerErr, "can't clear user identity").Error()) diff --git a/entities/identity/resolver.go b/entities/identity/resolver.go index 5468a8f8..a4b676f3 100644 --- a/entities/identity/resolver.go +++ b/entities/identity/resolver.go @@ -16,19 +16,6 @@ func NewSimpleResolver(repo repository.Repo) *SimpleResolver { return &SimpleResolver{repo: repo} } -func (r *SimpleResolver) Resolve(id entity.Id) (entity.Interface, error) { +func (r *SimpleResolver) Resolve(id entity.Id) (entity.Resolved, error) { return ReadLocal(r.repo, id) } - -var _ entity.Resolver = &StubResolver{} - -// StubResolver is a Resolver that doesn't load anything, only returning IdentityStub instances -type StubResolver struct{} - -func NewStubResolver() *StubResolver { - return &StubResolver{} -} - -func (s *StubResolver) Resolve(id entity.Id) (entity.Interface, error) { - return &IdentityStub{id: id}, nil -} |