github.com/bkosm/gompose/v2@v2.3.1/readyonstdout.go (about) 1 package gompose 2 3 import ( 4 "os/exec" 5 "strings" 6 ) 7 8 // ReadyOnStdout returns a ReadyOrErrChan that is ready when the specified string is found in the 9 // stdout or stderr produced by the specified exec.Cmd. 10 // The channel will be closed immediately if no options are specified. 11 // An ErrWaitTimedOut will be returned if the timeout is reached. 12 // Times is defaulted to 1, the timeout and interval to DefaultWaitTimeout, DefaultPollInterval. 13 // The command will be run once per poll interval. 14 func ReadyOnStdout(cmd *exec.Cmd, awaiting string, opts ...Option) ReadyOrErrChan { 15 options := timeBased{ 16 times: 1, 17 timeout: DefaultWaitTimeout, 18 pollInterval: DefaultPollInterval, 19 } 20 for _, opt := range opts { 21 if fn := opt.withTimeBasedFunc; fn != nil { 22 fn(&options) 23 } 24 } 25 26 readyOrErr := make(chan error) 27 28 go seekOrTimeout(options.timeout, options.pollInterval, readyOrErr, func() (bool, error) { 29 if res, err := run(*cmd); err != nil { 30 return false, err 31 } else { 32 return countLogOccurrences(res, awaiting) >= int(options.times), nil 33 } 34 }) 35 36 return readyOrErr 37 } 38 39 func countLogOccurrences(res cmdOutput, awaiting string) int { 40 count := 0 41 for _, line := range strings.Split(string(res), "\n") { 42 if strings.Contains(line, awaiting) { 43 count++ 44 } 45 } 46 return count 47 }