Passed
Push — master ( f5390f...ff2936 )
by Alexander
02:09
created

Package::getFiles()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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