aboutsummaryrefslogblamecommitdiffstats
path: root/entities/bug/bug.go
blob: 8958fbd0e1b93498dd46631b3f3696fb421bf5b7 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
                                                                          

           
        
             
 




                                                      

 

                               
 




                                                                                                      
 


                        
                         

                                        
                                                   
                                            

 
                                      
 



                                           
                                                                  
                                                                  
                                                       
                 
                   
 
 
                          
                    




                                    
 
 





                                                                       

                                                                    
                                                                

 

                                                                                                            
                                                          

 
                                        
                                                                              
                                                                     

 
                                                    
                                                                                                                      
                                                         

 
                                                    
                                                              
                                          

 

                                          

                                                     

         
                                                 
                                
                                                         
                                                                          

         
                                                  
                                                    

                                
                 

                                                                       
                 

         
                  

 
                                        
                                      
                             

 





                                                
         
                     

 
                                             

                                     
                                 
                                          

         
                                             
                              
                                                             

         
                   

 
                                                          
                                                       
                                     

                                                  
         

                  
 
                                                        
                                       
                                    

                                                 
         
                  
 
// Package bug contains the bug data model and low-level related functions
package bug

import (
	"fmt"

	"github.com/git-bug/git-bug/entities/common"
	"github.com/git-bug/git-bug/entities/identity"
	"github.com/git-bug/git-bug/entity"
	"github.com/git-bug/git-bug/entity/dag"
	"github.com/git-bug/git-bug/repository"
)

var _ Interface = &Bug{}
var _ entity.Interface = &Bug{}

// 1: original format
// 2: no more legacy identities
// 3: Ids are generated from the create operation serialized data instead of from the first git commit
// 4: with DAG entity framework
const formatVersion = 4

const Typename = "bug"
const Namespace = "bugs"

var def = dag.Definition{
	Typename:             Typename,
	Namespace:            Namespace,
	OperationUnmarshaler: operationUnmarshaler,
	FormatVersion:        formatVersion,
}

var ClockLoader = dag.ClockLoader(def)

type Interface interface {
	dag.Interface[*Snapshot, Operation]
}

// Bug holds the data of a bug thread, organized in a way close to
// how it will be persisted inside Git. This is the data structure
// used to merge two different version of the same Bug.
type Bug struct {
	*dag.Entity
}

// NewBug create a new Bug
func NewBug() *Bug {
	return wrapper(dag.New(def))
}

func wrapper(e *dag.Entity) *Bug {
	return &Bug{Entity: e}
}

func simpleResolvers(repo repository.ClockedRepo) entity.Resolvers {
	return entity.Resolvers{
		&identity.Identity{}: identity.NewSimpleResolver(repo),
	}
}

// Read will read a bug from a repository
func Read(repo repository.ClockedRepo, id entity.Id) (*Bug, error) {
	return ReadWithResolver(repo, simpleResolvers(repo), id)
}

// ReadWithResolver will read a bug from its Id, with custom resolvers
func ReadWithResolver(repo repository.ClockedRepo, resolvers entity.Resolvers, id entity.Id) (*Bug, error) {
	return dag.Read(def, wrapper, repo, resolvers, id)
}

// ReadAll read and parse all local bugs
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 entity.StreamedEntity[*Bug] {
	return dag.ReadAll(def, wrapper, repo, resolvers)
}

// ListLocalIds list all the available local bug ids
func ListLocalIds(repo repository.Repo) ([]entity.Id, error) {
	return dag.ListLocalIds(def, repo)
}

// Validate check if the Bug data is valid
func (bug *Bug) Validate() error {
	if err := bug.Entity.Validate(); err != nil {
		return err
	}

	// The very first Op should be a CreateOp
	firstOp := bug.FirstOp()
	if firstOp == nil || firstOp.Type() != CreateOp {
		return fmt.Errorf("first operation should be a Create op")
	}

	// Check that there is no more CreateOp op
	for i, op := range bug.Entity.Operations() {
		if i == 0 {
			continue
		}
		if op.Type() == CreateOp {
			return fmt.Errorf("only one Create op allowed")
		}
	}

	return nil
}

// Append add a new Operation to the Bug
func (bug *Bug) Append(op Operation) {
	bug.Entity.Append(op)
}

// Operations return the ordered operations
func (bug *Bug) Operations() []Operation {
	source := bug.Entity.Operations()
	result := make([]Operation, len(source))
	for i, op := range source {
		result[i] = op.(Operation)
	}
	return result
}

// Compile a bug in an easily usable snapshot
func (bug *Bug) Compile() *Snapshot {
	snap := &Snapshot{
		id:     bug.Id(),
		Status: common.OpenStatus,
	}

	for _, op := range bug.Operations() {
		op.Apply(snap)
		snap.Operations = append(snap.Operations, op)
	}

	return snap
}

// FirstOp lookup for the very first operation of the bug.
// For a valid Bug, this operation should be a CreateOp
func (bug *Bug) FirstOp() Operation {
	if fo := bug.Entity.FirstOp(); fo != nil {
		return fo.(Operation)
	}
	return nil
}

// LastOp lookup for the very last operation of the bug.
// For a valid Bug, should never be nil
func (bug *Bug) LastOp() Operation {
	if lo := bug.Entity.LastOp(); lo != nil {
		return lo.(Operation)
	}
	return nil
}