Passed
Push — develop ( e6f84d...350782 )
by Mikaël
09:01 queued 28s
created

GeneratePackageCommand::initGeneratorOptions()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 0
dl 0
loc 14
ccs 8
cts 8
cp 1
crap 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace WsdlToPhp\PackageGenerator\Command;
6
7
use DateTime;
8
use Symfony\Component\Console\Input\InputInterface;
9
use Symfony\Component\Console\Input\InputOption;
10
use Symfony\Component\Console\Output\OutputInterface;
11
use WsdlToPhp\PackageBase\AbstractSoapClientBase;
12
use WsdlToPhp\PackageBase\AbstractStructArrayBase;
13
use WsdlToPhp\PackageBase\AbstractStructBase;
14
use WsdlToPhp\PackageBase\AbstractStructEnumBase;
15
use WsdlToPhp\PackageGenerator\ConfigurationReader\GeneratorOptions;
16
use WsdlToPhp\PackageGenerator\Generator\Generator;
17
18
final class GeneratePackageCommand extends AbstractCommand
19
{
20
    public const GENERATOR_OPTIONS_CONFIG_OPTION = 'config';
21
    public const PROPER_USER_CONFIGURATION = 'wsdltophp.yml';
22
    public const DEFAULT_CONFIGURATION_FILE = 'wsdltophp.yml.dist';
23
24
    protected Generator $generator;
25
26
    protected GeneratorOptions $generatorOptions;
27
28 5
    public function getGenerator(): Generator
29
    {
30 5
        return $this->generator;
31
    }
32
33 19
    public function getGeneratorOptionsConfigOption()
34
    {
35 19
        return $this->getOptionValue(self::GENERATOR_OPTIONS_CONFIG_OPTION);
36
    }
37
38 19
    public function resolveGeneratorOptionsConfigPath(): ?string
39
    {
40 19
        $path = null;
41 19
        $possibilities = $this->getGeneratorOptionsPossibilities();
42 19
        foreach ($possibilities as $possibility) {
43 19
            if (!empty($possibility) && is_file($possibility)) {
44 19
                $path = $possibility;
45
46 19
                break;
47
            }
48
        }
49
50 19
        return $path;
51
    }
52
53 19
    public function getGeneratorOptionsPossibilities(): array
54
    {
55
        return [
56 19
            $this->getGeneratorOptionsConfigOption(),
57 19
            sprintf('%s/%s', getcwd(), self::PROPER_USER_CONFIGURATION),
58 19
            sprintf('%s/%s', getcwd(), self::DEFAULT_CONFIGURATION_FILE),
59 19
            GeneratorOptions::getDefaultConfigurationPath(),
60
        ];
61
    }
62
63 5
    protected function setGenerator(Generator $generator): self
64
    {
65 5
        $this->generator = $generator;
66
67 5
        return $this;
68
    }
69
70 7
    protected function initGenerator(): self
71
    {
72 7
        return $this->setGenerator(new Generator($this->generatorOptions));
73
    }
74
75 19
    protected function configure(): void
76
    {
77 19
        parent::configure();
78
        $this
79 19
            ->setName('generate:package')
80 19
            ->setDescription('Generate package based on options')
81 19
            ->addOption(
82
                'urlorpath',
83
                null,
84
                InputOption::VALUE_REQUIRED,
85
                'Url or path to WSDL'
86
            )
87 19
            ->addOption(
88
                'destination',
89
                null,
90
                InputOption::VALUE_REQUIRED,
91
                'Path to destination directory, where the package will be generated'
92
            )
93 19
            ->addOption(
94
                'login',
95
                null,
96
                InputOption::VALUE_OPTIONAL,
97
                'Basic authentication login required to access the WSDL url, can be avoided mot of the time'
98
            )
99 19
            ->addOption(
100
                'password',
101
                null,
102
                InputOption::VALUE_OPTIONAL,
103
                'Basic authentication password required to access the WSDL url, can be avoided mot of the time'
104
            )
105 19
            ->addOption(
106
                'proxy-host',
107
                null,
108
                InputOption::VALUE_OPTIONAL,
109
                'Use proxy url'
110
            )
111 19
            ->addOption(
112
                'proxy-port',
113
                null,
114
                InputOption::VALUE_OPTIONAL,
115
                'Use proxy port'
116
            )
117 19
            ->addOption(
118
                'proxy-login',
119
                null,
120
                InputOption::VALUE_OPTIONAL,
121
                'Use proxy login'
122
            )
123 19
            ->addOption(
124
                'proxy-password',
125
                null,
126
                InputOption::VALUE_OPTIONAL,
127
                'Use proxy password'
128
            )
129 19
            ->addOption(
130
                'prefix',
131
                null,
132
                InputOption::VALUE_REQUIRED,
133
                'Prepend generated classes'
134
            )
135 19
            ->addOption(
136
                'suffix',
137
                null,
138
                InputOption::VALUE_REQUIRED,
139
                'Append generated classes'
140
            )
141 19
            ->addOption(
142
                'namespace',
143
                null,
144
                InputOption::VALUE_OPTIONAL,
145
                'Package classes\' namespace'
146
            )
147 19
            ->addOption(
148
                'namespace-directories',
149
                null,
150
                InputOption::VALUE_OPTIONAL,
151
                'Should the directories match the namespace path or not? True by default'
152
            )
153 19
            ->addOption(
154
                'category',
155
                null,
156
                InputOption::VALUE_OPTIONAL,
157
                'First level directory name generation mode (start, end, cat, none)'
158
            )
159 19
            ->addOption(
160
                'gathermethods',
161
                null,
162
                InputOption::VALUE_OPTIONAL,
163
                'Gather methods based on operation name mode (start, end)'
164
            )
165 19
            ->addOption(
166
                'gentutorial',
167
                null,
168
                InputOption::VALUE_OPTIONAL,
169
                'Enable/Disable tutorial file, you should enable this option only on dev'
170
            )
171 19
            ->addOption(
172
                'genericconstants',
173
                null,
174
                InputOption::VALUE_OPTIONAL,
175
                'Enable/Disable usage of generic constants name (ex : ENUM_VALUE_0, ENUM_VALUE_1, etc) or contextual values (ex : VALUE_STRING, VALUE_YES, VALUES_NO, etc)'
176
            )
177 19
            ->addOption(
178
                'addcomments',
179
                null,
180 19
                InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
181
                'Set comments to be used within each generated file'
182
            )
183 19
            ->addOption(
184
                'standalone',
185
                null,
186
                InputOption::VALUE_OPTIONAL,
187
                'By default, the generated package can be used as a standalone. Otherwise, you must add wsdltophp/packagebase:dev-master to your main composer.json.'
188
            )
189 19
            ->addOption(
190
                'validation',
191
                null,
192
                InputOption::VALUE_OPTIONAL,
193
                'Enable/Disable the generation of validation rules in every generated setter.'
194
            )
195 19
            ->addOption(
196
                'struct',
197
                null,
198
                InputOption::VALUE_OPTIONAL,
199 19
                sprintf('Use this class as parent class for any StructType class. Default class is %s from wsdltophp/packagebase package', AbstractStructBase::class)
200
            )
201 19
            ->addOption(
202
                'structarray',
203
                null,
204
                InputOption::VALUE_OPTIONAL,
205 19
                sprintf('Use this class as parent class for any StructArrayType class. Default class is %s from wsdltophp/packagebase package', AbstractStructArrayBase::class)
206
            )
207 19
            ->addOption(
208
                'structenum',
209
                null,
210
                InputOption::VALUE_OPTIONAL,
211 19
                sprintf('Use this class as parent class for any StructEnumType class. Default class is %s from wsdltophp/packagebase package', AbstractStructEnumBase::class)
212
            )
213 19
            ->addOption(
214
                'soapclient',
215
                null,
216
                InputOption::VALUE_OPTIONAL,
217 19
                sprintf('Use this class as parent class for any ServiceType class. Default class is %s from wsdltophp/packagebase package', AbstractSoapClientBase::class)
218
            )
219 19
            ->addOption(
220
                'composer-name',
221
                null,
222
                InputOption::VALUE_REQUIRED,
223
                'Composer name of the generated package'
224
            )
225 19
            ->addOption(
226
                'composer-settings',
227
                null,
228 19
                InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
229
                'Composer settings of the generated package'
230
            )
231 19
            ->addOption(
232
                'structs-folder',
233
                null,
234
                InputOption::VALUE_OPTIONAL,
235
                'Structs folder name (default: SructType)'
236
            )
237 19
            ->addOption(
238
                'arrays-folder',
239
                null,
240
                InputOption::VALUE_OPTIONAL,
241
                'Arrays folder name (default: ArrayType)'
242
            )
243 19
            ->addOption(
244
                'enums-folder',
245
                null,
246
                InputOption::VALUE_OPTIONAL,
247
                'Enumerations folder name (default: EnumType)'
248
            )
249 19
            ->addOption(
250
                'services-folder',
251
                null,
252
                InputOption::VALUE_OPTIONAL,
253
                'Services class folder name (default: ServiceType)'
254
            )
255 19
            ->addOption(
256
                'src-dirname',
257
                null,
258
                InputOption::VALUE_OPTIONAL,
259
                'Source directory subfolder oof destination directory (default: src)'
260
            )
261 19
            ->addOption(
262
                'xsd-types-path',
263
                null,
264
                InputOption::VALUE_OPTIONAL,
265
                'Path to the xsd types configuration file to load'
266
            )
267 19
            ->addOption(
268
                self::GENERATOR_OPTIONS_CONFIG_OPTION,
269
                null,
270
                InputOption::VALUE_OPTIONAL,
271
                'Path to the generator\'s configuration file to load'
272
            )
273
        ;
274
    }
275
276 19
    protected function execute(InputInterface $input, OutputInterface $output): int
277
    {
278 19
        parent::execute($input, $output);
279 19
        $start = new DateTime();
280 19
        $this->writeLn(sprintf(' Start at %s', $start->format('Y-m-d H:i:s')));
281 19
        $this->initGeneratorOptions();
282 19
        if ($this->canExecute()) {
283 7
            $this->initGenerator()->getGenerator()->generatePackage();
284
        } else {
285 12
            $this->writeLn('  Generation not launched, use "--force" option to force generation');
286 12
            $this->writeLn(sprintf("  Generator's option file used: %s", $this->resolveGeneratorOptionsConfigPath()));
287 12
            $this->writeLn("  Used generator's options:");
288 12
            $this->writeLn('    '.implode(PHP_EOL.'    ', $this->formatArrayForConsole($this->generatorOptions->toArray())));
289
        }
290 13
        $end = new DateTime();
291 13
        $this->writeLn(sprintf(' End at %s, duration: %s', $end->format('Y-m-d H:i:s'), $start->diff($end)->format('%H:%I:%S')));
292
293 13
        return self::EXIT_OK;
294
    }
295
296
    protected function getPackageGenerationCommandLineOptions(): array
297
    {
298
        return [
299
            'addcomments' => GeneratorOptions::ADD_COMMENTS,
300
            'arrays-folder' => GeneratorOptions::ARRAYS_FOLDER,
301
            'composer-name' => GeneratorOptions::COMPOSER_NAME,
302
            'composer-settings' => GeneratorOptions::COMPOSER_SETTINGS,
303
            'category' => GeneratorOptions::CATEGORY,
304
            'destination' => GeneratorOptions::DESTINATION,
305
            'enums-folder' => GeneratorOptions::ENUMS_FOLDER,
306
            'gathermethods' => GeneratorOptions::GATHER_METHODS,
307
            'genericconstants' => GeneratorOptions::GENERIC_CONSTANTS_NAME,
308
            'gentutorial' => GeneratorOptions::GENERATE_TUTORIAL_FILE,
309
            'login' => GeneratorOptions::BASIC_LOGIN,
310
            'namespace' => GeneratorOptions::NAMESPACE_PREFIX,
311
            'namespace-directories' => GeneratorOptions::NAMESPACE_DICTATES_DIRECTORIES,
312
            'password' => GeneratorOptions::BASIC_PASSWORD,
313
            'prefix' => GeneratorOptions::PREFIX,
314
            'proxy-host' => GeneratorOptions::PROXY_HOST,
315
            'proxy-login' => GeneratorOptions::PROXY_LOGIN,
316
            'proxy-password' => GeneratorOptions::PROXY_PASSWORD,
317
            'proxy-port' => GeneratorOptions::PROXY_PORT,
318
            'services-folder' => GeneratorOptions::SERVICES_FOLDER,
319
            'src-dirname' => GeneratorOptions::SRC_DIRNAME,
320
            'structarray' => GeneratorOptions::STRUCT_ARRAY_CLASS,
321
            'structenum' => GeneratorOptions::STRUCT_ENUM_CLASS,
322
            'structs-folder' => GeneratorOptions::STRUCTS_FOLDER,
323
            'soapclient' => GeneratorOptions::SOAP_CLIENT_CLASS,
324
            'struct' => GeneratorOptions::STRUCT_CLASS,
325
            'standalone' => GeneratorOptions::STANDALONE,
326
            'suffix' => GeneratorOptions::SUFFIX,
327
            'urlorpath' => GeneratorOptions::ORIGIN,
328
            'validation' => GeneratorOptions::VALIDATION,
329
            'xsd-types-path' => GeneratorOptions::XSD_TYPES_PATH,
330
        ];
331
    }
332
333 19
    protected function initGeneratorOptions(): self
334
    {
335
        /** @var GeneratorOptions $generatorOptions */
336 19
        $generatorOptions = GeneratorOptions::instance($this->resolveGeneratorOptionsConfigPath());
337
338 19
        foreach ($this->getPackageGenerationCommandLineOptions() as $optionName => $generatorOptionName) {
339 19
            if (is_null($optionValue = $this->formatOptionValue($this->input->getOption($optionName)))) {
340 19
                continue;
341
            }
342 19
            $generatorOptions->setOptionValue($generatorOptionName, $optionValue);
343
        }
344 19
        $this->generatorOptions = $generatorOptions;
345
346 19
        return $this;
347
    }
348
349 19
    protected function formatOptionValue($optionValue)
350
    {
351 19
        if ('true' === $optionValue || (is_numeric($optionValue) && 1 === (int) $optionValue)) {
352
            return true;
353
        }
354 19
        if ('false' === $optionValue || (is_numeric($optionValue) && 0 === (int) $optionValue)) {
355
            return false;
356
        }
357
358 19
        return $optionValue;
359
    }
360
361
    /**
362
     * Utility method to return readable array based on "key: value".
363
     */
364 12
    protected function formatArrayForConsole(array $array): array
365
    {
366 12
        array_walk($array, function (&$value, $index) {
367 12
            $value = sprintf('%s: %s', $index, json_encode($value));
368
        });
369
370 12
        return $array;
371
    }
372
}
373