-
Notifications
You must be signed in to change notification settings - Fork 824
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
NEW Refactor CLI interaction with Silverstripe app
- Turn sake into a symfony/console app - Avoid using HTTPRequest for CLI interaction - Implement abstract hybrid execution path
- Loading branch information
1 parent
e3508d4
commit 314fc20
Showing
19 changed files
with
1,102 additions
and
288 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
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,21 @@ | ||
#!/usr/bin/env php | ||
<?php | ||
|
||
use SilverStripe\Cli\Sake; | ||
|
||
// Ensure that people can't access this from a web-server | ||
if (!in_array(PHP_SAPI, ['cli', 'cgi', 'cgi-fcgi'])) { | ||
echo 'sake cannot be run from a web request, you have to run it on the command-line.'; | ||
die(); | ||
} | ||
|
||
require_once __DIR__ . '/../src/includes/autoload.php'; | ||
|
||
$sake = new Sake(); | ||
$sake->addCommands([ | ||
// probably do this inside the sake app itself though | ||
// TODO: | ||
// - flush | ||
// - navigate (use HTTPRequest and spin off a "web" request from CLI) | ||
]); | ||
$sake->run(); |
This file was deleted.
Oops, something went wrong.
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,52 @@ | ||
<?php | ||
|
||
namespace SilverStripe\Cli; | ||
|
||
use Symfony\Component\Console\Command\Command; | ||
use Symfony\Component\Console\CommandLoader\CommandLoaderInterface; | ||
use Symfony\Component\Console\Exception\CommandNotFoundException; | ||
|
||
/** | ||
* Command loader that holds more command loaders | ||
*/ | ||
class ArrayCommandLoader implements CommandLoaderInterface | ||
{ | ||
/** | ||
* @var array<CommandLoaderInterface> | ||
*/ | ||
private array $loaders = []; | ||
|
||
public function __construct(array $loaders) | ||
{ | ||
$this->loaders = $loaders; | ||
} | ||
|
||
public function get(string $name): Command | ||
{ | ||
foreach ($this->loaders as $loader) { | ||
if ($loader->has($name)) { | ||
return $loader->get($name); | ||
} | ||
} | ||
throw new CommandNotFoundException("Can't find command $name"); | ||
} | ||
|
||
public function has(string $name): bool | ||
{ | ||
foreach ($this->loaders as $loader) { | ||
if ($loader->has($name)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
public function getNames(): array | ||
{ | ||
$names = []; | ||
foreach ($this->loaders as $loader) { | ||
$names = array_merge($names, $loader->getNames()); | ||
} | ||
return array_unique($names); | ||
} | ||
} |
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,89 @@ | ||
<?php | ||
|
||
namespace SilverStripe\Cli; | ||
|
||
use SilverStripe\Dev\DevelopmentAdmin; | ||
use SilverStripe\Dev\HybridExecution\Command\HybridCommand; | ||
use SilverStripe\Dev\HybridExecution\HybridOutput; | ||
use Symfony\Component\Console\Command\Command; | ||
use Symfony\Component\Console\CommandLoader\CommandLoaderInterface; | ||
use Symfony\Component\Console\Exception\CommandNotFoundException; | ||
use Symfony\Component\Console\Input\InputInterface; | ||
use Symfony\Component\Console\Output\OutputInterface; | ||
|
||
/** | ||
* Get commands for the controllers registered in DevelopmentAdmin | ||
*/ | ||
class DevCommandLoader implements CommandLoaderInterface | ||
{ | ||
private $commands = []; | ||
|
||
public function get(string $name): Command | ||
{ | ||
$this->init(); | ||
$name = $this->deAlias($name); | ||
if (!$this->has($name)) { | ||
throw new CommandNotFoundException("Can't find command $name"); | ||
} | ||
/** @var HybridCommand $commandClass */ | ||
$commandClass = $this->commands[$name]; | ||
$hybridCommand = $commandClass::create(); | ||
// Use the name that was passed into the method instead of fetching from the hybrid command | ||
// because it includes the full namespace. | ||
$command = new Command($name); | ||
$command->setAliases([$this->makeAlias($name)]); | ||
$command->setDescription($hybridCommand->getDescription()); | ||
$command->setCode(function (InputInterface $input, OutputInterface $output) use ($hybridCommand) { | ||
$hybridOutput = HybridOutput::create( | ||
HybridOutput::CONTEXT_CONSOLE, | ||
$output->getVerbosity(), | ||
$output->isDecorated(), | ||
$output | ||
); | ||
// TODO make the title look a lil nicer | ||
$hybridOutput->writeln([$hybridCommand->getTitle(), '--------']); | ||
return $hybridCommand->run($input, $hybridOutput); | ||
}); | ||
return $command; | ||
} | ||
|
||
public function has(string $name): bool | ||
{ | ||
$this->init(); | ||
if (array_key_exists($name, $this->commands)) { | ||
return true; | ||
} | ||
var_dump($name); | ||
return array_key_exists($this->deAlias($name), $this->commands); | ||
} | ||
|
||
public function getNames(): array | ||
{ | ||
$this->init(); | ||
return array_keys($this->commands); | ||
} | ||
|
||
private function init(): void | ||
{ | ||
if (!empty($this->commands)) { | ||
return; | ||
} | ||
$commands = DevelopmentAdmin::singleton()->getCommands(); | ||
foreach ($commands as $name => $class) { | ||
if (!$class::canRunInBrowser()) { | ||
unset($commands[$name]); | ||
} | ||
} | ||
$this->commands = $commands; | ||
} | ||
|
||
private function deAlias(string $name): string | ||
{ | ||
return str_replace('/', ':', $name); | ||
} | ||
|
||
private function makeAlias(string $name): string | ||
{ | ||
return str_replace(':', '/', $name); | ||
} | ||
} |
Oops, something went wrong.