Completed
Pull Request — master (#220)
by
unknown
07:57
created

Plugin   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 186
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 55.7%

Importance

Changes 0
Metric Value
wmc 35
lcom 1
cbo 8
dl 0
loc 186
ccs 44
cts 79
cp 0.557
rs 9.6
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
C activate() 0 49 15
A getSubscribedEvents() 0 12 2
A onPreFileDownload() 0 19 3
B prefetchComposerRepositories() 0 28 9
A onPostDependenciesSolving() 0 12 2
A disable() 0 4 1
A isDisabled() 0 4 1
A deactivate() 0 3 1
A uninstall() 0 3 1
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 3
        if (!defined('\Composer\Installer\InstallerEvents::POST_DEPENDENCIES_SOLVING')) {
67
            return $this->disable();
68
        }
69
70
        // load all classes
71 3
        foreach (self::$pluginClasses as $class) {
72 3
            class_exists(__NAMESPACE__ . '\\' . $class);
73
        }
74
75 3
        $this->io = $io;
76 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...
77 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...
78
79 3
        if (array_key_exists('argv', $GLOBALS)) {
80 3
            if (in_array('help', $GLOBALS['argv'])) {
81
                return $this->disable();
82
            }
83
84 3
            foreach ($GLOBALS['argv'] as $arg) {
85 3
                switch ($arg) {
86 3
                    case 'create-project':
87 3
                    case 'update':
88 3
                    case 'outdated':
89 3
                    case 'require':
90
                        $this->prefetchComposerRepositories();
91
                        break 2;
92 3
                    case 'install':
93
                        if (file_exists('composer.json') && !file_exists('composer.lock')) {
94
                            $this->prefetchComposerRepositories();
95
                        }
96
                        break 2;
97
                }
98
            }
99
        }
100 3
    }
101
102 1
    public static function getSubscribedEvents()
103
    {
104 1
        if (!defined('\Composer\Installer\InstallerEvents::POST_DEPENDENCIES_SOLVING')) {
105
            return array();
106
        }
107
        return array(
108 1
            CPlugin\PluginEvents::PRE_FILE_DOWNLOAD => 'onPreFileDownload',
109 1
            Installer\InstallerEvents::POST_DEPENDENCIES_SOLVING => array(
110 1
                array('onPostDependenciesSolving', PHP_INT_MAX),
111
            ),
112
        );
113
    }
114
115
    /**
116
     * Keep-Alived file downloader
117
     */
118
    public function onPreFileDownload(CPlugin\PreFileDownloadEvent $ev)
119
    {
120
        if ($this->disabled) {
121
            return;
122
        }
123
124
        $scheme = parse_url($ev->getProcessedUrl(), PHP_URL_SCHEME);
125
        if (!in_array($scheme, self::$supportedSchemes, true)) {
126
            return;
127
        }
128
129
        $rfs = $ev->getRemoteFilesystem();
130
        $curlrfs = new CurlRemoteFilesystem(
131
            $this->io,
132
            $this->config,
133
            $rfs->getOptions()
134
        );
135
        $ev->setRemoteFilesystem($curlrfs);
136
    }
137
138 1
    public function prefetchComposerRepositories()
139
    {
140 1
        if ($this->disabled) {
141 1
            return;
142
        }
143 1
        if ($this->cached) {
144
            return;
145
        }
146 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...
147 1
        foreach ($repos as $label => $repo) {
148
            if (isset($repo['type']) && $repo['type'] === 'composer') {
149
                if (!empty($repo['force-lazy-providers'])) {
150
                    continue;
151
                }
152
153
                if (substr($repo['url'], 0, 6) !== 'https?') {
154
                    $scheme = parse_url($repo['url'], PHP_URL_SCHEME);
155
                    if (!in_array($scheme, self::$supportedSchemes, true)) {
156
                        continue;
157
                    }
158
                }
159
160
                $r = new ParallelizedComposerRepository($repo, $this->io, $this->config);
161
                $r->prefetch();
162
            }
163
        }
164 1
        $this->cached = true;
165 1
    }
166
167
    /**
168
     * pre-fetch parallel by curl_multi
169
     */
170 1
    public function onPostDependenciesSolving(Installer\InstallerEvent $ev)
171
    {
172 1
        if ($this->disabled) {
173 1
            return;
174
        }
175 1
        $prefetcher = new Prefetcher;
176 1
        $prefetcher->fetchAllFromOperations(
177 1
            $this->io,
178 1
            $this->config,
179 1
            $ev->getOperations()
180
        );
181 1
    }
182
183 2
    public function disable()
184
    {
185 2
        $this->disabled = true;
186 2
    }
187
188 1
    public function isDisabled()
189
    {
190 1
        return $this->disabled;
191
    }
192
193
    public function deactivate(Composer $composer, IO\IOInterface $io)
0 ignored issues
show
Unused Code introduced by
The parameter $composer is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $io is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
194
    {
195
    }
196
197
    public function uninstall(Composer $composer, IO\IOInterface $io)
0 ignored issues
show
Unused Code introduced by
The parameter $composer is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $io is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
198
    {
199
    }
200
}
201