Skip to content
This repository has been archived by the owner on Mar 15, 2024. It is now read-only.

Commit

Permalink
Merge pull request #24 from tienvx/test-zip-handler
Browse files Browse the repository at this point in the history
Test zip handler
  • Loading branch information
tienvx authored Dec 1, 2022
2 parents c26ee28 + ac57adc commit 4c46195
Show file tree
Hide file tree
Showing 9 changed files with 307 additions and 38 deletions.
29 changes: 29 additions & 0 deletions src/BinariesInstaller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace LastCall\DownloadsPlugin;

use Composer\Installer\BinaryInstaller;
use Composer\IO\IOInterface;
use Composer\Util\Platform;
use Composer\Util\ProcessExecutor;

class BinariesInstaller
{
public function install(Subpackage $subpackage, string $baseDir, IOInterface $io): void
{
foreach ($subpackage->getBinaries() as $bin) {
$path = $baseDir.\DIRECTORY_SEPARATOR.$bin;
if (Platform::isWindows() || (method_exists(Platform::class, 'isWindowsSubsystemForLinux') ? Platform::isWindowsSubsystemForLinux() : false)) {
$proxy = $path.'.bat';
if (file_exists($proxy)) {
$io->writeError(' Skipped installation of bin '.$bin.'.bat proxy for package '.$subpackage->getName().': a .bat proxy was already installed');
} else {
$caller = BinaryInstaller::determineBinaryCaller($path);
file_put_contents($proxy, '@'.$caller.' "%~dp0'.ProcessExecutor::escape(basename($proxy, '.bat')).'" %*');
}
} else {
chmod($path, 0777 ^ umask());
}
}
}
}
2 changes: 1 addition & 1 deletion src/GlobCleaner.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class GlobCleaner
{
public static function clean(string $baseDir, array $ignores): void
public function clean(string $baseDir, array $ignores): void
{
if (empty($ignores)) {
return;
Expand Down
21 changes: 18 additions & 3 deletions src/Handler/ArchiveHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,25 @@

use Composer\Composer;
use Composer\IO\IOInterface;
use Composer\Package\PackageInterface;
use LastCall\DownloadsPlugin\BinariesInstaller;
use LastCall\DownloadsPlugin\GlobCleaner;

abstract class ArchiveHandler extends BaseHandler
{
protected ?GlobCleaner $cleaner = null;

public function __construct(
PackageInterface $parent,
string $parentPath,
array $extraFile,
?BinariesInstaller $binariesInstaller = null,
?GlobCleaner $cleaner = null
) {
parent::__construct($parent, $parentPath, $extraFile, $binariesInstaller);
$this->cleaner = $cleaner ?? new GlobCleaner();
}

public function getTrackingFile(): string
{
$file = basename($this->extraFile['id']).'-'.md5($this->extraFile['id']).'.json';
Expand Down Expand Up @@ -38,7 +53,7 @@ protected function getChecksumData(): array
private function findIgnores(): array
{
if (isset($this->extraFile['ignore']) && !\is_array($this->extraFile['ignore'])) {
throw new \UnexpectedValueException(sprintf('Attribute "ignore" of extra file "%s" defined in package "%s" must be array, "%s" given.', $this->extraFile['id'], $this->parent->getId(), get_debug_type($this->extraFile['ignore'])));
throw new \UnexpectedValueException(sprintf('Attribute "ignore" of extra file "%s" defined in package "%s" must be array, "%s" given.', $this->extraFile['id'], $this->parent->getName(), get_debug_type($this->extraFile['ignore'])));
}

return $this->extraFile['ignore'] ?? [];
Expand All @@ -58,13 +73,13 @@ protected function download(Composer $composer, IOInterface $io): void
} else {
$downloadManager->download($this->getSubpackage(), $targetPath);
}
GlobCleaner::clean($targetPath, $this->findIgnores());
$this->cleaner->clean($targetPath, $this->findIgnores());
}

protected function getBinaries(): array
{
if (isset($this->extraFile['executable']) && !\is_array($this->extraFile['executable'])) {
throw new \UnexpectedValueException(sprintf('Attribute "executable" of extra file "%s" defined in package "%s" must be array, "%s" given.', $this->extraFile['id'], $this->parent->getId(), get_debug_type($this->extraFile['executable'])));
throw new \UnexpectedValueException(sprintf('Attribute "executable" of extra file "%s" defined in package "%s" must be array, "%s" given.', $this->extraFile['id'], $this->parent->getName(), get_debug_type($this->extraFile['executable'])));
}

return $this->extraFile['executable'] ?? [];
Expand Down
40 changes: 12 additions & 28 deletions src/Handler/BaseHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,28 @@
namespace LastCall\DownloadsPlugin\Handler;

use Composer\Composer;
use Composer\Installer\BinaryInstaller;
use Composer\IO\IOInterface;
use Composer\Package\PackageInterface;
use Composer\Package\RootPackageInterface;
use Composer\Package\Version\VersionParser;
use Composer\Util\Platform;
use Composer\Util\ProcessExecutor;
use LastCall\DownloadsPlugin\BinariesInstaller;
use LastCall\DownloadsPlugin\Subpackage;

abstract class BaseHandler implements HandlerInterface
{
public const FAKE_VERSION = 'dev-master';
public const DOT_DIR = '.composer-downloads';

protected ?Subpackage $subpackage = null;
private ?Subpackage $subpackage = null;
private BinariesInstaller $binariesInstaller;

public function __construct(protected PackageInterface $parent, protected string $parentPath, protected array $extraFile)
{
public function __construct(
protected PackageInterface $parent,
protected string $parentPath,
protected array $extraFile,
?BinariesInstaller $binariesInstaller = null
) {
$this->binariesInstaller = $binariesInstaller ?? new BinariesInstaller();
}

public function getSubpackage(): Subpackage
Expand Down Expand Up @@ -60,12 +64,11 @@ private function createSubpackage(): Subpackage
$parent,
$extraFile['id'],
$extraFile['url'],
null,
$this->getDistType(),
$extraFile['path'],
$version,
$prettyVersion
);
$package->setDistType($this->getDistType());
$package->setBinaries($this->getBinaries());

return $package;
Expand Down Expand Up @@ -117,27 +120,8 @@ protected function isComposerV2(): bool
public function install(Composer $composer, IOInterface $io): void
{
$this->download($composer, $io);
$this->markExecutable($io);
$this->binariesInstaller->install($this->getSubpackage(), $this->parentPath, $io);
}

abstract protected function download(Composer $composer, IOInterface $io): void;

private function markExecutable(IOInterface $io): void
{
$subpackage = $this->getSubpackage();
foreach ($subpackage->getBinaries() as $bin) {
$path = $this->parentPath.\DIRECTORY_SEPARATOR.$bin;
if (Platform::isWindows() || (method_exists(Platform::class, 'isWindowsSubsystemForLinux') ? Platform::isWindowsSubsystemForLinux() : false)) {
$proxy = $path.'.bat';
if (file_exists($proxy)) {
$io->writeError(' Skipped installation of bin '.$bin.'.bat proxy for package '.$subpackage->getName().': a .bat proxy was already installed');
} else {
$caller = BinaryInstaller::determineBinaryCaller($path);
file_put_contents($proxy, '@'.$caller.' "%~dp0'.ProcessExecutor::escape(basename($proxy, '.bat')).'" %*');
}
} else {
chmod($path, 0777 ^ umask());
}
}
}
}
2 changes: 1 addition & 1 deletion src/Handler/FileHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ protected function getDistType(): string
protected function getBinaries(): array
{
if (isset($this->extraFile['executable']) && !\is_bool($this->extraFile['executable'])) {
throw new \UnexpectedValueException(sprintf('Attribute "executable" of extra file "%s" defined in package "%s" must be boolean, "%s" given.', $this->extraFile['id'], $this->parent->getId(), get_debug_type($this->extraFile['executable'])));
throw new \UnexpectedValueException(sprintf('Attribute "executable" of extra file "%s" defined in package "%s" must be boolean, "%s" given.', $this->extraFile['id'], $this->parent->getName(), get_debug_type($this->extraFile['executable'])));
}

return empty($this->extraFile['executable']) ? [] : [$this->extraFile['path']];
Expand Down
12 changes: 7 additions & 5 deletions tests/Unit/GlobCleanerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ class GlobCleanerTest extends TestCase
'/file2.bat' => self::FILE,
];

protected ?FileSystem $fs = null;
private GlobCleaner $cleaner;
private ?FileSystem $fs = null;

protected function setUp(): void
{
$this->cleaner = new GlobCleaner();
$this->fs = new FileSystem(); // Keep virtual file system alive during test
$this->createFilesAndDirectories();
}
Expand All @@ -48,25 +50,25 @@ protected function tearDown(): void

public function testEmptyIgnore(): void
{
GlobCleaner::clean($this->fs->path('/dir1'), []);
$this->cleaner->clean($this->fs->path('/dir1'), []);
$this->assertRemaining(array_keys(self::FILES_AND_DIRECTORIES));
}

public function testNotEmptyIgnores(): void
{
GlobCleaner::clean($this->fs->path('/dir1'), [
$this->cleaner->clean($this->fs->path('/dir1'), [
'file*',
'!/dir11/file2.xls',
'/dir12',
]);
GlobCleaner::clean($this->fs->path('/dir2'), [
$this->cleaner->clean($this->fs->path('/dir2'), [
'/dir21',
'/dir22',
'/dir22/.composer-downloads',
'/dir22/.composer-downloads/*',
'/dir22/.composer-downloads/file1.json',
]);
GlobCleaner::clean($this->fs->path('/dir3'), [
$this->cleaner->clean($this->fs->path('/dir3'), [
'*',
]);
$this->assertRemaining([
Expand Down
28 changes: 28 additions & 0 deletions tests/Unit/Handler/ArchiveHandlerTestCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace LastCall\DownloadsPlugin\Tests\Unit\Handler;

abstract class ArchiveHandlerTestCase extends BaseHandlerTestCase
{
public function getBinariesTests(): array
{
return [
[null, []],
[[], []],
[['bin/file1'], ['bin/file1']],
[['bin/file1', 'bin/file2'], ['bin/file1', 'bin/file2']],
];
}

public function getInvalidBinariesTests(): array
{
return [
[true, 'bool'],
[false, 'bool'],
[123, 'int'],
[12.3, 'float'],
['test', 'string'],
[(object) ['key' => 'value'], 'stdClass'],
];
}
}
Loading

0 comments on commit 4c46195

Please sign in to comment.