Completed
Push — master ( f11a34...f2f137 )
by Christian
02:47
created

PackageConverter::packageCompare()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
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
 * @author     Andreas Schempp <[email protected]>
16
 * @copyright  2015 Christian Schiffler <[email protected]>
17
 * @license    https://github.com/tenside/core/blob/master/LICENSE MIT
18
 * @link       https://github.com/tenside/core
19
 * @filesource
20
 */
21
22
namespace Tenside\Core\Composer;
23
24
use Composer\Package\CompletePackageInterface;
25
use Composer\Package\Link;
26
use Composer\Package\PackageInterface;
27
use Composer\Package\RootPackageInterface;
28
use Composer\Repository\RepositoryInterface;
29
use Tenside\Core\Util\JsonArray;
30
31
/**
32
 * The main entry point.
33
 */
34
class PackageConverter
35
{
36
    /**
37
     * The root package of the installation.
38
     *
39
     * @var RootPackageInterface
40
     */
41
    private $rootPackage;
42
43
    /**
44
     * Create a new instance.
45
     *
46
     * @param RootPackageInterface $rootPackage The root package of the installation.
47
     */
48
    public function __construct(RootPackageInterface $rootPackage)
49
    {
50
        $this->rootPackage = $rootPackage;
51
    }
52
53
    /**
54
     * Create a new instance and return it.
55
     *
56
     * @param RootPackageInterface $rootPackage The root package of the installation.
57
     *
58
     * @return PackageConverter
59
     */
60
    public static function create(RootPackageInterface $rootPackage)
61
    {
62
        return new static($rootPackage);
63
    }
64
65
    /**
66
     * Convert a package version into string representation.
67
     *
68
     * @param PackageInterface $package       The package to extract the version from.
69
     *
70
     * @param bool             $fullReference Flag if the complete reference shall be added or an abbreviated form.
71
     *
72
     * @return string
73
     *
74
     * @throws \RuntimeException If the package is a dev package and does not have valid reference information.
75
     */
76
    public static function convertPackageVersion(PackageInterface $package, $fullReference = false)
77
    {
78
        $version = $package->getPrettyVersion();
79
80
        if ('dev' === $package->getStability()) {
81
            if (null === ($reference = $package->getDistReference())) {
82
                if (null === ($reference = $package->getSourceReference())) {
83
                    throw new \RuntimeException('Unable to determine reference for ' . $package->getPrettyName());
84
                }
85
            }
86
87
            $version .= '#' . (!$fullReference ? substr($reference, 0, 8) : $reference);
88
        }
89
90
        return $version;
91
    }
92
93
    /**
94
     * Convert a package to array information used by json API.
95
     *
96
     * @param PackageInterface      $package The package to convert.
97
     *
98
     * @param null|PackageInterface $upgrade The package to show as upgradable to.
99
     *
100
     * @return JsonArray
101
     */
102
    public function convertPackageToArray(PackageInterface $package, PackageInterface $upgrade = null)
103
    {
104
        $name = $package->getPrettyName();
105
        $data = new JsonArray([
106
            'name'       => $name,
107
            'version'    => $this->convertPackageVersion($package),
108
            'constraint' => $this->getConstraint($name),
109
            'type'       => $package->getType(),
110
            'locked'     => $this->isLocked($name),
111
        ]);
112
113
        if (null !== ($releaseDate = $package->getReleaseDate())) {
114
            $data->set('time', $releaseDate->format(\DateTime::ATOM));
115
        }
116
117
        if (null !== $upgrade) {
118
            $data->set('upgrade_version', $upgrade->getPrettyVersion());
119
            if (null !== ($upgradeReleaseDate = $upgrade->getReleaseDate())) {
120
                $data->set('upgrade_time', $upgradeReleaseDate->format(\DateTime::ATOM));
121
            }
122
        }
123
124
        if ($package instanceof CompletePackageInterface) {
125
            $this->convertCompletePackage($package, $data);
126
        }
127
128
        return $data;
129
    }
130
131
    /**
132
     * Convert the information of all packages in a repository to an array used by json API.
133
     *
134
     * @param RepositoryInterface $repository   The repository holding the packages to convert.
135
     *
136
     * @param bool                $requiredOnly If true, return only the packages added to the root package as require.
137
     *
138
     * @param RepositoryInterface $upgradeList  The packages available as upgrades.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $upgradeList not be null|RepositoryInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
139
     *
140
     * @return JsonArray
141
     */
142
    public function convertRepositoryToArray(
143
        RepositoryInterface $repository,
144
        $requiredOnly = false,
145
        RepositoryInterface $upgradeList = null
146
    ) {
147
        $requires = $requiredOnly ? $this->rootPackage->getRequires() : false;
148
        $packages = new JsonArray();
149
        /** @var \Composer\Package\PackageInterface $package */
150
        foreach ($repository->getPackages() as $package) {
151
            $name = $package->getPrettyName();
152
            $esc  = $packages->escape($name);
153
            if (false === $requires || (isset($requires[$name]))) {
154
                $upgradePkg = null;
155
                if ($upgradeList) {
156
                    $upgradePkg = $upgradeList->findPackage($name, '*');
157
                }
158
                $packages->set(
159
                    $esc,
160
                    $this->convertPackageToArray($package, $upgradePkg)->getData()
161
                );
162
            }
163
        }
164
165
        return $packages;
166
    }
167
168
    /**
169
     * Check if a package is locked.
170
     *
171
     * @param string $packageName The name of the package to test.
172
     *
173
     * @return bool
174
     *
175
     * @see ComposerJson::isLocked()
176
     */
177
    private function isLocked($packageName)
178
    {
179
        $extra = $this->rootPackage->getExtra();
180
        return isset($extra['tenside']['version-locks'][$packageName]);
181
    }
182
183
    /**
184
     * Determine the constraint defined for a given package (if required via root project).
185
     *
186
     * @param string $packageName The name of the package to retrieve the constraint for.
187
     *
188
     * @return string|null
189
     */
190
    private function getConstraint($packageName)
191
    {
192
        $requires = $this->rootPackage->getRequires();
193
        if (isset($requires[$packageName])) {
194
            /** @var Link $link */
195
            $link = $requires[$packageName];
196
            return $link->getConstraint()->getPrettyString();
197
        }
198
199
        foreach ($requires as $link) {
200
            /** @var Link $link */
201
            if ($link->getTarget() == $packageName) {
202
                return $link->getConstraint()->getPrettyString();
203
            }
204
        }
205
206
        return null;
207
    }
208
209
    /**
210
     * Convert the data of a complete package to the passed json array.
211
     *
212
     * @param CompletePackageInterface $package The package to process.
213
     *
214
     * @param JsonArray                $data    The json array to push the data to.
215
     *
216
     * @return void
217
     */
218
    private function convertCompletePackage(CompletePackageInterface $package, $data)
219
    {
220
        $data->set('description', $package->getDescription());
221
        $data->set('license', $package->getLicense());
222
        if ($keywords = $package->getKeywords()) {
223
            $data->set('keywords', $keywords);
224
        }
225
        if ($homepage = $package->getHomepage()) {
226
            $data->set('homepage', $homepage);
227
        }
228
        if ($authors = $package->getAuthors()) {
229
            $data->set('authors', $authors);
230
        }
231
        if ($support = $package->getSupport()) {
232
            $data->set('support', $support);
233
        }
234
        if ($extra = $package->getExtra()) {
235
            $data->set('extra', $extra);
236
        }
237
        $data->set('abandoned', $package->isAbandoned());
238
        if ($package->isAbandoned()) {
239
            $data->set('replacement', $package->getReplacementPackage());
240
        }
241
    }
242
}
243