Start executes the command and returns immediately.
(ctx context.Context)
| 106 | |
| 107 | // Start executes the command and returns immediately. |
| 108 | func (cmd Cmd) Start(ctx context.Context) (Process, error) { |
| 109 | // Deliberately a value receiver so the cmd object can be updated prior to execution |
| 110 | if cmd.Target == nil { |
| 111 | cmd.Target = LocalTarget |
| 112 | } else if cmd.Target != LocalTarget { |
| 113 | ctx = log.V{"On": cmd.Target}.Bind(ctx) |
| 114 | } |
| 115 | |
| 116 | if cmd.Dir != "" { |
| 117 | ctx = log.V{"Dir": cmd.Dir}.Bind(ctx) |
| 118 | } |
| 119 | // build our stdout and stderr handling |
| 120 | var logStdout, logStderr io.WriteCloser |
| 121 | if cmd.Verbosity { |
| 122 | ctx := log.PutProcess(ctx, filepath.Base(cmd.Name)) |
| 123 | logStdout = log.From(ctx).Writer(log.Info) |
| 124 | defer logStdout.Close() |
| 125 | if cmd.Stdout != nil { |
| 126 | cmd.Stdout = io.MultiWriter(cmd.Stdout, logStdout) |
| 127 | } else { |
| 128 | cmd.Stdout = logStdout |
| 129 | } |
| 130 | logStderr = log.From(ctx).Writer(log.Error) |
| 131 | defer logStderr.Close() |
| 132 | if cmd.Stderr != nil { |
| 133 | cmd.Stderr = io.MultiWriter(cmd.Stderr, logStderr) |
| 134 | } else { |
| 135 | cmd.Stderr = logStderr |
| 136 | } |
| 137 | } |
| 138 | // Ready to start |
| 139 | if cmd.Verbosity { |
| 140 | extra := "" |
| 141 | if cmd.Dir != "" { |
| 142 | extra = fmt.Sprintf(" In %v", cmd.Dir) |
| 143 | } |
| 144 | log.I(ctx, "Exec: %v%s", cmd, extra) |
| 145 | } |
| 146 | return cmd.Target.Start(cmd) |
| 147 | } |
| 148 | |
| 149 | // Run executes the command, and blocks until it completes or the context is cancelled. |
| 150 | func (cmd Cmd) Run(ctx context.Context) error { |