Completed
Push — master ( 580007...3ce141 )
by
unknown
9s
created

CheckComposerUpdatesTask   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 167
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 11
dl 0
loc 167
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A run() 0 14 2
B getPackages() 0 27 3
A getInstalledConstraint() 0 13 2
A isAllowedType() 0 6 1
A message() 0 8 2
A setComposerLoader() 0 5 1
A getComposerLoader() 0 4 1
A setUpdateChecker() 0 5 1
A getUpdateChecker() 0 4 1
1
<?php
2
3
use BringYourOwnIdeas\Maintenance\Tasks\UpdatePackageInfo;
4
use BringYourOwnIdeas\Maintenance\Util\ComposerLoader;
5
use BringYourOwnIdeas\UpdateChecker\UpdateChecker;
6
use Composer\Composer;
7
use Composer\Package\Link;
8
use Composer\Repository\ArrayRepository;
9
use Composer\Repository\BaseRepository;
10
use Composer\Repository\CompositeRepository;
11
12
/**
13
 * Task which does the actual checking of updates
14
 *
15
 * Originally from https://github.com/XploreNet/silverstripe-composerupdates
16
 *
17
 * @author Matt Dwen
18
 * @license MIT
19
 */
20
class CheckComposerUpdatesTask extends BuildTask
0 ignored issues
show
Coding Style Compatibility introduced by spekulatius
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
21
{
22
    /**
23
     * @var string
24
     */
25
    protected $title = 'Composer update checker';
26
27
    /**
28
     * @var string
29
     */
30
    protected $description = 'Checks if any composer dependencies can be updated.';
31
32
    private static $dependencies = [
0 ignored issues
show
Unused Code introduced by Robbie Averill
The property $dependencies 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...
33
        'ComposerLoader' => '%$BringYourOwnIdeas\\Maintenance\\Util\\ComposerLoader',
34
        'UpdateChecker' => '%$BringYourOwnIdeas\\UpdateChecker\\UpdateChecker',
35
    ];
36
37
    /**
38
     * @var ComposerLoader
39
     */
40
    protected $composerLoader;
41
42
    /**
43
     * @var UpdateChecker
44
     */
45
    protected $updateChecker;
46
47
    /**
48
     * Runs the actual steps to verify if there are updates available
49
     *
50
     * @param SS_HTTPRequest $request
51
     */
52
    public function run($request)
53
    {
54
        $packages = $this->getPackages();
55
56
        // Run through the packages and check each for updates
57
        foreach ($packages as $packageData) {
58
            $this->getUpdateChecker()->checkForUpdates(
59
                $packageData['package'],
60
                $packageData['constraint']
61
            );
62
        }
63
64
        $this->message('The task finished running. You can find the updated information in the database now.');
65
    }
66
67
    /**
68
     * Retrieve an array of primary composer dependencies from composer.json.
69
     *
70
     * Packages are filtered by allowed type.
71
     *
72
     * @return array[]
73
     */
74
    protected function getPackages()
75
    {
76
        /** @var Composer $composer */
77
        $composer = $this->getComposerLoader()->getComposer();
78
79
        /** @var BaseRepository $repository */
80
        $repository = new CompositeRepository([
81
            new ArrayRepository([$composer->getPackage()]),
82
            $composer->getRepositoryManager()->getLocalRepository(),
83
        ]);
84
85
        $packages = [];
86
        foreach ($repository->getPackages() as $package) {
87
            // Filter out packages that are not "allowed types"
88
            if (!$this->isAllowedType($package->getType())) {
89
                continue;
90
            }
91
92
            // Find the constraint used for installation
93
            $constraint = $this->getInstalledConstraint($repository, $package->getName());
94
            $packages[$package->getName()] = [
95
                'constraint' => $constraint,
96
                'package' => $package,
97
            ];
98
        }
99
        return $packages;
100
    }
101
102
    /**
103
     * Find all dependency constraints for the given package in the current repository and return the strictest one
104
     *
105
     * @param BaseRepository $repository
106
     * @param string $packageName
107
     * @return string
108
     */
109
    protected function getInstalledConstraint(BaseRepository $repository, $packageName)
110
    {
111
        $constraints = [];
112
        foreach ($repository->getDependents($packageName) as $dependent) {
113
            /** @var Link $link */
114
            list (, $link) = $dependent;
115
            $constraints[] = $link->getPrettyConstraint();
116
        }
117
118
        usort($constraints, 'version_compare');
119
120
        return array_pop($constraints);
121
    }
122
123
    /**
124
     * Check whether the package type is "allowed", which will include it in reports. If the type is not allowed
125
     * then the package will be skipped.
126
     *
127
     * @param string $type
128
     * @return bool
129
     */
130
    protected function isAllowedType($type)
131
    {
132
        $allowedTypes = (array) Config::inst()->get(UpdatePackageInfo::class, 'allowed_types');
133
134
        return in_array($type, $allowedTypes);
135
    }
136
137
    /**
138
     * prints a message during the run of the task
139
     *
140
     * @param string $text
141
     */
142
    protected function message($text)
143
    {
144
        if (!Director::is_cli()) {
145
            $text = '<p>' . $text . '</p>';
146
        }
147
148
        echo $text . PHP_EOL;
149
    }
150
151
    /**
152
     * @param ComposerLoader $composerLoader
153
     * @return $this
154
     */
155
    public function setComposerLoader(ComposerLoader $composerLoader)
156
    {
157
        $this->composerLoader = $composerLoader;
158
        return $this;
159
    }
160
161
    /**
162
     * @return ComposerLoader
163
     */
164
    public function getComposerLoader()
165
    {
166
        return $this->composerLoader;
167
    }
168
169
    /**
170
     * @param UpdateChecker $updateChecker
171
     * @return $this
172
     */
173
    public function setUpdateChecker(UpdateChecker $updateChecker)
174
    {
175
        $this->updateChecker = $updateChecker;
176
        return $this;
177
    }
178
179
    /**
180
     * @return UpdateChecker
181
     */
182
    public function getUpdateChecker()
183
    {
184
        return $this->updateChecker;
185
    }
186
}
187