Merge pull request #673 from flightphp/fix-other-commands

Fixed route and controller commands to accept old configs
master v3.17.4
n0nag0n 1 day ago committed by GitHub
commit 1833907181
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -29,8 +29,16 @@ class ControllerCommand extends AbstractBaseCommand
public function execute(string $controller) public function execute(string $controller)
{ {
$io = $this->app()->io(); $io = $this->app()->io();
if (isset($this->config['app_root']) === false) {
$io->error('app_root not set in .runway-config.json', true); if (empty($this->config['runway'])) {
$io->warn('Using a .runway-config.json file is deprecated. Move your config values to app/config/config.php with `php runway config:migrate`.', true); // @codeCoverageIgnore
$runwayConfig = json_decode(file_get_contents($this->projectRoot . '/.runway-config.json'), true); // @codeCoverageIgnore
} else {
$runwayConfig = $this->config['runway'];
}
if (isset($runwayConfig['app_root']) === false) {
$io->error('app_root not set in app/config/config.php', true);
return; return;
} }
@ -38,7 +46,7 @@ class ControllerCommand extends AbstractBaseCommand
$controller .= 'Controller'; $controller .= 'Controller';
} }
$controllerPath = getcwd() . DIRECTORY_SEPARATOR . $this->config['app_root'] . 'controllers' . DIRECTORY_SEPARATOR . $controller . '.php'; $controllerPath = $this->projectRoot . '/' . $runwayConfig['app_root'] . 'controllers/' . $controller . '.php';
if (file_exists($controllerPath) === true) { if (file_exists($controllerPath) === true) {
$io->error($controller . ' already exists.', true); $io->error($controller . ' already exists.', true);
return; return;
@ -70,7 +78,7 @@ class ControllerCommand extends AbstractBaseCommand
$namespace->add($class); $namespace->add($class);
$file->addNamespace($namespace); $file->addNamespace($namespace);
$this->persistClass($controller, $file); $this->persistClass($controller, $file, $runwayConfig['app_root']);
$io->ok('Controller successfully created at ' . $controllerPath, true); $io->ok('Controller successfully created at ' . $controllerPath, true);
} }
@ -80,12 +88,13 @@ class ControllerCommand extends AbstractBaseCommand
* *
* @param string $controllerName Name of the Controller * @param string $controllerName Name of the Controller
* @param PhpFile $file Class Object from Nette\PhpGenerator * @param PhpFile $file Class Object from Nette\PhpGenerator
* @param string $appRoot App Root from runway config
* *
* @return void * @return void
*/ */
protected function persistClass(string $controllerName, PhpFile $file) protected function persistClass(string $controllerName, PhpFile $file, string $appRoot)
{ {
$printer = new \Nette\PhpGenerator\PsrPrinter(); $printer = new \Nette\PhpGenerator\PsrPrinter();
file_put_contents(getcwd() . DIRECTORY_SEPARATOR . $this->config['app_root'] . 'controllers' . DIRECTORY_SEPARATOR . $controllerName . '.php', $printer->printFile($file)); file_put_contents($this->projectRoot . '/' . $appRoot . 'controllers/' . $controllerName . '.php', $printer->printFile($file));
} }
} }

