From 5ea939ba8e8dfb824989c652226fa89b66edfd85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Andr=C3=A9?= Date: Sun, 22 Dec 2024 21:05:47 +0100 Subject: [PATCH] fix: download minify.exe --- src/MinifyInstaller.php | 42 +++++++++++++++-------------- tests/MinifyFactoryTest.php | 51 +++++++++++++++++++++++++++++++++++ tests/MinifyInstallerTest.php | 44 ++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 20 deletions(-) create mode 100644 tests/MinifyFactoryTest.php create mode 100644 tests/MinifyInstallerTest.php diff --git a/src/MinifyInstaller.php b/src/MinifyInstaller.php index 74238e3..7221fdb 100644 --- a/src/MinifyInstaller.php +++ b/src/MinifyInstaller.php @@ -58,6 +58,10 @@ public function isInstalled(): bool public function getInstallBinaryPath(): string { + if ('\\' === \DIRECTORY_SEPARATOR) { + return Path::join($this->installDirectory, 'minify.exe'); + } + return Path::join($this->installDirectory, 'minify'); } @@ -82,32 +86,30 @@ public function download(string $version): void $this->filesystem->appendToFile($downloadFilename, $chunk->getContent(), true); } - if (str_ends_with($downloadFilename, '.zip')) { - $download = function () use ($downloadFilename, $tempDir) { - $archive = new \ZipArchive(); - $archive->open($downloadFilename); - $archive->extractTo($tempDir, 'minify'); - $archive->close(); - }; - } else { - $download = function () use ($downloadFilename, $tempDir) { - $archive = new \PharData($downloadFilename); - $archive->extractTo($tempDir, ['minify'], true); - }; - } + $this->filesystem->mkdir(Path::getDirectory($this->getInstallBinaryPath())); - try { - $download(); - } catch (\Throwable $e) { - throw new InstallException(sprintf('Error extracting the binary from archive "%s".', $downloadFilename), 0, $e->getPrevious()); - } - - $this->filesystem->mkdir(dirname($this->getInstallBinaryPath())); if (str_ends_with($downloadFilename, '.zip')) { + // Windows archive (minify.exe) + $archive = new \ZipArchive(); + if (true !== $archive->open($downloadFilename)) { + throw new InstallException(sprintf('Error opening archive "%s".', $downloadFilename)); + } + if (false === $archive->extractTo($tempDir, 'minify.exe')) { + throw new InstallException(sprintf('Error extracting minify.exe from archive "%s".', $downloadFilename)); + } + $archive->close(); $this->filesystem->copy(Path::join($tempDir, 'minify.exe'), $this->getInstallBinaryPath()); + $this->filesystem->chmod($this->getInstallBinaryPath(), 0755); } else { + $archive = new \PharData($downloadFilename); + try { + $archive->extractTo($tempDir, ['minify'], true); + } catch (\Exception $e) { + throw new InstallException(sprintf('Error extracting the binary from archive "%s".', $downloadFilename), 0, $e); + } $this->filesystem->copy(Path::join($tempDir, 'minify'), $this->getInstallBinaryPath()); } + $this->filesystem->remove($tempDir); } diff --git a/tests/MinifyFactoryTest.php b/tests/MinifyFactoryTest.php new file mode 100644 index 0000000..97a4b6b --- /dev/null +++ b/tests/MinifyFactoryTest.php @@ -0,0 +1,51 @@ +expectException(BinaryNotFoundException::class); + $factory = new MinifyFactory(false, $this->createMock(MinifierInstallerInterface::class)); + $factory->create(); + } + + public function testExceptionIsThrownWhenInstallerIsNullAndBinaryPathIsFalse(): void + { + $this->expectException(LogicException::class); + $factory = new MinifyFactory(false, null); + $factory->create(); + } + + public function testInstallerIsCalledWhenBinaryNotFound(): void + { + $installer = $this->createMock(MinifierInstallerInterface::class); + $installer->expects($this->once())->method('install'); + $installer->method('isInstalled')->willReturn(false); + $installer->method('getInstallBinaryPath')->willReturn('/usr/local/bin/minify'); + + $this->expectException(BinaryNotFoundException::class); + $factory = new MinifyFactory(false, $installer); + $factory->create(); + } +} diff --git a/tests/MinifyInstallerTest.php b/tests/MinifyInstallerTest.php new file mode 100644 index 0000000..d3b448a --- /dev/null +++ b/tests/MinifyInstallerTest.php @@ -0,0 +1,44 @@ +createMock(HttpClientInterface::class); + $httpClient->method('request')->willReturn($this->createMockResponse(500)); + $installer = new MinifyInstaller('/tmp/minify/'.rand(5, 999), $httpClient); + + $this->expectException(InstallException::class); + $installer->install(); + } + + private function createMockResponse(int $statusCode, string $content = ''): ResponseInterface + { + $response = $this->createMock(ResponseInterface::class); + $response->method('getStatusCode')->willReturn($statusCode); + $response->method('getContent')->willReturn($content); + + return $response; + } +}