Make the root package name and path dynamically discovered in MakerTestCase

This commit is contained in:
Jérôme Tamarelle
2026-01-09 00:36:30 +01:00
parent 9eddf6aae4
commit 5d8d6fb25a
4 changed files with 41 additions and 36 deletions

View File

@@ -14,6 +14,7 @@
"minimum-stability": "dev",
"require": {
"php": ">=8.1",
"composer-runtime-api": "^2.1",
"doctrine/inflector": "^2.0",
"nikic/php-parser": "^5.0",
"symfony/config": "^6.4|^7.0|^8.0",

View File

@@ -11,6 +11,7 @@
namespace Symfony\Bundle\MakerBundle\Test;
use Composer\InstalledVersions;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Process\InputStream;
@@ -28,9 +29,11 @@ final class MakerTestEnvironment
public const GENERATED_FILES_REGEX = '#(?:created|updated):\s(?:.*\\\\)*(.*\.[a-z]{3,4}).*(?:\\\\n)?#ui';
private Filesystem $fs;
private bool|string $rootPath;
private string $packageName;
private string $rootPath;
private string $cachePath;
private string $flexPath;
private string $fixturesPath;
private string $path;
private MakerTestProcess $runnedMakerProcess;
private bool $isWindows;
@@ -41,7 +44,9 @@ final class MakerTestEnvironment
$this->isWindows = '\\' === \DIRECTORY_SEPARATOR;
$this->fs = new Filesystem();
$this->rootPath = realpath(__DIR__.'/../../');
$composerPackage = InstalledVersions::getRootPackage();
$this->packageName = $composerPackage['name'];
$this->rootPath = realpath($composerPackage['install_path']);
$cachePath = $this->rootPath.'/tests/tmp/cache';
if (!$this->fs->exists($cachePath)) {
@@ -51,6 +56,7 @@ final class MakerTestEnvironment
$this->cachePath = realpath($cachePath);
$targetVersion = $this->getTargetSkeletonVersion();
$this->flexPath = $this->cachePath.'/flex_project'.$targetVersion;
$this->fixturesPath = $this->rootPath.'/tests/fixtures/';
$directoryName = $targetVersion ?: 'current';
if (str_ends_with($directoryName, '.*')) {
@@ -65,6 +71,11 @@ final class MakerTestEnvironment
return new self($testDetails);
}
public function getFixturesPath(string $path = ''): string
{
return $this->fixturesPath.$path;
}
public function getPath(): string
{
return $this->path;
@@ -134,7 +145,7 @@ final class MakerTestEnvironment
{
// 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();
MakerTestProcess::create(['git', 'clone', $this->rootPath, $makerRepoPath], $this->cachePath)->run();
}
if (!$this->fs->exists($this->flexPath)) {
@@ -150,15 +161,7 @@ final class MakerTestEnvironment
if (!$this->fs->exists($this->path)) {
try {
// let's do some magic here git is faster than copy
MakerTestProcess::create(
$this->isWindows ? 'git clone %FLEX_PATH% %APP_PATH%' : 'git clone "$FLEX_PATH" "$APP_PATH"',
\dirname($this->flexPath),
[
'FLEX_PATH' => $this->flexPath,
'APP_PATH' => $this->path,
]
)
->run();
MakerTestProcess::create(['git', 'clone', $this->flexPath, $this->path], \dirname($this->flexPath))->run();
// In Window's we have to require MakerBundle in each project - git clone doesn't symlink well
if ($this->isWindows) {
@@ -196,7 +199,10 @@ final class MakerTestEnvironment
}
}
public function runCommand(string $command): MakerTestProcess
/**
* @param string|list<string> $command
*/
public function runCommand(string|array $command): MakerTestProcess
{
return MakerTestProcess::create($command, $this->path)->run();
}
@@ -236,7 +242,7 @@ final class MakerTestEnvironment
public function runTwigCSLint(string $file): MakerTestProcess
{
if (!file_exists(__DIR__.'/../../tools/twigcs/vendor/bin/twigcs')) {
if (!file_exists($this->rootPath.'/tools/twigcs/vendor/bin/twigcs')) {
throw new \Exception('twigcs not found: run: "composer upgrade -W --working-dir=tools/twigcs".');
}
@@ -249,20 +255,20 @@ final class MakerTestEnvironment
$targetVersion = $this->getTargetSkeletonVersion();
$versionString = $targetVersion ? \sprintf(':%s', $targetVersion) : '';
$flexProjectDir = \sprintf('flex_project%s', $targetVersion);
$flexProjectDir = \sprintf('%s/flex_project%s', $this->cachePath, $targetVersion);
MakerTestProcess::create(
\sprintf('composer create-project symfony/skeleton%s %s --prefer-dist --no-progress --keep-vcs', $versionString, $flexProjectDir),
$this->cachePath
)->run();
$rootPath = str_replace('\\', '\\\\', realpath(__DIR__.'/../..'));
$rootPath = str_replace('\\', '\\\\', $this->rootPath);
$this->addMakerBundleRepoToComposer(\sprintf('%s/%s/composer.json', $this->cachePath, $flexProjectDir));
$this->addMakerBundleRepoToComposer($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));
$this->composerRequireMakerBundle($flexProjectDir);
}
// fetch a few packages needed for testing
@@ -411,9 +417,7 @@ echo json_encode($missingDependencies);
private function composerRequireMakerBundle(string $projectDirectory): void
{
MakerTestProcess::create('composer require --dev symfony/maker-bundle', $projectDirectory)
->run()
;
MakerTestProcess::create(['composer', 'require', '--dev', $this->packageName], $projectDirectory)->run();
$makerRepoSrcPath = \sprintf('%s/maker-repo/src', $this->cachePath);
@@ -425,26 +429,20 @@ echo json_encode($missingDependencies);
}
/**
* Adds Symfony/MakerBundle as a "path" repository to composer.json.
* Adds symfony/maker-bundle as a "path" repository to composer.json.
*/
private function addMakerBundleRepoToComposer(string $composerJsonPath): void
private function addMakerBundleRepoToComposer(string $projectDirectory): 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'] = [
$repo = [
'type' => 'path',
'url' => \sprintf('%s%smaker-repo', $this->cachePath, \DIRECTORY_SEPARATOR),
'options' => [
'versions' => [
'symfony/maker-bundle' => '9999.99', // Arbitrary version to avoid stability conflicts
$this->packageName => '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));
MakerTestProcess::create(['composer', 'repo', 'add', $this->packageName, json_encode($repo)], $projectDirectory)->run();
}
}

View File

@@ -22,7 +22,10 @@ final class MakerTestProcess
{
private Process $process;
private function __construct($commandLine, $cwd, array $envVars, $timeout)
/**
* @param string|list<string> $commandLine
*/
private function __construct(string|array $commandLine, string $cwd, array $envVars, ?float $timeout)
{
$this->process = \is_string($commandLine)
? Process::fromShellCommandline($commandLine, $cwd, null, null, $timeout)
@@ -31,7 +34,10 @@ final class MakerTestProcess
$this->process->setEnv($envVars);
}
public static function create($commandLine, $cwd, array $envVars = [], $timeout = null): self
/**
* @param string|list<string> $commandLine
*/
public static function create(string|array $commandLine, string $cwd, array $envVars = [], ?float $timeout = null): self
{
return new self($commandLine, $cwd, $envVars, $timeout);
}

View File

@@ -52,7 +52,7 @@ class MakerTestRunner
*/
public function copy(string $source, string $destination)
{
$path = __DIR__.'/../../tests/fixtures/'.$source;
$path = $this->environment->getFixturesPath($source);
if (!file_exists($path)) {
throw new \Exception(\sprintf('Cannot find file "%s"', $path));
@@ -76,7 +76,7 @@ class MakerTestRunner
public function renderTemplateFile(string $source, string $destination, array $variables): void
{
$twig = new Environment(
new FilesystemLoader(__DIR__.'/../../tests/fixtures')
new FilesystemLoader($this->environment->getFixturesPath())
);
$rendered = $twig->render($source, $variables);