Passed
Pull Request — master (#8)
by Dmitriy
11:32 queued 10s
created

Package::getSourceReference()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Yiisoft\Composer\Config;
4
5
use Composer\Package\CompletePackageInterface;
6
use Composer\Package\PackageInterface;
7
use Composer\Package\RootPackageInterface;
8
use Composer\Util\Filesystem;
9
10
/**
11
 * Class Package.
12
 */
13
class Package
14
{
15
    public const EXTRA_FILES_OPTION_NAME = 'config-plugin';
16
    public const EXTRA_DEV_FILES_OPTION_NAME = 'config-plugin-dev';
17
    public const EXTRA_OUTPUT_DIR_OPTION_NAME = 'config-plugin-output-dir';
18
    public const EXTRA_ALTERNATIVES_OPTION_NAME = 'config-plugin-alternatives';
19
20
    private PackageInterface $package;
21
22
    /**
23
     * @var array composer.json raw data array
24
     */
25
    private array $data;
26
27
    /**
28
     * @var string absolute path to the root base directory
29
     */
30
    private string $baseDir;
31
32
    /**
33
     * @var string absolute path to vendor directory
34
     */
35
    private string $vendorDir;
36
37
    /**
38
     * @var Filesystem utility
39
     */
40
    private Filesystem $filesystem;
41
42
    public function __construct(PackageInterface $package, string $vendorDir)
43
    {
44
        $this->package = $package;
45
        $this->filesystem = new Filesystem();
46
47
        $this->vendorDir = $this->filesystem->normalizePath($vendorDir);
48
        $this->baseDir = dirname($this->vendorDir);
49
        $this->data = $this->readRawData();
50
    }
51
52
    /**
53
     * @return string package pretty name, like: vendor/name
54
     */
55
    public function getPrettyName(): string
56
    {
57
        return $this->package->getPrettyName();
58
    }
59
60
    /**
61
     * @return string package version, like: 3.0.16.0, 9999999-dev
62
     */
63
    public function getVersion(): string
64
    {
65
        return $this->package->getVersion();
66
    }
67
68
    /**
69
     * @return string package CVS revision, like: 3a4654ac9655f32888efc82fb7edf0da517d8995
70
     */
71
    public function getSourceReference(): ?string
72
    {
73
        return $this->package->getSourceReference();
74
    }
75
76
    /**
77
     * @return string package dist revision, like: 3a4654ac9655f32888efc82fb7edf0da517d8995
78
     */
79
    public function getDistReference(): ?string
80
    {
81
        return $this->package->getDistReference();
82
    }
83
84
    /**
85
     * @return bool is package complete
86
     */
87
    public function isComplete(): bool
88
    {
89
        return $this->package instanceof CompletePackageInterface;
90
    }
91
92
    /**
93
     * @return bool is this a root package
94
     */
95
    public function isRoot(): bool
96
    {
97
        return $this->package instanceof RootPackageInterface;
98
    }
99
100
    /**
101
     * @return array autoload configuration array
102
     */
103
    public function getAutoload(): array
104
    {
105
        return $this->getRawValue('autoload') ?? $this->package->getAutoload();
106
    }
107
108
    /**
109
     * @return array autoload-dev configuration array
110
     */
111
    public function getDevAutoload(): array
112
    {
113
        return $this->getRawValue('autoload-dev') ?? $this->package->getDevAutoload();
114
    }
115
116
    /**
117
     * @return array require configuration array
118
     */
119
    public function getRequires(): array
120
    {
121
        return $this->getRawValue('require') ?? $this->package->getRequires();
122
    }
123
124
    /**
125
     * @return array requre-dev configuration array
126
     */
127
    public function getDevRequires(): array
128
    {
129
        return $this->getRawValue('require-dev') ?? $this->package->getDevRequires();
130
    }
131
132
    /**
133
     * @return array files array
134
     */
135
    public function getFiles(): array
136
    {
137
        return $this->getExtraValue(self::EXTRA_FILES_OPTION_NAME, []);
138
    }
139
140
    /**
141
     * @return array dev-files array
142
     */
143
    public function getDevFiles(): array
144
    {
145
        return $this->getExtraValue(self::EXTRA_DEV_FILES_OPTION_NAME, []);
146
    }
147
148
    /**
149
     * @return array output-dir option
150
     */
151
    public function getOutputDir(): ?string
152
    {
153
        return $this->getExtraValue(self::EXTRA_OUTPUT_DIR_OPTION_NAME);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getExtraVa...OUTPUT_DIR_OPTION_NAME) returns the type array which is incompatible with the type-hinted return null|string.
Loading history...
154
    }
155
156
    /**
157
     * @return mixed alternatives array or path to config
158
     */
159
    public function getAlternatives()
160
    {
161
        return $this->getExtraValue(self::EXTRA_ALTERNATIVES_OPTION_NAME);
162
    }
163
164
    /**
165
     * @return array alternatives array
166
     */
167
    private function getExtraValue($key, $default = null)
168
    {
169
        return $this->getExtra()[$key] ?? $default;
170
    }
171
172
    /**
173
     * @return array extra configuration array
174
     */
175
    private function getExtra(): array
176
    {
177
        return $this->getRawValue('extra') ?? $this->package->getExtra();
178
    }
179
180
    /**
181
     * @param string $name option name
182
     * @return mixed raw value from composer.json if available
183
     */
184
    private function getRawValue(string $name)
185
    {
186
        return $this->data[$name] ?? null;
187
    }
188
189
    /**
190
     * @return array composer.json contents as array
191
     * @throws \JsonException
192
     */
193
    private function readRawData(): array
194
    {
195
        $path = $this->preparePath('composer.json');
196
        if (file_exists($path)) {
197
            return json_decode(file_get_contents($path), true, 512, JSON_THROW_ON_ERROR);
198
        }
199
200
        return [];
201
    }
202
203
    /**
204
     * Builds path inside of a package.
205
     *
206
     * @param string $file
207
     * @return string absolute paths will stay untouched
208
     */
209
    public function preparePath(string $file): string
210
    {
211
        if (0 === strncmp($file, '$', 1)) {
212
            return $file;
213
        }
214
215
        $skippable = 0 === strncmp($file, '?', 1) ? '?' : '';
216
        if ($skippable) {
217
            $file = substr($file, 1);
218
        }
219
220
        if (!$this->filesystem->isAbsolutePath($file)) {
221
            $prefix = $this->isRoot()
222
                ? $this->baseDir
223
                : $this->vendorDir . '/' . $this->getPrettyName();
224
            $file = $prefix . '/' . $file;
225
        }
226
227
        return $skippable . $this->filesystem->normalizePath($file);
228
    }
229
230
    public function getVendorDir(): string
231
    {
232
        return $this->vendorDir;
233
    }
234
235
    public function getBaseDir(): string
236
    {
237
        return $this->baseDir;
238
    }
239
}
240