Completed
Push — master ( f7351b...ceb96e )
by Sullivan
04:36 queued 01:52
created

VersionsCheck::checkPackages()   B

Complexity

Conditions 5
Paths 9

Size

Total Lines 31
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 7
Bugs 0 Features 0
Metric Value
c 7
b 0
f 0
dl 0
loc 31
rs 8.439
cc 5
eloc 14
nc 9
nop 3
1
<?php
2
3
namespace SLLH\ComposerVersionsCheck;
4
5
use Composer\Package\Link;
6
use Composer\Package\LinkConstraint\VersionConstraint;
7
use Composer\Package\PackageInterface;
8
use Composer\Package\RootPackageInterface;
9
use Composer\Repository\ArrayRepository;
10
use Composer\Repository\WritableRepositoryInterface;
11
use Composer\Semver\Comparator;
12
use Composer\Semver\Constraint\Constraint;
13
14
/**
15
 * @author Sullivan Senechal <[email protected]>
16
 */
17
final class VersionsCheck
18
{
19
    /**
20
     * @var OutdatedPackage[]
21
     */
22
    private $outdatedPackages = array();
23
24
    /**
25
     * @var VersionConstraint|null
26
     */
27
    private $oldComparator = null;
0 ignored issues
show
Unused Code introduced by
The property $oldComparator is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
28
29
    /**
30
     * @param ArrayRepository             $distRepository
31
     * @param WritableRepositoryInterface $localRepository
32
     * @param RootPackageInterface        $rootPackage
33
     */
34
    public function checkPackages(ArrayRepository $distRepository, WritableRepositoryInterface $localRepository, RootPackageInterface $rootPackage)
35
    {
36
        $packages = $localRepository->getPackages();
37
        foreach ($packages as $package) {
38
            // Old composer versions BC
39
            $versionConstraint = class_exists('Composer\Semver\Constraint\Constraint')
40
                ? new Constraint('>', $package->getVersion())
41
                : 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...
42
            ;
43
44
            $higherPackages = $distRepository->findPackages($package->getName(), $versionConstraint);
45
46
            // Remove not stable packages if unwanted
47
            if (true === $rootPackage->getPreferStable()) {
48
                $higherPackages = array_filter($higherPackages, function (PackageInterface $package) {
49
                    return 'stable' === $package->getStability();
50
                });
51
            }
52
53
            // We got higher packages! Let's push it.
54
            if (count($higherPackages) > 0) {
55
                // Sort packages by highest version to lowest
56
                usort($higherPackages, function (PackageInterface $p1, PackageInterface $p2) {
57
                    return Comparator::compare($p1->getVersion(), '<', $p2->getVersion());
58
                });
59
60
                // Push actual and last package on outdated array
61
                array_push($this->outdatedPackages, new OutdatedPackage($package, $higherPackages[0], $this->getPackageDepends($localRepository, $package)));
62
            }
63
        }
64
    }
65
66
    /**
67
     * @param bool $showDepends
68
     *
69
     * @return string
70
     */
71
    public function getOutput($showDepends = true)
72
    {
73
        $output = array();
74
75
        if (0 === count($this->outdatedPackages)) {
76
            $output[] = '<info>All packages are up to date.</info>';
77
        } else {
78
            $this->createNotUpToDateOutput($output, $showDepends);
79
        }
80
81
        return implode(PHP_EOL, $output).PHP_EOL;
82
    }
83
84
    /**
85
     * @param WritableRepositoryInterface $localRepository
86
     * @param PackageInterface            $needle
87
     *
88
     * @return Link[]
89
     */
90
    private function getPackageDepends(WritableRepositoryInterface $localRepository, PackageInterface $needle)
91
    {
92
        $depends = array();
93
94
        foreach ($localRepository->getPackages() as $package) {
95
            // Skip root package
96
            if ($package instanceof RootPackageInterface) {
97
                continue;
98
            }
99
100
            foreach ($package->getRequires() as $link) {
101
                if ($link->getTarget() === $needle->getName() && !in_array($link, $depends, true)) {
102
                    $depends[] = $link;
103
                }
104
            }
105
        }
106
107
        return $depends;
108
    }
109
110
    /**
111
     * @param array $output
112
     * @param bool  $showLinks
113
     */
114
    private function createNotUpToDateOutput(array &$output, $showLinks = true)
115
    {
116
        $outdatedPackagesCount = count($this->outdatedPackages);
117
        $output[] = sprintf(
118
            '<warning>%d %s not up to date:</warning>',
119
            $outdatedPackagesCount,
120
            1 != $outdatedPackagesCount ? 'packages are' : 'package is'
121
        );
122
        $output[] = '';
123
124
        foreach ($this->outdatedPackages as $outdatedPackage) {
125
            $output[] = sprintf(
126
                '  - <info>%s</info> (<comment>%s</comment>) latest is <comment>%s</comment>',
127
                $outdatedPackage->getActual()->getPrettyName(),
128
                $outdatedPackage->getActual()->getPrettyVersion(),
129
                $outdatedPackage->getLast()->getPrettyVersion()
130
            );
131
132
            if (true === $showLinks) {
133
                foreach ($outdatedPackage->getLinks() as $depend) {
134
                    $output[] = sprintf(
135
                        '    Required by <info>%s</info> (<comment>%s</comment>)',
136
                        $depend->getSource(),
137
                        $depend->getPrettyConstraint()
138
                    );
139
                }
140
            }
141
142
            $output[] = '';
143
        }
144
    }
145
}
146