Completed
Push — master ( 4e4f6b...337813 )
by Andrii
12:30
created

Package::getDevRequires()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace hiqdev\composer\config;
4
5
use Composer\Composer;
6
use Composer\Package\CompletePackageInterface;
7
use Composer\Package\PackageInterface;
8
use Composer\Package\RootPackageInterface;
9
use Composer\Util\Filesystem;
10
11
/**
12
 * Class Package.
13
 * @author Andrii Vasyliev <[email protected]>
14
 */
15
class Package
16
{
17
    protected $package;
18
19
    /**
20
     * @var array composer.json raw data array
21
     */
22
    protected $data;
23
24
    /**
25
     * @var string absolute path to the root base directory
26
     */
27
    protected $baseDir;
28
29
    /**
30
     * @var string absolute path to vendor directory
31
     */
32
    protected $vendorDir;
33
34
    /**
35
     * @var Filesystem utility
36
     */
37
    protected $filesystem;
38
39
    public function __construct(PackageInterface $package, Composer $composer)
40
    {
41
        $this->package = $package;
42
        $this->composer = $composer;
0 ignored issues
show
Bug Best Practice introduced by
The property composer does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
43
    }
44
45
    /**
46
     * Collects package aliases.
47
     * @return array collected aliases
48
     */
49
    public function collectAliases(): array
50
    {
51
        $aliases = array_merge(
52
            $this->prepareAliases('psr-0'),
53
            $this->prepareAliases('psr-4')
54
        );
55
        if ($this->isRoot()) {
56
            $aliases = array_merge($aliases,
57
                $this->prepareAliases('psr-0', true),
58
                $this->prepareAliases('psr-4', true)
59
            );
60
        }
61
62
        return $aliases;
63
    }
64
65
    /**
66
     * Prepare aliases.
67
     * @param string 'psr-0' or 'psr-4'
0 ignored issues
show
Documentation Bug introduced by
The doc comment 'psr-0' at position 0 could not be parsed: Unknown type name ''psr-0'' at position 0 in 'psr-0'.
Loading history...
68
     * @return array
69
     */
70
    protected function prepareAliases($psr, $dev = false)
71
    {
72
        $autoload = $dev ? $this->getDevAutoload() : $this->getAutoload();
73
        if (empty($autoload[$psr])) {
74
            return [];
75
        }
76
77
        $aliases = [];
78
        foreach ($autoload[$psr] as $name => $path) {
79
            if (is_array($path)) {
80
                // ignore psr-4 autoload specifications with multiple search paths
81
                // we can not convert them into aliases as they are ambiguous
82
                continue;
83
            }
84
            $name = str_replace('\\', '/', trim($name, '\\'));
85
            $path = $this->preparePath($path);
86
            if ('psr-0' === $psr) {
87
                $path .= '/' . $name;
88
            }
89
            $aliases["@$name"] = $path;
90
        }
91
92
        return $aliases;
93
    }
94
95
    public function getPrettyName(): string
96
    {
97
        return $this->package->getPrettyName();
98
    }
99
100
    public function getVersion(): string
101
    {
102
        return $this->package->getVersion();
103
    }
104
105
    public function getFullPrettyVersion(): string
106
    {
107
        return $this->package->getFullPrettyVersion();
108
    }
109
110
    public function getSourceReference(): string
111
    {
112
        return $this->package->getSourceReference();
113
    }
114
115
    public function getDistReference(): string
116
    {
117
        return $this->package->getDistReference();
118
    }
119
120
    public function isComplete(): bool
121
    {
122
        return $this->package instanceof CompletePackageInterface;
123
    }
124
125
    public function isRoot(): bool
126
    {
127
        return $this->package instanceof RootPackageInterface;
128
    }
129
130
    public function getType(): string
131
    {
132
        return $this->getRawValue('type') ?? $this->package->getType();
133
    }
134
135
    public function getAutoload(): array
136
    {
137
        return $this->getRawValue('autoload') ?? $this->package->getAutoload();
138
    }
139
140
    public function getDevAutoload(): array
141
    {
142
        return $this->getRawValue('autoload-dev') ?? $this->package->getDevAutoload();
143
    }
144
145
    public function getRequires(): array
146
    {
147
        return $this->getRawValue('require') ?? $this->package->getRequires();
148
    }
149
150
    public function getDevRequires(): array
151
    {
152
        return $this->getRawValue('require-dev') ?? $this->package->getDevRequires();
153
    }
154
155
    public function getExtra(): array
156
    {
157
        return $this->getRawValue('extra') ?? $this->package->getExtra();
158
    }
159
160
    public function getRawValue(string $name)
161
    {
162
        if ($this->data === null) {
163
            $this->data = $this->readRawData();
164
        }
165
166
        return $this->data[$name] ?? null;
167
    }
168
169
    public function getRawData(): array
170
    {
171
        if ($this->data === null) {
172
            $this->data = $this->readRawData();
173
        }
174
175
        return $this->data;
176
    }
177
178
    /**
179
     * @return array
180
     */
181
    protected function readRawData(): array
182
    {
183
        $path = $this->preparePath('composer.json');
184
        if (file_exists($path)) {
185
            return json_decode(file_get_contents($path), true);
186
        }
187
188
        return [];
189
    }
190
191
    /**
192
     * Builds path inside of a package.
193
     * @param Package $package
194
     * @param mixed $path can be absolute or relative
195
     * @return string absolute paths will stay untouched
196
     */
197
    public function preparePath(string $file): string
198
    {
199
        if (0 === strncmp($file, '$', 1)) {
200
            return $file;
201
        }
202
203
        $skippable = 0 === strncmp($file, '?', 1) ? '?' : '';
204
        if ($skippable) {
205
            $file = substr($file, 1);
206
        }
207
208
209
        if (!$this->getFilesystem()->isAbsolutePath($file)) {
210
            $prefix = $this->isRoot()
211
                ? $this->getBaseDir()
212
                : $this->getVendorDir() . '/' . $this->getPrettyName();
213
            $file = $prefix . '/' . $file;
214
        }
215
216
        return $skippable . $this->getFilesystem()->normalizePath($file);
217
    }
218
219
    /**
220
     * Get absolute path to package base dir.
221
     * @return string
222
     */
223
    public function getBaseDir()
224
    {
225
        if (null === $this->baseDir) {
226
            $this->baseDir = dirname($this->getVendorDir());
227
        }
228
229
        return $this->baseDir;
230
    }
231
232
    /**
233
     * Get absolute path to composer vendor dir.
234
     * @return string
235
     */
236
    public function getVendorDir()
237
    {
238
        if (null === $this->vendorDir) {
239
            $dir = $this->composer->getConfig()->get('vendor-dir');
240
            $this->vendorDir = $this->getFilesystem()->normalizePath($dir);
241
        }
242
243
        return $this->vendorDir;
244
    }
245
246
    /**
247
     * Getter for filesystem utility.
248
     * @return Filesystem
249
     */
250
    public function getFilesystem()
251
    {
252
        if (null === $this->filesystem) {
253
            $this->filesystem = new Filesystem();
254
        }
255
256
        return $this->filesystem;
257
    }
258
}
259