Test Failed
Push — develop ( 8a31ce...8fcf9d )
by nguereza
02:43
created

VendorPublishCommand   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 254
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 114
dl 0
loc 254
rs 10
c 1
b 0
f 1
wmc 20

8 Methods

Rating   Name   Duplication   Size   Complexity  
A publishAll() 0 4 1
A publishPackage() 0 16 4
A publishMigration() 0 11 2
A execute() 0 49 3
A publishItem() 0 39 4
A getPackageInfo() 0 11 3
A __construct() 0 19 1
A publishConfiguration() 0 10 2
1
<?php
2
3
/**
4
 * Platine Framework
5
 *
6
 * Platine Framework is a lightweight, high-performance, simple and elegant
7
 * PHP Web framework
8
 *
9
 * This content is released under the MIT License (MIT)
10
 *
11
 * Copyright (c) 2020 Platine Framework
12
 *
13
 * Permission is hereby granted, free of charge, to any person obtaining a copy
14
 * of this software and associated documentation files (the "Software"), to deal
15
 * in the Software without restriction, including without limitation the rights
16
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
 * copies of the Software, and to permit persons to whom the Software is
18
 * furnished to do so, subject to the following conditions:
19
 *
20
 * The above copyright notice and this permission notice shall be included in all
21
 * copies or substantial portions of the Software.
22
 *
23
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
 * SOFTWARE.
30
 */
31
32
/**
33
 *  @file VendorPublishCommand.php
34
 *
35
 *  The Composer vendor publish command class
36
 *
37
 *  @package    Platine\Framework\Console\Command
38
 *  @author Platine Developers team
39
 *  @copyright  Copyright (c) 2020
40
 *  @license    http://opensource.org/licenses/MIT  MIT License
41
 *  @link   http://www.iacademy.cf
42
 *  @version 1.0.0
43
 *  @filesource
44
 */
45
46
declare(strict_types=1);
47
48
namespace Platine\Framework\Console\Command;
49
50
use Platine\Config\Config;
51
use Platine\Console\Command\Command;
52
use Platine\Filesystem\Filesystem;
53
use Platine\Framework\App\Application;
54
use Platine\Stdlib\Helper\Composer;
55
use Platine\Stdlib\Helper\Json;
56
use Platine\Stdlib\Helper\Path;
57
58
/**
59
 * @class VendorPublishCommand
60
 * @package Platine\Framework\Console\Command
61
 * @template T
62
 */
