Skip to content

Commit fc560cf

Browse files
authored
Add option "source-directory"
1 parent 108d3bb commit fc560cf

9 files changed

Lines changed: 271 additions & 8 deletions

File tree

src/ComposerEventHandler.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public function onPostAutoloadDump(Event $event): void
9696
$rootConfig = $this->getPluginConfig($rootPackage);
9797
$options = new Options($rootPackage->getExtra());
9898

99-
$outputDirectory = $this->getRootPath() . '/' . $options->outputDirectory();
99+
$outputDirectory = $this->getRootPath() . $options->outputDirectory();
100100
$this->ensureDirectoryExists($outputDirectory);
101101

102102
$allPackages = (new PackagesListBuilder($composer))->build();
@@ -113,6 +113,7 @@ public function onPostAutoloadDump(Event $event): void
113113

114114
foreach ($allPackages as $package) {
115115
$pluginConfig = $this->getPluginConfig($package);
116+
$pluginOptions = new Options($package->getExtra());
116117
foreach ($pluginConfig as $group => $files) {
117118
$files = (array)$files;
118119
foreach ($files as $file) {
@@ -129,7 +130,7 @@ public function onPostAutoloadDump(Event $event): void
129130
continue;
130131
}
131132

132-
$source = $this->getPackagePath($package) . '/' . $file;
133+
$source = $this->getPackagePath($package) . $pluginOptions->sourceDirectory() . '/' . $file;
133134

134135
if ($this->containsWildcard($file)) {
135136
$matches = glob($source);
@@ -165,7 +166,22 @@ public function onPostAutoloadDump(Event $event): void
165166

166167
// Append root package config.
167168
foreach ($rootConfig as $group => $files) {
168-
$mergePlan[$group] = ['/' => (array)$files] +
169+
$files = array_map(
170+
function ($file) use ($options) {
171+
$isOptional = $this->isOptional($file);
172+
if ($isOptional) {
173+
$file = substr($file, 1);
174+
}
175+
176+
$result = $isOptional ? '?' : '';
177+
if ($options->sourceDirectory() !== '/') {
178+
$result .= ltrim($options->sourceDirectory(), '/') . '/';
179+
}
180+
return $result . $file;
181+
},
182+
(array)$files
183+
);
184+
$mergePlan[$group] = ['/' => $files] +
169185
(array_key_exists($group, $mergePlan) ? $mergePlan[$group] : []);
170186
}
171187

src/Options.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
final class Options
1313
{
1414
private bool $silentOverride;
15+
private string $sourceDirectory;
1516
private string $outputDirectory;
1617

1718
public function __construct(array $extra)
@@ -23,14 +24,30 @@ public function __construct(array $extra)
2324
}
2425

2526
$this->silentOverride = (bool)($options['silent-override'] ?? false);
26-
$this->outputDirectory = (string)($options['output-directory'] ?? 'config/packages');
27+
$this->sourceDirectory = isset($options['source-directory'])
28+
? $this->normalizeRelativePath((string)$options['source-directory'])
29+
: '/';
30+
$this->outputDirectory = isset($options['output-directory'])
31+
? $this->normalizeRelativePath((string)$options['output-directory'])
32+
: '/config/packages';
2733
}
2834

35+
private function normalizeRelativePath(string $value): string
36+
{
37+
return '/' . trim(str_replace('\\', '/', $value), '/');
38+
}
39+
40+
2941
public function silentOverride(): bool
3042
{
3143
return $this->silentOverride;
3244
}
3345

46+
public function sourceDirectory(): string
47+
{
48+
return $this->sourceDirectory;
49+
}
50+
3451
public function outputDirectory(): string
3552
{
3653
return $this->outputDirectory;

tests/Integration/PackagesListBuilderTest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ protected function getStartComposerConfig(): array
1212
'a',
1313
'ba',
1414
'c',
15+
'custom-source',
1516
];
1617

1718
$repositories = [
@@ -140,6 +141,42 @@ public function testBase(): void
140141
],
141142
],
142143
]);
144+
145+
$this->execComposer('require test/custom-source');
146+
$this->assertMergePlan([
147+
'params' => [
148+
'/' => [
149+
'config/params.php',
150+
'?config/params-local.php',
151+
],
152+
'test/c' => [
153+
'config/params.php',
154+
],
155+
'test/custom-source' => [
156+
'params.php',
157+
],
158+
'test/a' => [
159+
'config/params.php',
160+
],
161+
],
162+
'web' => [
163+
'/' => [
164+
'config/web.php',
165+
],
166+
'test/ba' => [
167+
'config/web.php',
168+
],
169+
'test/c' => [
170+
'config/web.php',
171+
],
172+
'test/custom-source' => [
173+
'web.php',
174+
],
175+
'test/a' => [
176+
'config/web.php',
177+
],
178+
],
179+
]);
143180
}
144181

