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  }