stash/vendor/github.com/gobuffalo/genny/step.go

147 lines
2.6 KiB
Go

package genny
import (
"bytes"
"crypto/sha1"
"fmt"
"io"
"math/rand"
"strconv"
"sync"
"time"
"github.com/gobuffalo/events"
"github.com/markbates/safe"
"github.com/pkg/errors"
)
type DeleteFn func()
type Step struct {
as *Generator
before []*Generator
after []*Generator
index int
moot *sync.RWMutex
}
func (s *Step) Before(g *Generator) DeleteFn {
df := func() {
var a []*Generator
s.moot.Lock()
for _, b := range s.before {
if g.StepName == b.StepName {
continue
}
a = append(a, b)
}
s.before = a
s.moot.Unlock()
}
s.moot.Lock()
s.before = append(s.before, g)
s.moot.Unlock()
return df
}
func (s *Step) After(g *Generator) DeleteFn {
df := func() {
var a []*Generator
s.moot.Lock()
for _, b := range s.after {
if g.StepName == b.StepName {
continue
}
a = append(a, b)
}
s.after = a
s.moot.Unlock()
}
s.moot.Lock()
s.after = append(s.after, g)
s.moot.Unlock()
return df
}
func (s *Step) Run(r *Runner) error {
for _, b := range s.before {
if err := s.runGenerator(r, b); err != nil {
return errors.WithStack(err)
}
}
if err := s.runGenerator(r, s.as); err != nil {
return errors.WithStack(err)
}
for _, b := range s.after {
if err := s.runGenerator(r, b); err != nil {
return errors.WithStack(err)
}
}
return nil
}
func (s *Step) runGenerator(r *Runner, g *Generator) error {
r.curGen = g
payload := events.Payload{
"runner": r,
"step": s,
"generator": g,
}
if g.Should != nil {
err := safe.RunE(func() error {
if !g.Should(r) {
return io.EOF
}
return nil
})
if err != nil {
r.Logger.Debugf("Step: %s [skipped]", g.StepName)
events.EmitPayload(EvtStepPrefix+":skipping:"+g.StepName, payload)
return nil
}
}
r.Logger.Debugf("Step: %s", g.StepName)
events.EmitPayload(EvtStepPrefix+":running:"+g.StepName, payload)
return r.Chdir(r.Root, func() error {
for _, fn := range g.runners {
err := safe.RunE(func() error {
return fn(r)
})
if err != nil {
events.EmitError(EvtStepPrefix+":running:"+g.StepName+":err", err, payload)
return errors.WithStack(err)
}
}
return nil
})
}
func NewStep(g *Generator, index int) (*Step, error) {
if g == nil {
return nil, errors.New("generator can not be nil")
}
return &Step{
as: g,
index: index,
moot: &sync.RWMutex{},
}, nil
}
func init() {
rand.Seed(time.Now().UnixNano())
}
func stepName() string {
bb := &bytes.Buffer{}
bb.WriteString(fmt.Sprint(time.Now().UnixNano()))
bb.WriteString(strconv.Itoa(rand.Int()))
bb.WriteString(strconv.Itoa(rand.Int()))
h := sha1.New()
h.Write(bb.Bytes())
return fmt.Sprintf("%x", h.Sum(nil))[:8]
}