diff --git a/src/Idephix/Context.php b/src/Idephix/Context.php index 221a728..5ee3a8d 100644 --- a/src/Idephix/Context.php +++ b/src/Idephix/Context.php @@ -87,6 +87,15 @@ public function execute($name) call_user_func_array(array($this->idx, 'execute'), func_get_args()); } + /** + * @param $name + * @return integer 0 success, 1 fail + */ + public function executeOnce($name) + { + call_user_func_array(array($this->idx, 'executeOnce'), func_get_args()); + } + /** * Execute remote command. * diff --git a/src/Idephix/Idephix.php b/src/Idephix/Idephix.php index 67128e4..b405d29 100644 --- a/src/Idephix/Idephix.php +++ b/src/Idephix/Idephix.php @@ -41,6 +41,7 @@ class Idephix implements Builder, TaskExecutor /** @var Context */ protected $context; protected $invokerClassName; + protected $executed = array(); public function __construct( Config $config, @@ -266,6 +267,24 @@ public function execute($name) ); } + /** + * RunTask only once for multiple context + * + * @param string $name the name of the task you want to call + * @param (...) arbitrary number of parameter matching the target task interface + * @return integer + */ + public function executeOnce($name) + { + if (isset($this->executed[$name])) { + return $this->executed[$name]; + } + + $this->executed[$name] = call_user_func_array(array($this, 'execute'), func_get_args()); + + return $this->executed[$name]; + } + public function addSelfUpdateCommand() { if ('phar:' === substr(__FILE__, 0, 5)) { diff --git a/tests/unit/Idephix/IdephixTest.php b/tests/unit/Idephix/IdephixTest.php index c6b1403..7d79f60 100644 --- a/tests/unit/Idephix/IdephixTest.php +++ b/tests/unit/Idephix/IdephixTest.php @@ -231,6 +231,66 @@ function (Context $idx, $what, $go = false) { $this->assertEquals(0, $this->idx->execute('test', 42)); } + /** + * @test + */ + public function it_should_allow_to_invoke_tasks_only_once() + { + $this->idx->addTask( + CallableTask::buildFromClosure( + 'test', + function (Context $idx, $what) { + return $what; + } + ) + ); + $this->assertEquals(42, $this->idx->executeOnce('test', 42)); + $this->assertEquals(42, $this->idx->executeOnce('test', 24)); + } + + /** + * @test + */ + public function it_should_allow_to_invoke_tasks_only_once_cross_context() + { + $output = fopen('php://memory', 'r+'); + + $idx = new Idephix( + Config::fromArray(array( + Config::SSHCLIENT => new SshClient(new StubProxy()), + Config::ENVS => array( + 'prod' => array( + 'hosts' => array('127.0.0.1', 'localhost'), + 'ssh_params' => array('user' => 'kea') + ) + ))), + new StreamOutput($output), + new StringInput('test --env=prod') + ); + + $idx->addTask( + CallableTask::buildFromClosure( + 'test', + function (Context $idx) { + $idx->writeln("Always: ".$idx->currentHost()); + $idx->executeOnce('testOnce', $idx->currentHost()); + } + ) + ); + $idx->addTask( + CallableTask::buildFromClosure( + 'testOnce', + function (Context $idx, $what) { + $idx->writeln("Once: $what"); + } + ) + ); + $idx->run(); + + rewind($output); + $this->assertEquals("Always: 127.0.0.1\nOnce: 127.0.0.1\nAlways: localhost\n", stream_get_contents($output)); + } + /** * @test */