mirror of
https://github.com/andres-montanez/Magallanes
synced 2024-05-18 05:36:40 +02:00
Merge 91979c4b56
into ef72936c52
This commit is contained in:
commit
686817ef20
|
@ -14,10 +14,10 @@ use Mage\Deploy\Strategy\StrategyInterface;
|
|||
use Mage\Runtime\Exception\RuntimeException;
|
||||
use Mage\Runtime\Runtime;
|
||||
use Mage\Task\ExecuteOnRollbackInterface;
|
||||
use Mage\Task\AbstractTask;
|
||||
use Mage\Task\Exception\ErrorException;
|
||||
use Mage\Task\Exception\SkipException;
|
||||
use Mage\Task\TaskFactory;
|
||||
use Mage\Task\TaskInterface;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
@ -185,8 +185,17 @@ class DeployCommand extends AbstractCommand
|
|||
$succeededTasks = 0;
|
||||
|
||||
foreach ($tasks as $taskName) {
|
||||
/** @var AbstractTask $task */
|
||||
$task = $this->taskFactory->get($taskName);
|
||||
$options = null;
|
||||
|
||||
// Handle the options
|
||||
if (is_array($taskName)) {
|
||||
$options = $taskName;
|
||||
$taskName = key($options);
|
||||
$options = $options[$taskName];
|
||||
}
|
||||
|
||||
/** @var TaskInterface $task */
|
||||
$task = $this->taskFactory->get($taskName, $options);
|
||||
$output->write(sprintf(' Running <fg=magenta>%s</> ... ', $task->getDescription()));
|
||||
$this->log(sprintf('Running task %s (%s)', $task->getDescription(), $task->getName()));
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ use Mage\Runtime\Runtime;
|
|||
*
|
||||
* @author Andrés Montañez <andresmontanez@gmail.com>
|
||||
*/
|
||||
abstract class AbstractTask
|
||||
abstract class AbstractTask implements TaskInterface
|
||||
{
|
||||
/**
|
||||
* @var array Task custom options
|
||||
|
@ -29,27 +29,6 @@ abstract class AbstractTask
|
|||
*/
|
||||
protected $runtime;
|
||||
|
||||
/**
|
||||
* Get the Name/Code of the Task
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getName();
|
||||
|
||||
/**
|
||||
* Get a short Description of the Task
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getDescription();
|
||||
|
||||
/**
|
||||
* Executes the Command
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function execute();
|
||||
|
||||
/**
|
||||
* Set additional Options for the Task
|
||||
*
|
||||
|
|
|
@ -20,18 +20,21 @@ use ReflectionClass;
|
|||
* Task Factory
|
||||
*
|
||||
* @author Andrés Montañez <andresmontanez@gmail.com>
|
||||
* @author Kamil Kuzminski <https://github.com/qzminski>
|
||||
*/
|
||||
class TaskFactory
|
||||
{
|
||||
/**
|
||||
* Runtime
|
||||
* @var Runtime
|
||||
*/
|
||||
protected $runtime;
|
||||
private $runtime;
|
||||
|
||||
/**
|
||||
* @var array Registered Tasks
|
||||
* Registered tasks
|
||||
* @var TaskInterface[]
|
||||
*/
|
||||
protected $registeredTasks = [];
|
||||
private $tasks = [];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -48,11 +51,29 @@ class TaskFactory
|
|||
* Add a Task
|
||||
*
|
||||
* @param AbstractTask $task
|
||||
*
|
||||
* @deprecated Deprecated since 3.0, to be removed in 4.0.
|
||||
* Use the TaskFactory::addTask() instead.
|
||||
*/
|
||||
public function add(AbstractTask $task)
|
||||
{
|
||||
@trigger_error(
|
||||
'Using TaskFactory::add() has been deprecated and will no longer work in 4.0. Use the TaskFactory::addTask() instead.',
|
||||
E_USER_DEPRECATED
|
||||
);
|
||||
|
||||
$task->setRuntime($this->runtime);
|
||||
$this->registeredTasks[$task->getName()] = $task;
|
||||
$this->tasks[$task->getName()] = $task;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a task
|
||||
*
|
||||
* @param TaskInterface $task
|
||||
*/
|
||||
public function addTask(TaskInterface $task)
|
||||
{
|
||||
$this->tasks[$task->getName()] = $task;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,58 +81,101 @@ class TaskFactory
|
|||
* in that case the class will be instantiated
|
||||
*
|
||||
* @param string $name Name/Code or Class of the Task
|
||||
* @return AbstractTask
|
||||
* @param array $options
|
||||
*
|
||||
* @return TaskInterface
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function get($name)
|
||||
public function get($name, array $options = null)
|
||||
{
|
||||
$options = [];
|
||||
// TODO: backwards compatibility, remove in 4.0
|
||||
if (is_array($name)) {
|
||||
$options = $name;
|
||||
list($name) = array_keys($name);
|
||||
$name = key($options);
|
||||
$options = $options[$name];
|
||||
}
|
||||
|
||||
if (array_key_exists($name, $this->registeredTasks)) {
|
||||
/** @var AbstractTask $task */
|
||||
$task = $this->registeredTasks[$name];
|
||||
$task->setOptions($options);
|
||||
return $task;
|
||||
} elseif (class_exists($name)) {
|
||||
$reflex = new ReflectionClass($name);
|
||||
if ($reflex->isInstantiable()) {
|
||||
$task = new $name();
|
||||
if ($task instanceof AbstractTask) {
|
||||
$task->setOptions($options);
|
||||
$this->add($task);
|
||||
return $task;
|
||||
}
|
||||
}
|
||||
if (array_key_exists($name, $this->tasks)) {
|
||||
$task = $this->tasks[$name];
|
||||
} else {
|
||||
$task = $this->createTask($name);
|
||||
}
|
||||
|
||||
throw new RuntimeException(sprintf('Invalid task name "%s"', $name));
|
||||
$task->setRuntime($this->runtime);
|
||||
|
||||
if ($options !== null) {
|
||||
$task->setOptions($options);
|
||||
}
|
||||
|
||||
return $task;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load BuiltIn Tasks
|
||||
* Load the built-in tasks
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function loadBuiltInTasks()
|
||||
private function loadBuiltInTasks()
|
||||
{
|
||||
$finder = new Finder();
|
||||
$finder->files()->in(__DIR__ . '/BuiltIn')->name('*Task.php');
|
||||
$finder->files()->in(__DIR__.'/BuiltIn')->name('*Task.php');
|
||||
|
||||
/** @var SplFileInfo $file */
|
||||
foreach ($finder as $file) {
|
||||
$class = substr('\\Mage\\Task\\BuiltIn\\' . str_replace('/', '\\', $file->getRelativePathname()), 0, -4);
|
||||
if (class_exists($class)) {
|
||||
$reflex = new ReflectionClass($class);
|
||||
if ($reflex->isInstantiable()) {
|
||||
$task = new $class();
|
||||
if ($task instanceof AbstractTask) {
|
||||
$this->add($task);
|
||||
}
|
||||
}
|
||||
$class = substr('\\Mage\\Task\\BuiltIn\\'.str_replace('/', '\\', $file->getRelativePathname()), 0, -4);
|
||||
$reflex = new ReflectionClass($class);
|
||||
|
||||
// Some classes found in the folder can be abstract
|
||||
if (!$reflex->isInstantiable()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->createTask($class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the task
|
||||
*
|
||||
* @param string $class
|
||||
*
|
||||
* @return TaskInterface
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
private function createTask($class)
|
||||
{
|
||||
$this->validateTask($class);
|
||||
|
||||
/** @var TaskInterface $task */
|
||||
$task = new $class();
|
||||
|
||||
// Register the task
|
||||
$this->addTask($task);
|
||||
|
||||
return $task;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the task
|
||||
*
|
||||
* @param string $class
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
private function validateTask($class)
|
||||
{
|
||||
if (!class_exists($class)) {
|
||||
throw new RuntimeException(sprintf('The class "%s" does not exist', $class));
|
||||
}
|
||||
|
||||
$reflex = new ReflectionClass($class);
|
||||
|
||||
if (!$reflex->implementsInterface(TaskInterface::class)) {
|
||||
throw new RuntimeException(
|
||||
sprintf('The class "%s" must implement the "%s" interface', $class, TaskInterface::class)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
60
src/Task/TaskInterface.php
Normal file
60
src/Task/TaskInterface.php
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of the Magallanes package.
|
||||
*
|
||||
* (c) Andrés Montañez <andres@andresmontanez.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Mage\Task;
|
||||
|
||||
use Mage\Runtime\Runtime;
|
||||
|
||||
/**
|
||||
* The task interface
|
||||
*
|
||||
* @author Kamil Kuzminski <https://github.com/qzminski>
|
||||
*/
|
||||
interface TaskInterface
|
||||
{
|
||||
/**
|
||||
* Get the Name/Code of the Task
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* Get a short Description of the Task
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription();
|
||||
|
||||
/**
|
||||
* Executes the Command
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function execute();
|
||||
|
||||
/**
|
||||
* Set additional Options for the Task
|
||||
*
|
||||
* @param array $options Options
|
||||
*
|
||||
* @return TaskInterface
|
||||
*/
|
||||
public function setOptions($options = []);
|
||||
|
||||
/**
|
||||
* Set the Runtime instance
|
||||
*
|
||||
* @param Runtime $runtime
|
||||
*
|
||||
* @return TaskInterface
|
||||
*/
|
||||
public function setRuntime(Runtime $runtime);
|
||||
}
|
|
@ -122,7 +122,7 @@ class DeployCommandMiscTasksTest extends TestCase
|
|||
|
||||
$tester->execute(['command' => $command->getName(), 'environment' => 'test']);
|
||||
$this->assertEquals(7, $tester->getStatusCode());
|
||||
$this->assertContains('Invalid task name "invalid/task"', $tester->getDisplay());
|
||||
$this->assertContains('The class "invalid/task" does not exist', $tester->getDisplay());
|
||||
}
|
||||
|
||||
public function testBrokenGitBranch()
|
||||
|
|
|
@ -18,29 +18,31 @@ use PHPUnit_Framework_TestCase as TestCase;
|
|||
|
||||
class TaskFactoryTest extends TestCase
|
||||
{
|
||||
public function testNonInstantiable()
|
||||
public function testClassNotExists()
|
||||
{
|
||||
$runtime = new Runtime();
|
||||
$factory = new TaskFactory($runtime);
|
||||
|
||||
try {
|
||||
$factory->get('Traversable');
|
||||
$this->getFactory()->get('Foobar');
|
||||
} catch (Exception $exception) {
|
||||
$this->assertTrue($exception instanceof RuntimeException);
|
||||
$this->assertEquals('Invalid task name "Traversable"', $exception->getMessage());
|
||||
$this->assertEquals('The class "Foobar" does not exist', $exception->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function testNotExtendingAbstractTask()
|
||||
public function testNotImplementingInterface()
|
||||
{
|
||||
$runtime = new Runtime();
|
||||
$factory = new TaskFactory($runtime);
|
||||
|
||||
try {
|
||||
$factory->get('stdClass');
|
||||
$this->getFactory()->get('stdClass');
|
||||
} catch (Exception $exception) {
|
||||
$this->assertTrue($exception instanceof RuntimeException);
|
||||
$this->assertEquals('Invalid task name "stdClass"', $exception->getMessage());
|
||||
$this->assertEquals(
|
||||
'The class "stdClass" must implement the "Mage\Task\TaskInterface" interface',
|
||||
$exception->getMessage()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function getFactory()
|
||||
{
|
||||
return new TaskFactory(new Runtime());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue