Completed
Push — master ( b34ff2...164f63 )
by Billie
12s
created

SwaggerApiInstaller::getSchemaFile()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

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