Skip to content

Commit

Permalink
Merge pull request #54 from mvorisek/fix_53
Browse files Browse the repository at this point in the history
Fix plugin config must be kept after upgrade/downgrade
  • Loading branch information
alecpl authored May 16, 2024
2 parents 2adeb2a + a762400 commit f77c307
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 9 deletions.
13 changes: 13 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,16 @@ jobs:
cd test-composer/vendor/roundcube/roundcubemail
ls -lah plugins/acl/config.*
if [ ! -f plugins/acl/config.inc.php ]; then echo 'Config file was not created' && exit 1; fi
- name: Test update - install plugin
run: |
cd test-composer
echo '// xxx no config update xxx' >> vendor/roundcube/roundcubemail/plugins/carddav/config.inc.php
composer update -v --prefer-dist --no-interaction --no-progress roundcube/carddav --prefer-lowest
- name: Test update - verify install
run: |
cd test-composer
ls -lah vendor/roundcube/roundcubemail/plugins/carddav/config.*
if [ ! -f vendor/roundcube/roundcubemail/plugins/carddav/config.inc.php ]; then echo 'Config file was deleted' && exit 1; fi
if ! grep -Fq 'xxx no config update xxx' vendor/roundcube/roundcubemail/plugins/carddav/config.inc.php; then echo 'Config file was replaced' && exit 1; fi
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
],
"require": {
"php": ">=7.3 <8.4",
"composer-plugin-api": "^1.0 || ^2.0",
"composer-plugin-api": "^2.1",
"roundcube/roundcubemail": "*"
},
"require-dev": {
"composer/composer": "^2.0",
"composer/composer": "^2.1",
"ergebnis/composer-normalize": "^2.13",
"friendsofphp/php-cs-fixer": "^3.0",
"phpstan/extension-installer": "^1.1",
Expand Down
1 change: 1 addition & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ includes:

parameters:
level: 4
checkMissingOverrideMethodAttribute: true
paths:
- .
excludePaths:
Expand Down
44 changes: 37 additions & 7 deletions src/ExtensionInstaller.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Roundcube\Composer;

use Composer\Installer\InstallationManager;
use Composer\Installer\LibraryInstaller;
use Composer\Package\PackageInterface;
use Composer\Package\Version\VersionParser;
Expand Down Expand Up @@ -35,23 +36,41 @@ protected function setRoundcubemailInstallPath(InstalledRepositoryInterface $ins

if ($roundcubemailPackage === $rootPackage) { // $this->getInstallPath($package) does not work for root package
$this->initializeVendorDir();
$this->roundcubemailInstallPath = dirname($this->vendorDir);
$installPath = dirname($this->vendorDir);
} else {
$this->roundcubemailInstallPath = $this->getInstallPath($roundcubemailPackage);
$installPath = $this->getInstallPath($roundcubemailPackage);
}

if ($this->roundcubemailInstallPath === null) {
$this->roundcubemailInstallPath = $installPath;
} elseif ($this->roundcubemailInstallPath !== $installPath) {
throw new \Exception('Install path of "roundcube/roundcubemail" package has unexpectedly changed');
}
}

protected function getRoundcubemailInstallPath(): string
{
// install path is not set at composer download phase
// never assume any path, but for this known composer behaviour get it from backtrace instead
if ($this->roundcubemailInstallPath === null) {
$backtrace = debug_backtrace();
foreach ($backtrace as $frame) {
// relies on https://github.com/composer/composer/blob/2.7.4/src/Composer/Installer/InstallationManager.php#L243
if (($frame['object'] ?? null) instanceof InstallationManager
&& $frame['function'] === 'downloadAndExecuteBatch'
) {
$this->setRoundcubemailInstallPath($frame['args'][0]);
}
}
}

return $this->roundcubemailInstallPath;
}

#[\Override]
public function getInstallPath(PackageInterface $package)
{
if (
!$this->supports($package->getType())
|| $this->roundcubemailInstallPath === null // install path is not known at download phase
) {
if (!$this->supports($package->getType())) {
return parent::getInstallPath($package);
}

Expand All @@ -63,13 +82,21 @@ public function getInstallPath(PackageInterface $package)

private function initializeRoundcubemailEnvironment(): void
{
// initialize Roundcube environment
if (!defined('INSTALL_PATH')) {
define('INSTALL_PATH', $this->getRoundcubemailInstallPath() . '/');
}
require_once INSTALL_PATH . 'program/include/iniset.php';
}

#[\Override]
public function isInstalled(InstalledRepositoryInterface $repo, PackageInterface $package)
{
$this->setRoundcubemailInstallPath($repo);

return parent::isInstalled($repo, $package);
}

#[\Override]
public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
{
$this->setRoundcubemailInstallPath($repo);
Expand Down Expand Up @@ -131,6 +158,7 @@ public function install(InstalledRepositoryInterface $repo, PackageInterface $pa
return null;
}

#[\Override]
public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
{
$this->setRoundcubemailInstallPath($repo);
Expand Down Expand Up @@ -196,6 +224,7 @@ public function update(InstalledRepositoryInterface $repo, PackageInterface $ini
return null;
}

#[\Override]
public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
{
$this->setRoundcubemailInstallPath($repo);
Expand Down Expand Up @@ -237,6 +266,7 @@ public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $
return null;
}

#[\Override]
public function supports($packageType)
{
return $packageType === $this->composer_type;
Expand Down
3 changes: 3 additions & 0 deletions src/PluginInstaller.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ class PluginInstaller extends ExtensionInstaller
{
protected $composer_type = 'roundcube-plugin';

#[\Override]
public function getVendorDir()
{
return $this->getRoundcubemailInstallPath() . \DIRECTORY_SEPARATOR . 'plugins';
}

#[\Override]
protected function confirmInstall($package_name)
{
$config = $this->composer->getConfig()->get('roundcube');
Expand All @@ -24,6 +26,7 @@ protected function confirmInstall($package_name)
return $answer;
}

#[\Override]
protected function getConfig($package_name, $config, $add)
{
$cur_config = !empty($config['plugins'])
Expand Down
3 changes: 3 additions & 0 deletions src/RoundcubeInstaller.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class RoundcubeInstaller implements PluginInterface
private $extentions = [PluginInstaller::class, SkinInstaller::class];
private $installers = [];

#[\Override]
public function activate(Composer $composer, IOInterface $io)
{
foreach ($this->extentions as $extension) {
Expand All @@ -20,12 +21,14 @@ public function activate(Composer $composer, IOInterface $io)
}
}

#[\Override]
public function deactivate(Composer $composer, IOInterface $io)
{
foreach ($this->installers as $installer) {
$composer->getInstallationManager()->removeInstaller($installer);
}
}

#[\Override]
public function uninstall(Composer $composer, IOInterface $io) {}
}
3 changes: 3 additions & 0 deletions src/SkinInstaller.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ class SkinInstaller extends ExtensionInstaller
{
protected $composer_type = 'roundcube-skin';

#[\Override]
public function getVendorDir()
{
return $this->getRoundcubemailInstallPath() . \DIRECTORY_SEPARATOR . 'skins';
}

#[\Override]
protected function confirmInstall($package_name)
{
$config = $this->composer->getConfig()->get('roundcube');
Expand All @@ -24,6 +26,7 @@ protected function confirmInstall($package_name)
return $answer;
}

#[\Override]
protected function getConfig($package_name, $config, $add)
{
$cur_config = !empty($config['skin'])
Expand Down

0 comments on commit f77c307

Please sign in to comment.