Skip to content

Instantly share code, notes, and snippets.

@JohnStarich
Last active January 4, 2020 19:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JohnStarich/719c2154225f2db2fe5c2f22df0a44fc to your computer and use it in GitHub Desktop.
Save JohnStarich/719c2154225f2db2fe5c2f22df0a44fc to your computer and use it in GitHub Desktop.
Functional Pipes in Go
package pipe
// Op is the common pipe operation. Can be composed into Ops and run as a single unit
type Op interface {
Do() error
}
// OpFunc makes it easy to wrap an anonymous function into an Op
type OpFunc func() error
// Do implements the Op interface
func (o OpFunc) Do() error {
return o()
}
// Ops can run a slice of Op's in series, stopping on the first error
type Ops []Op
// Do implements the Op interface
func (ops Ops) Do() error {
for _, op := range ops {
if err := op.Do(); err != nil {
return err
}
}
return nil
}
// OpFuncs makes it easy to wrap a slice of functions into an Op
type OpFuncs []func() error
// Do implements the Op interface
func (ops OpFuncs) Do() error {
for _, op := range ops {
if err := op(); err != nil {
return err
}
}
return nil
}
import (
"gopkg.in/src-d/go-git.v4"
"gopkg.in/src-d/go-git.v4/plumbing"
"gopkg.in/src-d/go-git.v4/plumbing/object"
"github.com/johnstarich/sage/pipe"
)
func initVCS(path string) (*git.Repository, error) {
var err error
var repo *git.Repository
var tree *git.Worktree
var status git.Status
return repo, pipe.OpFuncs{
func() error {
repo, err = git.PlainInit(path, false)
return err
},
func() error {
tree, err = repo.Worktree()
return err
},
func() error {
status, err = tree.Status()
return err
},
func() error {
var ops pipe.OpFuncs
added := false
for file, stat := range status {
// add any untracked files, excluding hidden and tmp files
if stat.Worktree == git.Untracked && !strings.HasPrefix(file, ".") && !strings.HasSuffix(file, ".tmp") {
fileCopy := file
ops = append(ops, func() error {
_, err := tree.Add(fileCopy)
return err
})
added = true
}
}
if added {
ops = append(ops, func() error {
_, err := tree.Commit("Initial commit", &git.CommitOptions{
Author: &object.Signature{
Name: "Sage",
When: time.Now(),
},
})
return err
})
}
return ops.Do()
},
}.Do()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment