AbstractCommand::doesPropertyExist()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
1
<?php
2
/**
3
 * VersionControl_HG
4
 * Simple OO implementation for Mercurial.
5
 *
6
 * PHP Version 5.4
7
 *
8
 * @copyright 2014 Siad Ardroumli
9
 * @license http://www.opensource.org/licenses/mit-license.php MIT
10
 * @link http://siad007.github.io/versioncontrol_hg
11
 */
12
13
namespace Siad007\VersionControl\HG\Command;
14
15
/**
16
 * Abstract class for VersionControl_HG.
17
 *
18
 * This class maintains all global options and take care about getters and
19
 * setters.
20
 *
21
 * @method boolean getVerbose()
22
 * @method void setVerbose(boolean $flag)
23
 * @method boolean getQuiet()
24
 * @method void setQuiet(boolean $flag)
25
 * @method boolean getNoninteractive()
26
 * @method void setNoninteractive(boolean $flag)
27
 * @method boolean getCwd()
28
 * @method void setCwd(string $directory)
29
 * @method boolean getDebug()
30
 * @method void setDebug(boolean $flag)
31
 * @method boolean getDebugger()
32
 * @method void setDebugger(boolean $flag)
33
 * @method string getEncoding()
34
 * @method void setEncoding(string $encoding)
35
 * @method string getEncodingmode()
36
 * @method void setEncodingmode(string $mode)
37
 * @method boolean getTraceback()
38
 * @method void setTraceback(boolean $flag)
39
 * @method boolean getTime()
40
 * @method void setTime(boolean $flag)
41
 * @method boolean getProfile()
42
 * @method void setProfile(boolean $flag)
43
 * @method boolean getVersion()
44
 * @method void setVersion(boolean $flag)
45
 * @method boolean getHelp()
46
 * @method void setHelp(boolean $flag)
47
 * @method boolean getHidden()
48
 * @method void setHidden(boolean $flag)
49
 * @method array getConfig()
50
 * @method void addConfig(string $config)
51
 */
52
abstract class AbstractCommand
53
{
54
    /** @var string $name */
55
    protected $name = '';
56
57
    /** @var string $hgPath */
58
    protected $hgPath = 'hg';
59
60
    /** @var string $command */
61
    protected $command = '%s %s';
62
63
    /**
64
     * Command specific options.
65
     *
66
     * @var array $options
67
     */
68
    protected $options = [];
69
70
    /** @var array $globalOptions */
71
    protected $globalOptions = [
72
        '--repository'     => '',
73
        '--cwd'            => '',
74
        '--noninteractive' => false,
75
        '--quiet'          => false,
76
        '--verbose'        => false,
77
        '--config'         => [],
78
        '--debug'          => false,
79
        '--debugger'       => false,
80
        '--encoding'       => '',
81
        '--encodingmode'   => '',
82
        '--traceback'      => false,
83
        '--time'           => false,
84
        '--profile'        => false,
85
        '--version'        => false,
86
        '--help'           => false,
87
        '--hidden'         => false,
88
    ];
89
90
    /**
91
     * Get hg path.
92
     *
93
     * @return string
94
     */
95 1
    public function getHgPath()
96
    {
97 1
        return $this->hgPath;
98
    }
99
100
    /**
101
     * Set path to hg executable.
102
     *
103
     * @param string $path
104
     *
105
     * @return $this
106
     */
107 1
    public function setHgPath($path)
108
    {
109 1
        $this->hgPath = $path;
110
111 1
        return $this;
112
    }
113
114
    /**
115
     * Returns a string representation for the mercurial shell command.
116
     *
117
     * @return string
118
     */
119 44
    public function __toString()
120
    {
121 44
        return sprintf($this->command, $this->hgPath, $this);
122
    }
123
124
    /**
125
     * Standard constructor.
126
     *
127
     * - sets the concrete commands name
128
     * - merges the global options with the concrete commands options
129
     *
130
     * @param mixed $options
131
     */
132 51
    public function __construct($options = [])
133
    {
134 51
        $this->name = $this->getCommandName();
135
136 51
        $this->options = array_merge($this->options, $options);
137 51
    }
138
139
    /**
140
     * Execute mercurial command.
141
     *
142
     * @return string
143
     *
144
     * @throws \RuntimeException
145
     */
146 2
    public function execute()
147
    {
148 2
        $output = [];
149 2
        $code = 0;
150
151 2
        exec(sprintf($this->command, $this->hgPath, $this) . " 2>&1", $output, $code);
152
153 2
        if ($code != 0) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $code of type integer|null to 0; this is ambiguous as not only 0 == 0 is true, but null == 0 is true, too. Consider using a strict comparison ===.
Loading history...
154 1
            throw new \RuntimeException(
155
                'An error occurred while using VersionControl_HG; hg returned: '
156 1
                . implode(PHP_EOL, $output),
157
                $code
158
            );
159
        }
160
161 1
        return implode(PHP_EOL, $output);
162
    }
