func (cmd *ExecCommandImpl) ExitCode() (int, error) {
	select {
	case <-cmd.ctx.Done():
		return 0, fmt.Errorf("failed to fetch the command's exit code: %v", cmd.ctx.Err())
	case exitCode := <-cmd.exitCodeCh:
		return exitCode, nil
	case err := <-cmd.exitCodeErrCh:
		return 0, err
	}
}
ExitCode implements ExecCommand#ExitCode
package plugin
import (
	"context"
	"fmt"
)
type ExecCommandImpl struct {
	ctx           context.Context
	outputCh      chan ExecOutputChunk
	stdout        *OutputStream
	stderr        *OutputStream
	exitCodeCh    chan int
	exitCodeErrCh chan error
}
func NewExecCommand(ctx context.Context) *ExecCommandImpl {
	if ctx == nil {
		panic("plugin.NewExecCommand called with a nil context")
	}
	cmd := &ExecCommandImpl{
		ctx:           ctx,
		exitCodeCh:    make(chan int, 1),
		exitCodeErrCh: make(chan error, 1),
	}
	cmd.outputCh = make(chan ExecOutputChunk)
	closer := &multiCloser{ch: cmd.outputCh, countdown: 2}
	cmd.stdout = &OutputStream{ctx: cmd.ctx, id: Stdout, ch: cmd.outputCh, closer: closer}
	cmd.stderr = &OutputStream{ctx: cmd.ctx, id: Stderr, ch: cmd.outputCh, closer: closer}
	go func() {
		<-cmd.ctx.Done()
		cmd.CloseStreamsWithError(ctx.Err())
	}()
	return cmd
}
func (cmd *ExecCommandImpl) SetStopFunc(stopFunc func()) {
	if stopFunc != nil {
		go func() {
			<-cmd.ctx.Done()
			stopFunc()
		}()
	}
}
func (cmd *ExecCommandImpl) Stdout() *OutputStream {
	return cmd.stdout
}
func (cmd *ExecCommandImpl) Stderr() *OutputStream {
	return cmd.stderr
}
func (cmd *ExecCommandImpl) CloseStreamsWithError(err error) {
	cmd.Stdout().CloseWithError(err)
	cmd.Stderr().CloseWithError(err)
}
func (cmd *ExecCommandImpl) SetExitCode(exitCode int) {
	select {
	case <-cmd.ctx.Done():
	default:
		cmd.exitCodeCh <- exitCode
	}
}
func (cmd *ExecCommandImpl) SetExitCodeErr(err error) {
	select {
	case <-cmd.ctx.Done():
	default:
		cmd.exitCodeErrCh <- err
	}
}
func (cmd *ExecCommandImpl) OutputCh() <-chan ExecOutputChunk {
	return cmd.outputCh
}