mirror of https://github.com/hauke68/Magallanes
Yanick Witschi
8 years ago
2 changed files with 303 additions and 0 deletions
@ -0,0 +1,146 @@
|
||||
<?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\BuiltIn\Composer; |
||||
|
||||
use Symfony\Component\Process\Process; |
||||
use Mage\Task\AbstractTask; |
||||
|
||||
/** |
||||
* Composer Task - Self update |
||||
* |
||||
* @author Yanick Witschi <https://github.com/Toflar> |
||||
*/ |
||||
class SelfUpdateTask extends AbstractTask |
||||
{ |
||||
/** |
||||
* Only used for unit tests. |
||||
* |
||||
* @var \DateTime |
||||
*/ |
||||
private $dateToCompare; |
||||
|
||||
/** |
||||
* @return string |
||||
*/ |
||||
public function getName() |
||||
{ |
||||
return 'composer/selfupdate'; |
||||
} |
||||
|
||||
/** |
||||
* @return string |
||||
*/ |
||||
public function getDescription() |
||||
{ |
||||
return '[Composer] Selfupdate'; |
||||
} |
||||
|
||||
/** |
||||
* @return bool |
||||
*/ |
||||
public function execute() |
||||
{ |
||||
$options = $this->getOptions(); |
||||
$days = $options['days']; |
||||
$versionCommand = sprintf('%s --version', $options['path']); |
||||
|
||||
/** @var Process $process */ |
||||
$process = $this->runtime->runCommand(trim($versionCommand)); |
||||
|
||||
if (!$process->isSuccessful()) { |
||||
return false; |
||||
} |
||||
|
||||
$dt = $this->extractDate($process->getOutput()); |
||||
|
||||
// Date could not be extracted, always run update |
||||
if (false === $dt) { |
||||
return $this->selfUpdate($options); |
||||
} |
||||
|
||||
// Check age |
||||
if (!$this->isOlderThan($dt, $days)) { |
||||
return true; |
||||
} |
||||
|
||||
return $this->selfUpdate($options); |
||||
} |
||||
|
||||
/** |
||||
* This tasks obviously always takes the current date to compare the age |
||||
* of the composer.phar. This method is used for unit test purposes |
||||
* only. |
||||
* |
||||
* @param \DateTime $dateToCompare |
||||
*/ |
||||
public function setDateToCompare(\DateTime $dateToCompare) |
||||
{ |
||||
$this->dateToCompare = $dateToCompare; |
||||
} |
||||
|
||||
/** |
||||
* @param \DateTime $dt |
||||
* @param int $days |
||||
* |
||||
* @return bool |
||||
*/ |
||||
protected function isOlderThan(\DateTime $dt, $days) |
||||
{ |
||||
$dtComp = new \DateTime($days . ' days ago'); |
||||
|
||||
if (null !== $this->dateToCompare) { |
||||
$dtComp = $this->dateToCompare; |
||||
} |
||||
|
||||
return $dt < $dtComp; |
||||
} |
||||
|
||||
/** |
||||
* @param array $options |
||||
* |
||||
* @return bool |
||||
*/ |
||||
protected function selfUpdate(array $options) |
||||
{ |
||||
$selfupdateCommand = sprintf('%s selfupdate %s', $options['path'], $options['release']); |
||||
|
||||
/** @var Process $process */ |
||||
$process = $this->runtime->runCommand(trim($selfupdateCommand)); |
||||
|
||||
return $process->isSuccessful(); |
||||
} |
||||
|
||||
/** |
||||
* @param string $output |
||||
* |
||||
* @return \DateTime|false |
||||
*/ |
||||
protected function extractDate($output) |
||||
{ |
||||
$date = substr($output, -19); |
||||
|
||||
return \DateTime::createFromFormat('Y-m-d H:i:s', $date); |
||||
} |
||||
|
||||
/** |
||||
* @return array |
||||
*/ |
||||
protected function getOptions() |
||||
{ |
||||
$options = array_merge( |
||||
['path' => 'composer', 'release' => '', 'days' => 30], |
||||
$this->runtime->getMergedOption('composer'), |
||||
$this->options |
||||
); |
||||
|
||||
return $options; |
||||
} |
||||
} |
@ -0,0 +1,157 @@
|
||||
<?php |
||||
|
||||
namespace Mage\Tests\Command\BuiltIn\Composer; |
||||
|
||||
use Mage\Runtime\Runtime; |
||||
use Mage\Task\BuiltIn\Composer\SelfUpdateTask; |
||||
use PHPUnit_Framework_TestCase as TestCase; |
||||
use Symfony\Component\Process\Process; |
||||
|
||||
class SelfUpdateTaskTest extends TestCase |
||||
{ |
||||
public function testBasics() |
||||
{ |
||||
$task = new SelfUpdateTask(); |
||||
$this->assertSame('composer/selfupdate', $task->getName()); |
||||
$this->assertSame('[Composer] Selfupdate', $task->getDescription()); |
||||
} |
||||
|
||||
public function testExecuteWithFailingVersionDoesNotCallSelfupdate() |
||||
{ |
||||
$runtime = $this->getMockBuilder(Runtime::class) |
||||
->setMethods(['runCommand']) |
||||
->getMock(); |
||||
|
||||
$runtime |
||||
->expects($this->once()) |
||||
->method('runCommand') |
||||
->with('composer --version') |
||||
->willReturn($this->mockProcess(false)); |
||||
|
||||
$task = $this->getTask($runtime); |
||||
$this->assertFalse($task->execute()); |
||||
} |
||||
|
||||
public function testExecuteWithNoDateVersionDoesCallSelfupdate() |
||||
{ |
||||
$runtime = $this->getMockBuilder(Runtime::class) |
||||
->setMethods(['runCommand']) |
||||
->getMock(); |
||||
|
||||
$runtime |
||||
->expects($this->exactly(2)) |
||||
->method('runCommand') |
||||
->withConsecutive( |
||||
['composer --version'], |
||||
['composer selfupdate'] |
||||
) |
||||
->willReturnOnConsecutiveCalls( |
||||
$this->mockProcess(true, 'whatever-without-valid-date'), |
||||
$this->mockProcess(true) |
||||
); |
||||
|
||||
$task = $this->getTask($runtime); |
||||
$this->assertTrue($task->execute()); |
||||
} |
||||
|
||||
public function testExecuteShouldUpdate() |
||||
{ |
||||
$runtime = $this->getMockBuilder(Runtime::class) |
||||
->setMethods(['runCommand']) |
||||
->getMock(); |
||||
|
||||
$runtime |
||||
->expects($this->exactly(2)) |
||||
->method('runCommand') |
||||
->withConsecutive( |
||||
['composer --version'], |
||||
['composer selfupdate'] |
||||
) |
||||
->willReturnOnConsecutiveCalls( |
||||
$this->mockProcess(true, 'Composer version 1.3.2 2017-01-01 18:23:41'), |
||||
$this->mockProcess(true) |
||||
); |
||||
|
||||
$task = $this->getTask($runtime); |
||||
$task->setOptions(['days' => 30]); |
||||
$this->assertTrue($task->execute()); |
||||
} |
||||
|
||||
public function testExecuteShouldNotUpdate() |
||||
{ |
||||
$runtime = $this->getMockBuilder(Runtime::class) |
||||
->setMethods(['runCommand']) |
||||
->getMock(); |
||||
|
||||
$runtime |
||||
->expects($this->exactly(1)) |
||||
->method('runCommand') |
||||
->with('composer --version') |
||||
->willReturn($this->mockProcess(true, 'Composer version 1.3.2 2017-01-01 18:23:41')); |
||||
|
||||
$task = $this->getTask($runtime); |
||||
$task->setDateToCompare(\DateTime::createFromFormat('Y-m-d H:i:s', '2016-12-10 18:23:41')); |
||||
$task->setOptions(['days' => 30]); |
||||
$this->assertTrue($task->execute()); |
||||
} |
||||
|
||||
public function testWithRelease() |
||||
{ |
||||
$runtime = $this->getMockBuilder(Runtime::class) |
||||
->setMethods(['runCommand']) |
||||
->getMock(); |
||||
|
||||
$runtime |
||||
->expects($this->exactly(2)) |
||||
->method('runCommand') |
||||
->withConsecutive( |
||||
['composer --version'], |
||||
['composer selfupdate 1.3.1'] |
||||
) |
||||
->willReturnOnConsecutiveCalls( |
||||
$this->mockProcess(true, 'Composer version 1.3.2 2017-01-01 18:23:41'), |
||||
$this->mockProcess(true) |
||||
); |
||||
|
||||
$task = $this->getTask($runtime); |
||||
$task->setOptions(['days' => 30, 'release' => '1.3.1']); |
||||
$this->assertTrue($task->execute()); |
||||
} |
||||
|
||||
private function getTask($runtime) |
||||
{ |
||||
$config = [ |
||||
'magephp' => [ |
||||
'composer' => [ |
||||
'path' => 'composer.phar' |
||||
] |
||||
] |
||||
]; |
||||
|
||||
/** @var Runtime $runtime */ |
||||
$runtime->setConfiguration($config); |
||||
|
||||
$task = new SelfUpdateTask(); |
||||
$task->setRuntime($runtime); |
||||
|
||||
return $task; |
||||
} |
||||
|
||||
private function mockProcess($successful, $output = '') |
||||
{ |
||||
$process = $this->getMockBuilder(Process::class) |
||||
->disableOriginalConstructor() |
||||
->getMock(); |
||||
$process |
||||
->expects($this->any()) |
||||
->method('isSuccessful') |
||||
->willReturn($successful); |
||||
|
||||
$process |
||||
->expects($this->any()) |
||||
->method('getOutput') |
||||
->willReturn($output); |
||||
|
||||
return $process; |
||||
} |
||||
} |
Loading…
Reference in new issue