Completed
Pull Request — master (#39)
by Simon
01:37
created

Application::getPaddingSize()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 5
nc 3
nop 1
1
<?php declare(strict_types=1);
2
3
4
namespace Shopware\Psh\Application;
5
6
use Khill\Duration\Duration;
7
use League\CLImate\CLImate;
8
use Shopware\Psh\Config\Config;
9
use Shopware\Psh\Listing\Script;
10
use Shopware\Psh\Listing\ScriptNotFoundException;
11
use Shopware\Psh\Listing\ScriptPathNotValidException;
12
use Shopware\Psh\ScriptRuntime\ExecutionErrorException;
13
use Shopware\Psh\ScriptRuntime\TemplateNotValidException;
14
15
/**
16
 * Main application entry point. moves the requested data around and outputs user information.
17
 */
18
class Application
19
{
20
    const RESULT_SUCCESS = 0;
21
22
    const RESULT_ERROR = 1;
23
24
    /**
25
     * @var CLImate
26
     */
27
    public $cliMate;
28
29
    /**
30
     * @var string
31
     */
32
    private $rootDirectory;
33
34
    /**
35
     * @var ApplicationFactory
36
     */
37
    private $applicationFactory;
38
39
    /**
40
     * @var Duration
41
     */
42
    private $duration;
43
44
    /**
45
     * @param string $rootDirectory
46
     */
47
    public function __construct(string $rootDirectory)
48
    {
49
        $this->rootDirectory = $rootDirectory;
50
        $this->applicationFactory = new ApplicationFactory();
51
        $this->cliMate = new CLImate();
52
        $this->duration = new Duration();
53
    }
54
55
    /**
56
     * Main entry point to execute the application.
57
     *
58
     * @param array $inputArgs
59
     * @return int exit code
60
     */
61
    public function run(array $inputArgs): int
62
    {
63
        $config = $this->applicationFactory
64
            ->createConfig($this->rootDirectory);
65
66
        $scriptFinder = $this->applicationFactory
67
            ->createScriptFinder($config);
68
69
        $this->printHeader($config);
70
        $scriptNames = $this->extractScriptNames($inputArgs);
71
72
        try {
73
            foreach ($scriptNames as $scriptName) {
74
                $executionExitCode = $this->execute($scriptFinder->findScriptByName($scriptName), $config);
75
76
                if ($executionExitCode !== self::RESULT_SUCCESS) {
77
                    return $executionExitCode;
78
                }
79
            }
80
81
            if (isset($executionExitCode)) {
82
                return $executionExitCode;
83
            }
84
        } catch (ScriptNotFoundException $e) {
85
            $this->notifyError("Script with name {$inputArgs[1]} not found\n");
86
            return self::RESULT_ERROR;
87
        }
88
89
        try {
90
            $this->showListing($scriptFinder->getAllScripts());
91
        } catch (ScriptPathNotValidException $e) {
92
            $this->notifyError($e->getMessage() . "\n");
93
            return self::RESULT_ERROR;
94
        }
95
96
        return self::RESULT_SUCCESS;
97
    }
98
99
    /**
100
     * @param Script[] $scripts
101
     */
102
    public function showListing(array $scripts)
103
    {
104
        $this->cliMate->green()->bold("Available commands:\n");
105
106
        if (!count($scripts)) {
107
            $this->cliMate->yellow()->bold('-> Currently no scripts available');
108
        }
109
110
        $longestName = $this->getPaddingSize($scripts);
111
112
        $padding = $this->cliMate->padding($longestName)->char(' ');
113
        foreach ($scripts as $script) {
114
            $padding->label('<bold> - ' . $script->getName() . '</bold>')->result('<dim>' . $script->getDescription() . '</dim>');
115
        }
116
117
        $this->cliMate->green()->bold("\n" . count($scripts) . " script(s) available\n");
118
    }
119
120
    /**
121
     * @param array $inputArgs
122
     * @return array
123
     */
124
    protected function extractScriptNames(array $inputArgs): array
125
    {
126
        if (!isset($inputArgs[1])) {
127
            return [];
128
        }
129
130
        return explode(',', $inputArgs[1]);
131
    }
132
133
    /**
134
     * @param Script $script
135
     * @param Config $config
136
     * @return int
137
     */
138
    protected function execute(Script $script, Config $config): int
139
    {
140
        $commands = $this->applicationFactory
141
            ->createCommands($script);
142
143
        $logger = new ClimateLogger($this->cliMate, $this->duration);
144
        $executor = $this->applicationFactory
145
            ->createProcessExecutor($script, $config, $logger, $this->rootDirectory);
146
147
        try {
148
            $executor->execute($script, $commands);
149
        } catch (ExecutionErrorException $e) {
150
            $this->notifyError("\nExecution aborted, a subcommand failed!\n");
151
            return self::RESULT_ERROR;
152
        } catch (TemplateNotValidException $e) {
153
            $this->notifyError("\n" . $e->getMessage() . "\n");
154
            return self::RESULT_ERROR;
155
        }
156
157
        $this->notifySuccess("All commands successfully executed!\n");
158
159
        return self::RESULT_SUCCESS;
160
    }
161
162
    /**
163
     * @param $string
164
     */
165
    public function notifySuccess($string)
166
    {
167
        $this->cliMate->bold()->green($string);
168
    }
169
170
    /**
171
     * @param $string
172
     */
173
    public function notifyError($string)
174
    {
175
        $this->cliMate->bold()->red($string);
176
    }
177
178
    /**
179
     * @param $config
180
     */
181
    protected function printHeader(Config $config)
182
    {
183
        $this->cliMate->green()->bold()->out("\n###################");
184
185
        if ($config->getHeader()) {
186
            $this->cliMate->out("\n" . $config->getHeader());
187
        }
188
    }
189
190
    /**
191
     * @param Script[] $scripts
192
     * @return Int
193
     */
194
    private function getPaddingSize(array $scripts): Int
195
    {
196
        $paddingSize = 0;
197
        foreach ($scripts as $script) {
198
            $paddingSize = strlen($script->getName()) > $paddingSize ? strlen($script->getName()): $paddingSize;
199
        }
200
        return $paddingSize + 8;
201
    }
202
}
203