163
164
    /**
165
     * Returns the string representation of the command.
166
     *
167
     * @return string
168
     */
169 44
    public function asString()
170
    {
171 44
        return self::__toString();
172
    }
173
174
    /**
175
     * Magic method to get option entries with a getter/setter method.
176
     *
177
     * @param string $name
178
     * @param array  $arguments
179
     *
180
     * @return boolean|array|string|self
181
     *
182
     * @throws \InvalidArgumentException
183
     */
184 43
    public function __call($name, $arguments)
185
    {
186 43
        if (preg_match('~^(set|get|add)([A-Z])([a-z]*)([A-Z]?)(.*)$~', $name, $matches)) {
187 42
            $match = !empty($matches[4]) ? sprintf('-%s%s', strtolower($matches[4]), $matches[5]) : '';
188 42
            $property = strtolower($matches[2]) . $matches[3] . $match;
189
190 42
            $this->options = array_merge($this->globalOptions, $this->options);
191
192 42
            $this->doesPropertyExist($property);
193
194 41
            $result = false;
195
196 41
            switch ($matches[1]) {
197 41
                case 'set':
198 39
                    $this->options["--{$property}"] = $arguments[0];
199 39
                    $result = $this;
200 39
                    break;
201 17
                case 'add':
202 16
                    $this->options["--{$property}"][] = $arguments[0];
203 16
                    $result = $this;
204 16
                    break;
205 1
                case 'get':
206 1
                    $result = $this->options["--{$property}"];
207 1
                    break;
208
            }
209
210 41
            return $result;
211
        }
212
213 1
        throw new \InvalidArgumentException('Method ' . $name . ' not exists');
214
    }
215
216
    /**
217
     * Does property exist check.
218
     *
219
     * @param string $property
220
     *
221
     * @throws \InvalidArgumentException
222
     */
223 42
    private function doesPropertyExist($property)
224
    {
225 42
        if (! isset($this->options["--{$property}"])) {
226 1
            throw new \InvalidArgumentException('Property ' . $property . ' not exists');
227
        }
228 41
    }
229
230
    /**
231
     * Concatinates string options.
232
     *
233
     * @return string
234
     */
235 41
    protected function assembleOptionString()
236
    {
237 41
        $optionString = '';
238
239 41
        foreach ($this->options as $name => $option) {
240 40
            if ($option === true) {
241 37
                $optionString .= " {$name}";
242 40
            } elseif (is_string($option) && $option !== '') {
243 20
                $optionString .= " {$name} " . escapeshellarg($option);
244 40
            } elseif (is_array($option) && !empty($option)) {
245 40
                $optionString .= " {$name} " . implode(' ', $option);
246
            }
247
        }
248
249 41
        return $optionString !== '' ? $optionString . '' : ' ';
250
    }
251
252
    /**
253
     * Returns the concrete commands name.
254
     *
255
     * @return string
256
     */
257 51
    private function getCommandName()
258
    {
259 51
        $className   = implode('', array_slice(explode('\\', get_class($this)), -1));
260 51
        $commandName = str_replace('command', '', strtolower($className));
261
262 51
        return $commandName;
263
    }
264
}
265