Completed
Pull Request — master (#19)
by Sullivan
06:00
created

VersionsCheck   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 141
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 11
Bugs 0 Features 0
Metric Value
wmc 16
c 11
b 0
f 0
lcom 1
cbo 9
dl 0
loc 141
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
B checkPackages() 0 37 5
A getOutput() 0 12 2
A versionCompare() 0 10 3
A getPackageDepends() 0 6 1
B createNotUpToDateOutput() 0 27 5
1
<?php
2
3
namespace SLLH\ComposerVersionsCheck;
4
5
use Composer\Composer;
6
use Composer\DependencyResolver\Pool;
7
use Composer\Package\LinkConstraint\VersionConstraint;
8
use Composer\Package\PackageInterface;
9
use Composer\Package\RootPackageInterface;
10
use Composer\Repository\ArrayRepository;
11
use Composer\Repository\WritableRepositoryInterface;
12
use Composer\Semver\Comparator;
13
use Composer\Semver\Constraint\Constraint;
14
15
/**
16
 * @author Sullivan Senechal <[email protected]>
17
 */
18
final class VersionsCheck
19
{
20
    /**
21
     * @var OutdatedPackage[]
22
     */
23
    private $outdatedPackages = array();
24
25
    /**
26
     * @var VersionConstraint|null
27
     */
28
    private $oldComparator = null;
29
30
    /**
31
     * @param ArrayRepository             $distRepository
32
     * @param WritableRepositoryInterface $localRepository
33
     * @param RootPackageInterface        $rootPackage
34
     */
35
    public function checkPackages(ArrayRepository $distRepository, WritableRepositoryInterface $localRepository, RootPackageInterface $rootPackage)
36
    {
37
        $pool = new Pool();
38
        $pool->addRepository($localRepository);
39
40
        $packages = $localRepository->getPackages();
41
        foreach ($packages as $package) {
42
            // Old composer versions BC
43
            $versionConstraint = class_exists('Composer\Semver\Constraint\Constraint')
44
                ? new Constraint('>', $package->getVersion())
45
                : new VersionConstraint('>', $package->getVersion())
0 ignored issues
show
Deprecated Code introduced by
The class Composer\Package\LinkConstraint\VersionConstraint has been deprecated with message: use Composer\Semver\Constraint\Constraint instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
46
            ;
47
48
            $higherPackages = $distRepository->findPackages($package->getName(), $versionConstraint);
49
50
            // Remove not stable packages if unwanted
51
            if (true === $rootPackage->getPreferStable()) {
52
                $higherPackages = array_filter($higherPackages, function (PackageInterface $package) {
53
                    return 'stable' === $package->getStability();
54
                });
55
            }
56
57
            // We got higher packages! Let's push it.
58
            if (count($higherPackages) > 0) {
59
                // PHP 5.3 BC
60
                $that = $this;
61
62
                // Sort packages by highest version to lowest
63
                usort($higherPackages, function (PackageInterface $p1, PackageInterface $p2) use ($that) {
64
                    return $that->versionCompare($p1->getVersion(), '<', $p2->getVersion());
65
                });
66
67
                // Push actual and last package on outdated array
68
                array_push($this->outdatedPackages, new OutdatedPackage($package, $higherPackages[0], $this->getPackageDepends($pool, $package)));
69
            }
70
        }
71
    }
72
73
    /**
74
     * @param bool $showDepends
75
     *
76
     * @return string
77
     */
78
    public function getOutput($showDepends = true)
79
    {
80
        $output = array();
81
82
        if (0 === count($this->outdatedPackages)) {
83
            $output[] = '<info>All packages are up to date.</info>';
84
        } else {
85
            $this->createNotUpToDateOutput($output, $showDepends);
86
        }
87
88
        return implode(PHP_EOL, $output).PHP_EOL;
89
    }
90
91
    /**
92
     * Version comparator bridge to handle BC with old composer versions.
93
     *
94
     * This method is public only for PHP 5.3 BC and SHOULD NOT be used.
95
     * Deprecate it and remove it on next major when PHP 5.3 support will be droped.
96
     *
97
     * @param string $version1
98
     * @param string $operator
99
     * @param string $version2
100
     *
101
     * @return bool
102
     */
103
    public function versionCompare($version1, $operator, $version2)
104
    {
105
        if (!class_exists('Composer\Semver\Comparator')) {
106
            $this->oldComparator = $this->oldComparator ?: new VersionConstraint('==', '1.0');
0 ignored issues
show
Deprecated Code introduced by
The class Composer\Package\LinkConstraint\VersionConstraint has been deprecated with message: use Composer\Semver\Constraint\Constraint instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
107
108
            return $this->oldComparator->versionCompare($version1, $version2, $operator);
109
        }
110
111
        return Comparator::compare($version1, $operator, $version2);
112
    }
113
114
    /**
115
     * @param Pool             $pool
116
     * @param PackageInterface $package
117
     *
118
     * @return PackageInterface[]
119
     */
120
    private function getPackageDepends(Pool $pool, PackageInterface $package)
121
    {
122
        return array_filter($pool->whatProvides($package->getName()), function (PackageInterface $dependsPackage) use ($package) {
123
            return $dependsPackage !== $package;
124
        });
125
    }
126
127
    /**
128
     * @param array $output
129
     * @param bool  $showDepends
130
     */
131
    private function createNotUpToDateOutput(array &$output, $showDepends = true)
132
    {
133
        $outdatedPackagesCount = count($this->outdatedPackages);
134
        $output[] = sprintf(
135
            '<warning>%d %s not up to date:</warning>',
136
            $outdatedPackagesCount,
137
            1 != $outdatedPackagesCount ? 'packages are' : 'package is'
138
        );
139
        $output[] = '';
140
141
        foreach ($this->outdatedPackages as $outdatedPackage) {
142
            $output[] = sprintf(
143
                '  - <info>%s</info> (<comment>%s</comment>) latest is <comment>%s</comment>',
144
                $outdatedPackage->getActual()->getPrettyName(),
145
                $outdatedPackage->getActual()->getPrettyVersion(),
146
                $outdatedPackage->getLast()->getPrettyVersion()
147
            );
148
149
            if (true === $showDepends) {
150
                foreach ($outdatedPackage->getDepends() as $depend) {
151
                    $output[] = sprintf('    Required by %s (%s)', $depend->getName(), '?');
152
                }
153
            }
154
155
            $output[] = '';
156
        }
157
    }
158
}
159