Passed
Push — master ( 800a06...e6cd3c )
by Timm
01:52
created

AppParser::parse()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 41
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 21
nc 5
nop 2
dl 0
loc 41
rs 9.2728
c 0
b 0
f 0
1
<?php
2
3
4
namespace Stefaminator\Cli;
5
6
7
use Exception;
8
use GetOptionKit\ContinuousOptionParser;
9
use GetOptionKit\OptionResult;
10
11
class AppParser {
12
13
    public static function run(App $app): void {
14
        global $argv;
15
16
        try {
17
            $cmd = self::parse($app, $argv);
18
19
            if ($cmd !== null) {
20
21
                if ($cmd->handleOptionParseException()) {
22
                    return;
23
                }
24
25
                if (self::callCallable($cmd)) {
26
                    return;
27
                }
28
29
                if (self::callMethod($app, $cmd)) {
30
                    return;
31
                }
32
33
            }
34
        } catch (Exception $e) {
35
36
            App::eol();
37
            App::echo('Uups, someting went wrong!', Color::FOREGROUND_COLOR_RED);
38
            App::eol();
39
            App::echo($e->getMessage(), Color::FOREGROUND_COLOR_RED);
40
            App::eol();
41
        }
42
43
    }
44
45
    /**
46
     * @param Cmd $cmd
47
     * @return bool
48
     * @throws Exception
49
     */
50
    private static function callCallable(Cmd $cmd): bool {
51
52
        $callable = $cmd->getCallable();
53
54
        if ($callable !== null) {
55
            $callable($cmd);
56
            return true;
57
        }
58
59
        return false;
60
    }
61
62
    /**
63
     * @param App $app
64
     * @param Cmd $cmd
65
     * @return bool
66
     * @throws Exception
67
     */
68
    private static function callMethod(App $app, Cmd $cmd): bool {
69
70
        $methodName = $cmd->getMethodName();
71
72
        if (method_exists($app, $methodName)) {
73
            $app->$methodName($cmd);
74
            return true;
75
        }
76
77
        return false;
78
    }
79
80
    /**
81
     * @param App $app
82
     * @param array $argv
83
     * @return Cmd
84
     */
85
    public static function parse(App $app, array $argv): Cmd {
86
87
        $cmd = $app->setup();
88
89
        $appspecs = $cmd->getOptionCollection();
90
91
        $parser = new ContinuousOptionParser($appspecs);
92
93
        try {
94
            $cmd->optionResult = $parser->parse($argv);
95
96
        } catch (Exception $e) {
97
98
            $cmd->optionParseException = $e;
99
100
            return $cmd;
101
        }
102
103
        while (!$parser->isEnd()) {
104
105
            $currentArgument = $parser->getCurrentArgument();
106
107
            $subcommand = self::getSubcommand($currentArgument, $cmd);
108
109
            if ($subcommand !== null) {
110
111
                $cmd = $subcommand;
112
113
                try {
114
                    self::parseSubcommand($parser, $cmd);
115
                } catch (Exception $e) {
116
                    $cmd->optionParseException = $e;
117
                    return $cmd;
118
                }
119
120
            } else {
121
                $cmd->arguments[] = $parser->advance();
122
            }
123
        }
124
125
        return $cmd;
126
    }
127
128
    /**
129
     * @param string $argument
130
     * @param Cmd $cmd
131
     * @return Cmd|null
132
     */
133
    private static function getSubcommand(string $argument, Cmd $cmd): ?Cmd {
134
135
        $subcommand = null;
136
        if ($cmd->hasSubCmd($argument)) {
137
            $subcommand = $cmd->getSubCmd($argument);
138
        }
139
140
        return $subcommand;
141
    }
142
143
    /**
144
     * @param ContinuousOptionParser $parser
145
     * @param Cmd $cmd
146
     * @throws Exception
147
     */
148
    private static function parseSubcommand(ContinuousOptionParser $parser, Cmd $cmd): void {
149
150
        $parser->advance();
151
152
        $cmd->optionResult = new OptionResult();
153
154
        if (!empty($cmd->optionSpecs)) {
155
156
            $specs = $cmd->getOptionCollection();
157
158
            $parser->setSpecs($specs);
159
160
            $cmd->optionResult = $parser->continueParse();
161
        }
162
    }
163
164
165
}