From c7aadd33589cd0c3bcfc154f696726798546e802 Mon Sep 17 00:00:00 2001 From: Sven Jungnickel Date: Tue, 7 May 2019 17:01:45 +0200 Subject: [PATCH 1/2] Add possibility to set a fallback url --- composer.json | 1 + src/Factory/ToolFactory.php | 5 + src/Model/Tool.php | 24 +++- .../Decision/UseFallbackURLDecision.php | 41 +++++++ src/Script/Processor.php | 19 +++- tests/Factory/ToolFactoryTest.php | 9 +- .../Decision/UseFallbackUrlDecisionTest.php | 103 ++++++++++++++++++ 7 files changed, 197 insertions(+), 5 deletions(-) create mode 100644 src/Script/Decision/UseFallbackURLDecision.php create mode 100644 tests/Script/Decision/UseFallbackUrlDecisionTest.php diff --git a/composer.json b/composer.json index c7e1d90..8707881 100644 --- a/composer.json +++ b/composer.json @@ -65,6 +65,7 @@ }, "phpmd": { "url": "http://static.phpmd.org/php/latest/phpmd.phar", + "fallback-url": "https://tooly.me-dresden.de/phpmd/2.6.0/phpmd.phar", "force-replace": true }, "security-checker": { diff --git a/src/Factory/ToolFactory.php b/src/Factory/ToolFactory.php index b61d137..9ebbf16 100644 --- a/src/Factory/ToolFactory.php +++ b/src/Factory/ToolFactory.php @@ -24,6 +24,7 @@ public static function createTool($name, $directory, array $parameters) 'only-dev' => true, 'force-replace' => false, 'rename' => false, + 'fallback-url' => null, ]; $parameters = array_merge($defaults, $parameters); @@ -47,6 +48,10 @@ public static function createTool($name, $directory, array $parameters) $tool->setNameToToolKey(); } + if (null !== $parameters['fallback-url']) { + $tool->setFallbackUrl($parameters['fallback-url']); + } + return $tool; } diff --git a/src/Model/Tool.php b/src/Model/Tool.php index d2910d8..664fae7 100644 --- a/src/Model/Tool.php +++ b/src/Model/Tool.php @@ -42,12 +42,16 @@ class Tool */ private $rename = false; + /** + * @var string + */ + private $fallbackUrl; + /** * @param string $name * @param string $filename * @param string $url * @param string $signUrl - * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct($name, $filename, $url, $signUrl = null) @@ -137,4 +141,22 @@ public function renameToConfigKey() { return $this->rename; } + + /** + * @param string $url + * + * @return void + */ + public function setFallbackUrl($url) + { + $this->fallbackUrl = $url; + } + + /** + * @return string + */ + public function getFallbackUrl() + { + return $this->fallbackUrl; + } } diff --git a/src/Script/Decision/UseFallbackURLDecision.php b/src/Script/Decision/UseFallbackURLDecision.php new file mode 100644 index 0000000..1876276 --- /dev/null +++ b/src/Script/Decision/UseFallbackURLDecision.php @@ -0,0 +1,41 @@ +helper->getDownloader()->isAccessible($tool->getUrl())) { + return true; + } + + if (empty($tool->getFallbackUrl())) { + return true; + } + + if (false === $this->helper->getDownloader()->isAccessible($tool->getFallbackUrl())){ + return false; + } + + return true; + } + + /** + * @return string + */ + public function getReason() + { + return 'Fallback URL is not accessible!'; + } +} diff --git a/src/Script/Processor.php b/src/Script/Processor.php index 95a7ddc..0b11f61 100644 --- a/src/Script/Processor.php +++ b/src/Script/Processor.php @@ -9,7 +9,7 @@ use Tooly\Script\Decision\IsAccessibleDecision; use Tooly\Script\Decision\IsVerifiedDecision; use Tooly\Script\Decision\OnlyDevDecision; -use Tooly\Script\Helper; +use Tooly\Script\Decision\UseFallbackURLDecision; use Tooly\Model\Tool; /** @@ -80,7 +80,7 @@ public function process(Tool $tool) return; } - $data = $this->helper->getDownloader()->download($tool->getUrl()); + $data = $this->helper->getDownloader()->download($this->getDownloadUrl($tool)); $filename = $tool->getFilename(); $this->helper->getFilesystem()->createFile($filename, $data); @@ -124,6 +124,7 @@ private function getDecisions() return [ new OnlyDevDecision($this->configuration, $this->helper), new IsAccessibleDecision($this->configuration, $this->helper), + new UseFallbackURLDecision($this->configuration, $this->helper), new FileAlreadyExistDecision($this->configuration, $this->helper), new IsVerifiedDecision($this->configuration, $this->helper), new DoReplaceDecision($this->configuration, $this->helper, $this->io), @@ -166,4 +167,18 @@ private function removeFromDir($dir, array $excludeToolNames = []) $this->helper->getFilesystem()->remove($path); } } + + /** + * @param Tool $tool + * + * @return string + */ + private function getDownloadUrl(Tool $tool) + { + if (false === $this->helper->getDownloader()->isAccessible($tool->getUrl())) { + return $tool->getFallbackUrl(); + } + + return $tool->getUrl(); + } } diff --git a/tests/Factory/ToolFactoryTest.php b/tests/Factory/ToolFactoryTest.php index 1baf06f..79ceca4 100644 --- a/tests/Factory/ToolFactoryTest.php +++ b/tests/Factory/ToolFactoryTest.php @@ -18,14 +18,19 @@ public function testCanCreateATool() $tool = ToolFactory::createTool('test', 'vfs://root', [ 'url' => 'my-url', 'sign-url' => 'my-sign-url', - 'force-replace' => true + 'force-replace' => true, + 'only-dev' => false, + 'rename' => true, + 'fallback-url' => 'fallback-url' ]); $this->assertInstanceOf(Tool::class, $tool); $this->assertEquals('my-url', $tool->getUrl()); $this->assertEquals('my-sign-url', $tool->getSignUrl()); $this->assertTrue($tool->forceReplace()); - $this->assertTrue($tool->isOnlyDev()); + $this->assertFalse($tool->isOnlyDev()); + $this->assertTrue($tool->renameToConfigKey()); + $this->assertEquals('fallback-url', $tool->getFallbackUrl()); } public function testCanCreateMultipleTools() diff --git a/tests/Script/Decision/UseFallbackUrlDecisionTest.php b/tests/Script/Decision/UseFallbackUrlDecisionTest.php new file mode 100644 index 0000000..df7b5fd --- /dev/null +++ b/tests/Script/Decision/UseFallbackUrlDecisionTest.php @@ -0,0 +1,103 @@ +getMockBuilder(Downloader::class) + ->getMock(); + + $downloader + ->expects($this->once()) + ->method('isAccessible') + ->willReturn(true); + + $this->helper + ->expects($this->once()) + ->method('getDownloader') + ->willReturn($downloader); + + $decision = new UseFallbackURLDecision($this->configuration, $this->helper); + $this->assertTrue($decision->canProceed(ToolFactory::createTool('tool', __DIR__, []))); + } + + public function testEmptySignUrlReturnsTrue() + { + $downloader = $this + ->getMockBuilder(Downloader::class) + ->getMock(); + + $downloader + ->expects($this->once()) + ->method('isAccessible') + ->willReturn(false); + + $this->helper + ->expects($this->once()) + ->method('getDownloader') + ->willReturn($downloader); + + $decision = new UseFallbackURLDecision($this->configuration, $this->helper); + $this->assertTrue($decision->canProceed(ToolFactory::createTool('tool', __DIR__, []))); + } + + public function testNotAccessibleFallbackUrlReturnsFalse() + { + $downloader = $this + ->getMockBuilder(Downloader::class) + ->getMock(); + + $downloader + ->expects($this->exactly(2)) + ->method('isAccessible') + ->will($this->onConsecutiveCalls(false, false)); + + $this->helper + ->expects($this->exactly(2)) + ->method('getDownloader') + ->willReturn($downloader); + + $decision = new UseFallbackURLDecision($this->configuration, $this->helper); + $this->assertFalse($decision->canProceed(ToolFactory::createTool('tool', __DIR__, [ + 'fallback-url' => 'fallback-url' + ]))); + } + + public function testAccessibleFallbackUrlWillReturnTrue() + { + $downloader = $this + ->getMockBuilder(Downloader::class) + ->getMock(); + + $downloader + ->expects($this->exactly(2)) + ->method('isAccessible') + ->will($this->onConsecutiveCalls(false, true)); + + $this->helper + ->expects($this->exactly(2)) + ->method('getDownloader') + ->willReturn($downloader); + + $decision = new UseFallbackURLDecision($this->configuration, $this->helper); + $this->assertTrue($decision->canProceed(ToolFactory::createTool('tool', __DIR__, [ + 'fallback-url' => 'fallback-url' + ]))); + } + + public function testCanGetReason() + { + $decision = new UseFallbackURLDecision($this->configuration, $this->helper); + $this->assertRegExp('/error/', $decision->getReason()); + } +} From 6e258bd906767226a19a897ac52c0e1ec28257b7 Mon Sep 17 00:00:00 2001 From: Sven Jungnickel Date: Wed, 8 May 2019 10:04:13 +0200 Subject: [PATCH 2/2] Fix download from a fallback url --- composer.json | 2 +- src/Script/Decision/IsAccessibleDecision.php | 14 ++- .../Decision/UseFallbackURLDecision.php | 41 ------- src/Script/Processor.php | 2 - .../Decision/IsAccessibleDecisionTest.php | 22 ++++ .../Decision/UseFallbackUrlDecisionTest.php | 103 ------------------ tests/Script/Processor/ProcessTest.php | 52 +++++++++ 7 files changed, 88 insertions(+), 148 deletions(-) delete mode 100644 src/Script/Decision/UseFallbackURLDecision.php delete mode 100644 tests/Script/Decision/UseFallbackUrlDecisionTest.php diff --git a/composer.json b/composer.json index 8707881..2f2fba7 100644 --- a/composer.json +++ b/composer.json @@ -65,7 +65,7 @@ }, "phpmd": { "url": "http://static.phpmd.org/php/latest/phpmd.phar", - "fallback-url": "https://tooly.me-dresden.de/phpmd/2.6.0/phpmd.phar", + "fallback-url": "https://github.com/jakzal/phpmd/releases/download/2.6.0-jakzal-2/phpmd.phar", "force-replace": true }, "security-checker": { diff --git a/src/Script/Decision/IsAccessibleDecision.php b/src/Script/Decision/IsAccessibleDecision.php index dfed98d..268822e 100644 --- a/src/Script/Decision/IsAccessibleDecision.php +++ b/src/Script/Decision/IsAccessibleDecision.php @@ -17,7 +17,7 @@ class IsAccessibleDecision extends AbstractDecision public function canProceed(Tool $tool) { if (false === $this->helper->getDownloader()->isAccessible($tool->getUrl())) { - return false; + return $this->fallbackUrlIsAccessible($tool); } if (empty($tool->getSignUrl())) { @@ -38,4 +38,16 @@ public function getReason() { return 'At least one given URL are not accessible!'; } + + /** + * @param Tool $tool + * + * @return bool + */ + private function fallbackUrlIsAccessible(Tool $tool) + { + $fallbackUrl = $tool->getFallbackUrl(); + + return false === empty($fallbackUrl) && true === $this->helper->getDownloader()->isAccessible($fallbackUrl); + } } diff --git a/src/Script/Decision/UseFallbackURLDecision.php b/src/Script/Decision/UseFallbackURLDecision.php deleted file mode 100644 index 1876276..0000000 --- a/src/Script/Decision/UseFallbackURLDecision.php +++ /dev/null @@ -1,41 +0,0 @@ -helper->getDownloader()->isAccessible($tool->getUrl())) { - return true; - } - - if (empty($tool->getFallbackUrl())) { - return true; - } - - if (false === $this->helper->getDownloader()->isAccessible($tool->getFallbackUrl())){ - return false; - } - - return true; - } - - /** - * @return string - */ - public function getReason() - { - return 'Fallback URL is not accessible!'; - } -} diff --git a/src/Script/Processor.php b/src/Script/Processor.php index 0b11f61..18d48cd 100644 --- a/src/Script/Processor.php +++ b/src/Script/Processor.php @@ -9,7 +9,6 @@ use Tooly\Script\Decision\IsAccessibleDecision; use Tooly\Script\Decision\IsVerifiedDecision; use Tooly\Script\Decision\OnlyDevDecision; -use Tooly\Script\Decision\UseFallbackURLDecision; use Tooly\Model\Tool; /** @@ -124,7 +123,6 @@ private function getDecisions() return [ new OnlyDevDecision($this->configuration, $this->helper), new IsAccessibleDecision($this->configuration, $this->helper), - new UseFallbackURLDecision($this->configuration, $this->helper), new FileAlreadyExistDecision($this->configuration, $this->helper), new IsVerifiedDecision($this->configuration, $this->helper), new DoReplaceDecision($this->configuration, $this->helper, $this->io), diff --git a/tests/Script/Decision/IsAccessibleDecisionTest.php b/tests/Script/Decision/IsAccessibleDecisionTest.php index 2f34d6b..0e99cf0 100644 --- a/tests/Script/Decision/IsAccessibleDecisionTest.php +++ b/tests/Script/Decision/IsAccessibleDecisionTest.php @@ -74,6 +74,28 @@ public function testNotAccessibleToolSignUrlReturnsFalse() ]))); } + public function testNotAccessibleToolUrlButAccessibleFallbackUrlReturnsTrue() + { + $downloader = $this + ->getMockBuilder(Downloader::class) + ->getMock(); + + $downloader + ->expects($this->exactly(2)) + ->method('isAccessible') + ->will($this->onConsecutiveCalls(false, true)); + + $this->helper + ->expects($this->exactly(2)) + ->method('getDownloader') + ->willReturn($downloader); + + $decision = new IsAccessibleDecision($this->configuration, $this->helper); + $this->assertTrue($decision->canProceed(ToolFactory::createTool('tool', __DIR__, [ + 'fallback-url' => 'fallback-url' + ]))); + } + public function testAccessibleUrlsWillReturnTrue() { $downloader = $this diff --git a/tests/Script/Decision/UseFallbackUrlDecisionTest.php b/tests/Script/Decision/UseFallbackUrlDecisionTest.php deleted file mode 100644 index df7b5fd..0000000 --- a/tests/Script/Decision/UseFallbackUrlDecisionTest.php +++ /dev/null @@ -1,103 +0,0 @@ -getMockBuilder(Downloader::class) - ->getMock(); - - $downloader - ->expects($this->once()) - ->method('isAccessible') - ->willReturn(true); - - $this->helper - ->expects($this->once()) - ->method('getDownloader') - ->willReturn($downloader); - - $decision = new UseFallbackURLDecision($this->configuration, $this->helper); - $this->assertTrue($decision->canProceed(ToolFactory::createTool('tool', __DIR__, []))); - } - - public function testEmptySignUrlReturnsTrue() - { - $downloader = $this - ->getMockBuilder(Downloader::class) - ->getMock(); - - $downloader - ->expects($this->once()) - ->method('isAccessible') - ->willReturn(false); - - $this->helper - ->expects($this->once()) - ->method('getDownloader') - ->willReturn($downloader); - - $decision = new UseFallbackURLDecision($this->configuration, $this->helper); - $this->assertTrue($decision->canProceed(ToolFactory::createTool('tool', __DIR__, []))); - } - - public function testNotAccessibleFallbackUrlReturnsFalse() - { - $downloader = $this - ->getMockBuilder(Downloader::class) - ->getMock(); - - $downloader - ->expects($this->exactly(2)) - ->method('isAccessible') - ->will($this->onConsecutiveCalls(false, false)); - - $this->helper - ->expects($this->exactly(2)) - ->method('getDownloader') - ->willReturn($downloader); - - $decision = new UseFallbackURLDecision($this->configuration, $this->helper); - $this->assertFalse($decision->canProceed(ToolFactory::createTool('tool', __DIR__, [ - 'fallback-url' => 'fallback-url' - ]))); - } - - public function testAccessibleFallbackUrlWillReturnTrue() - { - $downloader = $this - ->getMockBuilder(Downloader::class) - ->getMock(); - - $downloader - ->expects($this->exactly(2)) - ->method('isAccessible') - ->will($this->onConsecutiveCalls(false, true)); - - $this->helper - ->expects($this->exactly(2)) - ->method('getDownloader') - ->willReturn($downloader); - - $decision = new UseFallbackURLDecision($this->configuration, $this->helper); - $this->assertTrue($decision->canProceed(ToolFactory::createTool('tool', __DIR__, [ - 'fallback-url' => 'fallback-url' - ]))); - } - - public function testCanGetReason() - { - $decision = new UseFallbackURLDecision($this->configuration, $this->helper); - $this->assertRegExp('/error/', $decision->getReason()); - } -} diff --git a/tests/Script/Processor/ProcessTest.php b/tests/Script/Processor/ProcessTest.php index 9f96469..1d09996 100644 --- a/tests/Script/Processor/ProcessTest.php +++ b/tests/Script/Processor/ProcessTest.php @@ -121,4 +121,56 @@ public function testCanSuccessfullyDownloadATool() $processor = new Processor($this->io, $this->helper, $this->configuration); $processor->process($tool); } + + public function testCanSuccessfullyDownloadAToolViaFallbackUrl() + { + vfsStream::setup('bin'); + + $downloader = $this + ->getMockBuilder(Downloader::class) + ->getMock(); + + $downloader + ->expects($this->exactly(3)) + ->method('isAccessible') + ->will($this->onConsecutiveCalls(false, true, false)); + + $filesystem = $this + ->getMockBuilder(Filesystem::class) + ->getMock(); + + $filesystem + ->method('isFileAlreadyExist') + ->willReturn(false); + + $this->helper + ->method('getFilesystem') + ->willReturn($filesystem); + + $this->helper + ->expects($this->exactly(4)) + ->method('getDownloader') + ->willReturn($downloader); + + $this->helper + ->method('isFileAlreadyExist') + ->willReturn(false); + + $this->io + ->expects($this->exactly(2)) + ->method('write'); + + $tool = $this + ->getMockBuilder(Tool::class) + ->disableOriginalConstructor() + ->getMock(); + + $tool + ->expects($this->exactly(2)) + ->method('getFallbackUrl') + ->willReturn('//test.html'); + + $processor = new Processor($this->io, $this->helper, $this->configuration); + $processor->process($tool); + } }