Completed
Pull Request — master (#214)
by Ion
02:41
created

Plugin::activate()   C

Complexity

Conditions 15
Paths 24

Size

Total Lines 51

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 19.9392

Importance

Changes 0
Metric Value
dl 0
loc 51
ccs 18
cts 25
cp 0.72
rs 5.9166
c 0
b 0
f 0
cc 15
nc 24
nop 2
crap 19.9392

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*
3
 * hirak/prestissimo
4
 * @author Hiraku NAKANO
5
 * @license MIT https://github.com/hirak/prestissimo
6
 */
7
namespace Hirak\Prestissimo;
8
9
use Composer\Composer;
10
use Composer\IO;
11
use Composer\Plugin as CPlugin;
12
use Composer\EventDispatcher;
13
use Composer\Installer;
14
15
class Plugin implements
16
    CPlugin\PluginInterface,
17
    EventDispatcher\EventSubscriberInterface
18
{
19
    /** @var IO\IOInterface */
20
    private $io;
21
22
    /** @var Composer\Config */
23
    private $config;
24
25
    /** @var array */
26
    private $package;
27
    private $cached = false;
28
29
    /** @var boolean */
30
    private $disabled = false;
31
32
    private static $pluginClasses = array(
33
        'BaseRequest',
34
        'ConfigFacade',
35
        'CopyRequest',
36
        'CurlMulti',
37
        'CurlRemoteFilesystem',
38
        'FetchException',
39
        'FetchRequest',
40
        'FileDownloaderDummy',
41
        'ParallelizedComposerRepository',
42
        'Plugin',
43
        'Prefetcher',
44
        'Share',
45
    );
46
47
    private static $supportedSchemes = array(
48
        'http',
49
        'https'
50
    );
51
52 3
    public function activate(Composer $composer, IO\IOInterface $io)
53
    {
54
        // @codeCoverageIgnoreStart
55
        // guard for self-update problem
56
        if (__CLASS__ !== 'Hirak\Prestissimo\Plugin') {
57
            return $this->disable();
58
        }
59
        // guard for missing curl extension problem
60
        if (!extension_loaded('curl')) {
61
            $io->writeError('<error>Error: "curl" PHP extension not loaded; Prestissmo Composer plugin disabled.</error>');
62
            return $this->disable();
63
        }
64
        // @codeCoverageIgnoreEnd
65
66
        // load all classes
67 3
        foreach (self::$pluginClasses as $class) {
68 3
            class_exists(__NAMESPACE__ . '\\' . $class);
69
        }
70
71 3
        $this->io = $io;
72 3
        $this->config = $composer->getConfig();
0 ignored issues
show
Documentation Bug introduced by
It seems like $composer->getConfig() of type object<Composer\Config> is incompatible with the declared type object<Composer\Composer\Config> of property $config.

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...
73 3
        $this->package = $composer->getPackage();
0 ignored issues
show
Documentation Bug introduced by
It seems like $composer->getPackage() of type object<Composer\Package\RootPackageInterface> is incompatible with the declared type array of property $package.

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...
74
75 3
        $cacheDir = rtrim($this->config->get('cache-files-dir'), '\/');
76
77 3
        if (preg_match('{(^|[\\\\/])(\$null|nul|NUL|/dev/null)([\\\\/]|$)}', $cacheDir)) {
78
            return $this->disable();
79
        }
80
81 3
        if (array_key_exists('argv', $GLOBALS)) {
82 3
            if (in_array('help', $GLOBALS['argv'])) {
83
                return $this->disable();
84
            }
85
86 3
            foreach ($GLOBALS['argv'] as $arg) {
87 3
                switch ($arg) {
88 3
                    case 'create-project':
89 3
                    case 'update':
90 3
                    case 'outdated':
91 3
                    case 'require':
92
                        $this->prefetchComposerRepositories();
93
                        break 2;
94 3
                    case 'install':
95
                        if (file_exists('composer.json') && !file_exists('composer.lock')) {
96
                            $this->prefetchComposerRepositories();
97
                        }
98
                        break 2;
99
                }
100
            }
101
        }
102 3
    }
103
104 1
    public static function getSubscribedEvents()
105
    {
106
        return array(
107 1
            CPlugin\PluginEvents::PRE_FILE_DOWNLOAD => 'onPreFileDownload',
108 1
            Installer\InstallerEvents::POST_DEPENDENCIES_SOLVING => array(
109 1
                array('onPostDependenciesSolving', PHP_INT_MAX),
110
            ),
111
        );
112
    }
113
114
    /**
115
     * Keep-Alived file downloader
116
     */
117
    public function onPreFileDownload(CPlugin\PreFileDownloadEvent $ev)
118
    {
119
        if ($this->disabled) {
120
            return;
121
        }
122
123
        $scheme = parse_url($ev->getProcessedUrl(), PHP_URL_SCHEME);
124
        if (!in_array($scheme, self::$supportedSchemes, true)) {
125
            return;
126
        }
127
128
        $rfs = $ev->getRemoteFilesystem();
129
        $curlrfs = new CurlRemoteFilesystem(
130
            $this->io,
131
            $this->config,
132
            $rfs->getOptions()
133
        );
134
        $ev->setRemoteFilesystem($curlrfs);
135
    }
136
137 1
    public function prefetchComposerRepositories()
138
    {
139 1
        if ($this->disabled) {
140 1
            return;
141
        }
142 1
        if ($this->cached) {
143
            return;
144
        }
145 1
        $repos = $this->package->getRepositories();
0 ignored issues
show
Bug introduced by
The method getRepositories cannot be called on $this->package (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
146 1
        foreach ($repos as $label => $repo) {
147
            if (isset($repo['type']) && $repo['type'] === 'composer') {
148
                if (!empty($repo['force-lazy-providers'])) {
149
                    continue;
150
                }
151
152
                if (substr($repo['url'], 0, 6) !== 'https?') {
153
                    $scheme = parse_url($repo['url'], PHP_URL_SCHEME);
154
                    if (!in_array($scheme, self::$supportedSchemes, true)) {
155
                        continue;
156
                    }
157
                }
158
159
                $r = new ParallelizedComposerRepository($repo, $this->io, $this->config);
160
                $r->prefetch();
161
            }
162
        }
163 1
        $this->cached = true;
164 1
    }
165
166
    /**
167
     * pre-fetch parallel by curl_multi
168
     */
169 1
    public function onPostDependenciesSolving(Installer\InstallerEvent $ev)
170
    {
171 1
        if ($this->disabled) {
172 1
            return;
173
        }
174 1
        $prefetcher = new Prefetcher;
175 1
        $prefetcher->fetchAllFromOperations(
176 1
            $this->io,
177 1
            $this->config,
178 1
            $ev->getOperations()
179
        );
180 1
    }
181
182 2
    public function disable()
183
    {
184 2
        $this->disabled = true;
185 2
    }
186
187 1
    public function isDisabled()
188
    {
189 1
        return $this->disabled;
190
    }
191
}
192