diff options
author | Máximo Cuadros Ortiz <mcuadros@gmail.com> | 2015-04-05 23:34:43 +0200 |
---|---|---|
committer | Máximo Cuadros Ortiz <mcuadros@gmail.com> | 2015-04-06 04:12:04 +0200 |
commit | 5d7303c49ac984a9fec60523f2d5297682e16646 (patch) | |
tree | 53ac3a7eae7e271e58cc37ab1b7d2c27f3f2a9e5 /packfile/packfile.go | |
download | go-git-5d7303c49ac984a9fec60523f2d5297682e16646.tar.gz |
some refactor in folders and crawler
Diffstat (limited to 'packfile/packfile.go')
-rw-r--r-- | packfile/packfile.go | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/packfile/packfile.go b/packfile/packfile.go new file mode 100644 index 0000000..e670cd0 --- /dev/null +++ b/packfile/packfile.go @@ -0,0 +1,82 @@ +package packfile + +import "fmt" + +type Packfile struct { + Version uint32 + ObjectCount int + Checksum []byte + Commits map[string]*Commit + Trees map[string]*Tree + Blobs map[string]*Blob +} + +func NewPackfile() *Packfile { + return &Packfile{ + Commits: make(map[string]*Commit, 0), + Trees: make(map[string]*Tree, 0), + Blobs: make(map[string]*Blob, 0), + } +} + +type BlobEntry struct { + path string + *Blob +} + +type SubtreeEntry struct { + path string + *Tree + TreeCh +} + +type treeEntry interface { + isTreeEntry() + Path() string +} + +func (b BlobEntry) isTreeEntry() {} +func (b BlobEntry) Path() string { return b.path } +func (b SubtreeEntry) isTreeEntry() {} +func (b SubtreeEntry) Path() string { return b.path } + +type TreeCh <-chan treeEntry + +func (p *Packfile) WalkCommit(commitHash string) (TreeCh, error) { + commit, ok := p.Commits[commitHash] + if !ok { + return nil, fmt.Errorf("Unable to find %q commit", commitHash) + } + + treeHash := fmt.Sprintf("%x", string(commit.Tree)) + return p.WalkTree(p.Trees[treeHash]), nil +} + +func (p *Packfile) WalkTree(tree *Tree) TreeCh { + return p.walkTree(tree, "") +} + +func (p *Packfile) walkTree(tree *Tree, pathPrefix string) TreeCh { + ch := make(chan treeEntry) + + if tree == nil { + close(ch) + return ch + } + + go func() { + defer func() { + close(ch) + }() + for _, e := range tree.Entries { + path := pathPrefix + e.Name + if blob, ok := p.Blobs[e.Hash]; ok { + ch <- BlobEntry{path, blob} + } else if subtree, ok := p.Trees[e.Hash]; ok { + ch <- SubtreeEntry{path, subtree, p.walkTree(subtree, path+"/")} + } + } + }() + + return ch +} |