diff --git a/README.md b/README.md
index 9cf33a1bd..e15b63741 100644
--- a/README.md
+++ b/README.md
@@ -244,6 +244,22 @@ Searching for regex: #this->get\((.*)\)#
```
+
+
+
+## 9. Convert Alice fixtures from YAML to PHP
+
+The `nelmio/alice` package [allows to use PHP](https://github.com/nelmio/alice/blob/v2.3.0/doc/complete-reference.md#php) for test fixture definitions. It's much better format, because Rector and PHPStan can understand it.
+
+But what if we have 100+ YAML files in our project?
+
+```bash
+vendor/bin/swiss-knife convert-alice-yaml-to-php fixtures
+```
+
+That's it!
+
+
Happy coding!
diff --git a/composer.json b/composer.json
index 0b78d6a29..5b00b12e9 100644
--- a/composer.json
+++ b/composer.json
@@ -13,6 +13,7 @@
"nikic/php-parser": "^5.4",
"symfony/console": "^6.4",
"symfony/finder": "^6.4",
+ "symfony/yaml": "^7.2",
"webmozart/assert": "^1.11"
},
"require-dev": {
diff --git a/src/Command/AliceYamlFixturesToPhpCommand.php b/src/Command/AliceYamlFixturesToPhpCommand.php
new file mode 100644
index 000000000..e4020a37e
--- /dev/null
+++ b/src/Command/AliceYamlFixturesToPhpCommand.php
@@ -0,0 +1,90 @@
+setName('alice-yaml-fixtures-to-php');
+
+ $this->addArgument(
+ 'sources',
+ InputArgument::REQUIRED | InputArgument::IS_ARRAY,
+ 'One or more paths to check'
+ );
+
+ $this->setDescription('Converts Alice YAML fixtures to PHP format, so Rector and PHPStan can understand it');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): int
+ {
+ $sources = (array) $input->getArgument('sources');
+ $yamlFileInfos = FilesFinder::findYamlFiles($sources);
+
+ $standard = new Standard();
+
+ // use php-parser to dump their PHP version, @see https://github.com/nelmio/alice/blob/main/doc%2Fcomplete-reference.md#php
+ foreach ($yamlFileInfos as $yamlFileInfo) {
+ $yaml = Yaml::parseFile($yamlFileInfo->getRealPath());
+
+ $return = $this->createArrayReturn($yaml);
+ $phpFileContents = $standard->prettyPrintFile([$return]);
+
+ // get real path without yml/yaml suffix
+ if (str_ends_with($yamlFileInfo->getRealPath(), '.yml')) {
+ $phpFilePath = substr($yamlFileInfo->getRealPath(), 0, -4) . '.php';
+ } else {
+ $phpFilePath = substr($yamlFileInfo->getRealPath(), 0, -5) . '.php';
+ }
+
+ FileSystem::write($phpFilePath, $phpFileContents);
+
+ // remove YAML file
+ unlink($yamlFileInfo->getRealPath());
+
+ $this->symfonyStyle->writeln('[DELETED] ' . $yamlFileInfo->getRelativePathname());
+ $this->symfonyStyle->writeln('[ADDED] ' . $phpFilePath);
+ $this->symfonyStyle->newLine();
+ }
+
+ $this->symfonyStyle->success(
+ sprintf('Successfully converted %d Alice YAML fixtures to PHP', count($yamlFileInfos))
+ );
+
+ return self::SUCCESS;
+ }
+
+ /**
+ * @param mixed[] $yaml
+ */
+ private function createArrayReturn(array $yaml): Return_
+ {
+ $expr = BuilderHelpers::normalizeValue($yaml);
+
+ return new Return_($expr);
+ }
+}