Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
55 changes: 23 additions & 32 deletions src/Test/MakerTestEnvironment.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Symfony\Bundle\MakerBundle\Test;

use Composer\InstalledVersions;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Process\InputStream;

Expand All @@ -28,7 +29,8 @@ 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 $path;
Expand All @@ -41,7 +43,9 @@ private function __construct(
$this->isWindows = str_contains(strtolower(\PHP_OS), 'win');

$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)) {
Expand Down Expand Up @@ -134,7 +138,7 @@ 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();
MakerTestProcess::create(['git', 'clone', $this->rootPath, $makerRepoPath], $this->cachePath)->run();
}

if (!$this->fs->exists($this->flexPath)) {
Expand All @@ -144,15 +148,7 @@ public function prepareDirectory(): void
if (!$this->fs->exists($this->path)) {
try {
// 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),
[
'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) {
Expand Down Expand Up @@ -190,7 +186,10 @@ public function prepareDirectory(): void
}
}

public function runCommand(string $command): MakerTestProcess
/**
* @param string|list<string> $command
*/
public function runCommand(string|array $command): MakerTestProcess
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a breaking change because the class is internal.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest adding a phpdoc @param string|list<string> $command to document the type of the array.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same in MakerTestProcess btw

{
return MakerTestProcess::create($command, $this->path)->run();
}
Expand Down Expand Up @@ -230,7 +229,7 @@ public function fileExists(string $file): bool

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".');
}

Expand All @@ -243,20 +242,20 @@ private function buildFlexSkeleton(): void
$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
Expand Down Expand Up @@ -411,9 +410,7 @@ public function getTargetSkeletonVersion(): ?string

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);

Expand All @@ -425,26 +422,20 @@ private function composerRequireMakerBundle(string $projectDirectory): void
}

/**
* 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();
}
}
10 changes: 8 additions & 2 deletions src/Test/MakerTestProcess.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -31,7 +34,10 @@ private function __construct($commandLine, $cwd, array $envVars, $timeout)
$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
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a breaking change because the class is final and internal

{
return new self($commandLine, $cwd, $envVars, $timeout);
}
Expand Down
10 changes: 8 additions & 2 deletions src/Test/MakerTestRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Symfony\Bundle\MakerBundle\Test;

use Composer\InstalledVersions;
use PHPUnit\Framework\ExpectationFailedException;
use Symfony\Bundle\MakerBundle\Util\ClassSourceManipulator;
use Symfony\Bundle\MakerBundle\Util\YamlSourceManipulator;
Expand Down Expand Up @@ -52,7 +53,7 @@ public function runMaker(array $inputs, string $argumentsString = '', bool $allo
*/
public function copy(string $source, string $destination)
{
$path = __DIR__.'/../../tests/fixtures/'.$source;
$path = self::getFixturesDir().$source;

if (!file_exists($path)) {
throw new \Exception(\sprintf('Cannot find file "%s"', $path));
Expand All @@ -76,7 +77,7 @@ public function copy(string $source, string $destination)
public function renderTemplateFile(string $source, string $destination, array $variables): void
{
$twig = new Environment(
new FilesystemLoader(__DIR__.'/../../tests/fixtures')
new FilesystemLoader(self::getFixturesDir())
);

$rendered = $twig->render($source, $variables);
Expand Down Expand Up @@ -272,4 +273,9 @@ public function doesClassExist(string $class): bool
{
return $this->environment->doesClassExistInApp($class);
}

private static function getFixturesDir(): string
{
return realpath(InstalledVersions::getRootPackage()['install_path']).'/tests/fixtures/';
}
}
Loading