-
Notifications
You must be signed in to change notification settings - Fork 407
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #586 from flightphp/runway-reconfig
Changed it so runway commands are run from any repo
- Loading branch information
Showing
8 changed files
with
438 additions
and
9 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,4 @@ coverage/ | |
*.sublime* | ||
clover.xml | ||
phpcs.xml | ||
.runway-config.json |
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace flight\commands; | ||
|
||
use Nette\PhpGenerator\ClassType; | ||
use Nette\PhpGenerator\PhpFile; | ||
use Nette\PhpGenerator\PhpNamespace; | ||
|
||
class ControllerCommand extends AbstractBaseCommand | ||
{ | ||
/** | ||
* Construct | ||
* | ||
* @param array<string,mixed> $config JSON config from .runway-config.json | ||
*/ | ||
public function __construct(array $config) | ||
{ | ||
parent::__construct('make:controller', 'Create a controller', $config); | ||
$this->argument('<controller>', 'The name of the controller to create (with or without the Controller suffix)'); | ||
} | ||
|
||
/** | ||
* Executes the function | ||
* | ||
* @return void | ||
*/ | ||
public function execute(string $controller) | ||
{ | ||
$io = $this->app()->io(); | ||
if (isset($this->config['app_root']) === false) { | ||
$io->error('app_root not set in .runway-config.json', true); | ||
return; | ||
} | ||
|
||
if (!preg_match('/Controller$/', $controller)) { | ||
$controller .= 'Controller'; | ||
} | ||
|
||
$controllerPath = getcwd() . DIRECTORY_SEPARATOR . $this->config['app_root'] . 'controllers' . DIRECTORY_SEPARATOR . $controller . '.php'; | ||
if (file_exists($controllerPath) === true) { | ||
$io->error($controller . ' already exists.', true); | ||
return; | ||
} | ||
|
||
if (is_dir(dirname($controllerPath)) === false) { | ||
$io->info('Creating directory ' . dirname($controllerPath), true); | ||
mkdir(dirname($controllerPath), 0755, true); | ||
} | ||
|
||
$file = new PhpFile(); | ||
$file->setStrictTypes(); | ||
|
||
$namespace = new PhpNamespace('app\\controllers'); | ||
$namespace->addUse('flight\\Engine'); | ||
|
||
$class = new ClassType($controller); | ||
$class->addProperty('app') | ||
->setVisibility('protected') | ||
->setType('flight\\Engine') | ||
->addComment('@var Engine'); | ||
$method = $class->addMethod('__construct') | ||
->addComment('Constructor') | ||
->setVisibility('public') | ||
->setBody('$this->app = $app;'); | ||
$method->addParameter('app') | ||
->setType('flight\\Engine'); | ||
|
||
$namespace->add($class); | ||
$file->addNamespace($namespace); | ||
|
||
$this->persistClass($controller, $file); | ||
|
||
$io->ok('Controller successfully created at ' . $controllerPath, true); | ||
} | ||
|
||
/** | ||
* Saves the class name to a file | ||
* | ||
* @param string $controllerName Name of the Controller | ||
* @param PhpFile $file Class Object from Nette\PhpGenerator | ||
* | ||
* @return void | ||
*/ | ||
protected function persistClass(string $controllerName, PhpFile $file) | ||
{ | ||
$printer = new \Nette\PhpGenerator\PsrPrinter(); | ||
file_put_contents(getcwd() . DIRECTORY_SEPARATOR . $this->config['app_root'] . 'controllers' . DIRECTORY_SEPARATOR . $controllerName . '.php', $printer->printFile($file)); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace flight\commands; | ||
|
||
use Flight; | ||
use flight\net\Route; | ||
|
||
/** | ||
* @property-read ?bool $get | ||
* @property-read ?bool $post | ||
* @property-read ?bool $delete | ||
* @property-read ?bool $put | ||
* @property-read ?bool $patch | ||
*/ | ||
class RouteCommand extends AbstractBaseCommand | ||
{ | ||
/** | ||
* Construct | ||
* | ||
* @param array<string,mixed> $config JSON config from .runway-config.json | ||
*/ | ||
public function __construct(array $config) | ||
{ | ||
parent::__construct('routes', 'Gets all routes for an application', $config); | ||
|
||
$this->option('--get', 'Only return GET requests'); | ||
$this->option('--post', 'Only return POST requests'); | ||
$this->option('--delete', 'Only return DELETE requests'); | ||
$this->option('--put', 'Only return PUT requests'); | ||
$this->option('--patch', 'Only return PATCH requests'); | ||
} | ||
|
||
/** | ||
* Executes the function | ||
* | ||
* @return void | ||
*/ | ||
public function execute() | ||
{ | ||
$io = $this->app()->io(); | ||
|
||
if(isset($this->config['index_root']) === false) { | ||
$io->error('index_root not set in .runway-config.json', true); | ||
return; | ||
} | ||
|
||
$io->bold('Routes', true); | ||
|
||
$cwd = getcwd(); | ||
|
||
$index_root = $cwd . '/' . $this->config['index_root']; | ||
|
||
// This makes it so the framework doesn't actually execute | ||
Flight::map('start', function () { | ||
return; | ||
}); | ||
include($index_root); | ||
$routes = Flight::router()->getRoutes(); | ||
$arrayOfRoutes = []; | ||
foreach ($routes as $route) { | ||
if ($this->shouldAddRoute($route) === true) { | ||
$middlewares = []; | ||
if (!empty($route->middleware)) { | ||
try { | ||
$middlewares = array_map(function ($middleware) { | ||
$middleware_class_name = explode("\\", get_class($middleware)); | ||
return preg_match("/^class@anonymous/", end($middleware_class_name)) ? 'Anonymous' : end($middleware_class_name); | ||
}, $route->middleware); | ||
} catch (\TypeError $e) { | ||
$middlewares[] = 'Bad Middleware'; | ||
} finally { | ||
if(is_string($route->middleware) === true) { | ||
$middlewares[] = $route->middleware; | ||
} | ||
} | ||
} | ||
|
||
$arrayOfRoutes[] = [ | ||
'Pattern' => $route->pattern, | ||
'Methods' => implode(', ', $route->methods), | ||
'Alias' => $route->alias ?? '', | ||
'Streamed' => $route->is_streamed ? 'Yes' : 'No', | ||
'Middleware' => !empty($middlewares) ? implode(",", $middlewares) : '-' | ||
]; | ||
} | ||
} | ||
$io->table($arrayOfRoutes, [ | ||
'head' => 'boldGreen' | ||
]); | ||
} | ||
|
||
/** | ||
* Whether or not to add the route based on the request | ||
* | ||
* @param Route $route Flight Route object | ||
* | ||
* @return boolean | ||
*/ | ||
public function shouldAddRoute(Route $route) | ||
{ | ||
$boolval = false; | ||
|
||
$showAll = !$this->get && !$this->post && !$this->put && !$this->delete && !$this->patch; | ||
if ($showAll === true) { | ||
$boolval = true; | ||
} else { | ||
$methods = [ 'GET', 'POST', 'PUT', 'DELETE', 'PATCH' ]; | ||
foreach ($methods as $method) { | ||
$lowercaseMethod = strtolower($method); | ||
if ( | ||
$this->{$lowercaseMethod} === true && | ||
( | ||
$route->methods[0] === '*' || | ||
in_array($method, $route->methods, true) === true | ||
) | ||
) { | ||
$boolval = true; | ||
break; | ||
} | ||
} | ||
} | ||
return $boolval; | ||
} | ||
} |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace tests\commands; | ||
|
||
use Ahc\Cli\Application; | ||
use Ahc\Cli\IO\Interactor; | ||
use flight\commands\ControllerCommand; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
class ControllerCommandTest extends TestCase | ||
{ | ||
|
||
protected static $in = __DIR__ . '/input.test'; | ||
protected static $ou = __DIR__ . '/output.test'; | ||
|
||
public function setUp(): void | ||
{ | ||
file_put_contents(static::$in, '', LOCK_EX); | ||
file_put_contents(static::$ou, '', LOCK_EX); | ||
} | ||
|
||
public function tearDown(): void | ||
{ | ||
// Make sure we clean up after ourselves: | ||
if (file_exists(static::$in)) { | ||
unlink(static::$in); | ||
} | ||
if (file_exists(static::$ou)) { | ||
unlink(static::$ou); | ||
} | ||
|
||
if (file_exists(__DIR__.'/controllers/TestController.php')) { | ||
unlink(__DIR__.'/controllers/TestController.php'); | ||
} | ||
|
||
if (file_exists(__DIR__.'/controllers/')) { | ||
rmdir(__DIR__.'/controllers/'); | ||
} | ||
} | ||
|
||
protected function newApp(string $name, string $version = '') | ||
{ | ||
$app = new Application($name, $version ?: '0.0.1', fn () => false); | ||
|
||
return $app->io(new Interactor(static::$in, static::$ou)); | ||
} | ||
|
||
public function testConfigAppRootNotSet() | ||
{ | ||
$app = $this->newApp('test', '0.0.1'); | ||
$app->add(new ControllerCommand([])); | ||
$app->handle(['runway', 'make:controller', 'Test']); | ||
|
||
$this->assertStringContainsString('app_root not set in .runway-config.json', file_get_contents(static::$ou)); | ||
} | ||
|
||
public function testControllerAlreadyExists() | ||
{ | ||
$app = $this->newApp('test', '0.0.1'); | ||
mkdir(__DIR__.'/controllers/'); | ||
file_put_contents(__DIR__.'/controllers/TestController.php', '<?php class TestController {}'); | ||
$app->add(new ControllerCommand(['app_root' => 'tests/commands/'])); | ||
$app->handle(['runway', 'make:controller', 'Test']); | ||
|
||
$this->assertStringContainsString('TestController already exists.', file_get_contents(static::$ou)); | ||
} | ||
|
||
public function testCreateController() | ||
{ | ||
$app = $this->newApp('test', '0.0.1'); | ||
$app->add(new ControllerCommand(['app_root' => 'tests/commands/'])); | ||
$app->handle(['runway', 'make:controller', 'Test']); | ||
|
||
$this->assertFileExists(__DIR__.'/controllers/TestController.php'); | ||
} | ||
|
||
} |
Oops, something went wrong.