1
0
Fork 0

Remove plugin installer hackery

pull/9696/head
Jordi Boggiano 2021-02-17 23:21:18 +01:00
parent 7267533690
commit f7e8f7625f
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC
10 changed files with 39 additions and 61 deletions

View File

@ -467,11 +467,7 @@ class InstallationManager
{ {
$package = $operation->getPackage(); $package = $operation->getPackage();
$installer = $this->getInstaller($package->getType()); $installer = $this->getInstaller($package->getType());
if ($installer instanceof PluginInstaller) {
$promise = $installer->install($repo, $package, $this);
} else {
$promise = $installer->install($repo, $package); $promise = $installer->install($repo, $package);
}
$this->markForNotification($package); $this->markForNotification($package);
return $promise; return $promise;
@ -493,11 +489,7 @@ class InstallationManager
if ($initialType === $targetType) { if ($initialType === $targetType) {
$installer = $this->getInstaller($initialType); $installer = $this->getInstaller($initialType);
if ($installer instanceof PluginInstaller) {
$promise = $installer->update($repo, $initial, $target, $this);
} else {
$promise = $installer->update($repo, $initial, $target); $promise = $installer->update($repo, $initial, $target);
}
$this->markForNotification($target); $this->markForNotification($target);
} else { } else {
$promise = $this->getInstaller($initialType)->uninstall($repo, $initial); $promise = $this->getInstaller($initialType)->uninstall($repo, $initial);
@ -505,12 +497,8 @@ class InstallationManager
$promise = \React\Promise\resolve(); $promise = \React\Promise\resolve();
} }
$installManager = $this;
$installer = $this->getInstaller($targetType); $installer = $this->getInstaller($targetType);
$promise->then(function () use ($installer, $repo, $target, $installManager) { $promise->then(function () use ($installer, $repo, $target) {
if ($installer instanceof PluginInstaller) {
return $installer->install($repo, $target, $installManager);
}
return $installer->install($repo, $target); return $installer->install($repo, $target);
}); });
} }

View File

