Skip to content

Commit 68857f1

Browse files
authored
fix: download minify.exe (#28)
Fix #27
1 parent 74ac9ee commit 68857f1

File tree

3 files changed

+117
-20
lines changed

3 files changed

+117
-20
lines changed

src/MinifyInstaller.php

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ public function isInstalled(): bool
5858

5959
public function getInstallBinaryPath(): string
6060
{
61+
if ('\\' === \DIRECTORY_SEPARATOR) {
62+
return Path::join($this->installDirectory, 'minify.exe');
63+
}
64+
6165
return Path::join($this->installDirectory, 'minify');
6266
}
6367

@@ -82,32 +86,30 @@ public function download(string $version): void
8286
$this->filesystem->appendToFile($downloadFilename, $chunk->getContent(), true);
8387
}
8488

85-
if (str_ends_with($downloadFilename, '.zip')) {
86-
$download = function () use ($downloadFilename, $tempDir) {
87-
$archive = new \ZipArchive();
88-
$archive->open($downloadFilename);
89-
$archive->extractTo($tempDir, 'minify');
90-
$archive->close();
91-
};
92-
} else {
93-
$download = function () use ($downloadFilename, $tempDir) {
94-
$archive = new \PharData($downloadFilename);
95-
$archive->extractTo($tempDir, ['minify'], true);
96-
};
97-
}
89+
$this->filesystem->mkdir(Path::getDirectory($this->getInstallBinaryPath()));
9890

99-
try {
100-
$download();
101-
} catch (\Throwable $e) {
102-
throw new InstallException(sprintf('Error extracting the binary from archive "%s".', $downloadFilename), 0, $e->getPrevious());
103-
}
104-
105-
$this->filesystem->mkdir(dirname($this->getInstallBinaryPath()));
10691
if (str_ends_with($downloadFilename, '.zip')) {
92+
// Windows archive (minify.exe)
93+
$archive = new \ZipArchive();
94+
if (true !== $archive->open($downloadFilename)) {
95+
throw new InstallException(sprintf('Error opening archive "%s".', $downloadFilename));
96+
}
97+
if (false === $archive->extractTo($tempDir, 'minify.exe')) {
98+
throw new InstallException(sprintf('Error extracting minify.exe from archive "%s".', $downloadFilename));
99+
}
100+
$archive->close();
107101
$this->filesystem->copy(Path::join($tempDir, 'minify.exe'), $this->getInstallBinaryPath());
102+
$this->filesystem->chmod($this->getInstallBinaryPath(), 0755);
108103
} else {
104+
$archive = new \PharData($downloadFilename);
105+
try {
106+
$archive->extractTo($tempDir, ['minify'], true);
107+
} catch (\Exception $e) {
108+
throw new InstallException(sprintf('Error extracting the binary from archive "%s".', $downloadFilename), 0, $e);
109+
}
109110
$this->filesystem->copy(Path::join($tempDir, 'minify'), $this->getInstallBinaryPath());
110111
}
112+
111113
$this->filesystem->remove($tempDir);
112114
}
113115

tests/MinifyFactoryTest.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the SensioLabs MinifyBundle package.
7+
*
8+
* (c) Simon André - Sensiolabs
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Sensiolabs\MinifyBundle\Tests;
15+
16+
use PHPUnit\Framework\Attributes\CoversClass;
17+
use PHPUnit\Framework\TestCase;
18+
use Sensiolabs\MinifyBundle\Exception\BinaryNotFoundException;
19+
use Sensiolabs\MinifyBundle\Exception\LogicException;
20+
use Sensiolabs\MinifyBundle\Minifier\MinifierInstallerInterface;
21+
use Sensiolabs\MinifyBundle\MinifyFactory;
22+
23+
#[CoversClass(MinifyFactory::class)]
24+
final class MinifyFactoryTest extends TestCase
25+
{
26+
public function testExceptionIsThrownWhenBinaryNotFound(): void
27+
{
28+
$this->expectException(BinaryNotFoundException::class);
29+
$factory = new MinifyFactory(false, $this->createMock(MinifierInstallerInterface::class));
30+
$factory->create();
31+
}
32+
33+
public function testExceptionIsThrownWhenInstallerIsNullAndBinaryPathIsFalse(): void
34+
{
35+
$this->expectException(LogicException::class);
36+
$factory = new MinifyFactory(false, null);
37+
$factory->create();
38+
}
39+
40+
public function testInstallerIsCalledWhenBinaryNotFound(): void
41+
{
42+
$installer = $this->createMock(MinifierInstallerInterface::class);
43+
$installer->expects($this->once())->method('install');
44+
$installer->method('isInstalled')->willReturn(false);
45+
$installer->method('getInstallBinaryPath')->willReturn('/usr/local/bin/minify');
46+
47+
$this->expectException(BinaryNotFoundException::class);
48+
$factory = new MinifyFactory(false, $installer);
49+
$factory->create();
50+
}
51+
}

tests/MinifyInstallerTest.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the SensioLabs MinifyBundle package.
7+
*
8+
* (c) Simon André - Sensiolabs
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Sensiolabs\MinifyBundle\Tests;
15+
16+
use PHPUnit\Framework\Attributes\CoversClass;
17+
use PHPUnit\Framework\TestCase;
18+
use Sensiolabs\MinifyBundle\Exception\InstallException;
19+
use Sensiolabs\MinifyBundle\MinifyInstaller;
20+
use Symfony\Contracts\HttpClient\HttpClientInterface;
21+
use Symfony\Contracts\HttpClient\ResponseInterface;
22+
23+
#[CoversClass(MinifyInstaller::class)]
24+
class MinifyInstallerTest extends TestCase
25+
{
26+
public function testExceptionIsThrownWhenBinaryCannotBeDownloaded(): void
27+
{
28+
$httpClient = $this->createMock(HttpClientInterface::class);
29+
$httpClient->method('request')->willReturn($this->createMockResponse(500));
30+
$installer = new MinifyInstaller('/tmp/minify/'.rand(5, 999), $httpClient);
31+
32+
$this->expectException(InstallException::class);
33+
$installer->install();
34+
}
35+
36+
private function createMockResponse(int $statusCode, string $content = ''): ResponseInterface
37+
{
38+
$response = $this->createMock(ResponseInterface::class);
39+
$response->method('getStatusCode')->willReturn($statusCode);
40+
$response->method('getContent')->willReturn($content);
41+
42+
return $response;
43+
}
44+
}

0 commit comments

Comments
 (0)