Skip to content

Commit

Permalink
[tests] use composer to require maker bundle in tests (#1248)
Browse files Browse the repository at this point in the history
  • Loading branch information
jrushlow authored Dec 6, 2022
1 parent 7c9e696 commit 16f26e4
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 27 deletions.
84 changes: 62 additions & 22 deletions src/Test/MakerTestEnvironment.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ final class MakerTestEnvironment
private string $flexPath;
private string $path;
private MakerTestProcess $runnedMakerProcess;
private bool $isWindows;

private function __construct(
private MakerTestDetails $testDetails,
) {
$this->isWindows = str_contains(strtolower(\PHP_OS), 'win');

$this->fs = new Filesystem();
$this->rootPath = realpath(__DIR__.'/../../');
$cachePath = $this->rootPath.'/tests/tmp/cache';
Expand Down Expand Up @@ -124,13 +127,18 @@ private function changeRootNamespaceIfNeeded(): void

public function prepareDirectory(): void
{
// Copy MakerBundle to a "repo" directory for tests
if (!file_exists($makerRepoPath = sprintf('%s/maker-repo', $this->cachePath))) {
MakerTestProcess::create(sprintf('git clone %s %s', $this->rootPath, $makerRepoPath), $this->cachePath)->run();
}

if (!$this->fs->exists($this->flexPath)) {
$this->buildFlexSkeleton();
}

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

// In Window's we have to require MakerBundle in each project - git clone doesn't symlink well
if ($this->isWindows) {
$this->composerRequireMakerBundle($this->path);
}

// install any missing dependencies
$dependencies = $this->determineMissingDependencies();
if ($dependencies) {
Expand Down Expand Up @@ -231,33 +244,21 @@ private function buildFlexSkeleton(): void
$targetVersion = $this->getTargetSkeletonVersion();
$versionString = $targetVersion ? sprintf(':%s', $targetVersion) : '';

$flexProjectDir = sprintf('flex_project%s', $targetVersion);

MakerTestProcess::create(
sprintf('composer create-project symfony/skeleton%s flex_project%s --prefer-dist --no-progress', $versionString, $targetVersion),
sprintf('composer create-project symfony/skeleton%s %s --prefer-dist --no-progress', $versionString, $flexProjectDir),
$this->cachePath
)->run();

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

// processes any changes needed to the Flex project
$replacements = [
[
'filename' => 'config/bundles.php',
'find' => "Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],",
'replace' => "Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],\n Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],",
],
[
// ugly way to autoload Maker & any other vendor libs needed in the command
'filename' => 'composer.json',
'find' => '"App\\\Tests\\\": "tests/"',
'replace' => sprintf(
'"App\\\Tests\\\": "tests/",'."\n".' "Symfony\\\Bundle\\\MakerBundle\\\": "%s/src/",'."\n".' "PhpParser\\\": "%s/vendor/nikic/php-parser/lib/PhpParser/"',
// escape \ for Windows
$rootPath,
$rootPath
),
],
];
$this->processReplacements($replacements, $this->flexPath);
$this->addMakerBundleRepoToComposer(sprintf('%s/%s/composer.json', $this->cachePath, $flexProjectDir));

// In Linux, git plays well with symlinks - we can add maker to the flex skeleton.
if (!$this->isWindows) {
$this->composerRequireMakerBundle(sprintf('%s/%s', $this->cachePath, $flexProjectDir));
}

if ($_SERVER['MAKER_ALLOW_DEV_DEPS_IN_APP'] ?? false) {
MakerTestProcess::create('composer config minimum-stability dev', $this->flexPath)->run();
Expand Down Expand Up @@ -411,4 +412,43 @@ private function getTargetSkeletonVersion(): ?string
{
return $_SERVER['SYMFONY_VERSION'] ?? '';
}

private function composerRequireMakerBundle(string $projectDirectory): void
{
MakerTestProcess::create('composer require --dev symfony/maker-bundle', $projectDirectory)
->run()
;

$makerRepoSrcPath = sprintf('%s/maker-repo/src', $this->cachePath);

// DX - So we can test local changes without having to commit them.
if (!is_link($makerRepoSrcPath)) {
$this->fs->remove($makerRepoSrcPath);
$this->fs->symlink(sprintf('%s/src', $this->rootPath), $makerRepoSrcPath);
}
}

/**
* Adds Symfony/MakerBundle as a "path" repository to composer.json.
*/
private function addMakerBundleRepoToComposer(string $composerJsonPath): void
{
$composerJson = json_decode(
file_get_contents($composerJsonPath), true, 512, \JSON_THROW_ON_ERROR);

// Require-dev is empty and composer complains about this being an array when we encode it again.
unset($composerJson['require-dev']);

$composerJson['repositories']['symfony/maker-bundle'] = [
'type' => 'path',
'url' => sprintf('%s%smaker-repo', $this->cachePath, \DIRECTORY_SEPARATOR),
'options' => [
'versions' => [
'symfony/maker-bundle' => '9999.99', // Arbitrary version to avoid stability conflicts
],
],
];

file_put_contents($composerJsonPath, json_encode($composerJson, \JSON_THROW_ON_ERROR | \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES));
}
}
15 changes: 11 additions & 4 deletions src/Test/MakerTestRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,17 @@ public function writeFile(string $filename, string $contents): void
*/
public function addToAutoloader(string $namespace, string $path)
{
$this->replaceInFile(
'composer.json',
'"App\\\Tests\\\": "tests/",',
sprintf('"App\\\Tests\\\": "tests/",'."\n".' "%s": "%s",', $namespace, $path)
$composerJson = json_decode(
json: file_get_contents($this->getPath('composer.json')),
associative: true,
flags: \JSON_THROW_ON_ERROR | \JSON_UNESCAPED_SLASHES
);

$composerJson['autoload-dev']['psr-4'][$namespace] = $path;

$this->filesystem->dumpFile(
$this->getPath('composer.json'),
json_encode($composerJson, \JSON_UNESCAPED_SLASHES | \JSON_PRETTY_PRINT | \JSON_THROW_ON_ERROR)
);

$this->environment->runCommand('composer dump-autoload');
Expand Down
2 changes: 1 addition & 1 deletion tests/Maker/MakeEntityTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ private function setupGroupEntityInVendor(MakerTestRunner $runner): void
);

$runner->addToAutoloader(
'Some\\\Vendor\\\\',
'Some\\Vendor\\',
'vendor/some-vendor/src'
);
}
Expand Down

0 comments on commit 16f26e4

Please sign in to comment.