Last active
February 18, 2023 21:56
-
-
Save thekid/ad6f908f4badbc3460a74a43e9544a86 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php namespace test; | |
use io\streams\LinesIn; | |
use io\{File, Files, Folder, Path}; | |
use util\cmd\Console; | |
// Yields all files with a given extension inside a given folder | |
function filesIn(Folder $folder, string $extension): iterable { | |
$end= -1 * strlen($extension); | |
foreach ($folder->entries() as $entry) { | |
if ($entry->isFolder()) { | |
yield from filesIn($entry->asFolder(), $extension); | |
} else if (0 === substr_compare($entry, $extension, $end)) { | |
yield $entry->asFile(); | |
} | |
} | |
} | |
// Parses an input line into an import | |
function importIn(string $line): array { | |
$p= strrpos($line, '\\'); | |
$ns= substr($line, 0, $p); | |
if ('{' === $line[$p + 1]) { | |
return ['ns' => $ns, 'classes' => preg_split('/, ?/', substr($line, $p + 2, -2))]; | |
} else { | |
return ['ns' => $ns, 'classes' => [substr($line, $p + 1, -1)]]; | |
} | |
} | |
// Rewrites annotations | |
function rewriteAnnotations(string $input): string { | |
static $patterns= [ | |
'/withMessage: /' => 'message: ', | |
'/Values\(\'(.+)\'\)/' => 'Values(from: \'$1\')', | |
'/Action\(eval: \'new RuntimeVersion\("([^"]+)"\)\'\)/' => 'Runtime(php: \'$1\')', | |
'/Action\(eval: \'new VerifyThat\((.+)\)\'\)/' => 'Condition(assert: \'$1\')', | |
]; | |
return preg_replace(array_keys($patterns), array_values($patterns), $input); | |
} | |
// Replace requirement in composer.json | |
function rewriteYaml(File $input): int { | |
return Files::write($input, preg_replace( | |
'/sh xp-run xp\.unittest\.TestRunner/', | |
'sh xp-run xp.test.Runner', | |
Files::read($input) | |
)); | |
} | |
// Rewrites the code in a given file and returns the performed operations | |
function rewriteSource(File $input): array { | |
$out= new File($input->getURI().'.rewrite'); | |
$out->open(File::WRITE); | |
$operations= []; | |
foreach (new LinesIn($input->in()) as $i => $line) { | |
// Remove newlines at the end of the file | |
if ($i > 1) $out->write("\n"); | |
// Adjust imports from unittest namespace -> test | |
if (0 === strncmp($line, 'use ', 4)) { | |
$import= importIn(rtrim(substr($line, 4))); | |
if ('unittest\\actions' === $import['ns']) { | |
$import['ns']= 'test\\verify'; | |
foreach ($import['classes'] as &$class) { | |
$class= strtr($class, ['RuntimeVersion' => 'Runtime', 'VerifyThat' => 'Condition']); | |
} | |
$operations[]= 'replaced imports'; | |
} else if ('unittest' === $import['ns']) { | |
$import['ns']= 'test'; | |
$operations[]= 'replaced imports'; | |
} | |
if (1 === sizeof($import['classes'])) { | |
$line= 'use '.$import['ns'].'\\'.$import['classes'][0].';'; | |
} else { | |
sort($import['classes']); | |
$line= 'use '.$import['ns'].'\\{'.implode(', ', $import['classes']).'};'; | |
} | |
} | |
// Rewrite annotations | |
if (preg_match('/(\s*)#\[(.+)\]\s?$/s', $line, $matches)) { | |
$line= $matches[1].'#['.rewriteAnnotations($matches[2]).']'; | |
} | |
$out->write($line); | |
} | |
$out->close(); | |
if (empty($operations)) { | |
$out->unlink(); | |
} else { | |
$out->move($input); | |
} | |
return $operations; | |
} | |
$module= realpath($argv[1]); | |
$composer= new File($module, 'composer.json'); | |
$paths= \xp\pathfiles($module); | |
if (!$composer->exists() || empty($paths)) { | |
Console::writeLine('No composer.json and no pathfiles found in ', $argv[1], ' - not a module?'); | |
return 1; | |
} | |
// Rewrite code in all paths in-place | |
foreach ($paths as $path) { | |
$resolved= realpath($module.DIRECTORY_SEPARATOR.$path); | |
if (!is_dir($resolved) || 0 !== strncmp($module, $resolved, strlen($module))) continue; | |
Console::writeLine('> Rewrite sources in ', $path); | |
foreach (filesIn(new Folder($resolved), '.php') as $origin) { | |
Console::writeLine(' * ', $origin, ': ', rewriteSource($origin)); | |
} | |
} | |
// Replace requirement in composer.json | |
Files::write($composer, preg_replace( | |
'/"xp-framework\/unittest"([ :]+)"[^"]+"/', | |
'"xp-framework/test"$1"^1.0"', | |
Files::read($composer) | |
)); | |
// Rewrite .github | |
$github= new Folder($module, '.github'); | |
if ($github->exists()) { | |
foreach (filesIn($github, '.yml') as $origin) { | |
Console::writeLine(' * ', $origin, ': ', rewriteYaml($origin)); | |
} | |
} | |
Console::writeLine(); | |
Console::writeLine('Done, now run `composer up` and then `xp test`'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment