Passed
Pull Request — master (#54)
by Alexander
12:39
created

Package::getAutoload()   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
c 0
b 0
f 0
rs 10
cc 1
nc 1
nop 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 require-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 mixed alternatives array or path to config
150
     */
151
    public function getAlternatives()
152
    {
153
        return $this->getExtraValue(self::EXTRA_ALTERNATIVES_OPTION_NAME);
154
    }
155
156
    /**
157
     * Get extra configuration value or default
158
     *
159
     * @param string $key key to look for in extra configuration
160
     * @param mixed $default default to return if there's no extra configuration value
161
     * @return mixed extra configuration value or default
162
     */
163
    private function getExtraValue(string $key, $default = null)
164
    {
165
        return $this->getExtra()[$key] ?? $default;
166
    }
167
168
    /**
169
     * @return array extra configuration array
170
     */
171
    private function getExtra(): array
172
    {
173
        return $this->getRawValue('extra') ?? $this->package->getExtra();
174
    }
175
176
    /**
177
     * @param string $name option name
178
     * @return mixed raw value from composer.json if available
179
     */
180
    private function getRawValue(string $name)
181
    {
182
        return $this->data[$name] ?? null;
183
    }
184
185
    /**
186
     * @return array composer.json contents as array
187
     * @throws \JsonException
188
     */
189
    private function readRawData(): array
190
    {
191
        $path = $this->preparePath('composer.json');
192
        if (file_exists($path)) {
193
            return json_decode(file_get_contents($path), true, 512, JSON_THROW_ON_ERROR);
194
        }
195
196
        return [];
197
    }
198
199
    /**
200
     * Builds path inside of a package.
201
     *
202
     * @param string $file
203
     * @return string absolute paths will stay untouched
204
     */
205
    public function preparePath(string $file): string
206
    {
207
        if (0 === strncmp($file, '$', 1)) {
208
            return $file;
209
        }
210
211
        $skippable = 0 === strncmp($file, '?', 1) ? '?' : '';
212
        if ($skippable) {
213
            $file = substr($file, 1);
214
        }
215
216
        if (!$this->filesystem->isAbsolutePath($file)) {
217
            $prefix = $this->isRoot()
218
                ? $this->baseDir
219
                : $this->vendorDir . '/' . $this->getPrettyName();
220
            $file = $prefix . '/' . $file;
221
        }
222
223
        return $skippable . $this->filesystem->normalizePath($file);
224
    }
225
226
    public function getVendorDir(): string
227
    {
228
        return $this->vendorDir;
229
    }
230
231
    public function getBaseDir(): string
232
    {
233
        return $this->baseDir;
234
    }
235
}
236