Completed
Push — master ( 1feb90...f64674 )
by Chris
34:59 queued 20:03
created

GitCommand::executeRaw()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 1
cts 1
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
namespace GitWrapper;
4
5
use Symfony\Component\Process\ProcessUtils;
6
7
/**
8
 * Base class extended by all Git command classes.
9
 */
10
class GitCommand
11
{
12
    /**
13
     * Path to the directory containing the working copy. If this variable is
14
     * set, then the process will change into this directory while the Git
15
     * command is being run.
16
     *
17
     * @var string|null
18
     */
19
    protected $directory;
20
21
    /**
22
     * The command being run, e.g. "clone", "commit", etc.
23
     *
24
     * @var string
25
     */
26
    protected $command = '';
27
28
    /**
29
     * An associative array of command line options and flags.
30
     *
31
     * @var array
32
     */
33
    protected $options = array();
34
35
    /**
36
     * Command line arguments passed to the Git command.
37
     *
38
     * @var array
39
     */
40
    protected $args = array();
41
42
    /**
43
     * Whether command execution should be bypassed.
44
     *
45
     * @var bool
46
     */
47
    protected $bypass = false;
48
49
    /**
50
     * Whether to execute the raw command without escaping it. This is useful
51
     * for executing arbitrary commands, e.g. "status -s". If this is true,
52
     * any options and arguments are ignored.
53
     *
54
     * @var bool
55
     */
56
    protected $executeRaw = false;
57 260
58
    /**
59 260
     * Constructs a GitCommand object.
60
     *
61
     * Use GitCommand::getInstance() as the factory method for this class.
62 244
     *
63
     * @param array $args
64
     *   The arguments passed to GitCommand::getInstance().
65 244
     */
66 244
    protected function __construct($args)
67 212
    {
68 212
        if ($args) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $args of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
69 212
70
            // The first argument is the command.
71
            $this->command = array_shift($args);
72 244
73 208
            // If the last element is an array, set it as the options.
74 244
            $options = end($args);
75 244
            if (is_array($options)) {
76 260
                $this->setOptions($options);
77
                array_pop($args);
78
            }
79
80
            // Pass all other method arguments as the Git command arguments.
81
            foreach ($args as $arg) {
82
                $this->addArgument($arg);
83
            }
84
        }
85
    }
86
87
    /**
88
     * Constructs a GitCommand object.
89
     *
90
     * Accepts a variable number of arguments to model the arguments passed to
91
     * the Git command line utility. If the last argument is an array, it is
92
     * passed as the command options.
93
     *
94 260
     * @param string $command
0 ignored issues
show
Bug introduced by
There is no parameter named $command. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
95
     *   The Git command being run, e.g. "clone", "commit", etc.
96 260
     * @param string ...
97 260
     *   Zero or more arguments passed to the Git command.
98
     * @param array $options
0 ignored issues
show
Bug introduced by
There is no parameter named $options. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
99
     *   An optional array of arguments to pass to the command.
100
     *
101
     * @return \GitWrapper\GitCommand
102
     */
103
    public static function getInstance()
104
    {
105 252
        $args = func_get_args();
106
        return new static($args);
107 252
    }
108
109
    /**
110
     * Returns Git command being run, e.g. "clone", "commit", etc.
111
     *
112
     * @return string
113
     */
114
    public function getCommand()
115
    {
116
        return $this->command;
117
    }
118 236
119
    /**
120 236
     * Sets the path to the directory containing the working copy.
121 236
     *
122
     * @param string $directory
123
     *   The path to the directory containing the working copy.
124
     *
125
     * @return \GitWrapper\GitCommand
126
     */
127
    public function setDirectory($directory)
128
    {
129
        $this->directory = $directory;
130 244
        return $this;
131
    }
132 244
133
    /**
134
     * Gets the path to the directory containing the working copy.
135
     *
136
     * @return string|null
137
     *   The path, null if no path is set.
138
     */
139
    public function getDirectory()
140
    {
141
        return $this->directory;
142
    }
143
144
    /**
145 12
     * A boolean flagging whether to skip running the command.
146
     *
147 12
     * @param boolean $bypass
148 12
     *   Whether to bypass execution of the command. The parameter defaults to
149
     *   true for code readability, however the default behavior of this class
150
     *   is to run the command.
151
     *
152
     * @return \GitWrapper\GitCommand
153
     */
154
    public function bypass($bypass = true)
155
    {
156
        $this->bypass = (bool) $bypass;
157
        return $this;
158
    }
159
160
    /**
161 240
     * Set whether to execute the command as-is without escaping it.
162
     *
163 240
     * @param boolean $executeRaw
164
     *   Whether to execute the command as-is without excaping it.
165
     *
166
     * @return \GitWrapper\GitCommand
167
     */
