Completed
Push — master ( 7df873...57a8d7 )
by Greg
02:28
created

src/Common/ExecCommand.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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()));
0 ignored issues
show
$command is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
141
        return new Result(
142
            $this,
143
            $result_data->getExitCode(),
144
            $result_data->getMessage(),
145
            $result_data->getData()
146
        );
147
    }
148
}
149