63
class VendorPublishCommand extends Command
64
{
65
66
    /**
67
     * Application instance
68
     * @var Application
69
     */
70
    protected Application $application;
71
72
    /**
73
     * The vendor path
74
     * @var string
75
     */
76
    protected string $vendorPath;
77
78
    /**
79
     * The package installation path
80
     * @var string
81
     */
82
    protected string $packagePath = '';
83
84
    /**
85
     * The file system to use
86
     * @var Filesystem
87
     */
88
    protected Filesystem $filesystem;
89
90
    /**
91
     * Package manifest information
92
     * @var array<string, mixed>
93
     */
94
    protected array $manifest = [];
95
96
    /**
97
     * The configuration to use
98
     * @var Config<T>
99
     */
100
    protected Config $config;
101
102
    /**
103
     * Create new instance
104
     * @param Application $app
105
     * @param Filesystem $filesystem
106
     */
107
    public function __construct(
108
        Application $app,
109
        Filesystem $filesystem,
110
        Config $config
111
    ) {
112
        parent::__construct(
113
            'vendor:publish',
114
            'Command to publish composer vendor configuration, migration, etc.'
115
        );
116
        $this->addArgument('name', 'The package name', null, true);
117
        $this->addOption('-o|--overwrite', 'Overwrite existing files.', false, false);
118
        $this->addOption('-c|--config', 'Publish only the configuration.', false, false);
119
        $this->addOption('-m|--migration', 'Publish only the migrations.', false, false);
120
        $this->addOption('-a|--all', 'Publish all files.', false, false);
121
122
        $this->config = $config;
123
        $this->filesystem = $filesystem;
124
        $this->application = $app;
125
        $this->vendorPath = Path::normalizePathDS($app->getVendorPath(), true);
126
    }
127
128
    /**
129
     * {@inheritodc}
130
     */
131
    public function execute()
132
    {
133
        $writer = $this->io()->writer();
134
        $name = $this->getArgumentValue('name');
135
        $writer->boldGreen(sprintf('PUBLISH OF PACKAGE [%s]', $name), true)->eol();
136
137
        $package = $this->getPackageInfo($name);
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type null; however, parameter $name of Platine\Framework\Consol...mmand::getPackageInfo() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

137
        $package = $this->getPackageInfo(/** @scrutinizer ignore-type */ $name);
Loading history...
138
        if (empty($package)) {
139
            $writer->red(sprintf(
140
                'Can not find the composer package [%s].',
141
                $name
142
            ), true);
143
            return;
144
        }
145
146
        $packagePath = $this->vendorPath . $name;
147
        $packagePath = Path::convert2Absolute($packagePath);
148
149
        $this->packagePath = $packagePath;
150
151
        $writer->bold('Name: ');
152
        $writer->boldBlueBgBlack($package['name'], true);
153
154
        $writer->bold('Description: ');
155
        $writer->boldBlueBgBlack($package['description'], true);
156
157
        $writer->bold('Version: ');
158
        $writer->boldBlueBgBlack($package['version'], true);
159
160
        $writer->bold('Type: ');
161
        $writer->boldBlueBgBlack($package['type'], true);
162
163
        $writer->bold('Path: ');
164
        $writer->boldBlueBgBlack($packagePath, true)->eol();
165
166
        $extras = $package['extra'] ?? [];
167
        $manifest = $extras['platine'] ?? [];
168
169
        if (empty($manifest)) {
170
            $writer->boldGreen('NOTHING TO PUBLISH, COMMAND ENDED!', true);
171
            return;
172
        }
173
174
        $this->manifest = $manifest;
175
176
        $this->publishPackage();
177
178
        $writer->eol();
179
        $writer->boldGreen('Command finished successfully')->eol();
180
    }
181
182
    /**
183
     * Package publication
184
     * @return void
185
     */
186
    protected function publishPackage(): void
187
    {
188
        $all = $this->getOptionValue('all');
189
        if ($all) {
190
            $this->publishAll();
191
            return;
192
        }
193
194
        $config = $this->getOptionValue('config');
195
        if ($config) {
196
            $this->publishConfiguration();
197
        }
198
199
        $migration = $this->getOptionValue('migration');
200
        if ($migration) {
201
            $this->publishMigration();
202
        }
203
    }
204
205
    /**
206
     * Publish all assets for this package
207
     * @return void
208
     */
209
    protected function publishAll(): void
210
    {
211
        $this->publishConfiguration();
212
        $this->publishMigration();
213
    }
214
215
    /**
216
     * Publish the configuration
217
     * @return void
218
     */
219
    protected function publishConfiguration(): void
220
    {
221
        $manifest = $this->manifest;
222
        $config = $manifest['config'] ?? [];
223
        $destinationPath = Path::normalizePathDS(
224
            $this->application->getConfigPath(),
225
            true
226
        );
227
        foreach ($config as $cfg) {
228
            $this->publishItem($cfg, $destinationPath, 'configuration');
229
        }
230
    }
231
232
    /**
233
     * Publish the migration
234
     * @return void
235
     */
236
    protected function publishMigration(): void
237
    {
238
        $path = Path::convert2Absolute(
239
            $this->config->get('migration.path', 'migrations')
240
        );
241
        $destinationPath = Path::normalizePathDS($path, true);
242
243
        $manifest = $this->manifest;
244
        $migrations = $manifest['migration'] ?? [];
245
        foreach ($migrations as $migration) {
246
            $this->publishItem($migration, $destinationPath, 'migration');
247
        }
248
    }
249
250
    /**
251
     * Publish asset
252
     * @param string $src
253
     * @param string $dest
254
     * @param string $type
255
     * @return void
256
     */
257
    protected function publishItem(string $src, string $dest, string $type): void
258
    {
259
        $writer = $this->io()->writer();
260
261
        $writer->boldYellow(sprintf('Publish of package %s', $type), true);
262
263
        $sourceFilename = basename($src);
264
        $sourcePath = $this->packagePath . '/' . $src;
265
        $file = $this->filesystem->file($sourcePath);
266
        if (!$file->exists()) {
267
            $writer->red(sprintf(
268
                'Can not find the package file %s [%s].',
269
                $type,
270
                $file->getPath()
271
            ), true);
272
        } else {
273
            $destFile = $this->filesystem->file(
274
                $dest . $sourceFilename
275
            );
276
277
            $overwrite = $this->getOptionValue('overwrite');
278
279
            if ($destFile->exists() && !$overwrite) {
280
                $writer->red(sprintf(
281
                    "%s file \n[%s]\n already exist, if you want to overwrite"
282
                        . ' use option "--overwrite".',
283
                    $type,
284
                    $destFile->getPath()
285
                ), true);
286
            } else {
287
                $file->copyTo($dest);
288
                $writer->boldGreen(
289
                    sprintf(
290
                        'Package %s [%s] publish successfully',
291
                        $type,
292
                        $src,
293
                        $dest . $sourceFilename
294
                    ),
295
                    true
296
                );
297
            }
298
        }
299
    }
300
301
    /**
302
     * Return the information for given package
303
     * @param string $name
304
     * @return array<string, mixed>
305
     */
306
    protected function getPackageInfo(string $name): array
307
    {
308
        $packages = Composer::parseLockFile($this->application->getAppPath());
309
        foreach ($packages as $package) {
310
            $packageName = $package['name'] ?? '';
311
            if ($name === $packageName) {
312
                return $package;
313
            }
314
        }
315
316
        return [];
317
    }
318
}
319