mirror of https://github.com/hauke68/Magallanes
Andrés Montañez
8 years ago
committed by
GitHub
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