Completed
Pull Request — 3.x (#123)
by Sullivan
03:11 queued 01:41
created

GenerateCommand   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 119
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Importance

Changes 0
Metric Value
wmc 8
lcom 1
cbo 11
dl 0
loc 119
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 6 1
C execute() 0 88 7
1
<?php
2
3
namespace SLLH\IsoCodesValidator\Dev\Console\Command;
4
5
use Doctrine\Common\Inflector\Inflector;
6
use Gnugat\NomoSpaco\File\FileRepository;
7
use Gnugat\NomoSpaco\FqcnRepository;
8
use Gnugat\NomoSpaco\Token\ParserFactory;
9
use Symfony\Component\Console\Command\Command;
10
use Symfony\Component\Console\Input\InputInterface;
11
use Symfony\Component\Console\Output\OutputInterface;
12
use Symfony\Component\Finder\Finder;
13
use Symfony\Component\Translation\Dumper\XliffFileDumper;
14
use Symfony\Component\Translation\Loader\XliffFileLoader;
15
use Symfony\Component\Translation\MessageCatalogue;
16
17
/**
18
 * @author Sullivan Senechal <[email protected]>
19
 */
20
final class GenerateCommand extends Command
21
{
22
    /**
23
     * IsoCodes classes to not generate as validator.
24
     *
25
     * Generally abstract classes, interfaces or deprecations.
26
     *
27
     * @var string[]
28
     */
29
    private $excludedClasses = [
30
        'Luhn',
31
        'Gtin',
32
        'Dun14',
33
        'Itf14',
34
        'Upca',
35
    ];
36
37
    /**
38
     * {@inheritdoc}
39
     */
40
    protected function configure()
41
    {
42
        $this
43
            ->setName('generate')
44
        ;
45
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50
    protected function execute(InputInterface $input, OutputInterface $output)
51
    {
52
        $isoCodePath = __DIR__.'/../../../vendor/ronanguilloux/isocodes';
53
        if (!file_exists($isoCodePath.'/.git')) {
54
            $output->writeln(
55
                '<error>No .git directory found on ronanguilloux/isocodes package. Please run rm -r vendor/ronanguilloux/isocodes && composer update ronanguilloux/isocodes --prefer-source command.</error>'
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 205 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
56
            );
57
58
            return 1;
59
        }
60
61
        $fqcnRepository = new FqcnRepository(new FileRepository(), new ParserFactory());
62
63
        $isoCodesClasses = array_diff(
64
            array_map(function ($fqcn) {
65
                return str_replace('IsoCodes\\', '', $fqcn);
66
            }, $fqcnRepository->findIn(__DIR__.'/../../../vendor/ronanguilloux/isocodes/src/IsoCodes')),
67
            $this->excludedClasses
68
        );
69
70
        $constraintClasses = array_filter(array_map(function ($fqcn) {
71
            return str_replace('SLLH\\IsoCodesValidator\\Constraints\\', '', $fqcn);
72
        }, $fqcnRepository->findIn(__DIR__.'/../../../src/Constraints')), function ($className) {
73
            return !empty(trim($className));
74
        });
75
76
        $twig = new \Twig_Environment(new \Twig_Loader_Filesystem(__DIR__.'/../..'));
77
78
        $xliffLoader = new XliffFileLoader();
79
        $xliffDumper = new XliffFileDumper();
80
81
        /** @var MessageCatalogue[] $catalogues */
82
        $catalogues = [];
83
        foreach (Finder::create()->in(__DIR__.'/../../../src/translations') as $fileInfo) {
84
            $locale = explode('.', $fileInfo->getBasename())[1];
85
            $catalogues[$locale] = $xliffLoader->load($fileInfo->getRealPath(), $locale, 'validators');
86
        }
87
88
        foreach (array_udiff($isoCodesClasses, $constraintClasses, 'strcasecmp') as $className) {
89
            $classVersion = str_replace(
90
                'v',
91
                '',
92
                exec("git -C ${isoCodePath} tag --list --contains $(git -C ${isoCodePath} log --pretty=format:\"%h\" --diff-filter=A src/IsoCodes/${className}.php) | head -n 1")
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 177 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
93
            );
94
            $classMessage = 'This value is not a valid '.strtoupper($className).'.';
95
96
            $output->writeln("Generate <comment>${className}</comment> constraint (<info>v${classVersion}</info>).");
97
98
            file_put_contents(
99
                __DIR__."/../../../src/Constraints/${className}.php",
100
                $twig->render('templates/Constraint.php.twig', [
101
                    'class_name' => $className,
102
                    'class_message' => $classMessage,
103
                    'class_version' => $classVersion,
104
                ])
105
            );
106
107
            file_put_contents(
108
                __DIR__."/../../../tests/Constraints/${className}ValidatorTest.php",
109
                $twig->render('templates/ConstraintValidatorTest.php.twig', [
110
                    'class_name' => $className,
111
                ])
112
            );
113
114
            foreach ($catalogues as $locale => $catalogue) {
115
                $catalogue->set(
116
                    $classMessage,
117
                    'en' === $locale
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of 'en' (string) and $locale (integer) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
118
                        ? $classMessage
119
                        : Inflector::tableize($className)
120
                    ,
121
                    'validators'
122
                );
123
            }
124
        }
125
126
        foreach ($catalogues as $locale => $catalogue) {
127
            $fileContents = $xliffDumper->formatCatalogue($catalogue, 'validators', [
128
                'default_locale' => 'en',
129
            ]);
130
            file_put_contents(
131
                __DIR__."/../../../src/translations/validators.${locale}.xlf",
132
                str_replace('  ', '    ', $fileContents)
133
            );
134
        }
135
136
        return 0;
137
    }
138
}
139