SwaggerApiInstaller::getSchemaFile()   B
last analyzed

Complexity

Conditions 4
Paths 6

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 14
nc 6
nop 1
1
<?php
2
3
/*
4
 * Copyright (C) 2016 Billie Thompson
5
 *
6
 * This software may be modified and distributed under the terms
7
 * of the MIT license.  See the LICENSE.md file for details.
8
 */
9
10
namespace PurpleBooth\JaneOpenApiAutogenerate;
11
12
use Composer\Composer;
13
use Composer\Installer\BinaryInstaller;
14
use Composer\Installer\LibraryInstaller;
15
use Composer\IO\IOInterface;
16
use Composer\Package\PackageInterface;
17
use Composer\Util\Filesystem;
18
use Joli\Jane\OpenApi\JaneOpenApi;
19
use RecursiveDirectoryIterator;
20
use RecursiveIteratorIterator;
21
use SplFileInfo;
22
23
class SwaggerApiInstaller extends LibraryInstaller
24
{
25
    const PACKAGE_TYPE = 'swagger-api';
26
27
    const EXTRA_KEY_NAMESPACE = 'namespace';
28
29
    const EXTRA_KEY_SCHEMA_FILE = 'schema-file';
30
31
    const EXTRA_KEY_ENVIRONMENT_VARIABLE = 'environment-variable';
32
33
    const GENERATED_DIRECTORY = 'generated';
34
35
    const SCHEMA_PATH_IS_DOWNLOAD_PATTERN = '/^https?:/';
36
37
    /**
38
     * {@inheritdoc}
39
     */
40
    public function __construct(
41
        IOInterface $inputOutput,
42
        Composer $composer,
43
        $type = self::PACKAGE_TYPE,
44
        Filesystem $filesystem = null,
45
        BinaryInstaller $binaryInstaller = null
46
    ) {
47
        parent::__construct($inputOutput, $composer, $type, $filesystem, $binaryInstaller);
48
    }
49
50
    protected function updateCode(PackageInterface $initial, PackageInterface $target)
51
    {
52
        $this->removeCode($initial);
53
        $this->installCode($target);
54
    }
55
56
    protected function removeCode(PackageInterface $package)
57
    {
58
        // Is this a schema we download from the internet or checkout locally
59
        if (!$this->isSchemaToDownload($package)) {
60
            parent::removeCode($package);
61
        } else {
62
            $downloadPath = $this->getInstallPath($package);
63
            $this->removeDirectory($downloadPath);
64
        }
65
    }
66
67
    /**
68
     * Do we download or checkout this schema.
69
     *
70
     * @param PackageInterface $package
71
     *
72
     * @return bool
73
     */
74
    private function isSchemaToDownload(PackageInterface $package)
75
    {
76
        return 1 === preg_match(self::SCHEMA_PATH_IS_DOWNLOAD_PATTERN, $this->getInstallPath($package));
77
    }
78
79
    /**
80
     * RM -rf in PHP.
81
     *
82
     * @param string $downloadPath
83
     */
84
    private function removeDirectory($downloadPath)
85
    {
86
        if (!(new SplFileInfo($downloadPath))->isDir()) {
87
            return;
88
        }
89
90
        $directory = new RecursiveDirectoryIterator($downloadPath);
91
        $iterator = new RecursiveIteratorIterator(
92
            -$directory,
93
            RecursiveIteratorIterator::CHILD_FIRST
94
        );
95
96
        /** @var SplFileInfo $item */
97
        foreach ($iterator as $item) {
98
            if ($item->isFile()) {
99
                unlink($item->getPathname());
100
            }
101
102
            if ($item->isDir()) {
103
                rmdir($item->getPathname());
104
            }
105
        }
106
107
        rmdir($downloadPath);
108
    }
109
110
    protected function installCode(PackageInterface $package)
111
    {
112
        // Is this a schema we download from the internet or checkout locally
113
        if (!$this->isSchemaToDownload($package)) {
114
            parent::installCode($package);
115
        }
116
117
        $this->generateSwaggerClient(
118
            $package,
119
            $this->getInstallPath($package)
120
        );
121
    }
122
123
    /**
124
     * Generate the client for a package.
125
     *
126
     * @param PackageInterface $package
127
     * @param string           $downloadPath
128
     */
129
    protected function generateSwaggerClient(PackageInterface $package, $downloadPath)
130
    {
131
        $janeOpenApi = JaneOpenApi::build();
132
133
        $extra = $package->getExtra();
134
        $namespace = $extra[self::EXTRA_KEY_NAMESPACE];
135
        $openApiSchemaFile = $this->getSchemaFile($package);
136
137
        $this->io->write(
138
            sprintf('Generating <info>%s</info> from <info>%s</info>', $namespace, $openApiSchemaFile),
139
            true,
140
            IOInterface::VERBOSE
141
        );
142
143
        $this->io->write(
144
            sprintf('Writing to <info>%s</info>', $downloadPath),
145
            true,
146
            IOInterface::VERY_VERBOSE
147
        );
148
149
        $generatePath = implode(DIRECTORY_SEPARATOR, [$downloadPath, self::GENERATED_DIRECTORY]);
150
        $files = $janeOpenApi->generate($openApiSchemaFile, $namespace, $generatePath);
151
        $janeOpenApi->printFiles($files, $downloadPath);
152
153
        foreach ($files as $file) {
154
            $this->io->write(
155
                sprintf('Generated <info>%s</info>', $file->getFilename()),
156
                true,
157
                IOInterface::DEBUG
158
            );
159
        }
160
161
        $this->io->write(
162
            sprintf('Generated <info>%s</info> from <info>%s</info>', $namespace, $openApiSchemaFile),
163
            true,
164
            IOInterface::VERBOSE
165
        );
166
    }
167
168
    /**
169
     * Get the schema file.
170
     *
171
     * @param PackageInterface $package
172
     *
173
     * @return string
174
     */
175
    private function getSchemaFile(PackageInterface $package)
176
    {
177
        $downloadPath = $this->getInstallPath($package);
178
        $extra = $package->getExtra();
179
        $openApiSchemaFile = $extra[self::EXTRA_KEY_SCHEMA_FILE];
180
181
        if (isset($extra[self::EXTRA_KEY_ENVIRONMENT_VARIABLE])) {
182
            $envVariableName = $extra[self::EXTRA_KEY_ENVIRONMENT_VARIABLE];
183
            $envVariable = getenv($envVariableName);
184
185
            if ($envVariable) {
186
                $openApiSchemaFile = $envVariable;
187
            }
188
        }
189
190
        $vendorSchemaPath = implode(DIRECTORY_SEPARATOR, [$downloadPath, $openApiSchemaFile]);
191
192
        if (file_exists($vendorSchemaPath)) {
193
            $openApiSchemaFile = $vendorSchemaPath;
194
195
            return $openApiSchemaFile;
196
        }
197
198
        return $openApiSchemaFile;
199
    }
200
}
201