@ -41,16 +41,21 @@ class RouteCommand extends AbstractBaseCommand
{ {
$io = $this->app()->io(); $io = $this->app()->io();
if (isset($this->config['index_root']) === false) { if (empty($this->config['runway'])) {
$io->error('index_root not set in .runway-config.json', true); $io->warn('Using a .runway-config.json file is deprecated. Move your config values to app/config/config.php with `php runway config:migrate`.', true); // @codeCoverageIgnore
$runwayConfig = json_decode(file_get_contents($this->projectRoot . '/.runway-config.json'), true); // @codeCoverageIgnore
} else {
$runwayConfig = $this->config['runway'];
}
if (isset($runwayConfig['index_root']) === false) {
$io->error('index_root not set in app/config/config.php', true);
return; return;
} }
$io->bold('Routes', true); $io->bold('Routes', true);
$cwd = getcwd(); $index_root = $this->projectRoot . '/' . $runwayConfig['index_root'];
$index_root = $cwd . '/' . $this->config['index_root'];
// This makes it so the framework doesn't actually execute // This makes it so the framework doesn't actually execute
Flight::map('start', function () { Flight::map('start', function () {
@ -72,8 +77,8 @@ class RouteCommand extends AbstractBaseCommand
} }
return preg_match("/^class@anonymous/", end($middleware_class_name)) ? 'Anonymous' : end($middleware_class_name); return preg_match("/^class@anonymous/", end($middleware_class_name)) ? 'Anonymous' : end($middleware_class_name);
}, $route->middleware); }, $route->middleware);
} catch (\TypeError $e) { } catch (\TypeError $e) { // @codeCoverageIgnore
$middlewares[] = 'Bad Middleware'; $middlewares[] = 'Bad Middleware'; // @codeCoverageIgnore
} finally { } finally {
if (is_string($route->middleware) === true) { if (is_string($route->middleware) === true) {
$middlewares[] = $route->middleware; $middlewares[] = $route->middleware;

@ -174,7 +174,7 @@ class Request
} }
$base = dirname($base); $base = dirname($base);
if ($base === '\\') { if ($base === '\\') {
$base = '/'; $base = '/'; // @codeCoverageIgnore
} }
$config = [ $config = [
'url' => $url, 'url' => $url,
@ -243,8 +243,8 @@ class Request
$this->data->setData($data); $this->data->setData($data);
} }
} }
// Check PUT, PATCH, DELETE for application/x-www-form-urlencoded data or multipart/form-data // Check PUT, PATCH, DELETE for application/x-www-form-urlencoded data or multipart/form-data
} elseif (in_array($this->method, [ 'PUT', 'DELETE', 'PATCH' ], true) === true) { } elseif (in_array($this->method, ['PUT', 'DELETE', 'PATCH'], true) === true) {
$this->parseRequestBodyForHttpMethods(); $this->parseRequestBodyForHttpMethods();
} }
@ -478,7 +478,7 @@ class Request
/** /**
* Retrieves the array of uploaded files. * Retrieves the array of uploaded files.
* *
* @return array<string, UploadedFile|array<int, UploadedFile>> Key is field name; value is either a single UploadedFile or an array of UploadedFile when multiple were uploaded. * @return array<string, UploadedFile|array<int, UploadedFile>> Key is field name; value is either a single UploadedFile or an array of UploadedFile when multiple were uploaded.
*/ */
public function getUploadedFiles(): array public function getUploadedFiles(): array
{ {

@ -25,8 +25,8 @@ class UploadedFileTest extends TestCase
unlink('real_file'); unlink('real_file');
} }
// not found with file_exists...just delete it brute force // not found with file_exists...just delete it brute force
@unlink('tmp_symlink'); @unlink('tmp_symlink');
} }
public function testMoveToFalseSuccess(): void public function testMoveToFalseSuccess(): void

