Binary::detectCommand()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 4
eloc 6
c 2
b 0
f 0
nc 4
nop 1
dl 0
loc 11
ccs 0
cts 10
cp 0
crap 20
rs 10
1
<?php
2
/**
3
 * Automation tool mixed with code generator for easier continuous development
4
 *
5
 * @link      https://github.com/hiqdev/hidev
6
 * @package   hidev
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2015-2018, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hidev\base;
12
13
use hidev\components\Binaries;
14
use hidev\modifiers\ModifierInterface;
15
use Yii;
16
use yii\base\InvalidConfigException;
17
18
class Binary extends \yii\base\BaseObject
19
{
20
    /** @var Binaries component */
21
    public $binaries;
22
23
    /**
24
     * @var string command name, eg.: phpunit, composer
25
     */
26
    public $name;
27
28
    /**
29
     * @var string full path to the binary, eg.: /usr/bin/git
30
     */
31
    protected $_path;
32
33
    /**
34
     * @var string full command to run the binary, possibly with added command runner, eg.: /usr/bin/env php /home/user/command.phar
35
     */
36
    protected $_command;
37
38
    /**
39
     * @var string package full name, e.g. pytest
40
     */
41
    public $package;
42
43
    /**
44
     * @var string package version constraint, e.g. ^1.1
45
     */
46
    public $version;
47
48
    /**
49
     * @var string installer URL
50
     */
51
    public $installer;
52
53
    /**
54
     * @var array installer options
55
     */
56
    public $installer_options = [];
57
58
    /**
59
     * @var string URL to download binary
60
     */
61
    public $download;
62
63
    /**
64
     * @var string filename to be added to VCS ignore file
65
     */
66
    protected $_vcsignore;
67
68
    /**
69
     * Prepares and runs with passthru, returns exit code.
70
     * @param string|array $args
71
     * @return int exit code
72
     */
73
    public function passthru($args = [])
74
    {
75
        $command = $this->prepareCommand($args);
76
        Yii::info("> $command");
77
        passthru($command, $exitcode);
78
79
        return $exitcode;
80
    }
81
82
    /**
83
     * Prepares and runs with exec, returns stdout array.
84
     * @param string|array $args
85
     * @param bool $returnExitCode default false
86
     * @return array|int stdout or exit code
87
     */
88
    public function exec($args = [], $returnExitCode = false)
89
    {
90
        $command = $this->prepareCommand($args);
91
        Yii::info("& $command");
92
        exec($command, $array, $exitcode);
93
94
        return $returnExitCode ? $exitcode : $array;
95
    }
96
97
    /**
98
     * Prepare full command line ready for execution.
99
     * @param string|array $args
100
     * @return string
101
     */
102
    public function prepareCommand($args)
103
    {
104
        $command = $this->getCommand();
105
        if (is_string($args)) {
106
            return $command . ' ' . trim($args);
107
        }
108
109
        foreach ($args as $arg) {
110
            if ($arg instanceof ModifierInterface) {
111
                $command = $arg->modify($command);
112
            } else {
113
                $command .= ' ' . escapeshellarg($arg);
114
            }
115
        }
116
117
        return $command;
118
    }
119
120
    public function install()
121
    {
122
        throw new InvalidConfigException('Don\'t know how to install ' . $this->name);
123
    }
124
125
    /**
126
     * Setter for path.
127
     * @param string $value the path
128
     */
129
    public function setPath($value)
130
    {
131
        $this->_path = $value;
132
    }
133
134
    /**
135
     * Getter for path.
136
     * @return string
137
     */
138
    public function getPath()
139
    {
140
        if (!$this->_path) {
141
            $this->_path = $this->detectPath($this->name);
142
        }
143
144
        return $this->_path;
145
    }
146
147
    /**
148
     * Detects how to run the binary with `which` utility.
149
     * @param string $name
150
     * @return string path to the binary
151
     */
152
    public function detectPath($name)
153
    {
154
        return exec('which ' . $name) ?: null;
155
    }
156
157
    /**
158
     * Setter for command.
159
     * @param string $value the command
160
     */
161
    public function setCommand($value)
162
    {
163
        $this->_command = $value;
164
    }
165
166
    /**
167
     * @return string full command to run the binary
168
     */
169
    public function getCommand()
170
    {
171
        if ($this->_command === null) {
172
            $this->_command = $this->detectCommand($this->getPath());
173
        }
174
175
        return $this->_command;
176
    }
177
178
    /**
179
     * Detects command to run the given path, e.g. /usr/bin/env php /the/dir/command.phar.
180
     * @return string path to the binary
181
     */
182
    public function detectCommand($path)
183
    {
184
        if (!$path) {
185
            $this->install();
186
            $path = $this->getPath();
187
        }
188
        if (!$path || !file_exists($path)) {
189
            throw new InvalidConfigException('Failed to find how to run ' . $this->name);
190
        }
191
192
        return $path;
193
    }
194
195
    public function setVcsignore($value)
196
    {
197
        $this->_vcsignore = $value;
198
    }
199
200
    public function getVcsignore()
201
    {
202
        return $this->_vcsignore;
203
    }
204
}
205