Passed
Pull Request — master (#6)
by Dmitriy
10:56
created

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