Completed
Push — master ( a6e986...36a29e )
by Andreas
10:44
created

PackageConverter::convertPackageToArray()   F

Complexity

Conditions 10
Paths 260

Size

Total Lines 45
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 45
rs 3.1304
c 1
b 0
f 0
cc 10
eloc 29
nc 260
nop 2

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
/**
4
 * This file is part of tenside/core.
5
 *
6
 * (c) Christian Schiffler <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 *
11
 * This project is provided in good faith and hope to be usable by anyone.
12
 *
13
 * @package    tenside/core
14
 * @author     Christian Schiffler <[email protected]>
15
 * @copyright  2015 Christian Schiffler <[email protected]>
16
 * @license    https://github.com/tenside/core/blob/master/LICENSE MIT
17
 * @link       https://github.com/tenside/core
18
 * @filesource
19
 */
20
21
namespace Tenside\Core\Composer;
22
23
use Composer\Package\CompletePackageInterface;
24
use Composer\Package\Link;
25
use Composer\Package\PackageInterface;
26
use Composer\Package\RootPackageInterface;
27
use Composer\Repository\RepositoryInterface;
28
use Tenside\Core\Util\JsonArray;
29
30
/**
31
 * The main entry point.
32
 */
33
class PackageConverter
34
{
35
    /**
36
     * The root package of the installation.
37
     *
38
     * @var RootPackageInterface
39
     */
40
    private $rootPackage;
41
42
    /**
43
     * Create a new instance.
44
     *
45
     * @param RootPackageInterface $rootPackage The root package of the installation.
46
     */
47
    public function __construct(RootPackageInterface $rootPackage)
48
    {
49
        $this->rootPackage = $rootPackage;
50
    }
51
52
    /**
53
     * Create a new instance and return it.
54
     *
55
     * @param RootPackageInterface $rootPackage The root package of the installation.
56
     *
57
     * @return PackageConverter
58
     */
59
    public static function create(RootPackageInterface $rootPackage)
60
    {
61
        return new static($rootPackage);
62
    }
63
64
    /**
65
     * Convert a package version into string representation.
66
     *
67
     * @param PackageInterface $package       The package to extract the version from.
68
     *
69
     * @param bool             $fullReference Flag if the complete reference shall be added or an abbreviated form.
70
     *
71
     * @return string
72
     *
73
     * @throws \RuntimeException If the package is a dev package and does not have valid reference information.
74
     */
75
    public static function convertPackageVersion(PackageInterface $package, $fullReference = false)
76
    {
77
        $version = $package->getPrettyVersion();
78
79
        if ('dev' === $package->getStability()) {
80
            if (null === ($reference = $package->getDistReference())) {
81
                if (null === ($reference = $package->getSourceReference())) {
82
                    throw new \RuntimeException('Unable to determine reference for ' . $package->getPrettyName());
83
                }
84
            }
85
86
            $version .= '#' . (!$fullReference ? substr($reference, 0, 8) : $reference);
87
        }
88
89
        return $version;
90
    }
91
92
    /**
93
     * Convert a package to array information used by json API.
94
     *
95
     * @param PackageInterface $package        The package to convert.
96
     *
97
     * @param null|string      $upgradeVersion The package version to show as upgradable to.
98
     *
99
     * @return JsonArray
100
     */
101
    public function convertPackageToArray(PackageInterface $package, $upgradeVersion = null)
102
    {
103
        $name = $package->getPrettyName();
104
        $data = new JsonArray([
105
            'name'       => $name,
106
            'version'    => $this->convertPackageVersion($package),
107
            'constraint' => $this->getConstraint($name),
108
            'type'       => $package->getType(),
109
            'locked'     => $this->isLocked($name),
110
        ]);
111
112
        if (null !== ($releaseDate = $package->getReleaseDate())) {
113
            $data->set('time', $releaseDate->format(\DateTime::ATOM));
114
        }
115
116
        if (null !== $upgradeVersion) {
117
            $data->set('upgrade_version', $upgradeVersion);
118
        }
119
120
        if ($package instanceof CompletePackageInterface) {
121
            $data->set('description', $package->getDescription());
122
            $data->set('license', $package->getLicense());
123
            if ($keywords = $package->getKeywords()) {
124
                $data->set('keywords', $keywords);
125
            }
126
            if ($homepage = $package->getHomepage()) {
127
                $data->set('homepage', $homepage);
128
            }
129
            if ($authors = $package->getAuthors()) {
130
                $data->set('authors', $authors);
131
            }
132
            if ($support = $package->getSupport()) {
133
                $data->set('support', $support);
134
            }
135
            if ($extra = $package->getExtra()) {
136
                $data->set('extra', $extra);
137
            }
138
            $data->set('abandoned', $package->isAbandoned());
139
            if ($package->isAbandoned()) {
140
                $data->set('replacement', $package->getReplacementPackage());
141
            }
142
        }
143
144
        return $data;
145
    }
146
147
    /**
148
     * Convert the information of all packages in a repository to an array used by json API.
149
     *
150
     * @param RepositoryInterface $repository   The repository holding the packages to convert.
151
     *
152
     * @param bool                $requiredOnly If true, return only the packages added to the root package as require.
153
     *
154
     * @param null|JsonArray      $upgradeList  The package version to show as upgradable to.
155
     *
156
     * @return JsonArray
157
     */
158
    public function convertRepositoryToArray(
159
        RepositoryInterface $repository,
160
        $requiredOnly = false,
161
        JsonArray $upgradeList = null
162
    ) {
163
        $requires = $requiredOnly ? $this->rootPackage->getRequires() : false;
164
        $packages = new JsonArray();
165
        /** @var \Composer\Package\PackageInterface $package */
166
        foreach ($repository->getPackages() as $package) {
167
            $name = $package->getPrettyName();
168
            $esc  = $packages->escape($name);
169
            if (false === $requires || (isset($requires[$name]))) {
170
                $upgradeVersion = null;
171
                if ($upgradeList && $upgradeList->has($esc)) {
172
                    $upgradeVersion = $upgradeList->get($esc);
173
                }
174
                $packages->set(
175
                    $esc,
176
                    $this->convertPackageToArray($package, $upgradeVersion)->getData()
177
                );
178
            }
179
        }
180
181
        return $packages;
182
    }
183
184
    /**
185
     * Compare two packages by their names.
186
     *
187
     * @param array $left  The first package for comparison.
188
     *
189
     * @param array $right The second package for comparison.
190
     *
191
     * @return int
192
     *
193
     * @internal
194
     */
195
    public function packageCompare($left, $right)
196
    {
197
        return strnatcasecmp($left['name'], $right['name']);
198
    }
199
200
    /**
201
     * Check if a package is locked.
202
     *
203
     * @param string $packageName The name of the package to test.
204
     *
205
     * @return bool
206
     *
207
     * @see ComposerJson::isLocked()
208
     */
209
    private function isLocked($packageName)
210
    {
211
        $extra = $this->rootPackage->getExtra();
212
        return isset($extra['tenside']['version-locks'][$packageName]);
213
    }
214
215
    /**
216
     * Determine the constraint defined for a given package (if required via root project).
217
     *
218
     * @param string $packageName The name of the package to retrieve the constraint for.
219
     *
220
     * @return string|null
221
     */
222
    private function getConstraint($packageName)
223
    {
224
        $requires = $this->rootPackage->getRequires();
225
        if (isset($requires[$packageName])) {
226
            /** @var Link $link */
227
            $link = $requires[$packageName];
228
            return $link->getConstraint()->getPrettyString();
229
        }
230
231
        foreach ($requires as $link) {
232
            /** @var Link $link */
233
            if ($link->getTarget() == $packageName) {
234
                return $link->getConstraint()->getPrettyString();
235
            }
236
        }
237
238
        return null;
239
    }
240
}
241