c3e6c3af636c77db54884ae85d66b3f5583139ea
[yaffs-website] / vendor / consolidation / robo / src / Common / ExecCommand.php
1 <?php
2 namespace Robo\Common;
3
4 use Robo\Result;
5 use Symfony\Component\Process\ExecutableFinder;
6 use Symfony\Component\Process\Process;
7
8 /**
9  * This task is supposed to be executed as shell command.
10  * You can specify working directory and if output is printed.
11  */
12 trait ExecCommand
13 {
14     use ExecTrait;
15
16     /**
17      * @var \Robo\Common\TimeKeeper
18      */
19     protected $execTimer;
20
21     /**
22      * @return \Robo\Common\TimeKeeper
23      */
24     protected function getExecTimer()
25     {
26         if (!isset($this->execTimer)) {
27             $this->execTimer = new TimeKeeper();
28         }
29         return $this->execTimer;
30     }
31
32     /**
33      * Look for a "{$cmd}.phar" in the current working
34      * directory; return a string to exec it if it is
35      * found.  Otherwise, look for an executable command
36      * of the same name via findExecutable.
37      *
38      * @param string $cmd
39      *
40      * @return bool|string
41      */
42     protected function findExecutablePhar($cmd)
43     {
44         if (file_exists("{$cmd}.phar")) {
45             return "php {$cmd}.phar";
46         }
47         return $this->findExecutable($cmd);
48     }
49
50     /**
51      * Return the best path to the executable program
52      * with the provided name.  Favor vendor/bin in the
53      * current project. If not found there, use
54      * whatever is on the $PATH.
55      *
56      * @param string $cmd
57      *
58      * @return bool|string
59      */
60     protected function findExecutable($cmd)
61     {
62         $pathToCmd = $this->searchForExecutable($cmd);
63         if ($pathToCmd) {
64             return $this->useCallOnWindows($pathToCmd);
65         }
66         return false;
67     }
68
69     /**
70      * @param string $cmd
71      *
72      * @return string
73      */
74     private function searchForExecutable($cmd)
75     {
76         $projectBin = $this->findProjectBin();
77
78         $localComposerInstallation = $projectBin . DIRECTORY_SEPARATOR . $cmd;
79         if (file_exists($localComposerInstallation)) {
80             return $localComposerInstallation;
81         }
82         $finder = new ExecutableFinder();
83         return $finder->find($cmd, null, []);
84     }
85
86     /**
87      * @return bool|string
88      */
89     protected function findProjectBin()
90     {
91         $cwd = getcwd();
92         $candidates = [ __DIR__ . '/../../vendor/bin', __DIR__ . '/../../bin', $cwd . '/vendor/bin' ];
93
94         // If this project is inside a vendor directory, give highest priority
95         // to that directory.
96         $vendorDirContainingUs = realpath(__DIR__ . '/../../../..');
97         if (is_dir($vendorDirContainingUs) && (basename($vendorDirContainingUs) == 'vendor')) {
98             array_unshift($candidates, $vendorDirContainingUs . '/bin');
99         }
100
101         foreach ($candidates as $dir) {
102             if (is_dir("$dir")) {
103                 return realpath($dir);
104             }
105         }
106         return false;
107     }
108
109     /**
110      * Wrap Windows executables in 'call' per 7a88757d
111      *
112      * @param string $cmd
113      *
114      * @return string
115      */
116     protected function useCallOnWindows($cmd)
117     {
118         if (defined('PHP_WINDOWS_VERSION_BUILD')) {
119             if (file_exists("{$cmd}.bat")) {
120                 $cmd = "{$cmd}.bat";
121             }
122             return "call $cmd";
123         }
124         return $cmd;
125     }
126
127     protected function getCommandDescription()
128     {
129         return $this->process->getCommandLine();
130     }
131
132     /**
133      * @param string $command
134      *
135      * @return \Robo\Result
136      */
137     protected function executeCommand($command)
138     {
139         // TODO: Symfony 4 requires that we supply the working directory.
140         $result_data = $this->execute(new Process($command, getcwd()));
141         return new Result(
142             $this,
143             $result_data->getExitCode(),
144             $result_data->getMessage(),
145             $result_data->getData()
146         );
147     }
148 }