Completed
Pull Request — master (#117)
by Hiraku
02:57
created

Plugin::prefetchComposerRepositories()   C

Complexity

Conditions 11
Paths 7

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 33.5738

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 26
ccs 9
cts 21
cp 0.4286
rs 5.2653
cc 11
eloc 17
nc 7
nop 0
crap 33.5738

How to fix   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 3
    public function activate(Composer $composer, IO\IOInterface $io)
0 ignored issues
show
Coding Style introduced by
activate uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
48
    {
49
        // @codeCoverageIgnoreStart
50
        // guard for self-update problem
51
        if (__CLASS__ !== 'Hirak\Prestissimo\Plugin') {
52
            return $this->disable();
53
        }
54
        // @codeCoverageIgnoreEnd
55
56
        // load all classes
57 3
        foreach (self::$pluginClasses as $class) {
58 3
            class_exists(__NAMESPACE__ . '\\' . $class);
59 3
        }
60
61 3
        $this->io = $io;
62 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...
63 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...
64
65 3
        foreach ($GLOBALS['argv'] as $arg) {
66
            switch ($arg) {
67 3
                case 'create-project':
68 3
                case 'update':
69 3
                case 'outdated':
70 3
                case 'require':
71
                    $this->prefetchComposerRepositories();
72
                    break 2;
73 3
                case 'install':
74
                    if (file_exists('composer.json') && !file_exists('composer.lock')) {
75
                        $this->prefetchComposerRepositories();
76
                    }
77
                    break 2;
78
            }
79 3
        }
80 3
    }
81
82 1
    public static function getSubscribedEvents()
83
    {
84
        return array(
85 1
            CPlugin\PluginEvents::PRE_FILE_DOWNLOAD => 'onPreFileDownload',
86 1
            Installer\InstallerEvents::POST_DEPENDENCIES_SOLVING => array(
87 1
                array('onPostDependenciesSolving', PHP_INT_MAX),
88 1
            ),
89 1
        );
90
    }
91
92
    /**
93
     * Keep-Alived file downloader
94
     */
95
    public function onPreFileDownload(CPlugin\PreFileDownloadEvent $ev)
96
    {
97
        if ($this->disabled) {
98
            return;
99
        }
100
        $rfs = $ev->getRemoteFilesystem();
101
        $curlrfs = new CurlRemoteFilesystem(
102
            $this->io,
103
            $this->config,
104
            $rfs->getOptions()
105
        );
106
        $ev->setRemoteFilesystem($curlrfs);
107
    }
108
109 1
    public function prefetchComposerRepositories()
110
    {
111 1
        if ($this->disabled) {
112 1
            return;
113
        }
114 1
        if ($this->cached) {
115
            return;
116
        }
117 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...
118 1
        foreach ($repos as $label => $repo) {
119
            if (isset($repo['type']) && $repo['type'] === 'composer') {
120
                if (isset($repo['force-lazy-providers']) && $repo['force-lazy-providers']) {
121
                    continue;
122
                }
123
                if ('http?://' === substr($repo['url'], 0, 8) && isset($repo['allow_ssl_downgrade']) && $repo['allow_ssl_downgrade']) {
124
                    $repo = array(
125
                        'type' => $repo['type'],
126
                        'url' => str_replace('https?://', 'https://', $repo['url']),
127
                    );
128
                }
129
                $r = new ParallelizedComposerRepository($repo, $this->io, $this->config);
130
                $r->prefetch();
131
            }
132 1
        }
133 1
        $this->cached = true;
134 1
    }
135
136
    /**
137
     * pre-fetch parallel by curl_multi
138
     */
139 1
    public function onPostDependenciesSolving(Installer\InstallerEvent $ev)
140
    {
141 1
        if ($this->disabled) {
142 1
            return;
143
        }
144 1
        $prefetcher = new Prefetcher;
145 1
        $prefetcher->fetchAllFromOperations(
146 1
            $this->io,
147 1
            $this->config,
148 1
            $ev->getOperations()
149 1
        );
150 1
    }
151
152 2
    public function disable()
153
    {
154 2
        $this->disabled = true;
155 2
    }
156
157 1
    public function isDisabled()
158
    {
159 1
        return $this->disabled;
160
    }
161
}
162