Completed
Pull Request — develop (#575)
by
unknown
102:40 queued 37:52
created

GenerateCommand::setFilesystem()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
/**
3
 * cleans dynamic bundle directory
4
 */
5
6
namespace Graviton\GeneratorV2Bundle\Command;
7
8
use Graviton\GeneratorBundle\Definition\JsonDefinition;
9
use Graviton\GeneratorBundle\Definition\Loader\Loader;
10
use Graviton\GeneratorBundle\Definition\Schema\Definition;
11
use Graviton\GeneratorBundle\Generator\ResourceGenerator\FieldMapper;
12
use Graviton\GeneratorV2Bundle\Service\SchemaMapper;
13
use Symfony\Bundle\FrameworkBundle\Console\Application;
14
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
15
use Symfony\Component\Console\Command\Command;
16
use Symfony\Component\Console\Helper\ProgressBar;
17
use Symfony\Component\Console\Input\InputInterface;
18
use Symfony\Component\Console\Output\OutputInterface;
19
use Symfony\Component\DependencyInjection\ContainerInterface;
20
use Symfony\Component\Filesystem\Filesystem;
21
use Symfony\Component\Finder\Finder;
22
use Symfony\Component\Finder\SplFileInfo;
23
24
/**
25
 * php -d memory_limit=-1 vendor/graviton/graviton/app/console graviton:generate-v2:service-files
26
 *
27
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
28
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
29
 * @link     http://swisscom.ch
30
 */
31
class GenerateCommand extends Command
32
{
33
34
    /* @var \Graviton\AppKernel */
35
    private $kernel;
36
37
    /** @var Filesystem */
38
    private $filesystem;
39
40
    /** @var FieldMapper */
41
    private $mapper;
42
43
    /** @var Loader */
44
    private $loader;
45
46
    /** @var OutputInterface */
47
    private $output;
48
49
    /** @var string */
50
    private $contextMode;
51
52
    /** @var string */
53
    private $destinationDir;
54
55
    /** @var Definition */
56
    private $currentDefinition;
57
58
    /**
59
     * {@inheritDoc}
60
     *
61
     * @return void
62
     */
63
    protected function configure()
64
    {
65
        parent::configure();
66
67
        $this->setName('graviton:generate-v2:service-files')
68
            ->setDescription(
69
                'Will create the requires services definition files and routing'
70
            );
71
    }
72
73
    /**
74
     * set kernel
75
     *
76
     * @param mixed $kernel kernel
77
     *
78
     * @return void
79
     */
80
    public function setKernel($kernel)
81
    {
82
        $this->kernel = $kernel;
83
    }
84
85
    /**
86
     * set filesystem
87
     *
88
     * @param mixed $filesystem filesystem
89
     *
90
     * @return void
91
     */
92
    public function setFilesystem($filesystem)
93
    {
94
        $this->filesystem = $filesystem;
95
    }
96
97
    /**
98
     * {@inheritDoc}
99
     *
100
     * @param InputInterface $input input
101
     * @param OutputInterface $output output
102
     *
103
     * @return void
104
     */
105
    protected function execute(InputInterface $input, OutputInterface $output)
106
    {
107
        $this->output = $output;
108
        $this->output->writeln('<info>');
109
        $this->output->writeln('Welcome to Service Generator v2.');
110
        $this->output->writeln('Hold on for a second while we fetch the definition files.');
111
        $this->output->writeln('</info>');
112
113
        /** @var Application $application */
114
        $application = $this->getApplication();
115
        /** @var ContainerInterface $container */
116
        $container = $application->getKernel()->getContainer();
117
118
        $this->loader = $container->get('graviton_generator.definition.loader');
119
        $this->mapper = $container->get('graviton_generator.resourcegenerator.field_mapper');
120
121
        // Get the base dir of the project to know if it's installed as vendor or stand alone app.
122
        $this->destinationDir = $container->getParameter('graviton.api.generated_service_directory');
123
        $this->contextMode = strpos($this->destinationDir, 'vendor/graviton/graviton') ? 'WRAPPER' : 'CORE';
124
        if ('WRAPPER' == $this->contextMode) {
125
            $this->destinationDir = str_replace('vendor/graviton/graviton/', '', $this->destinationDir);
126
        }
127
128
        $this->output->writeln(sprintf('Starting generation in %s context mode.', $this->contextMode));
129
130
        $this->generateServices($container->getParameter('kernel.root_dir'));
131
132
        $this->output->writeln('<info>');
133
        $this->output->writeln('Thanks you for using the service.');
134
        $this->output->writeln('Generated files are located in: ' . $this->destinationDir);
135
        $this->output->writeln('</info>');
136
137
    }
138
139
    /**
140
     * @param $rootDir
141
     */
142
    private function generateServices($rootDir)
143
    {
144
        $this->output->writeln('<info>Generating folder structure for services.</info>');
145
        $fileSystem = new Filesystem();
146
        if ($fileSystem->exists($this->destinationDir)) {
147
            $this->output->writeln('<comment> - > Removing old services.</comment>');
148
            $fileSystem->remove($this->destinationDir);
149
        }
150
        $fileSystem->mkdir($this->destinationDir);
151
        $fileSystem->mkdir($this->destinationDir . '/definition/');
152
        $fileSystem->mkdir($this->destinationDir . '/schema/');
153
154
        // Let get all definition files
155
        if ('CORE' == $this->contextMode) {
156
            $rootDir = realpath( $rootDir . '/../');
157
            $directories = [
158
                $rootDir . '/src/Graviton',
159
                $rootDir . '/vendor/libgraviton'
160
            ];
161
        } else {
162
            $rootDir = realpath($rootDir . '/../../../../vendor/');
163
            $directories = [
164
                $rootDir . '/graviton',
165
                $rootDir . '/grv',
166
            ];
167
        }
168
        $this->output->writeln('<info>Scanning for services in.</info>');
169
        foreach ($directories as $dir) {
170
            $this->output->writeln('<comment> - > '. $dir . '</comment>');
171
        }
172
173
        $finder = new Finder();
174
        $finder->files()->in($directories)
175
            ->name('*.json')
176
            ->notName('_*')
177
            ->path('/(^|\/)resources\/definition($|\/)/i');
178
        if ('WRAPPER' == $this->contextMode) {
179
            $finder->notPath('/(^|\/)Tests($|\/)/i');
180
        }
181
182
        $routes = [];
183
184
        $progress = new ProgressBar($this->output, $finder->count());
185
186
        foreach ($finder as $file) {
187
            $progress->advance();
188
            $path = $file->getRealPath();
189
190
            $json = json_decode($file->getContents());
191
            if (!$json || json_last_error()) {
192
                throw new InvalidConfigurationException('Failure: ' . $path . ': ' . json_last_error_msg());
193
            } elseif (!property_exists($json, 'id')) {
194
                throw new InvalidConfigurationException('Failure: ' . $path . ': id field is required');
195
            }
196
197
            // Routes
198
            if (property_exists($json, 'service' ) && property_exists($json->service, 'routerBase' )) {
199
                $routes[$json->id] = trim( $json->service->routerBase, "/" );
200
            }
201
202
            // Copy definition
203
            if (property_exists($json, 'service') && property_exists($json->service, 'fixtures')) {
204
                unset($json->service->fixtures);
205
            }
206
            $fileSystem->dumpFile($this->destinationDir . '/definition/' . $file->getFilename(), json_encode($json, JSON_PRETTY_PRINT));
207
208
            // Generate Schema
209
            $schema = $this->generateSchema($file);
210
            $fileSystem->dumpFile($this->destinationDir . '/schema/' . $file->getFilename(), $schema);
211
        }
212
213
        // Save routing
214
        $fileSystem->dumpFile($this->destinationDir . '/routes.json', json_encode($routes, JSON_PRETTY_PRINT));
215
216
    }
217
218
219
    /**
220
     * @param SplFileInfo $file
221
     * @return string
222
     */
223
    private function generateSchema($file)
224
    {
225
        $path = $file->getRealPath();
226
227
        /** @var JsonDefinition[] $definition */
228
        $definition = $this->loader->load($path);
229
        if (!array_key_exists(0, $definition) || !($definition[0] instanceof JsonDefinition)) {
230
            throw new InvalidConfigurationException('Failure: ' . $path . ': Incorrect JsonDefinition load.');
231
        }
232
233
        $this->currentDefinition = $definition[0];
0 ignored issues
show
Documentation Bug introduced by
It seems like $definition[0] of type object<Graviton\Generato...inition\JsonDefinition> is incompatible with the declared type object<Graviton\Generato...tion\Schema\Definition> of property $currentDefinition.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
234
235
        $mp = new SchemaMapper();
236
        $schema = $mp->convert($definition[0]);
237
238
        return json_encode($schema, JSON_PRETTY_PRINT);
239
    }
240
}
241