1
0
Fork 0

Revert composer.json changes when require process stops

pull/7555/head
Pierre du Plessis 2018-08-15 12:59:05 +02:00
parent db13cc4960
commit d65e1c0112
No known key found for this signature in database
GPG Key ID: DCB9DD926044955D
1 changed files with 44 additions and 23 deletions

View File

@ -32,6 +32,11 @@ use Composer\Repository\PlatformRepository;
*/ */
class RequireCommand extends InitCommand class RequireCommand extends InitCommand
{ {
private $newlyCreated;
private $json;
private $file;
private $composerBackup;
protected function configure() protected function configure()
{ {
$this $this
@ -75,32 +80,39 @@ EOT
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output)
{ {
$file = Factory::getComposerFile(); if (function_exists('pcntl_async_signals')) {
pcntl_async_signals(true);
pcntl_signal(SIGINT, array($this, 'revertComposerFile'));
pcntl_signal(SIGTERM, array($this, 'revertComposerFile'));
pcntl_signal(SIGHUP, array($this, 'revertComposerFile'));
}
$this->file = Factory::getComposerFile();
$io = $this->getIO(); $io = $this->getIO();
$newlyCreated = !file_exists($file); $this->newlyCreated = !file_exists($this->file);
if ($newlyCreated && !file_put_contents($file, "{\n}\n")) { if ($this->newlyCreated && !file_put_contents($this->file, "{\n}\n")) {
$io->writeError('<error>'.$file.' could not be created.</error>'); $io->writeError('<error>'.$this->file.' could not be created.</error>');
return 1; return 1;
} }
if (!is_readable($file)) { if (!is_readable($this->file)) {
$io->writeError('<error>'.$file.' is not readable.</error>'); $io->writeError('<error>'.$this->file.' is not readable.</error>');
return 1; return 1;
} }
if (!is_writable($file)) { if (!is_writable($this->file)) {
$io->writeError('<error>'.$file.' is not writable.</error>'); $io->writeError('<error>'.$this->file.' is not writable.</error>');
return 1; return 1;
} }
if (filesize($file) === 0) { if (filesize($this->file) === 0) {
file_put_contents($file, "{\n}\n"); file_put_contents($this->file, "{\n}\n");
} }
$json = new JsonFile($file); $this->json = new JsonFile($this->file);
$composerBackup = file_get_contents($json->getPath()); $this->composerBackup = file_get_contents($this->json->getPath());
$composer = $this->getComposer(true, $input->getOption('no-plugins')); $composer = $this->getComposer(true, $input->getOption('no-plugins'));
$repos = $composer->getRepositoryManager()->getRepositories(); $repos = $composer->getRepositoryManager()->getRepositories();
@ -133,16 +145,16 @@ EOT
$sortPackages = $input->getOption('sort-packages') || $composer->getConfig()->get('sort-packages'); $sortPackages = $input->getOption('sort-packages') || $composer->getConfig()->get('sort-packages');
if (!$this->updateFileCleanly($json, $requirements, $requireKey, $removeKey, $sortPackages)) { if (!$this->updateFileCleanly($this->json, $requirements, $requireKey, $removeKey, $sortPackages)) {
$composerDefinition = $json->read(); $composerDefinition = $this->json->read();
foreach ($requirements as $package => $version) { foreach ($requirements as $package => $version) {
$composerDefinition[$requireKey][$package] = $version; $composerDefinition[$requireKey][$package] = $version;
unset($composerDefinition[$removeKey][$package]); unset($composerDefinition[$removeKey][$package]);
} }
$json->write($composerDefinition); $this->json->write($composerDefinition);
} }
$io->writeError('<info>'.$file.' has been '.($newlyCreated ? 'created' : 'updated').'</info>'); $io->writeError('<info>'.$this->file.' has been '.($this->newlyCreated ? 'created' : 'updated').'</info>');
if ($input->getOption('no-update')) { if ($input->getOption('no-update')) {
return 0; return 0;
@ -183,13 +195,7 @@ EOT
$status = $install->run(); $status = $install->run();
if ($status !== 0) { if ($status !== 0) {
if ($newlyCreated) { $this->revertComposerFile();
$io->writeError("\n".'<error>Installation failed, deleting '.$file.'.</error>');
unlink($json->getPath());
} else {
$io->writeError("\n".'<error>Installation failed, reverting '.$file.' to its original content.</error>');
file_put_contents($json->getPath(), $composerBackup);
}
} }
return $status; return $status;
@ -219,4 +225,19 @@ EOT
{ {
return; return;
} }
public function revertComposerFile()
{
$io = $this->getIO();
if ($this->newlyCreated) {
$io->writeError("\n".'<error>Installation failed, deleting '.$this->file.'.</error>');
unlink($this->json->getPath());
} else {
$io->writeError("\n".'<error>Installation failed, reverting '.$this->file.' to its original content.</error>');
file_put_contents($this->json->getPath(), $this->composerBackup);
}
exit(1);
}
} }