5 use Robo\Common\ExecCommand;
6 use Robo\Contract\PrintedInterface;
8 use Robo\Contract\CommandInterface;
9 use Robo\Exception\TaskException;
11 abstract class CommandStack extends BaseTask implements CommandInterface, PrintedInterface
14 use \Robo\Common\CommandReceiver;
19 protected $executable;
31 protected $stopOnFail = false;
36 public function getCommand()
39 foreach ($this->exec as $command) {
40 $commands[] = $this->receiveCommand($command);
43 return implode(' && ', $commands);
47 * @param string $executable
51 public function executable($executable)
53 $this->executable = $executable;
58 * @param string|string[]|CommandInterface $command
62 public function exec($command)
64 if (is_array($command)) {
65 $command = implode(' ', array_filter($command));
68 if (is_string($command)) {
69 $command = $this->executable . ' ' . $this->stripExecutableFromCommand($command);
70 $command = trim($command);
73 $this->exec[] = $command;
79 * @param bool $stopOnFail
83 public function stopOnFail($stopOnFail = true)
85 $this->stopOnFail = $stopOnFail;
89 public function result($result)
91 $this->result = $result;
96 * @param string $command
100 protected function stripExecutableFromCommand($command)
102 $command = trim($command);
103 $executable = $this->executable . ' ';
104 if (strpos($command, $executable) === 0) {
105 $command = substr($command, strlen($executable));
113 public function run()
115 if (empty($this->exec)) {
116 throw new TaskException($this, 'You must add at least one command');
118 // If 'stopOnFail' is not set, or if there is only one command to run,
119 // then execute the single command to run.
120 if (!$this->stopOnFail || (count($this->exec) == 1)) {
121 $this->printTaskInfo('{command}', ['command' => $this->getCommand()]);
122 return $this->executeCommand($this->getCommand());
125 // When executing multiple commands in 'stopOnFail' mode, run them
126 // one at a time so that the result will have the exact command
127 // that failed available to the caller. This is at the expense of
128 // losing the output from all successful commands.
132 foreach ($this->exec as $command) {
133 $this->printTaskInfo("Executing {command}", ['command' => $command]);
134 $result = $this->executeCommand($command);
135 $result->accumulateExecutionTime($data);
136 $message = $result->accumulateMessage($message);
137 $data = $result->mergeData($data);
138 if (!$result->wasSuccessful()) {