multistep is a Go library for building up complex actions using discrete, individual "steps." These steps are strung together and run in sequence to achieve a more complex goal. The runner handles cleanup, cancelling, etc. if necessary.

Basic Example

Make a step to perform some action. The step can access your "state", which is passed between steps by the runner.

type stepAdd struct{}

func (s *stepAdd) Run(state multistep.StateBag) multistep.StepAction {
    // Read our value and assert that it is they type we want
    value := state.Get("value").(int)
    fmt.Printf("Value is %d\n", value)

	// Store some state back
	state.Put("value", value + 1)
    return multistep.ActionContinue

func (s *stepAdd) Cleanup(multistep.StateBag) {
	// This is called after all the steps have run or if the runner is
	// cancelled so that cleanup can be performed.

Make a runner and call your array of Steps.

func main() {
    // Our "bag of state" that we read the value from
    state := new(multistep.BasicStateBag)
	state.Put("value", 0)

    steps := []multistep.Step{

    runner := &multistep.BasicRunner{Steps: steps}

    // Executes the steps

This will produce:

Value is 0
Value is 1
Value is 2



    multistep is a library for bulding up complex actions using individual, discrete steps.



    View Source
    const StateCancelled = "cancelled"

      This is the key set in the state bag when using the basic runner to signal that the step sequence was cancelled.

      View Source
      const StateHalted = "halted"

        This is the key set in the state bag when a step halted the sequence.


        This section is empty.


        func DebugPauseDefault

        func DebugPauseDefault(loc DebugLocation, name string, state StateBag)

          DebugPauseDefault is the default pause function when using the DebugRunner if no PauseFn is specified. It outputs some information to stderr about the step and waits for keyboard input on stdin before continuing.


          type BasicRunner

          type BasicRunner struct {
          	// Steps is a slice of steps to run. Once set, this should _not_ be
          	// modified.
          	Steps []Step
          	// contains filtered or unexported fields

            BasicRunner is a Runner that just runs the given slice of steps.

            func (*BasicRunner) Cancel

            func (b *BasicRunner) Cancel()

            func (*BasicRunner) Run

            func (b *BasicRunner) Run(state StateBag)

            type BasicStateBag

            type BasicStateBag struct {
            	// contains filtered or unexported fields

              BasicStateBag implements StateBag by using a normal map underneath protected by a RWMutex.

              func (*BasicStateBag) Get

              func (b *BasicStateBag) Get(k string) interface{}

              func (*BasicStateBag) GetOk

              func (b *BasicStateBag) GetOk(k string) (interface{}, bool)

              func (*BasicStateBag) Put

              func (b *BasicStateBag) Put(k string, v interface{})

              type DebugLocation

              type DebugLocation uint

                DebugLocation is the location where the pause is occuring when debugging a step sequence. "DebugLocationAfterRun" is after the run of the named step. "DebugLocationBeforeCleanup" is before the cleanup of the named step.

                const (
                	DebugLocationAfterRun DebugLocation = iota

                type DebugPauseFn

                type DebugPauseFn func(DebugLocation, string, StateBag)

                  DebugPauseFn is the type signature for the function that is called whenever the DebugRunner pauses. It allows the caller time to inspect the state of the multi-step sequence at a given step.

                  type DebugRunner

                  type DebugRunner struct {
                  	// Steps is the steps to run. These will be run in order.
                  	Steps []Step
                  	// PauseFn is the function that is called whenever the debug runner
                  	// pauses. The debug runner continues when this function returns.
                  	// The function is given the state so that the state can be inspected.
                  	PauseFn DebugPauseFn
                  	// contains filtered or unexported fields

                    DebugRunner is a Runner that runs the given set of steps in order, but pauses between each step until it is told to continue.

                    func (*DebugRunner) Cancel

                    func (r *DebugRunner) Cancel()

                    func (*DebugRunner) Run

                    func (r *DebugRunner) Run(state StateBag)

                    type Runner

                    type Runner interface {
                    	// Run runs the steps with the given initial state.
                    	// Cancel cancels a potentially running stack of steps.

                      Runner is a thing that runs one or more steps.

                      type StateBag

                      type StateBag interface {
                      	Get(string) interface{}
                      	GetOk(string) (interface{}, bool)
                      	Put(string, interface{})

                        StateBag holds the state that is used by the Runner and Steps. The StateBag implementation must be safe for concurrent access.

                        type Step

                        type Step interface {
                        	// Run is called to perform the action. The parameter is a "state bag"
                        	// of untyped things. Please be very careful about type-checking the
                        	// items in this bag.
                        	// The return value determines whether multi-step sequences continue
                        	// or should halt.
                        	Run(StateBag) StepAction
                        	// Cleanup is called in reverse order of the steps that have run
                        	// and allow steps to clean up after themselves. Do not assume if this
                        	// ran that the entire multi-step sequence completed successfully. This
                        	// method can be ran in the face of errors and cancellations as well.
                        	// The parameter is the same "state bag" as Run, and represents the
                        	// state at the latest possible time prior to calling Cleanup.

                          Step is a single step that is part of a potentially large sequence of other steps, responsible for performing some specific action.

                          type StepAction

                          type StepAction uint

                            A StepAction determines the next step to take regarding multi-step actions.

                            const (
                            	ActionContinue StepAction = iota

                            type StepWrapper

                            type StepWrapper interface {
                            	// InnerStepName should return the human readable name of the wrapped step.
                            	InnerStepName() string

                              StepWrapper is an interface that wrapped steps can implement to expose their inner step names to the debug runner.