Completed
Push — dev ( 304c3a...c8d9f4 )
by James Ekow Abaka
05:39
created

ArgumentParser::addOption()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 6
cts 6
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 1
crap 2
1
<?php
2
3
namespace clearice\argparser;
4
5
6
class ArgumentParser
7
{
8
    private $description;
9
    private $footer;
10
    private $options = [];
11
12
    public function setDescription($description)
13
    {
14
        $this->description = $description;
15
    }
16
17
    public function setFooter($footer)
18
    {
19
        $this->footer = $footer;
20
    }
21
22
    /**
23
     * @param $key
24
     * @param $value
25
     * @throws OptionExistsException
26
     */
27 3
    private function addToOptionArray($key, $value)
28
    {
29 3
        if(isset($value[$key]) && !isset($this->options[$value[$key]])) {
30 3
            $this->options[$value[$key]] = $value;
31 2
        } else if(isset($value[$key])) {
32 2
            throw new OptionExistsException("An argument option with $key {$value[$key]} already exists.");
33
        }
34 3
    }
35
36
    /**
37
     * Add an option to be parsed.
38
     * Arguments are presented as a structured array with the following possible keys.
39
     *
40
     *  name: The name of the option prefixed with a double dash --
41
     *  short_name: A shorter single character option prefixed with a single dash -
42
     *  type: Required for all options that take values. An option specified without a type is considered to be a
43
     *        boolean flag.
44
     *  help: A help message for the option
45
     *
46
     * @param $option
47
     * @throws OptionExistsException
48
     * @throws InvalidArgumentDescriptionException
49
     */
50 4
    public function addOption($option)
51
    {
52 4
        if(!isset($option['name'])) {
53 1
            throw new InvalidArgumentDescriptionException("Argument must have a name");
54
        }
55 3
        $this->addToOptionArray('name', $option);
56 3
        $this->addToOptionArray('short_name', $option);
57 3
    }
58
59
    /**
60
     * Parse a long argument that is prefixed with a double dash "--"
61
     *
62
     * @param $arguments
63
     * @param $argPointer
64
     * @return array
65
     * @throws InvalidValueException
66
     */
67 1
    private function parseLongArgument($arguments, &$argPointer)
68
    {
69 1
        $string = substr($arguments[$argPointer], 2);
70 1
        preg_match("/(?<name>[a-zA-Z_0-9-]+)(?<equal>=?)(?<value>.*)/", $string, $matches);
71 1
        $name = $matches['name'];
72 1
        $option = $this->options[$name];
73
74 1
        if(isset($option['type'])) {
75 1
            if($matches['equal'] === '=') {
76 1
                $value = $matches['value'];
77 1
            } else if (isset($arguments[$argPointer + 1]) && $arguments[$argPointer + 1][0] != '-') {
78 1
                $value = $arguments[$argPointer + 1];
79 1
                $argPointer++;
80
            } else {
81 1
                throw new InvalidValueException("A value must be passed along with argument $name.");
82
            }
83
        } else {
84 1
            $value = true;
85
        }
86
87 1
        return [$name => $value];
88
    }
89
90
    /**
91
     * Parses command line arguments and return a structured array of options and their associated values.
92
     *
93
     * @param array $arguments An optional array of arguments that would be parsed instead of those passed to the CLI.
94
     * @return array
95
     * @throws InvalidValueException
96
     */
97 1
    public function parse($arguments = null)
98
    {
99 1
        global $argv;
100 1
        $arguments = $arguments ?? $argv;
101 1
        $numArguments = count($arguments);
102 1
        $output = [];
103
104 1
        for($argPointer = 1; $argPointer < $numArguments; $argPointer++) {
105 1
            $arg = $arguments[$argPointer];
106 1
            if(substr($arg, 0, 2) == "--") {
107 1
                $output = array_merge($output, $this->parseLongArgument($arguments, $argPointer));
108 1
            } else if ($arg[0] == '-') {
109
                $output = array_merge($output, $this->parseShortArgument($arguments, $argPointer));
0 ignored issues
show
Bug introduced by
The method parseShortArgument() does not seem to exist on object<clearice\argparser\ArgumentParser>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
110
            } else {
111 1
                $output['__args'] = isset($output['__args']) ? array_merge($output['__args'], [$arg]) : [$arg];
112
            }
113
        }
114
115 1
        return $output;
116
    }
117
118
    public function getHelp()
119
    {
120
121
    }
122
}
123