Spaces:
No application file
No application file
File size: 5,261 Bytes
d2897cd |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
<?php
declare(strict_types=1);
namespace Mautic\CoreBundle\Helper;
use Composer\Console\Application;
use Mautic\MarketplaceBundle\DTO\ConsoleOutput;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\HttpKernel\KernelInterface;
/**
* Provides several helper functions to interact with Composer (composer require, remove, etc.).
*/
class ComposerHelper
{
public function __construct(
private KernelInterface $kernel,
private LoggerInterface $logger
) {
}
/**
* Installs a package using its Packagist name.
*
* @param string $packageName The package name, e.g. mautic/example-plugin
* @param bool $dryRun Whether to dry-run the installation. Comes in handy during automated tests
* and to test whether an installation would succeed or not.
*/
public function install(string $packageName, bool $dryRun = false): ConsoleOutput
{
$input = [
'command' => 'require',
'packages' => [$packageName],
];
if (true === $dryRun) {
$input['--dry-run'] = null;
}
return $this->runCommand($input);
}
/**
* Removes a package using its Packagist name.
*
* @param string $packageName The package name, e.g. mautic/example-plugin
* @param bool $dryRun Whether to dry-run the removal. Comes in handy during automated tests
* and to test whether an removal would succeed or not.
*/
public function remove(string $packageName, bool $dryRun = false): ConsoleOutput
{
/**
* "composer remove package-name" also triggers an update of all other Mautic dependencies.
* By using the --no-update option first, we can work around that issue and only delete
* this specific package from the composer.json file.
*/
$input = [
'command' => 'remove',
'packages' => [$packageName],
'--no-update' => null,
];
if (true === $dryRun) {
$input['--dry-run'] = null;
}
$firstOutput = $this->runCommand($input);
if (0 === $firstOutput->exitCode) {
/**
* Triggering an update of the package we just removed from composer.json
* will remove it from composer.lock and actually delete the plugin folder
* as well.
*/
$input = [
'command' => 'update',
'packages' => [$packageName],
];
if (true === $dryRun) {
$input['--dry-run'] = null;
}
$secondOutput = $this->runCommand($input);
// Let's merge the output so that we return all the output we have.
return new ConsoleOutput(
$secondOutput->exitCode,
$firstOutput->output."\n".$secondOutput->output
);
}
return $firstOutput;
}
/**
* Checks if the given Composer package is installed.
*
* @param string $packageName The package name, e.g. mautic/exmple-plugin
*/
public function isInstalled(string $packageName): bool
{
return \Composer\InstalledVersions::isInstalled($packageName);
}
/**
* Returns a list of installed Composer packages that are of type mautic-plugin.
*
* @return string[]
*/
public function getMauticPluginPackages(): array
{
return \Composer\InstalledVersions::getInstalledPackagesByType('mautic-plugin');
}
/**
* Updates one or multiple Composer packages.
*/
public function update(?string $packageName = null, bool $dryRun = false): ConsoleOutput
{
$input = [
'command' => 'update',
];
if (!empty($packageName)) {
$input['packages'] = [$packageName];
}
if (true === $dryRun) {
$input['--dry-run'] = null;
}
return $this->runCommand($input);
}
/**
* @param array<string,mixed> $input
*/
private function runCommand(array $input): ConsoleOutput
{
$arrayInput = new ArrayInput(array_merge(
$input, [
'--no-interaction',
'--working-dir' => $this->kernel->getProjectDir(),
]));
$application = new Application();
// We don't want our script to stop after running a Composer command
$application->setAutoExit(false);
$this->logger->info('Running Composer command: '.$arrayInput->__toString());
$output = new BufferedOutput();
$exitCode = 1;
try {
$exitCode = $application->run($arrayInput, $output);
} catch (\Exception $e) {
$output->writeln('Exception while running Composer command: '.$e->getMessage());
$this->logger->error('Exception while running Composer command: '.$e->getMessage());
}
$this->logger->info('Composer command output: '.$output->fetch());
return new ConsoleOutput($exitCode, $output->fetch());
}
}
|