@ -9,12 +9,14 @@ use flight\commands\AiGenerateInstructionsCommand;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use tests\classes\NoExitInteractor; use tests\classes\NoExitInteractor;
class AiGenerateInstructionsCommandTest extends TestCase { class AiGenerateInstructionsCommandTest extends TestCase
{
protected static $in; protected static $in;
protected static $ou; protected static $ou;
protected $baseDir; protected $baseDir;
public function setUp(): void { public function setUp(): void
{
self::$in = __DIR__ . DIRECTORY_SEPARATOR . 'input.test' . uniqid('', true) . '.txt'; self::$in = __DIR__ . DIRECTORY_SEPARATOR . 'input.test' . uniqid('', true) . '.txt';
self::$ou = __DIR__ . DIRECTORY_SEPARATOR . 'output.test' . uniqid('', true) . '.txt'; self::$ou = __DIR__ . DIRECTORY_SEPARATOR . 'output.test' . uniqid('', true) . '.txt';
file_put_contents(self::$in, ''); file_put_contents(self::$in, '');
@ -25,7 +27,8 @@ class AiGenerateInstructionsCommandTest extends TestCase {
} }
} }
public function tearDown(): void { public function tearDown(): void
{
if (file_exists(self::$in)) { if (file_exists(self::$in)) {
unlink(self::$in); unlink(self::$in);
} }
@ -35,7 +38,8 @@ class AiGenerateInstructionsCommandTest extends TestCase {
$this->recursiveRmdir($this->baseDir); $this->recursiveRmdir($this->baseDir);
} }
protected function recursiveRmdir($dir) { protected function recursiveRmdir($dir)
{
if (!is_dir($dir)) { if (!is_dir($dir)) {
return; return;
} }
@ -46,7 +50,8 @@ class AiGenerateInstructionsCommandTest extends TestCase {
return rmdir($dir); return rmdir($dir);
} }
protected function newApp($command): Application { protected function newApp($command): Application
{
$app = new Application('test', '0.0.1', function ($exitCode) { $app = new Application('test', '0.0.1', function ($exitCode) {
return $exitCode; return $exitCode;
}); });
@ -55,11 +60,13 @@ class AiGenerateInstructionsCommandTest extends TestCase {
return $app; return $app;
} }
protected function setInput(array $lines): void { protected function setInput(array $lines): void
{
file_put_contents(self::$in, implode("\n", $lines) . "\n"); file_put_contents(self::$in, implode("\n", $lines) . "\n");
} }
protected function setProjectRoot($command, $path) { protected function setProjectRoot($command, $path)
{
$reflection = new \ReflectionClass(get_class($command)); $reflection = new \ReflectionClass(get_class($command));
$property = null; $property = null;
$currentClass = $reflection; $currentClass = $reflection;
@ -79,7 +86,8 @@ class AiGenerateInstructionsCommandTest extends TestCase {
} }
} }
public function testFailsIfAiConfigMissing() { public function testFailsIfAiConfigMissing()
{
$this->setInput([ $this->setInput([
'desc', 'desc',
'none', 'none',
@ -107,7 +115,8 @@ class AiGenerateInstructionsCommandTest extends TestCase {
$this->assertStringContainsString('Missing AI configuration', file_get_contents(self::$ou)); $this->assertStringContainsString('Missing AI configuration', file_get_contents(self::$ou));
} }
public function testWritesInstructionsToFiles() { public function testWritesInstructionsToFiles()
{
$creds = [ $creds = [
'api_key' => 'key', 'api_key' => 'key',
'model' => 'gpt-4o', 'model' => 'gpt-4o',
@ -154,7 +163,8 @@ class AiGenerateInstructionsCommandTest extends TestCase {
$this->assertFileExists($this->baseDir . '.windsurfrules'); $this->assertFileExists($this->baseDir . '.windsurfrules');
} }
public function testNoInstructionsReturnedFromLlm() { public function testNoInstructionsReturnedFromLlm()
{
$creds = [ $creds = [
'api_key' => 'key', 'api_key' => 'key',
'model' => 'gpt-4o', 'model' => 'gpt-4o',
@ -196,7 +206,8 @@ class AiGenerateInstructionsCommandTest extends TestCase {
$this->assertSame(1, $result); $this->assertSame(1, $result);
} }
public function testLlmApiCallFails() { public function testLlmApiCallFails()
{
$creds = [ $creds = [
'api_key' => 'key', 'api_key' => 'key',
'model' => 'gpt-4o', 'model' => 'gpt-4o',
@ -234,7 +245,8 @@ class AiGenerateInstructionsCommandTest extends TestCase {
$this->assertSame(1, $result); $this->assertSame(1, $result);
} }
public function testUsesDeprecatedConfigFile() { public function testUsesDeprecatedConfigFile()
{
$creds = [ $creds = [
'ai' => [ 'ai' => [
'api_key' => 'key', 'api_key' => 'key',

@ -48,7 +48,7 @@ class ControllerCommandTest extends TestCase
protected function newApp(string $name, string $version = '') protected function newApp(string $name, string $version = '')
{ {
$app = @new Application($name, $version ?: '0.0.1', fn () => false); $app = @new Application($name, $version ?: '0.0.1', fn() => false);
return @$app->io(new Interactor(static::$in, static::$ou)); return @$app->io(new Interactor(static::$in, static::$ou));
} }
@ -56,10 +56,10 @@ class ControllerCommandTest extends TestCase
public function testConfigAppRootNotSet(): void public function testConfigAppRootNotSet(): void
{ {
$app = $this->newApp('test', '0.0.1'); $app = $this->newApp('test', '0.0.1');
$app->add(new ControllerCommand([])); $app->add(new ControllerCommand(['runway' => ['something' => '']]));
@$app->handle(['runway', 'make:controller', 'Test']); @$app->handle(['runway', 'make:controller', 'Test']);
$this->assertStringContainsString('app_root not set in .runway-config.json', file_get_contents(static::$ou)); $this->assertStringContainsString('app_root not set in app/config/config.php', file_get_contents(static::$ou));
} }
public function testControllerAlreadyExists(): void public function testControllerAlreadyExists(): void
@ -67,7 +67,7 @@ class ControllerCommandTest extends TestCase
$app = $this->newApp('test', '0.0.1'); $app = $this->newApp('test', '0.0.1');
mkdir(__DIR__ . '/controllers/'); mkdir(__DIR__ . '/controllers/');
file_put_contents(__DIR__ . '/controllers/TestController.php', '<?php class TestController {}'); file_put_contents(__DIR__ . '/controllers/TestController.php', '<?php class TestController {}');
$app->add(new ControllerCommand(['app_root' => 'tests/commands/'])); $app->add(new ControllerCommand(['runway' => ['app_root' => 'tests/commands/']]));
$app->handle(['runway', 'make:controller', 'Test']); $app->handle(['runway', 'make:controller', 'Test']);
$this->assertStringContainsString('TestController already exists.', file_get_contents(static::$ou)); $this->assertStringContainsString('TestController already exists.', file_get_contents(static::$ou));
@ -76,7 +76,7 @@ class ControllerCommandTest extends TestCase
public function testCreateController(): void public function testCreateController(): void
{ {
$app = $this->newApp('test', '0.0.1'); $app = $this->newApp('test', '0.0.1');
$app->add(new ControllerCommand(['app_root' => 'tests/commands/'])); $app->add(new ControllerCommand(['runway' => ['app_root' => 'tests/commands/']]));
$app->handle(['runway', 'make:controller', 'Test']); $app->handle(['runway', 'make:controller', 'Test']);
$this->assertFileExists(__DIR__ . '/controllers/TestController.php'); $this->assertFileExists(__DIR__ . '/controllers/TestController.php');

@ -23,6 +23,7 @@ class RouteCommandTest extends TestCase
static::$ou = __DIR__ . DIRECTORY_SEPARATOR . 'output.test' . uniqid('', true) . '.txt'; static::$ou = __DIR__ . DIRECTORY_SEPARATOR . 'output.test' . uniqid('', true) . '.txt';
file_put_contents(static::$in, ''); file_put_contents(static::$in, '');
file_put_contents(static::$ou, ''); file_put_contents(static::$ou, '');
$_SERVER = []; $_SERVER = [];
$_REQUEST = []; $_REQUEST = [];
Flight::init(); Flight::init();
@ -91,21 +92,22 @@ PHP;
public function testConfigIndexRootNotSet(): void public function testConfigIndexRootNotSet(): void
{ {
$app = @$this->newApp('test', '0.0.1'); $app = @$this->newApp('test', '0.0.1');
$app->add(new RouteCommand([])); $app->add(new RouteCommand(['runway' => ['something' => 'else']]));
@$app->handle(['runway', 'routes']); @$app->handle(['runway', 'routes']);
$this->assertStringContainsString('index_root not set in .runway-config.json', file_get_contents(static::$ou)); $this->assertStringContainsString('index_root not set in app/config/config.php', file_get_contents(static::$ou));
} }
public function testGetRoutes(): void public function testGetRoutes(): void
{ {
$app = @$this->newApp('test', '0.0.1'); $app = @$this->newApp('test', '0.0.1');
$this->createIndexFile(); $this->createIndexFile();
$app->add(new RouteCommand(['index_root' => 'tests/commands/index.php'])); $app->add(new RouteCommand(['runway' => ['index_root' => 'tests/commands/index.php']]));
@$app->handle(['runway', 'routes']); @$app->handle(['runway', 'routes']);
$this->assertStringContainsString('Routes', file_get_contents(static::$ou)); $this->assertStringContainsString('Routes', file_get_contents(static::$ou));
$expected = <<<'output' $expected = <<<'output'
Routes
+---------+--------------------+-------+----------+----------------+ +---------+--------------------+-------+----------+----------------+
| Pattern | Methods | Alias | Streamed | Middleware | | Pattern | Methods | Alias | Streamed | Middleware |
+---------+--------------------+-------+----------+----------------+ +---------+--------------------+-------+----------+----------------+
@ -127,12 +129,13 @@ PHP;
{ {
$app = @$this->newApp('test', '0.0.1'); $app = @$this->newApp('test', '0.0.1');
$this->createIndexFile(); $this->createIndexFile();
$app->add(new RouteCommand(['index_root' => 'tests/commands/index.php'])); $app->add(new RouteCommand(['runway' => ['index_root' => 'tests/commands/index.php']]));
@$app->handle(['runway', 'routes', '--post']); @$app->handle(['runway', 'routes', '--post']);
$this->assertStringContainsString('Routes', file_get_contents(static::$ou)); $this->assertStringContainsString('Routes', file_get_contents(static::$ou));
$expected = <<<'output' $expected = <<<'output'
Routes
+---------+---------------+-------+----------+------------+ +---------+---------------+-------+----------+------------+
| Pattern | Methods | Alias | Streamed | Middleware | | Pattern | Methods | Alias | Streamed | Middleware |
+---------+---------------+-------+----------+------------+ +---------+---------------+-------+----------+------------+
@ -140,6 +143,8 @@ PHP;
+---------+---------------+-------+----------+------------+ +---------+---------------+-------+----------+------------+
output; // phpcs:ignore output; // phpcs:ignore
$expected = str_replace(["\r\n", "\\n", "\n"], ["\n", "", "\n"], $expected);
$this->assertStringContainsString( $this->assertStringContainsString(
$expected, $expected,
$this->removeColors(file_get_contents(static::$ou)) $this->removeColors(file_get_contents(static::$ou))

Loading…
Cancel
Save