Skip to content

Commit 16f26e4

Browse files
authored
[tests] use composer to require maker bundle in tests (#1248)
1 parent 7c9e696 commit 16f26e4

File tree

3 files changed

+74
-27
lines changed

3 files changed

+74
-27
lines changed

src/Test/MakerTestEnvironment.php

Lines changed: 62 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,13 @@ final class MakerTestEnvironment
2828
private string $flexPath;
2929
private string $path;
3030
private MakerTestProcess $runnedMakerProcess;
31+
private bool $isWindows;
3132

3233
private function __construct(
3334
private MakerTestDetails $testDetails,
3435
) {
36+
$this->isWindows = str_contains(strtolower(\PHP_OS), 'win');
37+
3538
$this->fs = new Filesystem();
3639
$this->rootPath = realpath(__DIR__.'/../../');
3740
$cachePath = $this->rootPath.'/tests/tmp/cache';
@@ -124,13 +127,18 @@ private function changeRootNamespaceIfNeeded(): void
124127

125128
public function prepareDirectory(): void
126129
{
130+
// Copy MakerBundle to a "repo" directory for tests
131+
if (!file_exists($makerRepoPath = sprintf('%s/maker-repo', $this->cachePath))) {
132+
MakerTestProcess::create(sprintf('git clone %s %s', $this->rootPath, $makerRepoPath), $this->cachePath)->run();
133+
}
134+
127135
if (!$this->fs->exists($this->flexPath)) {
128136
$this->buildFlexSkeleton();
129137
}
130138

131139
if (!$this->fs->exists($this->path)) {
132140
try {
133-
// lets do some magic here git is faster than copy
141+
// let's do some magic here git is faster than copy
134142
MakerTestProcess::create(
135143
'\\' === \DIRECTORY_SEPARATOR ? 'git clone %FLEX_PATH% %APP_PATH%' : 'git clone "$FLEX_PATH" "$APP_PATH"',
136144
\dirname($this->flexPath),
@@ -141,6 +149,11 @@ public function prepareDirectory(): void
141149
)
142150
->run();
143151

152+
// In Window's we have to require MakerBundle in each project - git clone doesn't symlink well
153+
if ($this->isWindows) {
154+
$this->composerRequireMakerBundle($this->path);
155+
}
156+
144157
// install any missing dependencies
145158
$dependencies = $this->determineMissingDependencies();
146159
if ($dependencies) {
@@ -231,33 +244,21 @@ private function buildFlexSkeleton(): void
231244
$targetVersion = $this->getTargetSkeletonVersion();
232245
$versionString = $targetVersion ? sprintf(':%s', $targetVersion) : '';
233246

247+
$flexProjectDir = sprintf('flex_project%s', $targetVersion);
248+
234249
MakerTestProcess::create(
235-
sprintf('composer create-project symfony/skeleton%s flex_project%s --prefer-dist --no-progress', $versionString, $targetVersion),
250+
sprintf('composer create-project symfony/skeleton%s %s --prefer-dist --no-progress', $versionString, $flexProjectDir),
236251
$this->cachePath
237252
)->run();
238253

239254
$rootPath = str_replace('\\', '\\\\', realpath(__DIR__.'/../..'));
240255

241-
// processes any changes needed to the Flex project
242-
$replacements = [
243-
[
244-
'filename' => 'config/bundles.php',
245-
'find' => "Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],",
246-
'replace' => "Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],\n Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],",
247-
],
248-
[
249-
// ugly way to autoload Maker & any other vendor libs needed in the command
250-
'filename' => 'composer.json',
251-
'find' => '"App\\\Tests\\\": "tests/"',
252-
'replace' => sprintf(
253-
'"App\\\Tests\\\": "tests/",'."\n".' "Symfony\\\Bundle\\\MakerBundle\\\": "%s/src/",'."\n".' "PhpParser\\\": "%s/vendor/nikic/php-parser/lib/PhpParser/"',
254-
// escape \ for Windows
255-
$rootPath,
256-
$rootPath
257-
),
258-
],
259-
];
260-
$this->processReplacements($replacements, $this->flexPath);
256+
$this->addMakerBundleRepoToComposer(sprintf('%s/%s/composer.json', $this->cachePath, $flexProjectDir));
257+
258+
// In Linux, git plays well with symlinks - we can add maker to the flex skeleton.
259+
if (!$this->isWindows) {
260+
$this->composerRequireMakerBundle(sprintf('%s/%s', $this->cachePath, $flexProjectDir));
261+
}
261262

262263
if ($_SERVER['MAKER_ALLOW_DEV_DEPS_IN_APP'] ?? false) {
263264
MakerTestProcess::create('composer config minimum-stability dev', $this->flexPath)->run();
@@ -411,4 +412,43 @@ private function getTargetSkeletonVersion(): ?string
411412
{
412413
return $_SERVER['SYMFONY_VERSION'] ?? '';
413414
}
415+
416+
private function composerRequireMakerBundle(string $projectDirectory): void
417+
{
418+
MakerTestProcess::create('composer require --dev symfony/maker-bundle', $projectDirectory)
419+
->run()
420+
;
421+
422+
$makerRepoSrcPath = sprintf('%s/maker-repo/src', $this->cachePath);
423+
424+
// DX - So we can test local changes without having to commit them.
425+
if (!is_link($makerRepoSrcPath)) {
426+
$this->fs->remove($makerRepoSrcPath);
427+
$this->fs->symlink(sprintf('%s/src', $this->rootPath), $makerRepoSrcPath);
428+
}
429+
}
430+
431+
/**
432+
* Adds Symfony/MakerBundle as a "path" repository to composer.json.
433+
*/
434+
private function addMakerBundleRepoToComposer(string $composerJsonPath): void
435+
{
436+
$composerJson = json_decode(
437+
file_get_contents($composerJsonPath), true, 512, \JSON_THROW_ON_ERROR);
438+
439+
// Require-dev is empty and composer complains about this being an array when we encode it again.
440+
unset($composerJson['require-dev']);
441+
442+
$composerJson['repositories']['symfony/maker-bundle'] = [
443+
'type' => 'path',
444+
'url' => sprintf('%s%smaker-repo', $this->cachePath, \DIRECTORY_SEPARATOR),
445+
'options' => [
446+
'versions' => [
447+
'symfony/maker-bundle' => '9999.99', // Arbitrary version to avoid stability conflicts
448+
],
449+
],
450+
];
451+
452+
file_put_contents($composerJsonPath, json_encode($composerJson, \JSON_THROW_ON_ERROR | \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES));
453+
}
414454
}

src/Test/MakerTestRunner.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,17 @@ public function writeFile(string $filename, string $contents): void
224224
*/
225225
public function addToAutoloader(string $namespace, string $path)
226226
{
227-
$this->replaceInFile(
228-
'composer.json',
229-
'"App\\\Tests\\\": "tests/",',
230-
sprintf('"App\\\Tests\\\": "tests/",'."\n".' "%s": "%s",', $namespace, $path)
227+
$composerJson = json_decode(
228+
json: file_get_contents($this->getPath('composer.json')),
229+
associative: true,
230+
flags: \JSON_THROW_ON_ERROR | \JSON_UNESCAPED_SLASHES
231+
);
232+
233+
$composerJson['autoload-dev']['psr-4'][$namespace] = $path;
234+
235+
$this->filesystem->dumpFile(
236+
$this->getPath('composer.json'),
237+
json_encode($composerJson, \JSON_UNESCAPED_SLASHES | \JSON_PRETTY_PRINT | \JSON_THROW_ON_ERROR)
231238
);
232239

233240
$this->environment->runCommand('composer dump-autoload');

tests/Maker/MakeEntityTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ private function setupGroupEntityInVendor(MakerTestRunner $runner): void
637637
);
638638

639639
$runner->addToAutoloader(
640-
'Some\\\Vendor\\\\',
640+
'Some\\Vendor\\',
641641
'vendor/some-vendor/src'
642642
);
643643
}

0 commit comments

Comments
 (0)