Completed
Pull Request — master (#54)
by Hiraku
06:18
created

ParallelDownloader::filterPackages()   C

Complexity

Conditions 7
Paths 18

Size

Total Lines 34
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 7.0035

Importance

Changes 3
Bugs 1 Features 0
Metric Value
c 3
b 1
f 0
dl 0
loc 34
ccs 23
cts 24
cp 0.9583
rs 6.7272
cc 7
eloc 25
nc 18
nop 2
crap 7.0035
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\Package;
10
use Composer\IO;
11
use Composer\Config as CConfig;
12
13
/**
14
 *
15
 */
16
class ParallelDownloader
17
{
18
    /** @var IO/IOInterface */
19
    protected $io;
20
21
    /** @var CConfig */
22
    protected $config;
23
24
    /** @var int */
25
    protected $totalCnt = 0;
26
    protected $successCnt = 0;
27
    protected $skippedCnt = 0;
28
    protected $failureCnt = 0;
29
30 4
    public function __construct(IO\IOInterface $io, CConfig $config)
31
    {
32 4
        $this->io = $io;
33 4
        $this->config = $config;
34 4
    }
35
36
    /**
37
     * @param Package\PackageInterface[] $packages
38
     * @param array $pluginConfig
39
     * @return void
40
     */
41 3
    public function download(array $packages, array $pluginConfig)
42
    {
43 3
        $multi = new CurlMulti($pluginConfig['maxConnections']);
44 3
        $multi->setupShareHandler($pluginConfig['pipeline']);
45 3
46 3
        $this->totalCnt = count($packages);
47 3
        $this->successCnt = $this->skippedCnt = $this->failureCnt = 0;
48
        $this->io->write("    Prefetch start: <comment>total: $this->totalCnt</comment>");
49 3
50
        $multi->setTargets($this->filterPackages($packages, $pluginConfig));
51 3
52 3
        do {
53 3
            $multi->setupEventLoop();
54 3
            $multi->wait();
55 3
56
            $result = $multi->getFinishedResults();
57 3
            $this->successCnt += $result['successCnt'];
58
            $this->failureCnt += $result['failureCnt'];
59
            foreach ($result['results'] as $url) {
60 3
                $this->io->write($this->makeDownloadingText($url));
61 2
            }
62 2
        } while ($multi->remain());
63
64 2
        $this->io->write(
65 2
            "    Finished: <comment>success:$this->successCnt,"
66 2
            . "skipped:$this->skippedCnt, failure:$this->failureCnt,"
67
            . "total: $this->totalCnt</comment>"
68 2
        );
69
    }
70 2
71 2
    /**
72 2
     * @param Package\PackageInterface[] $packages
73 2
     * @param string[] $pluginConfig
74 2
     * @return array [{src: Aspects\HttpGetRequest, dest: OutputFile}]
75
     */
76
    private function filterPackages(array $packages, array $pluginConfig)
77
    {
78 3
        $cachedir = rtrim($this->config->get('cache-files-dir'), '\/');
79 3
        $targets = array();
80
        foreach ($packages as $p) {
81
            $url = $p->getDistUrl();
82 3
            if (!$url) {
83 1
                ++$this->skippedCnt;
84 1
                continue;
85
            }
86
            if ($p->getDistMirrors()) {
87 2
                $url = current($p->getDistUrls());
88 2
            }
89
            $host = parse_url($url, PHP_URL_HOST) ?: '';
90
            $src = Factory::getHttpGetRequest($host, $url, $this->io, $this->config, $pluginConfig);
91
            if (in_array($p->getName(), $pluginConfig['privatePackages'])) {
92
                $src->maybePublic = false;
93 2
            } else {
94 2
                $src->maybePublic = (bool)preg_match('%^(?:https|git)://github\.com%', $p->getSourceUrl());
95 2
            }
96 2
            // make file resource
97 2
            $filepath = $cachedir
98 2
                . DIRECTORY_SEPARATOR
99 2
                . FileDownloaderDummy::getCacheKeyCompat($p, $src->getURL());
100 2
            if (file_exists($filepath)) {
101 2
                ++$this->skippedCnt;
102 1
                continue;
103 1
            }
104 1
            $dest = new OutputFile($filepath);
105 1
106
            $targets[] = compact('src', 'dest');
107 2
        }
108 2
        return $targets;
109 2
    }
110 2
111 2
    /**
112 2
     * @param string $url
113
     * @return string
114 2
     */
115
    private function makeDownloadingText($url)
116
    {
117 3
        $request = new Aspects\HttpGetRequest('example.com', $url, $this->io);
118
        $request->query = array();
119 3
        return "    <comment>$this->successCnt/$this->totalCnt</comment>:    {$request->getURL()}";
120
    }
121
}
122