@ -63,7 +63,7 @@ class PluginInstaller extends LibraryInstaller
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function install(InstalledRepositoryInterface $repo, PackageInterface $package, InstallationManager $installationManager = null) public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
{ {
$promise = parent::install($repo, $package); $promise = parent::install($repo, $package);
if (!$promise instanceof PromiseInterface) { if (!$promise instanceof PromiseInterface) {
@ -73,11 +73,8 @@ class PluginInstaller extends LibraryInstaller
$pluginManager = $this->composer->getPluginManager(); $pluginManager = $this->composer->getPluginManager();
$self = $this; $self = $this;
return $promise->then(function () use ($self, $pluginManager, $package, $repo, $installationManager) { return $promise->then(function () use ($self, $pluginManager, $package, $repo) {
try { try {
if ($installationManager) {
$self->updateInstalledVersions($repo, $installationManager);
}
$pluginManager->registerPackage($package, true); $pluginManager->registerPackage($package, true);
} catch (\Exception $e) { } catch (\Exception $e) {
$self->rollbackInstall($e, $repo, $package); $self->rollbackInstall($e, $repo, $package);
@ -88,7 +85,7 @@ class PluginInstaller extends LibraryInstaller
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target, InstallationManager $installationManager = null) public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
{ {
$promise = parent::update($repo, $initial, $target); $promise = parent::update($repo, $initial, $target);
if (!$promise instanceof PromiseInterface) { if (!$promise instanceof PromiseInterface) {
@ -98,12 +95,9 @@ class PluginInstaller extends LibraryInstaller
$pluginManager = $this->composer->getPluginManager(); $pluginManager = $this->composer->getPluginManager();
$self = $this; $self = $this;
return $promise->then(function () use ($self, $pluginManager, $initial, $target, $repo, $installationManager) { return $promise->then(function () use ($self, $pluginManager, $initial, $target, $repo) {
try { try {
$pluginManager->deactivatePackage($initial, true); $pluginManager->deactivatePackage($initial, true);
if ($installationManager) {
$self->updateInstalledVersions($repo, $installationManager);
}
$pluginManager->registerPackage($target, true); $pluginManager->registerPackage($target, true);
} catch (\Exception $e) { } catch (\Exception $e) {
$self->rollbackInstall($e, $repo, $target); $self->rollbackInstall($e, $repo, $target);
@ -128,16 +122,4 @@ class PluginInstaller extends LibraryInstaller
parent::uninstall($repo, $package); parent::uninstall($repo, $package);
throw $e; throw $e;
} }
/**
* TODO v3 should make this private once we can drop PHP 5.3 support
* @private
*/
public function updateInstalledVersions(InstalledRepositoryInterface $repo, InstallationManager $installationManager)
{
$versions = $repo->generateInstalledVersions($installationManager);
if ($versions) {
\Composer\InstalledVersions::reload($versions);
}
}
} }

View File

@ -141,9 +141,8 @@ class FilesystemRepository extends WritableArrayRepository
/** /**
* @return ?array * @return ?array
* @internal
*/ */
public function generateInstalledVersions(InstallationManager $installationManager) private function generateInstalledVersions(InstallationManager $installationManager)
{ {
if (!$this->dumpVersions) { if (!$this->dumpVersions) {
return null; return null;

View File

@ -1,8 +1,8 @@
--TEST-- --TEST--
Checks that package versions in InstalledVersions are correct on initial install. Noteworthy things: Checks that package versions in InstalledVersions are correct on initial install. Noteworthy things:
- PluginA is already found at the moment where it is first initialized - PluginA is not yet found at the moment where it is first initialized. This is a quirk which we are unlikely to fix
- PluginB is already found at the moment where it is first initialized - PluginB is not yet found at the moment where it is first initialized, but it finds PluginA which was installed before
- Local dependencies (symfony/*) show the local version over the Composer-bundled version once they are installed locally - Local dependencies (symfony/*) show the local version over the Composer-bundled version once they are installed locally
--RUN-- --RUN--
update update
@ -26,12 +26,14 @@ Package operations: 6 installs, 0 updates, 0 removals
- Downloading symfony/filesystem (%v?[2-8]\.\d+\.\d+%) - Downloading symfony/filesystem (%v?[2-8]\.\d+\.\d+%)
- Installing symfony/console (99999.1.2): Symlinking from symfony-console - Installing symfony/console (99999.1.2): Symlinking from symfony-console
- Installing plugin/a (1.1.1): Symlinking from plugin-a - Installing plugin/a (1.1.1): Symlinking from plugin-a
!!PluginA:1.1.1.0["root/pkg","symfony/console","composer/ca-bundle","composer/composer","composer/semver","composer/spdx-licenses","composer/xdebug-handler","justinrainbow/json-schema","psr/log","react/promise","seld/jsonlint","seld/phar-utils","symfony/debug","symfony/filesystem","symfony/finder","symfony/polyfill-ctype","symfony/polyfill-mbstring","symfony/process","plugin/a"] !!PluginAInit["root/pkg","symfony/console","composer/ca-bundle","composer/composer","composer/semver","composer/spdx-licenses","composer/xdebug-handler","justinrainbow/json-schema","psr/log","react/promise","seld/jsonlint","seld/phar-utils","symfony/debug","symfony/filesystem","symfony/finder","symfony/polyfill-ctype","symfony/polyfill-mbstring","symfony/process"]
!!PluginA:null
!!PluginB:null !!PluginB:null
!!Versions:console:99999.1.2.0;process:%[2-8]\.\d+\.\d+.0%;filesystem:%[2-8]\.\d+\.\d+.0% !!Versions:console:99999.1.2.0;process:%[2-8]\.\d+\.\d+.0%;filesystem:%[2-8]\.\d+\.\d+.0%
- Installing plugin/b (2.2.2): Symlinking from plugin-b - Installing plugin/b (2.2.2): Symlinking from plugin-b
!!PluginB:2.2.2.0["plugin/a","root/pkg","symfony/console","composer/ca-bundle","composer/composer","composer/semver","composer/spdx-licenses","composer/xdebug-handler","justinrainbow/json-schema","psr/log","react/promise","seld/jsonlint","seld/phar-utils","symfony/debug","symfony/filesystem","symfony/finder","symfony/polyfill-ctype","symfony/polyfill-mbstring","symfony/process","plugin/b"] !!PluginBInit["plugin/a","root/pkg","symfony/console","composer/ca-bundle","composer/composer","composer/semver","composer/spdx-licenses","composer/xdebug-handler","justinrainbow/json-schema","psr/log","react/promise","seld/jsonlint","seld/phar-utils","symfony/debug","symfony/filesystem","symfony/finder","symfony/polyfill-ctype","symfony/polyfill-mbstring","symfony/process"]
!!PluginA:1.1.1.0 !!PluginA:1.1.1.0
!!PluginB:null
!!Versions:console:99999.1.2.0;process:%[2-8]\.\d+\.\d+.0%;filesystem:%[2-8]\.\d+\.\d+.0% !!Versions:console:99999.1.2.0;process:%[2-8]\.\d+\.\d+.0%;filesystem:%[2-8]\.\d+\.\d+.0%
- Installing symfony/polyfill-ctype (%v?[1-8]\.\d+\.\d+%): Extracting archive - Installing symfony/polyfill-ctype (%v?[1-8]\.\d+\.\d+%): Extracting archive
- Installing symfony/filesystem (%v?[2-8]\.\d+\.\d+%): Extracting archive - Installing symfony/filesystem (%v?[2-8]\.\d+\.\d+%): Extracting archive

View File

@ -10,7 +10,8 @@ class PluginA implements PluginInterface
{ {
public function activate(Composer $composer, IOInterface $io) public function activate(Composer $composer, IOInterface $io)
{ {
echo '!!PluginA:'.InstalledVersions::getVersion('plugin/a').JsonFile::encode(InstalledVersions::getInstalledPackages(), 320)."\n"; echo '!!PluginAInit'.JsonFile::encode(InstalledVersions::getInstalledPackages(), 320)."\n";
echo '!!PluginA:'.(InstalledVersions::isInstalled('plugin/a') ? InstalledVersions::getVersion('plugin/a') : 'null')."\n";
echo '!!PluginB:'.(InstalledVersions::isInstalled('plugin/b') ? InstalledVersions::getVersion('plugin/b') : 'null')."\n"; echo '!!PluginB:'.(InstalledVersions::isInstalled('plugin/b') ? InstalledVersions::getVersion('plugin/b') : 'null')."\n";
echo '!!Versions:console:'.InstalledVersions::getVersion('symfony/console').';process:'.InstalledVersions::getVersion('symfony/process').';filesystem:'.InstalledVersions::getVersion('symfony/filesystem')."\n"; echo '!!Versions:console:'.InstalledVersions::getVersion('symfony/console').';process:'.InstalledVersions::getVersion('symfony/process').';filesystem:'.InstalledVersions::getVersion('symfony/filesystem')."\n";
} }

View File

@ -10,8 +10,9 @@ class PluginB implements PluginInterface
{ {
public function activate(Composer $composer, IOInterface $io) public function activate(Composer $composer, IOInterface $io)
{ {
echo '!!PluginB:'.InstalledVersions::getVersion('plugin/b').JsonFile::encode(InstalledVersions::getInstalledPackages(), 320)."\n"; echo '!!PluginBInit'.JsonFile::encode(InstalledVersions::getInstalledPackages(), 320)."\n";
echo '!!PluginA:'.(InstalledVersions::isInstalled('plugin/a') ? InstalledVersions::getVersion('plugin/a') : 'null')."\n"; echo '!!PluginA:'.(InstalledVersions::isInstalled('plugin/a') ? InstalledVersions::getVersion('plugin/a') : 'null')."\n";
echo '!!PluginB:'.(InstalledVersions::isInstalled('plugin/b') ? InstalledVersions::getVersion('plugin/b') : 'null')."\n";
echo '!!Versions:console:'.InstalledVersions::getVersion('symfony/console').';process:'.InstalledVersions::getVersion('symfony/process').';filesystem:'.InstalledVersions::getVersion('symfony/filesystem')."\n"; echo '!!Versions:console:'.InstalledVersions::getVersion('symfony/console').';process:'.InstalledVersions::getVersion('symfony/process').';filesystem:'.InstalledVersions::getVersion('symfony/filesystem')."\n";
} }

View File

@ -2,19 +2,20 @@
Checks that package versions in InstalledVersions are correct during an upgrade. Noteworthy things: Checks that package versions in InstalledVersions are correct during an upgrade. Noteworthy things:
- PluginA sees the old version of PluginB until that upgrade happened - PluginA sees the old version of PluginB until that upgrade happened
- PluginA/PluginB see an old version of themselves as the plugin is marked install InstalledVersions::reload() but that is used as fallback vs what is in vendor dir. This is a quirk which we are unlikely to fix - PluginA/PluginB see an old version of themselves. This is a quirk which we are unlikely to fix
- Local dependencies (symfony/*) always show the local version over the Composer-bundled version, and show the correct new version as soon as they are done upgrading - Local dependencies (symfony/*) always show the local version over the Composer-bundled version, and show the correct new version as soon as they are done upgrading
--RUN-- --RUN--
update update plugin/* symfony/console symfony/filesystem symfony/process
--EXPECT-- --EXPECT--
!!PluginA:1.1.1.0["plugin/a","plugin/b","root/pkg","symfony/console","symfony/filesystem","symfony/polyfill-ctype","symfony/process","composer/ca-bundle","composer/composer","composer/semver","composer/spdx-licenses","composer/xdebug-handler","justinrainbow/json-schema","psr/log","react/promise","seld/jsonlint","seld/phar-utils","symfony/debug","symfony/finder","symfony/polyfill-mbstring"] !!PluginA:1.1.1.0["plugin/a","plugin/b","root/pkg","symfony/console","symfony/filesystem","symfony/polyfill-ctype","symfony/process","composer/ca-bundle","composer/composer","composer/semver","composer/spdx-licenses","composer/xdebug-handler","justinrainbow/json-schema","psr/log","react/promise","seld/jsonlint","seld/phar-utils","symfony/debug","symfony/finder","symfony/polyfill-mbstring"]
!!PluginB:2.2.2.0 !!PluginB:2.2.2.0
!!Versions:console:99999.1.2.0;process:12345.1.2.0;filesystem:2.8.2.0 !!Versions:console:99999.1.2.0;process:12345.1.2.0;filesystem:2.8.2.0
!!PluginB:2.2.2.0["plugin/a","plugin/b","root/pkg","symfony/console","symfony/filesystem","symfony/polyfill-ctype","symfony/process","composer/ca-bundle","composer/composer","composer/semver","composer/spdx-licenses","composer/xdebug-handler","justinrainbow/json-schema","psr/log","react/promise","seld/jsonlint","seld/phar-utils","symfony/debug","symfony/finder","symfony/polyfill-mbstring"] !!PluginB:2.2.2.0["plugin/a","plugin/b","root/pkg","symfony/console","symfony/filesystem","symfony/polyfill-ctype","symfony/process","composer/ca-bundle","composer/composer","composer/semver","composer/spdx-licenses","composer/xdebug-handler","justinrainbow/json-schema","psr/log","react/promise","seld/jsonlint","seld/phar-utils","symfony/debug","symfony/finder","symfony/polyfill-mbstring"]
!!PluginA:1.1.1.0 !!PluginA:1.1.1.0
!!Versions:console:99999.1.2.0;process:12345.1.2.0;filesystem:2.8.2.0%(\n> Hooks::preUpdate)?% !!Versions:console:99999.1.2.0;process:12345.1.2.0;filesystem:2.8.2.0
> Hooks::preUpdate
!!PreUpdate:["plugin/a","plugin/b","root/pkg","symfony/console","symfony/filesystem","symfony/polyfill-ctype","symfony/process","composer/ca-bundle","composer/composer","composer/semver","composer/spdx-licenses","composer/xdebug-handler","justinrainbow/json-schema","psr/log","react/promise","seld/jsonlint","seld/phar-utils","symfony/debug","symfony/finder","symfony/polyfill-mbstring"] !!PreUpdate:["plugin/a","plugin/b","root/pkg","symfony/console","symfony/filesystem","symfony/polyfill-ctype","symfony/process","composer/ca-bundle","composer/composer","composer/semver","composer/spdx-licenses","composer/xdebug-handler","justinrainbow/json-schema","psr/log","react/promise","seld/jsonlint","seld/phar-utils","symfony/debug","symfony/finder","symfony/polyfill-mbstring"]
!!Versions:console:99999.1.2.0;process:12345.1.2.0;filesystem:2.8.2.0%(\n> Hooks::preUpdate)?% !!Versions:console:99999.1.2.0;process:12345.1.2.0;filesystem:2.8.2.0
Loading composer repositories with package information Loading composer repositories with package information
Updating dependencies Updating dependencies
Lock file operations: 0 installs, 5 updates, 0 removals Lock file operations: 0 installs, 5 updates, 0 removals
@ -26,16 +27,19 @@ Lock file operations: 0 installs, 5 updates, 0 removals
Writing lock file Writing lock file
Installing dependencies from lock file (including require-dev) Installing dependencies from lock file (including require-dev)
Package operations: 0 installs, 5 updates, 0 removals Package operations: 0 installs, 5 updates, 0 removals
- Downloading symfony/filesystem (%v?[2-8]\.\d+\.\d+%)
- Upgrading symfony/console (99999.1.2 => 99999.1.3): Mirroring from symfony-console - Upgrading symfony/console (99999.1.2 => 99999.1.3): Mirroring from symfony-console
- Upgrading plugin/a (1.1.1 => 1.1.2): Mirroring from plugin-a - Upgrading plugin/a (1.1.1 => 1.1.2): Mirroring from plugin-a
!!PluginA:1.1.1.0["plugin/a","plugin/b","root/pkg","symfony/console","symfony/filesystem","symfony/polyfill-ctype","symfony/process","composer/ca-bundle","composer/composer","composer/semver","composer/spdx-licenses","composer/xdebug-handler","justinrainbow/json-schema","psr/log","react/promise","seld/jsonlint","seld/phar-utils","symfony/debug","symfony/finder","symfony/polyfill-mbstring"] !!PluginAInit["plugin/a","plugin/b","root/pkg","symfony/console","symfony/filesystem","symfony/polyfill-ctype","symfony/process","composer/ca-bundle","composer/composer","composer/semver","composer/spdx-licenses","composer/xdebug-handler","justinrainbow/json-schema","psr/log","react/promise","seld/jsonlint","seld/phar-utils","symfony/debug","symfony/finder","symfony/polyfill-mbstring"]
!!PluginA:1.1.1.0
!!PluginB:2.2.2.0 !!PluginB:2.2.2.0
!!Versions:console:99999.1.3.0;process:12345.1.2.0;filesystem:%[2-8]\.\d+\.\d+.0% !!Versions:console:99999.1.3.0;process:12345.1.2.0;filesystem:%[2-8]\.\d+\.\d+.0%
- Upgrading plugin/b (2.2.2 => 2.2.3): Mirroring from plugin-b - Upgrading plugin/b (2.2.2 => 2.2.3): Mirroring from plugin-b
!!PluginB:2.2.2.0["plugin/a","plugin/b","root/pkg","symfony/console","symfony/filesystem","symfony/polyfill-ctype","symfony/process","composer/ca-bundle","composer/composer","composer/semver","composer/spdx-licenses","composer/xdebug-handler","justinrainbow/json-schema","psr/log","react/promise","seld/jsonlint","seld/phar-utils","symfony/debug","symfony/finder","symfony/polyfill-mbstring"] !!PluginBInit["plugin/a","plugin/b","root/pkg","symfony/console","symfony/filesystem","symfony/polyfill-ctype","symfony/process","composer/ca-bundle","composer/composer","composer/semver","composer/spdx-licenses","composer/xdebug-handler","justinrainbow/json-schema","psr/log","react/promise","seld/jsonlint","seld/phar-utils","symfony/debug","symfony/finder","symfony/polyfill-mbstring"]
!!PluginA:1.1.2.0 !!PluginA:1.1.2.0
!!PluginB:2.2.2.0
!!Versions:console:99999.1.3.0;process:12345.1.2.0;filesystem:%[2-8]\.\d+\.\d+.0% !!Versions:console:99999.1.3.0;process:12345.1.2.0;filesystem:%[2-8]\.\d+\.\d+.0%
- Upgrading symfony/filesystem (v2.8.2 => %v?[2-8]\.\d+\.\d+%) - Upgrading symfony/filesystem (v2.8.2 => %v?[2-8]\.\d+\.\d+%): Extracting archive
- Upgrading symfony/process (12345.1.2 => 12345.1.3): Mirroring from symfony-process - Upgrading symfony/process (12345.1.2 => 12345.1.3): Mirroring from symfony-process
Generating autoload files Generating autoload files
2 packages you are using are looking for funding. 2 packages you are using are looking for funding.

View File

@ -8,16 +8,15 @@ class Hooks
{ {
public static function preUpdate(Event $event) public static function preUpdate(Event $event)
{ {
flush(); fwrite(STDERR, '!!PreUpdate:'.JsonFile::encode(InstalledVersions::getInstalledPackages(), 320)."\n");
echo '!!PreUpdate:'.JsonFile::encode(InstalledVersions::getInstalledPackages(), 320)."\n"; fwrite(STDERR, '!!Versions:console:'.InstalledVersions::getVersion('symfony/console').';process:'.InstalledVersions::getVersion('symfony/process').';filesystem:'.InstalledVersions::getVersion('symfony/filesystem')."\n");
echo '!!Versions:console:'.InstalledVersions::getVersion('symfony/console').';process:'.InstalledVersions::getVersion('symfony/process').';filesystem:'.InstalledVersions::getVersion('symfony/filesystem')."\n";
} }
public static function postUpdate(Event $event) public static function postUpdate(Event $event)
{ {
echo '!!PostUpdate:'.JsonFile::encode(InstalledVersions::getInstalledPackages(), 320)."\n"; fwrite(STDERR, '!!PostUpdate:'.JsonFile::encode(InstalledVersions::getInstalledPackages(), 320)."\n");
echo '!!Versions:console:'.InstalledVersions::getVersion('symfony/console').';process:'.InstalledVersions::getVersion('symfony/process').';filesystem:'.InstalledVersions::getVersion('symfony/filesystem')."\n"; fwrite(STDERR, '!!Versions:console:'.InstalledVersions::getVersion('symfony/console').';process:'.InstalledVersions::getVersion('symfony/process').';filesystem:'.InstalledVersions::getVersion('symfony/filesystem')."\n");
echo '!!PluginA:'.InstalledVersions::getVersion('plugin/a')."\n"; fwrite(STDERR, '!!PluginA:'.InstalledVersions::getVersion('plugin/a')."\n");
echo '!!PluginB:'.InstalledVersions::getVersion('plugin/b')."\n"; fwrite(STDERR, '!!PluginB:'.InstalledVersions::getVersion('plugin/b')."\n");
} }
} }

View File

@ -10,7 +10,8 @@ class PluginA implements PluginInterface
{ {
public function activate(Composer $composer, IOInterface $io) public function activate(Composer $composer, IOInterface $io)
{ {
echo '!!PluginA:'.InstalledVersions::getVersion('plugin/a').JsonFile::encode(InstalledVersions::getInstalledPackages(), 320)."\n"; echo '!!PluginAInit'.JsonFile::encode(InstalledVersions::getInstalledPackages(), 320)."\n";
echo '!!PluginA:'.(InstalledVersions::isInstalled('plugin/a') ? InstalledVersions::getVersion('plugin/a') : 'null')."\n";
echo '!!PluginB:'.(InstalledVersions::isInstalled('plugin/b') ? InstalledVersions::getVersion('plugin/b') : 'null')."\n"; echo '!!PluginB:'.(InstalledVersions::isInstalled('plugin/b') ? InstalledVersions::getVersion('plugin/b') : 'null')."\n";
echo '!!Versions:console:'.InstalledVersions::getVersion('symfony/console').';process:'.InstalledVersions::getVersion('symfony/process').';filesystem:'.InstalledVersions::getVersion('symfony/filesystem')."\n"; echo '!!Versions:console:'.InstalledVersions::getVersion('symfony/console').';process:'.InstalledVersions::getVersion('symfony/process').';filesystem:'.InstalledVersions::getVersion('symfony/filesystem')."\n";
} }

View File

@ -10,8 +10,9 @@ class PluginB implements PluginInterface
{ {
public function activate(Composer $composer, IOInterface $io) public function activate(Composer $composer, IOInterface $io)
{ {
echo '!!PluginB:'.InstalledVersions::getVersion('plugin/b').JsonFile::encode(InstalledVersions::getInstalledPackages(), 320)."\n"; echo '!!PluginBInit'.JsonFile::encode(InstalledVersions::getInstalledPackages(), 320)."\n";
echo '!!PluginA:'.(InstalledVersions::isInstalled('plugin/a') ? InstalledVersions::getVersion('plugin/a') : 'null')."\n"; echo '!!PluginA:'.(InstalledVersions::isInstalled('plugin/a') ? InstalledVersions::getVersion('plugin/a') : 'null')."\n";
echo '!!PluginB:'.(InstalledVersions::isInstalled('plugin/b') ? InstalledVersions::getVersion('plugin/b') : 'null')."\n";
echo '!!Versions:console:'.InstalledVersions::getVersion('symfony/console').';process:'.InstalledVersions::getVersion('symfony/process').';filesystem:'.InstalledVersions::getVersion('symfony/filesystem')."\n"; echo '!!Versions:console:'.InstalledVersions::getVersion('symfony/console').';process:'.InstalledVersions::getVersion('symfony/process').';filesystem:'.InstalledVersions::getVersion('symfony/filesystem')."\n";
} }