Skip to content

Commit

Permalink
[TASK] Renamed checkout task, added application specificity to after …
Browse files Browse the repository at this point in the history
…/ before, fixed some multi-application and multi-node bugs
  • Loading branch information
hlubek committed Jul 19, 2011
1 parent a722261 commit baa4af3
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 68 deletions.
10 changes: 6 additions & 4 deletions Classes/Application/FLOW3.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* */

use \TYPO3\Deploy\Domain\Model\Workflow;
use \TYPO3\Deploy\Domain\Model\Deployment;

/**
* A FLOW3 application template
Expand All @@ -26,18 +27,19 @@ public function __construct() {
* Register tasks for this application
*
* @param \TYPO3\Deploy\Domain\Model\Workflow $workflow
* @param \TYPO3\Deploy\Domain\Model\Deployment $deployment
* @return void
*/
public function registerTasks(Workflow $workflow) {
parent::registerTasks($workflow);
public function registerTasks(Workflow $workflow, Deployment $deployment) {
parent::registerTasks($workflow, $deployment);

$workflow
->forApplication($this, 'initialize', array(
'typo3.deploy:flow3:createdirectories'
))
->afterTask('typo3.deploy:checkout', array(
->afterTask('typo3.deploy:gitcheckout', array(
'typo3.deploy:flow3:symlink'
))
), $this)
->forApplication($this, 'migrate', array(
'typo3.deploy:flow3:migrate'
));
Expand Down
28 changes: 16 additions & 12 deletions Classes/Domain/Model/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,19 @@
* *
* */

use \TYPO3\Deploy\Domain\Model\Workflow;
use \TYPO3\Deploy\Domain\Model\Node;

/**
* A generic application
*
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 3 or later
*/
abstract class Application {
class Application {

/**
* The name
* @var string
*/
protected $name;

/**
* The application hierarchy
* @var string
*/
protected $hierarchy = array('_');

/**
* The nodes for this application
* @var array
Expand Down Expand Up @@ -56,13 +47,16 @@ public function __construct($name) {
}

/**
* Register tasks for this application
*
* @param \TYPO3\Deploy\Domain\Model\Workflow $workflow
* @param \TYPO3\Deploy\Domain\Model\Deployment $deployment
* @return void
*/
public function registerTasks(Workflow $workflow) {
public function registerTasks(Workflow $workflow, Deployment $deployment) {
$workflow
->forApplication($this, 'initialize', 'typo3.deploy:createdirectories')
->forApplication($this, 'update', 'typo3.deploy:checkout')
->forApplication($this, 'update', 'typo3.deploy:gitcheckout')
->forApplication($this, 'switch', 'typo3.deploy:symlink');
}

Expand Down Expand Up @@ -114,6 +108,16 @@ public function addNode(Node $node) {
$this->nodes[$node->getName()] = $node;
}

/**
* Return TRUE if the given node is registered for this application
*
* @param Node $node
* @return boolean
*/
public function hasNode(Node $node) {
return isset($this->nodes[$node->getName()]);
}

/**
*
* @return string
Expand Down
2 changes: 1 addition & 1 deletion Classes/Domain/Model/Deployment.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public function __construct($name) {
public function initialize() {
$this->releaseIdentifier = strftime('%Y%m%d%H%M%S', time());
foreach ($this->applications as $application) {
$application->registerTasks($this->workflow);
$application->registerTasks($this->workflow, $this);
}
foreach ($this->initCallbacks as $callback) {
$callback();
Expand Down
11 changes: 8 additions & 3 deletions Classes/Domain/Model/SimpleWorkflow.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,8 @@ class SimpleWorkflow extends Workflow {
);

/**
* Sequentially execute the stages for each node, so
* first all nodes will go through the initialize stage and
* then the next stage will be executed.
* Sequentially execute the stages for each node, so first all nodes will go through the initialize stage and
* then the next stage will be executed until the final stage is reached and the workflow is finished.
*
* A rollback will be done for all nodes as long as the stage switch was not completed.
*
Expand All @@ -52,8 +51,14 @@ public function run(Deployment $deployment) {
parent::run($deployment);
$nodes = $deployment->getNodes();
foreach ($this->stages as $stage) {
$deployment->getLogger()->log('====== Stage ' . $stage . ' ======', LOG_DEBUG);
foreach ($nodes as $node) {
$deployment->getLogger()->log('**** Node ' . $node->getName() . ' ****', LOG_DEBUG);
foreach ($deployment->getApplications() as $application) {
if (!$application->hasNode($node)) continue;

$deployment->getLogger()->log('* Application ' . $application->getName() . ' *', LOG_DEBUG);

try {
$this->executeStage($stage, $node, $application, $deployment);
} catch(\Exception $exception) {
Expand Down
131 changes: 84 additions & 47 deletions Classes/Domain/Model/Workflow.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,11 @@ public function run(Deployment $deployment) {
*/
abstract public function getName();

/**
*
* @param string $stage
* @param mixed $tasks
*/
public function forStage($stage, $tasks) {
if (!is_array($tasks)) $tasks = array($tasks);
if (!isset($this->tasks['stage']['_'][$stage])) $this->tasks['stage']['_'][$stage] = array();
$this->tasks['stage']['_'][$stage] = array_merge($this->tasks['stage']['_'][$stage], $tasks);
return $this;
}

/**
* Remove the given task from all stages and applications
*
* @param string $task
* @return void
* @return \TYPO3\Deploy\Domain\Model\Workflow
*/
public function removeTask($removeTask) {
if (isset($this->tasks['stage'])) {
Expand All @@ -69,53 +57,100 @@ public function removeTask($removeTask) {
}
}
if (isset($this->tasks['after'])) {
foreach ($this->tasks['after'] as $taskName => $tasks) {
$this->tasks['after'][$taskName] = array_filter($tasks, function($task) use ($removeTask) { return $task !== $removeTask; });
foreach ($this->tasks['after'] as $applicationName => $tasksByTask) {
foreach ($tasksByTask as $taskName => $tasks) {
$this->tasks['after'][$applicationName][$taskName] = array_filter($tasks, function($task) use ($removeTask) { return $task !== $removeTask; });
}
}
}
if (isset($this->tasks['before'])) {
foreach ($this->tasks['before'] as $taskName => $tasks) {
$this->tasks['before'][$taskName] = array_filter($tasks, function($task) use ($removeTask) { return $task !== $removeTask; });
foreach ($this->tasks['before'] as $applicationName => $tasksByTask) {
foreach ($tasksByTask as $taskName => $tasks) {
$this->tasks['before'][$applicationName][$taskName] = array_filter($tasks, function($task) use ($removeTask) { return $task !== $removeTask; });
}
}
}
return $this;
}

/**
*
* @param \TYPO3\Deploy\Domain\Model\Application $application
* @param string $stage
* @param mixed $tasks
* @return \TYPO3\Deploy\Domain\Model\Workflow
*/
public function forApplication(Application $application, $stage, $tasks) {
return $this->addTask($tasks, $stage, $application);
}

/**
*
* @param string $stage
* @param string $application
* @param mixed $tasks
* @return \TYPO3\Deploy\Domain\Model\Workflow
*/
public function forStage($stage, $tasks) {
return $this->addTask($tasks, $stage);
}

/**
* Add the given tasks for a stage and optionally a specific application
*
* The tasks will be executed for the given stage. If an application is given,
* the tasks will be executed only for the stage and application.
*
* @param mixed $tasks
* @param string $stage The name of the stage when this task shall be executed
* @param \TYPO3\Deploy\Domain\Model\Application $application If given the task will be specific for this application
* @return \TYPO3\Deploy\Domain\Model\Workflow
*/
public function forApplication($application, $stage, $tasks) {
public function addTask($tasks, $stage, Application $application = NULL) {
$applicationName = $application !== NULL ? $application->getName() : '_';

if (!is_array($tasks)) $tasks = array($tasks);
if (!isset($this->tasks['stage'][$application->getName()][$stage])) $this->tasks['stage'][$application->getName()][$stage] = array();
$this->tasks['stage'][$application->getName()][$stage] = array_merge($this->tasks['stage'][$application->getName()][$stage], $tasks);
return $this;
}

/**
* Add tasks that shall be executed after the given task
*
* The execution will not depend on a stage but on an optional application.
*
* @param string $task
* @param mixed $tasks
* @param \TYPO3\Deploy\Domain\Model\Application $application
* @return \TYPO3\Deploy\Domain\Model\Workflow
*/
public function afterTask($task, $tasks) {
public function afterTask($task, $tasks, Application $application = NULL) {
if (!is_array($tasks)) $tasks = array($tasks);
if (!isset($this->tasks['after'][$task])) $this->tasks['after'][$task] = array();
$this->tasks['after'][$task] = array_merge($this->tasks['after'][$task], $tasks);

$applicationName = $application !== NULL ? $application->getName() : '_';

if (!isset($this->tasks['after'][$applicationName][$task])) $this->tasks['after'][$applicationName][$task] = array();
$this->tasks['after'][$applicationName][$task] = array_merge($this->tasks['after'][$applicationName][$task], $tasks);
return $this;
}

/**
* Add tasks that shall be executed before the given task
*
* The execution will not depend on a stage but on an optional application.
*
* @param string $task
* @param mixed $tasks
* @param \TYPO3\Deploy\Domain\Model\Application $application
* @return \TYPO3\Deploy\Domain\Model\Workflow
*/
public function beforeTask($task, $tasks) {
public function beforeTask($task, $tasks, Application $application = NULL) {
if (!is_array($tasks)) $tasks = array($tasks);
if (!isset($this->tasks['before'][$task])) $this->tasks['before'][$task] = array();
$this->tasks['before'][$task] = array_merge($this->tasks['before'][$task], $tasks);

$applicationName = $application !== NULL ? $application->getName() : '_';

if (!isset($this->tasks['before'][$applicationName][$task])) $this->tasks['before'][$applicationName][$task] = array();
$this->tasks['before'][$applicationName][$task] = array_merge($this->tasks['before'][$applicationName][$task], $tasks);
return $this;
}

Expand All @@ -128,23 +163,20 @@ public function beforeTask($task, $tasks) {
* @param \TYPO3\Deploy\Domain\Model\Deployment $deployment
* @return void
*/
protected function executeStage($stage, \TYPO3\Deploy\Domain\Model\Node $node, \TYPO3\Deploy\Domain\Model\Application $application, \TYPO3\Deploy\Domain\Model\Deployment $deployment) {
if (isset($this->tasks['stage']['_'][$stage])) {
$deployment->getLogger()->log('Executing stage "' . $stage . '" on "' . $node->getName() . '" for all', LOG_DEBUG);
foreach ($this->tasks['stage']['_'][$stage] as $task) {
$this->executeTask($task, $node, $application, $deployment);
}
}
if (isset($this->tasks['stage'][$application->getName()][$stage])) {
$deployment->getLogger()->log('Executing stage "' . $stage . '" on "' . $node->getName() . '" for application "' . $application->getName() . '"', LOG_DEBUG);
foreach ($this->tasks['stage'][$application->getName()][$stage] as $task) {
$this->executeTask($task, $node, $application, $deployment);
protected function executeStage($stage, Node $node, Application $application, Deployment $deployment) {
foreach (array('_', $application->getName()) as $applicationName) {
$label = $applicationName === '_' ? 'for all' : 'for application ' . $applicationName;
if (isset($this->tasks['stage'][$applicationName][$stage])) {
$deployment->getLogger()->log('Executing stage "' . $stage . '" on "' . $node->getName() . '" ' . $label, LOG_DEBUG);
foreach ($this->tasks['stage'][$applicationName][$stage] as $task) {
$this->executeTask($task, $node, $application, $deployment);
}
}
}
}

/**
* Execute a taks
* Execute a task and consider configured before / after "hooks"
*
* Will also execute tasks that are registered to run before or after this task.
*
Expand All @@ -155,23 +187,28 @@ protected function executeStage($stage, \TYPO3\Deploy\Domain\Model\Node $node, \
* @param array $callstack
* @return void
*/
protected function executeTask($task, \TYPO3\Deploy\Domain\Model\Node $node, \TYPO3\Deploy\Domain\Model\Application $application, \TYPO3\Deploy\Domain\Model\Deployment $deployment, &$callstack = array()) {
if (isset($this->tasks['before'][$task])) {
foreach ($this->tasks['before'][$task] as $beforeTask) {
$deployment->getLogger()->log('Task "' . $beforeTask . '" before "' . $task, LOG_DEBUG);
$this->executeTask($beforeTask, $node, $application, $deployment, $callstack);
protected function executeTask($task, Node $node, Application $application, Deployment $deployment, array &$callstack = array()) {
foreach (array('_', $application->getName()) as $applicationName) {
if (isset($this->tasks['before'][$applicationName][$task])) {
foreach ($this->tasks['before'][$applicationName][$task] as $beforeTask) {
$deployment->getLogger()->log('Task "' . $beforeTask . '" before "' . $task, LOG_DEBUG);
$this->executeTask($beforeTask, $node, $application, $deployment, $callstack);
}
}
}
if (isset($callstack[$task])) {
throw new \Exception('Cycle for task "' . $task . '" detected, aborting.');
}
$deployment->getLogger()->log('Execute task "' . $task . '" on "' . $node->getName() . '" for application "' . $application->getName(), LOG_DEBUG);
$deployment->getLogger()->log('Execute task "' . $task . '" on "' . $node->getName() . '" for application "' . $application->getName() . '"', LOG_DEBUG);
$this->taskManager->execute($task, $node, $application, $deployment);
$callstack[$task] = TRUE;
if (isset($this->tasks['after'][$task])) {
foreach ($this->tasks['after'][$task] as $beforeTask) {
$deployment->getLogger()->log('Task "' . $beforeTask . '" after "' . $task, LOG_DEBUG);
$this->executeTask($beforeTask, $node, $application, $deployment, $callstack);
foreach (array('_', $application->getName()) as $applicationName) {
$label = $applicationName === '_' ? 'for all' : 'for application ' . $applicationName;
if (isset($this->tasks['after'][$applicationName][$task])) {
foreach ($this->tasks['after'][$applicationName][$task] as $beforeTask) {
$deployment->getLogger()->log('Task "' . $beforeTask . '" after "' . $task . '" ' . $label, LOG_DEBUG);
$this->executeTask($beforeTask, $node, $application, $deployment, $callstack);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 3 or later
*/
class CheckoutTask extends \TYPO3\Deploy\Domain\Model\Task {
class GitCheckoutTask extends \TYPO3\Deploy\Domain\Model\Task {

/**
* @inject
Expand Down

0 comments on commit baa4af3

Please sign in to comment.