Skip to content

Commit

Permalink
Merge pull request #51 from pact-foundation/allow-update-without-manu…
Browse files Browse the repository at this point in the history
…al-deletion

fix: Allow update extra file without manually deletion
  • Loading branch information
tienvx authored May 16, 2024
2 parents e278fde + ed68418 commit 0f9fdec
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 63 deletions.
8 changes: 4 additions & 4 deletions src/Composer/Installer/AbstractInstaller.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Composer\Package\PackageInterface;
use Composer\Repository\InstalledRepositoryInterface;
use LastCall\DownloadsPlugin\Composer\Package\ExtraDownloadInterface;
use LastCall\DownloadsPlugin\Composer\Repository\ExtraDownloadsRepositoryInterface;
use LastCall\DownloadsPlugin\Exception\ExtraDownloadHashMismatchException;
use LastCall\DownloadsPlugin\Installer\ExecutableInstaller;
use LastCall\DownloadsPlugin\Installer\ExecutableInstallerInterface;
Expand All @@ -27,14 +28,13 @@ public function __construct(

public function isInstalled(InstalledRepositoryInterface $repo, PackageInterface $package): bool
{
if (!$package instanceof ExtraDownloadInterface) {
if (!$package instanceof ExtraDownloadInterface || !$repo instanceof ExtraDownloadsRepositoryInterface) {
return false;
}

$hasPackage = $repo->hasPackage($package);
$fileExists = file_exists($package->getInstallPath());

if (!$hasPackage && $fileExists) {
if ($fileExists && !$repo->isTracked($package)) {
$this->io->write(
sprintf(
'<info>Extra file <comment>%s</comment> has been locally overriden in <comment>%s</comment>. To reset it, delete and reinstall.</info>',
Expand All @@ -47,7 +47,7 @@ public function isInstalled(InstalledRepositoryInterface $repo, PackageInterface
return true;
}

if ($hasPackage && $fileExists) {
if ($fileExists && $repo->hasPackage($package)) {
$this->io->write(
sprintf('<info>Skip extra file <comment>%s</comment></info>', $package->getName()),
true,
Expand Down
8 changes: 6 additions & 2 deletions src/Composer/Repository/ExtraDownloadsRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@
use Composer\Installer\InstallationManager;
use Composer\Json\JsonFile;
use Composer\Package\PackageInterface;
use Composer\Repository\InstalledRepositoryInterface;
use Composer\Repository\InvalidRepositoryException;
use LastCall\DownloadsPlugin\Composer\Package\ExtraDownloadInterface;

class ExtraDownloadsRepository implements InstalledRepositoryInterface
class ExtraDownloadsRepository implements ExtraDownloadsRepositoryInterface
{
private array $extraDownloads;

Expand Down Expand Up @@ -45,6 +44,11 @@ public function hasPackage(PackageInterface $package): bool
return $this->extraDownloads[$name] === $package->getTrackingChecksum();
}

public function isTracked(ExtraDownloadInterface $package): bool
{
return isset($this->extraDownloads[$package->getName()]);
}

protected function initialize(): void
{
$this->extraDownloads = [];
Expand Down
11 changes: 11 additions & 0 deletions src/Composer/Repository/ExtraDownloadsRepositoryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace LastCall\DownloadsPlugin\Composer\Repository;

use Composer\Repository\InstalledRepositoryInterface;
use LastCall\DownloadsPlugin\Composer\Package\ExtraDownloadInterface;

interface ExtraDownloadsRepositoryInterface extends InstalledRepositoryInterface
{
public function isTracked(ExtraDownloadInterface $extraDownload): bool;
}
136 changes: 88 additions & 48 deletions tests/Unit/Composer/Installer/AbstractInstallerTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
use Composer\Installer\InstallerInterface;
use Composer\IO\IOInterface;
use Composer\Package\PackageInterface;
use Composer\Repository\InstalledRepositoryInterface;
use Composer\Repository\InstalledArrayRepository;
use LastCall\DownloadsPlugin\Composer\Package\ExtraDownloadInterface;
use LastCall\DownloadsPlugin\Composer\Repository\ExtraDownloadsRepositoryInterface;
use LastCall\DownloadsPlugin\Exception\ExtraDownloadHashMismatchException;
use LastCall\DownloadsPlugin\Installer\ExecutableInstallerInterface;
use PHPUnit\Framework\MockObject\MockObject;
Expand All @@ -23,7 +24,7 @@ abstract class AbstractInstallerTestCase extends TestCase
protected IOInterface|MockObject $io;
protected DownloadManager|MockObject $downloadManager;
protected ExecutableInstallerInterface|MockObject $executableInstaller;
protected InstalledRepositoryInterface|MockObject $repository;
protected ExtraDownloadsRepositoryInterface|MockObject $repository;
protected ExtraDownloadInterface|MockObject $extraDownload;
protected PackageInterface|MockObject $package;
protected InstallerInterface $installer;
Expand All @@ -39,7 +40,7 @@ protected function setUp(): void
$this->io = $this->createMock(IOInterface::class);
$this->downloadManager = $this->createMock(DownloadManager::class);
$this->executableInstaller = $this->createMock(ExecutableInstallerInterface::class);
$this->repository = $this->createMock(InstalledRepositoryInterface::class);
$this->repository = $this->createMock(ExtraDownloadsRepositoryInterface::class);
$this->extraDownload = $this->createMock(ExtraDownloadInterface::class);
$this->package = $this->createMock(PackageInterface::class);
$this->installer = $this->createInstaller();
Expand All @@ -50,31 +51,103 @@ protected function tearDown(): void
$this->fs = null;
}

public function testIsInstalledPackage(): void
public function testIsInstalledNotSupportedPackage(): void
{
$this->assertFalse($this->installer->isInstalled($this->repository, $this->package));
}

public function getIsInstalledExtraDownloadTests(): array
public function testIsInstalledNotSupportedRepository(): void
{
return [
[true, true, true],
[false, true, true],
[true, false, false],
[false, false, false],
];
$this->assertFalse($this->installer->isInstalled(new InstalledArrayRepository(), $this->package));
}

public function testIsInstalledSkip(): void
{
$this->repository
->expects($this->once())
->method('hasPackage')
->with($this->extraDownload)
->willReturn(true);
$this->repository
->expects($this->once())
->method('isTracked')
->with($this->extraDownload)
->willReturn(true);
$this->extraDownload
->expects($this->once())
->method('getInstallPath')
->willReturn($this->fs->path($this->installPath));
$this->fs->createDirectory(\dirname($this->installPath), true);
$this->fs->createFile($this->installPath, 'downloaded file');
$this->extraDownload
->expects($this->once())
->method('getName')
->willReturn($this->name);
$this->io
->expects($this->once())
->method('write')
->with(
sprintf('<info>Skip extra file <comment>%s</comment></info>', $this->name),
true,
IOInterface::VERY_VERBOSE
);
$this->assertTrue($this->installer->isInstalled($this->repository, $this->extraDownload));
}

public function testIsInstalledLocalyOverriden(): void
{
$this->repository
->expects($this->once())
->method('isTracked')
->with($this->extraDownload)
->willReturn(false);
$this->extraDownload
->expects($this->once())
->method('getInstallPath')
->willReturn($this->fs->path($this->installPath));
$this->fs->createDirectory(\dirname($this->installPath), true);
$this->fs->createFile($this->installPath, 'downloaded file');
$this->extraDownload
->expects($this->once())
->method('getName')
->willReturn($this->name);
$this->extraDownload
->expects($this->once())
->method('getTargetDir')
->willReturn($this->targetDir);
$this->io
->expects($this->once())
->method('write')
->with(
sprintf(
'<info>Extra file <comment>%s</comment> has been locally overriden in <comment>%s</comment>. To reset it, delete and reinstall.</info>',
$this->name,
$this->targetDir,
),
true
);
$this->assertTrue($this->installer->isInstalled($this->repository, $this->extraDownload));
}

/**
* @dataProvider getIsInstalledExtraDownloadTests
* @testWith [false, true, true]
* [true, true, false]
* [true, false, false]
* [false, true, false]
* [false, false, false]
*/
public function testIsInstalledExtraDownload(bool $hasPackage, bool $fileExists, bool $isInstalled): void
public function testIsNotInstalled(bool $hasPackage, bool $isTracked, bool $fileExists): void
{
$this->repository
->expects($this->once())
->expects($this->any())
->method('hasPackage')
->with($this->extraDownload)
->willReturn($hasPackage);
$this->repository
->expects($this->any())
->method('isTracked')
->with($this->extraDownload)
->willReturn($isTracked);
$this->extraDownload
->expects($this->once())
->method('getInstallPath')
Expand All @@ -83,40 +156,7 @@ public function testIsInstalledExtraDownload(bool $hasPackage, bool $fileExists,
$this->fs->createDirectory(\dirname($this->installPath), true);
$this->fs->createFile($this->installPath, 'downloaded file');
}
if ($fileExists) {
$this->extraDownload
->expects($this->once())
->method('getName')
->willReturn($this->name);
}
if (!$hasPackage && $fileExists) {
$this->extraDownload
->expects($this->once())
->method('getTargetDir')
->willReturn($this->targetDir);
$this->io
->expects($this->once())
->method('write')
->with(
sprintf(
'<info>Extra file <comment>%s</comment> has been locally overriden in <comment>%s</comment>. To reset it, delete and reinstall.</info>',
$this->name,
$this->targetDir,
),
true
);
}
if ($hasPackage && $fileExists) {
$this->io
->expects($this->once())
->method('write')
->with(
sprintf('<info>Skip extra file <comment>%s</comment></info>', $this->name),
true,
IOInterface::VERY_VERBOSE
);
}
$this->assertSame($isInstalled, $this->installer->isInstalled($this->repository, $this->extraDownload));
$this->assertFalse($this->installer->isInstalled($this->repository, $this->extraDownload));
}

public function testDownloadPackage(): void
Expand Down
26 changes: 17 additions & 9 deletions tests/Unit/Composer/Repository/ExtraDownloadsRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,9 @@ public function testHasPackage(): void
$this->assertFalse($this->repository->hasPackage($this->package));
}

public function getHasExtraDownloadTests(): array
{
return [
[false],
[true],
];
}

/**
* @dataProvider getHasExtraDownloadTests
* @testWith [true]
* [false]
*/
public function testHasExtraDownload(bool $sameTrackingChecksum): void
{
Expand All @@ -114,6 +107,21 @@ public function testHasExtraDownload(bool $sameTrackingChecksum): void
$this->assertSame($sameTrackingChecksum, $this->repository->hasPackage($this->extraDownload));
}

public function testIsTracked(): void
{
$this->extraDownload
->expects($this->exactly(3))
->method('getName')
->willReturn($this->name);
$this->extraDownload
->expects($this->once())
->method('getTrackingChecksum')
->willReturn($this->trackingChecksum);
$this->assertFalse($this->repository->isTracked($this->extraDownload));
$this->repository->addPackage($this->extraDownload);
$this->assertTrue($this->repository->isTracked($this->extraDownload));
}

public function testReloadFromInvalidFile(): void
{
$this->fs->createDirectory(\dirname($this->path), true);
Expand Down

0 comments on commit 0f9fdec

Please sign in to comment.