145182
private function assertMergePlan(array $mergePlan): void
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\Config\Tests\Integration;
6+
7+
final class PackagesListBuilderWithSourceDirectoryTest extends ComposerTest
8+
{
9+
protected function getStartComposerConfig(): array
10+
{
11+
return [
12+
'name' => 'yiisoft/testpackage',
13+
'type' => 'library',
14+
'minimum-stability' => 'dev',
15+
'require' => [
16+
'yiisoft/config' => '*',
17+
'test/a' => '*',
18+
],
19+
'repositories' => [
20+
[
21+
'type' => 'path',
22+
'url' => '../../',
23+
],
24+
[
25+
'type' => 'path',
26+
'url' => '../Packages/test/a',
27+
'options' => [
28+
'symlink' => false,
29+
],
30+
]
31+
],
32+
'extra' => [
33+
'config-plugin-options' => [
34+
'source-directory' => 'app-configs',
35+
],
36+
'config-plugin' => [
37+
'params' => [
38+
'params.php',
39+
'?params-local.php',
40+
],
41+
'web' => 'web.php',
42+
],
43+
],
44+
];
45+
}
46+
47+
public function testBase(): void
48+
{
49+
$this->assertMergePlan([
50+
'params' => [
51+
'/' => [
52+
'app-configs/params.php',
53+
'?app-configs/params-local.php',
54+
],
55+
'test/a' => [
56+
'config/params.php',
57+
],
58+
],
59+
'web' => [
60+
'/' => [
61+
'app-configs/web.php',
62+
],
63+
'test/a' => [
64+
'config/web.php',
65+
],
66+
],
67+
]);
68+
}
69+
70+
private function assertMergePlan(array $mergePlan): void
71+
{
72+
$this->assertSame($mergePlan, require $this->workingDirectory . '/config/packages/merge_plan.php');
73+
}
74+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\Config\Tests\Integration;
6+
7+
final class SourceDirectoryTest extends ComposerTest
8+
{
9+
protected function getStartComposerConfig(): array
10+
{
11+
return [
12+
'name' => 'yiisoft/testpackage',
13+
'type' => 'library',
14+
'minimum-stability' => 'dev',
15+
'require' => [
16+
'yiisoft/config' => '*',
17+
'test/custom-source' => '*',
18+
],
19+
'repositories' => [
20+
[
21+
'type' => 'path',
22+
'url' => '../../',
23+
],
24+
[
25+
'type' => 'path',
26+
'url' => '../Packages/test/custom-source',
27+
'options' => [
28+
'symlink' => false,
29+
],
30+
],
31+
],
32+
];
33+
}
34+
35+
public function testBase(): void
36+
{
37+
$this->assertFileExists($this->workingDirectory . '/config/packages/test/custom-source/params.php');
38+
$this->assertFileExists($this->workingDirectory . '/config/packages/test/custom-source/web.php');
39+
}
40+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "test/custom-source",
3+
"version": "1.0.0",
4+
"extra": {
5+
"config-plugin-options": {
6+
"source-directory": "custom-dir"
7+
},
8+
"config-plugin": {
9+
"params": "params.php",
10+
"web": "web.php"
11+
}
12+
}
13+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
return [];
6+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/** @var array $params */
6+
7+
return [
8+
stdClass::class => stdClass::class,
9+
];

tests/Unit/OptionsTest.php

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,67 @@ public function testSilentOverride(): void
2929
$this->assertFalse($options->silentOverride());
3030
}
3131

32-
public function testOutputDirectory(): void
32+
public function testDefaultOutputDirectory(): void
3333
{
3434
$options = new Options([]);
35-
$this->assertSame('config/packages', $options->outputDirectory());
35+
$this->assertSame('/config/packages', $options->outputDirectory());
36+
}
3637

38+
public function dataOutputDirectory(): array
39+
{
40+
return [
41+
['/', ''],
42+
['/', '/'],
43+
['/', '\\'],
44+
['/custom-dir', 'custom-dir'],
45+
['/custom-dir', '/custom-dir'],
46+
['/custom-dir', '/custom-dir/'],
47+
['/custom-dir', '\\custom-dir\\'],
48+
];
49+
}
50+
51+
/**
52+
* @dataProvider dataOutputDirectory
53+
*/
54+
public function testOutputDirectory(string $expected, string $path): void
55+
{
56+
$options = new Options([
57+
'config-plugin-options' => [
58+
'output-directory' => $path,
59+
],
60+
]);
61+
$this->assertSame($expected, $options->outputDirectory());
62+
}
63+
64+
public function testDefaultSourceDirectory(): void
65+
{
66+
$options = new Options([]);
67+
$this->assertSame('/', $options->sourceDirectory());
68+
}
69+
70+
public function dataSourceDirectory(): array
71+
{
72+
return [
73+
['/', ''],
74+
['/', '/'],
75+
['/', '\\'],
76+
['/custom-dir', 'custom-dir'],
77+
['/custom-dir', '/custom-dir'],
78+
['/custom-dir', '/custom-dir/'],
79+
['/custom-dir', '\\custom-dir\\'],
80+
];
81+
}
82+
83+
/**
84+
* @dataProvider dataSourceDirectory
85+
*/
86+
public function testSourceDirectory(string $expected, string $path): void
87+
{
3788
$options = new Options([
3889
'config-plugin-options' => [
39-
'output-directory' => 'custom-dir-packages',
90+
'source-directory' => $path,
4091
],
4192
]);
42-
$this->assertSame('custom-dir-packages', $options->outputDirectory());
93+
$this->assertSame($expected, $options->sourceDirectory());
4394
}
4495
}

0 commit comments

Comments
 (0)