Skip to content
Snippets Groups Projects

Initial implementation of an elasticsearch indexer in Go

Merged Nick Thomas requested to merge 1-initial-implementation into master
All threads resolved!
1 file
+ 185
0
Compare changes
  • Side-by-side
  • Inline
main.go 0 → 100644
+ 185
0
package main
import (
"encoding/json"
"fmt"
"os"
"srcd.works/go-git.v4"
"srcd.works/go-git.v4/plumbing/difftree"
"srcd.works/go-git.v4/plumbing/object"
"srcd.works/go-git.v4/plumbing"
)
type ESConfig struct {
URL []string `json:"url"`
AWS bool `json:"aws"`
Region string `json:"aws_region"`
AccessKey string `json:"aws_access_key"`
SecretKey string `json:"aws_secret_access_key"`
}
type Repo struct {
Repo *git.Repository
FromHash plumbing.Hash
ToHash plumbing.Hash
FromCommit *object.Commit
ToCommit *object.Commit
}
func NewRepo(projectPath string, fromSHA string, toSHA string) (*Repo, error) {
out := &Repo{}
repo, err := git.PlainOpen(projectPath)
if err != nil {
return nil, err
}
out.Repo = repo
if fromSHA == "" {
out.FromHash = plumbing.ZeroHash
} else {
out.FromHash = plumbing.NewHash(fromSHA)
commit, err := repo.Commit(out.FromHash)
if err != nil {
return nil, fmt.Errorf("Bad from SHA (%s): %s", out.FromHash, err)
}
out.FromCommit = commit
}
if toSHA == "" {
ref, err := out.Repo.Head()
if err != nil {
return nil, err
}
out.ToHash = ref.Hash()
} else {
out.ToHash = plumbing.NewHash(toSHA)
}
commit, err := repo.Commit(out.ToHash)
if err != nil {
return nil, fmt.Errorf("Bad to SHA (%s): %s", out.ToHash, err)
}
out.ToCommit = commit
return out, nil
}
func (r *Repo) Diff() (difftree.Changes, error) {
var fromTree, toTree *object.Tree
if r.FromCommit != nil {
tree, err := r.FromCommit.Tree()
if err != nil {
return nil, err
}
fromTree = tree
}
toTree, err := r.ToCommit.Tree()
if err != nil {
return nil, err
}
return difftree.DiffTree(fromTree, toTree)
}
type FileFunc func(file *object.File)
func (r *Repo) EachFileChange(ins, mod, del FileFunc) error {
changes, err := r.Diff()
if err != nil {
fmt.Printf("Couldn't calculate diff: %s\n", err)
os.Exit(1)
}
for _, change := range changes {
fromF, toF, err := change.Files()
if err != nil {
return err
}
switch change.Action {
case difftree.Insert:
toF.Name = change.To.Name
ins(toF)
case difftree.Modify:
toF.Name = change.To.Name
mod(toF)
case difftree.Delete:
fromF.Name = change.From.Name
del(fromF)
}
}
return nil
}
var EndError = fmt.Errorf("Finished") // not really an error
func (r *Repo) EachCommit(f func(*object.Commit)) {
object.WalkCommitHistory(r.ToCommit, func(c *object.Commit) error {
if r.FromCommit != nil && c.ID() == r.FromCommit.ID() {
return EndError
}
f(c)
return nil
})
}
func main() {
var esConfig ESConfig
if len(os.Args) != 3 {
fmt.Printf("Usage: %s <project-id> <project-path>\n", os.Args[0])
os.Exit(1)
}
if err := json.Unmarshal([]byte(os.Getenv("ELASTIC_CONNECTION_INFO")), &esConfig); err != nil {
fmt.Printf("Error parsing ELASTIC_CONNECTION_INFO: %s\n", err)
os.Exit(1)
}
projectID := os.Args[1]
projectPath := os.Args[2]
fromSHA := os.Getenv("FROM_SHA")
toSHA := os.Getenv("TO_SHA")
railsEnv := os.Getenv("RAILS_ENV")
repo, err := NewRepo(projectPath, fromSHA, toSHA)
if err != nil {
fmt.Printf("Failed to open %s: %s\n", projectPath, err)
os.Exit(1)
}
fmt.Printf("From %s to %s\n", repo.FromHash, repo.ToHash)
fmt.Printf("Project ID: %s, rails env: %s\n", projectID, railsEnv)
insOrModFile := func(file *object.File) {
fmt.Println("Write", file.Name)
}
delFile := func(file *object.File) {
fmt.Println("Delete", file.Name)
}
// index_blobs
repo.EachFileChange(insOrModFile, insOrModFile, delFile)
commit := func(c *object.Commit) {
fmt.Println("Commit", c.ID())
}
// index_commits
repo.EachCommit(commit)
}
Loading