168
    public function executeRaw($executeRaw = true)
169
    {
170
        $this->executeRaw = $executeRaw;
171 252
        return $this;
172
    }
173 252
174 252
    /**
175 224
     * Returns true if the Git command should be run.
176 224
     *
177 224
     * The return value is the boolean opposite $this->bypass. Although this
178 224
     * seems complex, it makes the code more readable when checking whether the
179 208
     * command should be run or not.
180 208
     *
181 208
     * @return boolean
182 224
     *   If true, the command should be run.
183 224
     */
184 252
    public function notBypassed()
185 252
    {
186
        return !$this->bypass;
187
    }
188
189
    /**
190
     * Builds the command line options for use in the Git command.
191
     *
192
     * @return array
193
     */
194
    public function buildOptions(): array
195
    {
196
        $options = array();
197
        foreach ($this->options as $option => $values) {
198
            foreach ((array) $values as $value) {
199
200
                // Render the option.
201 228
                $prefix = (strlen($option) != 1) ? '--' : '-';
202
                $options[] = $prefix . $option;
203 228
204 228
                // Render apend the value if the option isn't a flag.
205
                if ($value !== true) {
206
                    $options[] = $value;
207
                }
208
            }
209
        }
210
        return $options;
211
    }
212
213
    /**
214
     * Sets a command line option.
215 212
     *
216
     * Option names are passed as-is to the command line, whereas the values are
217 212
     * escaped using \Symfony\Component\Process\ProcessUtils.
218 208
     *
219 212
     * @param string $option
220 212
     *   The option name, e.g. "branch", "q".
221
     * @param string|true $value
222
     *   The option's value, pass true if the options is a flag.
223
     *
224
     * @reutrn \GitWrapper\GitCommand
225
     */
226
    public function setOption($option, $value)
227
    {
228
        $this->options[$option] = $value;
229
        return $this;
230
    }
231
232
    /**
233 12
     * Sets multiple command line options.
234
     *
235 12
     * @param array $options
236
     *   An associative array of command line options.
237
     *
238
     * @reutrn \GitWrapper\GitCommand
239
     */
240
    public function setOptions(array $options)
241
    {
242
        foreach ($options as $option => $value) {
243
            $this->setOption($option, $value);
244
        }
245
        return $this;
246
    }
247
248 4
    /**
249
     * Sets a command line flag.
250 4
     *
251
     * @param string $flag
0 ignored issues
show
Bug introduced by
There is no parameter named $flag. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
252
     *   The flag name, e.g. "q", "a".
253
     *
254
     * @reutrn \GitWrapper\GitCommand
255
     *
256
     * @see \GitWrapper\GitCommand::setOption()
257
     */
258
    public function setFlag($option)
259
    {
260
        return $this->setOption($option, true);
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string|object<GitWrapper\true>.

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...
261 4
    }
262
263 4
    /**
264 4
     * Gets a command line option.
265
     *
266
     * @param string $option
267
     *   The option name, e.g. "branch", "q".
268
     * @param mixed $default
269
     *   Value that is returned if the option is not set, defaults to null.
270
     *
271
     * @return mixed
272
     */
273
    public function getOption($option, $default = null)
274
    {
275 212
        return (isset($this->options[$option])) ? $this->options[$option] : $default;
276
    }
277 212
278 212
    /**
279
     * Unsets a command line option.
280
     *
281
     * @param string $option
282
     *   The option name, e.g. "branch", "q".
283
     *
284
     * @return \GitWrapper\GitCommand
285
     */
286
    public function unsetOption($option)
287
    {
288
        unset($this->options[$option]);
289 252
        return $this;
290
    }
291
292 252
    /**
293 252
     * Adds a command line argument passed to the Git command.
294 252
     *
295 252
     * @param string $arg
296 252
     *   The argument, e.g. the repo URL, directory, etc.
297
     *
298
     * @return \GitWrapper\GitCommand
299
     */
300
    public function addArgument($arg)
301
    {
302
        $this->args[] = $arg;
303
        return $this;
304
    }
305
306
    /**
307
     * Renders the arguments and options for the Git command.
308
     *
309
     * @return string|array
310
     *
311
     * @see GitCommand::getCommand()
312
     * @see GitCommand::buildOptions()
313
     */
314
    public function getCommandLine()
315
    {
316
        if ($this->executeRaw) {
317
            return $this->getCommand();
318
        }
319
320
        $command = array_merge(
321
            [$this->getCommand()],
322
            $this->buildOptions(),
323
            $this->args
324
        );
325
326
        return array_filter($command);
327
    }
328
}
329