VendorExposeCommand   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 137
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 50
c 2
b 0
f 0
dl 0
loc 137
rs 10
wmc 19

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getAllLibraries() 0 23 5
A isPathModule() 0 4 2
B getModulePaths() 0 32 7
A configure() 0 10 1
A execute() 0 22 2
A getAllModules() 0 3 1
A getProjectPath() 0 3 1
1
<?php
2
3
namespace SilverStripe\VendorPlugin\Console;
4
5
use Composer\Command\BaseCommand;
6
use Composer\Factory;
7
use Composer\IO\ConsoleIO;
8
use Composer\Util\Filesystem;
9
use Generator;
10
use SilverStripe\VendorPlugin\Library;
11
use SilverStripe\VendorPlugin\Util;
12
use SilverStripe\VendorPlugin\VendorExposeTask;
13
use SilverStripe\VendorPlugin\VendorPlugin;
14
use Symfony\Component\Console\Input\InputArgument;
15
use Symfony\Component\Console\Input\InputInterface;
16
use Symfony\Component\Console\Output\OutputInterface;
17
18
/**
19
 * Provides `composer vendor-expose` behaviour
20
 */
21
class VendorExposeCommand extends BaseCommand
22
{
23
    public function configure()
24
    {
25
        $this->setName('vendor-expose');
26
        $this->setDescription('Refresh all exposed module/theme/project folders');
27
        $this->addArgument(
28
            'method',
29
            InputArgument::OPTIONAL,
30
            'Optional method to use. Defaults to last used value, or ' . VendorPlugin::METHOD_DEFAULT . ' otherwise'
31
        );
32
        $this->setHelp('This command will update all resources for all installed modules using the given method');
33
    }
34
35
    public function execute(InputInterface $input, OutputInterface $output)
36
    {
37
        $io = new ConsoleIO($input, $output, $this->getHelperSet());
0 ignored issues
show
Bug introduced by
It seems like $this->getHelperSet() can also be of type null; however, parameter $helperSet of Composer\IO\ConsoleIO::__construct() does only seem to accept Symfony\Component\Console\Helper\HelperSet, 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

37
        $io = new ConsoleIO($input, $output, /** @scrutinizer ignore-type */ $this->getHelperSet());
Loading history...
38
39
        // Check libraries to expose
40
        $modules = $this->getAllLibraries();
41
        if (empty($modules)) {
42
            $io->write("No modules to expose");
43
            return 0;
44
        }
45
46
        // Query first library for base destination
47
        $basePublicPath = $modules[0]->getBasePublicPath();
48
49
        // Expose all modules
50
        $method = $input->getArgument('method');
51
        $task = new VendorExposeTask($this->getProjectPath(), new Filesystem(), $basePublicPath);
52
        $task->process($io, $modules, $method);
0 ignored issues
show
Bug introduced by
It seems like $method can also be of type string[]; however, parameter $methodKey of SilverStripe\VendorPlugi...orExposeTask::process() 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

52
        $task->process($io, $modules, /** @scrutinizer ignore-type */ $method);
Loading history...
53
54
        // Success
55
        $io->write("All modules updated!");
56
        return 0;
57
    }
58
59
    /**
60
     * Get all libraries
61
     *
62
     * @return Library[]
63
     */
64
    protected function getAllLibraries()
65
    {
66
        $modules = [];
67
        $basePath = $this->getProjectPath();
68
69
        // Get all modules
70
        foreach ($this->getModulePaths() as $modulePath) {
71
            // Filter by non-composer folders
72
            $composerPath = Util::joinPaths($modulePath, 'composer.json');
73
            if (!file_exists($composerPath)) {
74
                continue;
75
            }
76
77
            // Ensure this library should be exposed, and has at least one folder
78
            $module = new Library($basePath, $modulePath);
79
            if (!$module->requiresExpose() || !$module->getExposedFolders()) {
80
                continue;
81
            }
82
83
            // Save this module
84
            $modules[] = $module;
85
        }
86
        return $modules;
87
    }
88
89
    /**
90
     * Find all modules
91
     *
92
     * @deprecated 1.3..2.0
93
     * @return Library[]
94
     */
95
    protected function getAllModules()
96
    {
97
        return $this->getAllLibraries();
98
    }
99
100
    /**
101
     * Search all paths that could contain a module / theme
102
     *
103
     * @return Generator
104
     */
105
    protected function getModulePaths()
106
    {
107
        // Project root is always returned
108
        $basePath = $this->getProjectPath();
109
        yield $basePath;
110
111
        // Get vendor modules
112
        $search = Util::joinPaths($basePath, 'vendor', '*', '*');
113
        foreach (glob($search, GLOB_ONLYDIR) as $modulePath) {
114
            if ($this->isPathModule($modulePath)) {
115
                yield $modulePath;
116
            }
117
        }
118
119
        // Check if public/ folder exists
120
        $publicExists = is_dir(Util::joinPaths($basePath, Library::PUBLIC_PATH));
121
        if (!$publicExists) {
122
            return;
123
        }
124
125
        // Search all base folders / modules
126
        $search = Util::joinPaths($basePath, '*');
127
        foreach (glob($search, GLOB_ONLYDIR) as $modulePath) {
128
            if ($this->isPathModule($modulePath)) {
129
                yield $modulePath;
130
            }
131
        }
132
133
        // Check all themes
134
        $search = Util::joinPaths($basePath, 'themes', '*');
135
        foreach (glob($search, GLOB_ONLYDIR) as $themePath) {
136
            yield $themePath;
137
        }
138
    }
139
140
    /**
141
     * Check if the given path is a silverstripe module
142
     *
143
     * @param string $path
144
     * @return bool
145
     */
146
    protected function isPathModule($path)
147
    {
148
        return file_exists(Util::joinPaths($path, '_config'))
149
            || file_exists(Util::joinPaths($path, '_config.php'));
150
    }
151
152
    /**
153
     * @return string
154
     */
155
    protected function getProjectPath()
156
    {
157
        return dirname(realpath(Factory::getComposerFile()));
158
    }
159
}
160