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