Completed
Pull Request — master (#531)
by
unknown
03:55 queued 46s
created

ExecCommand::printMetadata()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 1
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
    public function getCommand()
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
        $this->process = new Process($command);
140
        $result_data = $this->execute();
141
        return new Result(
142
            $this,
143
            $result_data->getExitCode(),
144
            $result_data->getMessage(),
145
            $result_data->getData()
146
        );
147
    }
148
}
149