func()

in astro/exec2/process.go [108:168]


func (p *Process) Run() error {
	command := p.config.Command
	args := p.config.Args

	logger.Trace.Printf("exec2: running command: %v; args: %v\n", command, args)
	p.execCmd = exec.Command(command, args...)

	// Apply options
	p.execCmd.Dir = p.config.WorkingDir
	p.execCmd.Env = p.config.Env
	p.configureOutputs()

	if isInterrupted {
		return fmt.Errorf("astro was interrupted, command won't be run: %s, args: %v", command, args)
	}

	// If no success codes were given, default to 0
	if p.config.ExpectedSuccessCodes == nil {
		p.config.ExpectedSuccessCodes = []int{0}
	}

	// Run the process
	started := time.Now()
	if err := p.execCmd.Start(); err != nil {
		p.time = time.Since(started)
		return err
	} else {
		// wait for the command to finish
		waitCh := make(chan error, 1)
		go func() {
			waitCh <- p.execCmd.Wait()
			close(waitCh)
		}()
		sigChan := make(chan os.Signal, 1)
		signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT)

		var errors error
		for {
			select {
			case sig := <-sigChan:
				isInterrupted = true
				errors = multierror.Append(fmt.Errorf("signal received: %s", sig))
				process := p.execCmd.Process
				logger.Trace.Printf("Signal: %s, process: %d\n", sig, process.Pid)
				if err := process.Signal(sig); err != nil {
					errors = multierror.Append(errors, err)
				}
			case err := <-waitCh:
				// Record run time
				p.time = time.Since(started)
				logger.Trace.Printf("exec2: command exit code: %v\n", p.ExitCode())
				// Return an error, if the command didn't exit with a success code
				if !p.Success() {
					errors = multierror.Append(errors, err)
					return fmt.Errorf("%s%v", p.Stderr().String(), errors)
				}
				return errors
			}
		}
	}
}