More updates to stop using dev or alpha or beta versions.
[yaffs-website] / vendor / consolidation / robo / src / Task / Remote / Ssh.php
1 <?php
2
3 namespace Robo\Task\Remote;
4
5 use Robo\Contract\CommandInterface;
6 use Robo\Exception\TaskException;
7 use Robo\Task\BaseTask;
8 use Robo\Contract\SimulatedInterface;
9
10 /**
11  * Runs multiple commands on a remote server.
12  * Per default, commands are combined with &&, unless stopOnFail is false.
13  *
14  * ```php
15  * <?php
16  *
17  * $this->taskSshExec('remote.example.com', 'user')
18  *     ->remoteDir('/var/www/html')
19  *     ->exec('ls -la')
20  *     ->exec('chmod g+x logs')
21  *     ->run();
22  *
23  * ```
24  *
25  * You can even exec other tasks (which implement CommandInterface):
26  *
27  * ```php
28  * $gitTask = $this->taskGitStack()
29  *     ->checkout('master')
30  *     ->pull();
31  *
32  * $this->taskSshExec('remote.example.com')
33  *     ->remoteDir('/var/www/html/site')
34  *     ->exec($gitTask)
35  *     ->run();
36  * ```
37  *
38  * You can configure the remote directory for all future calls:
39  *
40  * ```php
41  * \Robo\Task\Remote\Ssh::configure('remoteDir', '/some-dir');
42  * ```
43  */
44 class Ssh extends BaseTask implements CommandInterface, SimulatedInterface
45 {
46     use \Robo\Common\CommandReceiver;
47     use \Robo\Common\ExecOneCommand;
48
49     /**
50      * @var null|string
51      */
52     protected $hostname;
53
54     /**
55      * @var null|string
56      */
57     protected $user;
58
59     /**
60      * @var bool
61      */
62     protected $stopOnFail = true;
63
64     /**
65      * @var array
66      */
67     protected $exec = [];
68
69     /**
70      * Changes to the given directory before running commands.
71      *
72      * @var string
73      */
74     protected $remoteDir;
75
76     /**
77      * @param null|string $hostname
78      * @param null|string $user
79      */
80     public function __construct($hostname = null, $user = null)
81     {
82         $this->hostname = $hostname;
83         $this->user = $user;
84     }
85
86     /**
87      * @param string $hostname
88      *
89      * @return $this
90      */
91     public function hostname($hostname)
92     {
93         $this->hostname = $hostname;
94         return $this;
95     }
96
97     /**
98      * @param string $user
99      *
100      * @return $this
101      */
102     public function user($user)
103     {
104         $this->user = $user;
105         return $this;
106     }
107
108     /**
109      * Whether or not to chain commands together with && and stop the chain if one command fails.
110      *
111      * @param bool $stopOnFail
112      *
113      * @return $this
114      */
115     public function stopOnFail($stopOnFail = true)
116     {
117         $this->stopOnFail = $stopOnFail;
118         return $this;
119     }
120
121     /**
122      * Changes to the given directory before running commands.
123      *
124      * @param string $remoteDir
125      *
126      * @return $this
127      */
128     public function remoteDir($remoteDir)
129     {
130         $this->remoteDir = $remoteDir;
131         return $this;
132     }
133
134     /**
135      * @param string $filename
136      *
137      * @return $this
138      */
139     public function identityFile($filename)
140     {
141         $this->option('-i', $filename);
142
143         return $this;
144     }
145
146     /**
147      * @param int $port
148      *
149      * @return $this
150      */
151     public function port($port)
152     {
153         $this->option('-p', $port);
154
155         return $this;
156     }
157
158     /**
159      * @return $this
160      */
161     public function forcePseudoTty()
162     {
163         $this->option('-t');
164
165         return $this;
166     }
167
168     /**
169      * @return $this
170      */
171     public function quiet()
172     {
173         $this->option('-q');
174
175         return $this;
176     }
177
178     /**
179      * @return $this
180      */
181     public function verbose()
182     {
183         $this->option('-v');
184
185         return $this;
186     }
187
188     /**
189      * @param string|string[]|CommandInterface $command
190      *
191      * @return $this
192      */
193     public function exec($command)
194     {
195         if (is_array($command)) {
196             $command = implode(' ', array_filter($command));
197         }
198
199         $this->exec[] = $command;
200
201         return $this;
202     }
203
204     /**
205      * Returns command that can be executed.
206      * This method is used to pass generated command from one task to another.
207      *
208      * @return string
209      */
210     public function getCommand()
211     {
212         $commands = [];
213         foreach ($this->exec as $command) {
214             $commands[] = $this->receiveCommand($command);
215         }
216
217         $remoteDir = $this->remoteDir ? $this->remoteDir : $this->getConfigValue('remoteDir');
218         if (!empty($remoteDir)) {
219             array_unshift($commands, sprintf('cd "%s"', $remoteDir));
220         }
221         $command = implode($this->stopOnFail ? ' && ' : ' ; ', $commands);
222
223         return $this->sshCommand($command);
224     }
225
226     /**
227      * {@inheritdoc}
228      */
229     public function run()
230     {
231         $this->validateParameters();
232         $command = $this->getCommand();
233         return $this->executeCommand($command);
234     }
235
236     /**
237      * {@inheritdoc}
238      */
239     public function simulate($context)
240     {
241         $command = $this->getCommand();
242         $this->printTaskInfo("Running {command}", ['command' => $command] + $context);
243     }
244
245     protected function validateParameters()
246     {
247         if (empty($this->hostname)) {
248             throw new TaskException($this, 'Please set a hostname');
249         }
250         if (empty($this->exec)) {
251             throw new TaskException($this, 'Please add at least one command');
252         }
253     }
254
255     /**
256      * Returns an ssh command string running $command on the remote.
257      *
258      * @param string|CommandInterface $command
259      *
260      * @return string
261      */
262     protected function sshCommand($command)
263     {
264         $command = $this->receiveCommand($command);
265         $sshOptions = $this->arguments;
266         $hostSpec = $this->hostname;
267         if ($this->user) {
268             $hostSpec = $this->user . '@' . $hostSpec;
269         }
270
271         return "ssh{$sshOptions} {$hostSpec} '{$command}'";
272     }
273 }