Completed
Push — master ( 85c97a...a6409c )
by Matteo
16:08 queued 07:17
created

BaseCommand::getCLISubjects()   C

Complexity

Conditions 7
Paths 16

Size

Total Lines 29
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 7.8701

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 29
ccs 17
cts 23
cp 0.7391
rs 6.7272
cc 7
eloc 21
nc 16
nop 0
crap 7.8701
1
<?php
2
/**
3
 * GitElephant - An abstraction layer for git written in PHP
4
 * Copyright (C) 2013  Matteo Giachino
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program.  If not, see [http://www.gnu.org/licenses/].
18
 */
19
20
namespace GitElephant\Command;
21
22
use \GitElephant\Repository;
23
use \PhpCollection\Map;
24
25
/**
26
 * BaseCommand
27
 *
28
 * The base class for all the command generators
29
 *
30
 * @author Matteo Giachino <[email protected]>
31
 */
32
class BaseCommand
33
{
34
    /**
35
     * the command name
36
     *
37
     * @var string
38
     */
39
    private $commandName = null;
40
41
    /**
42
     * config options
43
     *
44
     * @var array
45
     */
46
    private $configs = array();
47
48
    /**
49
     * global configs
50
     *
51
     * @var array
52
     */
53
    private $globalConfigs = array();
54
55
    /**
56
     * global options
57
     *
58
     * @var array
59
     */
60
    private $globalOptions = array();
61
62
    /**
63
     * the command arguments
64
     *
65
     * @var array
66
     */
67
    private $commandArguments = array();
68
69
    /**
70
     * the global command arguments
71
     *
72
     * @var array
73
     */
74
    private $globalCommandArguments = array();
75
76
    /**
77
     * the command subject
78
     *
79
     * @var string|SubCommandCommand
80
     */
81
    private $commandSubject = null;
82
83
    /**
84
     * the command second subject (i.e. for branch)
85
     *
86
     * @var string|SubCommandCommand
87
     */
88
    private $commandSubject2 = null;
89
90
    /**
91
     * the path
92
     *
93
     * @var string
94
     */
95
    private $path = null;
96
97
    /**
98
     * constructor
99
     *
100
     * should be called by all child classes' constructors to permit use of 
101
     * global configs, options and command arguments
102
     *
103
     * @param null|\GitElephant\Repository $repo The repo object to read
104
     */
105 115
    public function __construct(Repository $repo = null)
106
    {
107 115
        if (!is_null($repo)) {
108 92
            $this->addGlobalConfigs($repo->getGlobalConfigs());
109 92
            $this->addGlobalOptions($repo->getGlobalOptions());
110
            
111 92
            $arguments = $repo->getGlobalCommandArguments();
112 92
            if (!empty($arguments)) {
113 1
                foreach ($arguments as $argument) {
114 1
                    $this->addGlobalCommandArgument($argument);
115 1
                }
116 1
            }
117 92
        }
118 115
    }
119
120
    /**
121
     * Clear all previous variables
122
     */
123 101
    public function clearAll()
124
    {
125 101
        $this->commandName            = null;
126 101
        $this->configs                = array();
127 101
        $this->commandArguments       = array();
128 101
        $this->commandSubject         = null;
129 101
        $this->commandSubject2        = null;
130 101
        $this->path                   = null;
131 101
    }
132
133 105
    public static function getInstance(Repository $repo = null)
134
    {
135 105
        return new static($repo);
136
    }
137
138
    /**
139
     * Add the command name
140
     *
141
     * @param string $commandName the command name
142
     */
143 102
    protected function addCommandName($commandName)
144
    {
145 102
        $this->commandName = $commandName;
146 102
    }
147
148
    /**
149
     * Get command name
150
     *
151
     * @return string
152
     */
153 11
    protected function getCommandName()
154
    {
155 11
        return $this->commandName;
156
    }
157
158
    /**
159
     * Set Configs
160
     *
161
     * @param array|Map $configs the config variable. i.e. { "color.status" => "false", "color.diff" => "true" }
162
     */
163 3
    public function addConfigs($configs)
164
    {
165 3
        foreach ($configs as $config => $value) {
166 3
            $this->configs[$config] = $value;
167 3
        }
168 3
    }
169
170
    /**
171
     * Set global configs
172
     *
173
     * @param array|Map $configs the config variable. i.e. { "color.status" => "false", "color.diff" => "true" }
174
     */
175 92
    protected function addGlobalConfigs($configs)
176
    {
177 92
        if (!empty($configs)) {
178 1
            foreach ($configs as $config => $value) {
179 1
                $this->globalConfigs[$config] = $value;
180 1
            }
181 1
        }
182 92
    }
183
184
    /**
185
     * Set global option
186
     *
187
     * @param array|Map $options a global option
188
     */
189 92
    protected function addGlobalOptions($options)
190
    {
191 92
        if (!empty($options)) {
192 1
            foreach ($options as $name => $value) {
193 1
                $this->globalOptions[$name] = $value;
194 1
            }
195 1
        }
196 92
    }
197
198
    /**
199
     * Get Configs
200
     *
201
     * @return array
202
     */
203
    public function getConfigs()
204
    {
205
        return $this->configs;
206
    }
207
208
    /**
209
     * Add a command argument
210
     *
211
     * @param string $commandArgument the command argument
212
     */
213 98
    protected function addCommandArgument($commandArgument)
214
    {
215 98
        $this->commandArguments[] = $commandArgument;
216 98
    }
217
218
    /**
219
     * Add a global command argument
220
     *
221
     * @param string $commandArgument the command argument
222
     */
223 1
    protected function addGlobalCommandArgument($commandArgument)
224
    {
225 1
        if (!empty($commandArgument)) {
226 1
            $this->globalCommandArguments[] = $commandArgument;
227 1
        }
228 1
    }
229
230
    /**
231
     * Get all added command arguments
232
     *
233
     * @return array
234
     */
235 11
    protected function getCommandArguments()
236
    {
237 11
        return ($this->commandArguments) ? $this->commandArguments: array();
238
    }
239
240
    /**
241
     * Add a command subject
242
     *
243
     * @param string $commandSubject the command subject
244
     */
245 93
    protected function addCommandSubject($commandSubject)
246
    {
247 93
        $this->commandSubject = $commandSubject;
248 93
    }
249
250
    /**
251
     * Add a second command subject
252
     *
253
     * @param string $commandSubject2 the second command subject
254
     */
255 18
    protected function addCommandSubject2($commandSubject2)
256
    {
257 18
        $this->commandSubject2 = $commandSubject2;
258 18
    }
259
260
    /**
261
     * Add a path to the git command
262
     *
263
     * @param string $path path
264
     */
265 19
    protected function addPath($path)
266
    {
267 19
        $this->path = $path;
268 19
    }
269
270
    /**
271
     * Normalize any valid option to its long name
272
     * an provide a structure that can be more intelligently
273
     * handled by other routines
274
     *
275
     * @param array $options       command options
276
     * @param array $switchOptions list of valid options that are switch like
277
     * @param array $valueOptions  list of valid options that must have a value assignment
278
     *
279
     * @return array Associative array of valid, normalized command options
280
     */
281 15
    public function normalizeOptions(Array $options = array(), Array $switchOptions = array(), $valueOptions = array())
282
    {
283 15
        $normalizedOptions = array();
284
285 15
        foreach ($options as $option) {
286 7
            if (array_key_exists($option, $switchOptions)) {
287 7
                $normalizedOptions[$switchOptions[$option]] = $switchOptions[$option];
288 7
            } else {
289 1
                $parts = preg_split('/([\s=])+/', $option, 2, PREG_SPLIT_DELIM_CAPTURE);
290 1
                if (count($parts)) {
291 1
                    $optionName = $parts[0];
292 1
                    if (in_array($optionName, $valueOptions)) {
293 1
                        $value = ($parts[1] == '=') ? $option : array($parts[0], $parts[2]);
294 1
                        $normalizedOptions[$optionName] = $value;
295 1
                    }
296 1
                }
297
            }
298 15
        }
299
300 15
        return $normalizedOptions;
301
    }
302
303
    /**
304
     * Get the current command
305
     *
306
     * @return string
307
     * @throws \RuntimeException
308
     */
309 103
    public function getCommand()
310
    {
311 103
        if (is_null($this->commandName)) {
312 1
            throw new \RuntimeException("You should pass a commandName to execute a command");
313
        }
314
315 102
        $command  = '';
316 102
        $command .= $this->getCLIConfigs();
317 102
        $command .= $this->getCLIGlobalOptions();
318 102
        $command .= $this->getCLICommandName();
319 102
        $command .= $this->getCLICommandArguments();
320 102
        $command .= $this->getCLISubjects();
321 102
        $command .= $this->getCLIPath();
322
323 102
        $command = preg_replace('/\\s{2,}/', ' ', $command);
324
325 102
        return trim($command);
326
    }
327
328
    /**
329
     * get a string of CLI-formatted command arguments
330
     *
331
     * @return string The command argument string
332
     */
333 103
    private function getCLICommandArguments()
334
    {
335 103
        $command = '';
336 103
        $combinedArguments = array_merge($this->globalCommandArguments, $this->commandArguments);
337 103
        if (count($combinedArguments) > 0) {
338 98
            $command .= ' ' . implode(' ', array_map('escapeshellarg', $combinedArguments));
339 98
        }
340 103
        return $command;
341
    }
342
343
    /**
344
     * get a string of CLI-formatted command name
345
     *
346
     * @return string The command name string
347
     */
348 103
    private function getCLICommandName()
349
    {
350 103
        return ' ' . $this->commandName;
351
    }
352
353
    /**
354
     * get a string of CLI-formatted configs
355
     *
356
     * @return string The config string
357
     */
358 103
    private function getCLIConfigs()
359
    {
360 103
        $command = '';
361 103
        $combinedConfigs = array_merge($this->globalConfigs, $this->configs);
362 103
        if (count($combinedConfigs)) {
363 4
            foreach ($combinedConfigs as $config => $value) {
364 4
                $command .= sprintf(
365 4
                    ' %s %s=%s',
366 4
                    escapeshellarg('-c'),
367 4
                    escapeshellarg($config),
368 4
                    escapeshellarg($value)
369 4
                );
370 4
            }
371 4
        }
372 103
        return $command;
373
    }
374
375
    /**
376
     * get a string of CLI-formatted global options
377
     *
378
     * @return string The global options string
379
     */
380 103
    private function getCLIGlobalOptions()
381
    {
382 103
        $command = '';
383 103
        if (count($this->globalOptions) > 0) {
384 1
            foreach ($this->globalOptions as $name => $value) {
385 1
                $command .= sprintf(' %s=%s', escapeshellarg($name), escapeshellarg($value));
386 1
            }
387 1
        }
388 103
        return $command;
389
    }
390
391
    /**
392
     * get a string of CLI-formatted path
393
     *
394
     * @return string The path string
395
     */
396 103
    private function getCLIPath()
397
    {
398 103
        $command = '';
399 103
        if (!is_null($this->path)) {
400 17
            $command .= sprintf(' -- %s', escapeshellarg($this->path));
401 17
        }
402 103
        return $command;
403
    }
404
405
    /**
406
     * get a string of CLI-formatted subjects
407
     *
408
     * @throws \RuntimeException
409
     * @return string The subjects string
410
     */
411 103
    private function getCLISubjects()
412
    {
413 103
        $command = '';
414 103
        if (!is_null($this->commandSubject)) {
415 94
            $command .= ' ';
416 94
            if ($this->commandSubject instanceof SubCommandCommand) {
417 10
                $command .= $this->commandSubject->getCommand();
418 10
            } else {
419 93
                if (is_array($this->commandSubject)) {
420
                    $command .= implode(' ', array_map('escapeshellarg', $this->commandSubject));
421
                } else {
422 93
                    $command .= escapeshellarg($this->commandSubject);
423
                }
424
            }
425 94
        }
426 103
        if (!is_null($this->commandSubject2)) {
427 19
            $command .= ' ';
428 19
            if ($this->commandSubject2 instanceof SubCommandCommand) {
429
                $command .= $this->commandSubject2->getCommand();
430
            } else {
431 19
                if (is_array($this->commandSubject2)) {
432
                    $command .= implode(' ', array_map('escapeshellarg', $this->commandSubject2));
433
                } else {
434 19
                    $command .= escapeshellarg($this->commandSubject2);
435
                }
436
            }
437 19
        }
438 103
        return $command;
439
    }
440
}
441