protected function execute(InputInterface $input, OutputInterface $output) { $packages = $input->getArgument('packages'); $file = Factory::getComposerFile(); $jsonFile = new JsonFile($file); $composer = $jsonFile->read(); $composerBackup = file_get_contents($jsonFile->getPath()); $json = new JsonConfigSource($jsonFile); $type = $input->getOption('dev') ? 'require-dev' : 'require'; $altType = !$input->getOption('dev') ? 'require-dev' : 'require'; $io = $this->getIO(); if ($input->getOption('update-with-dependencies')) { $io->writeError('<warning>You are using the deprecated option "update-with-dependencies". This is now default behaviour. The --no-update-with-dependencies option can be used to remove a package without its dependencies.</warning>'); } foreach ($packages as $package) { if (isset($composer[$type][$package])) { $json->removeLink($type, $package); } elseif (isset($composer[$altType][$package])) { $io->writeError('<warning>' . $package . ' could not be found in ' . $type . ' but it is present in ' . $altType . '</warning>'); if ($io->isInteractive()) { if ($io->askConfirmation('Do you want to remove it from ' . $altType . ' [<comment>yes</comment>]? ', true)) { $json->removeLink($altType, $package); } } } else { $io->writeError('<warning>' . $package . ' is not required in your composer.json and has not been removed</warning>'); } } if ($input->getOption('no-update')) { return 0; } // Update packages $this->resetComposer(); $composer = $this->getComposer(true, $input->getOption('no-plugins')); $composer->getDownloadManager()->setOutputProgress(!$input->getOption('no-progress')); $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'remove', $input, $output); $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent); $install = Installer::create($io, $composer); $updateDevMode = !$input->getOption('update-no-dev'); $optimize = $input->getOption('optimize-autoloader') || $composer->getConfig()->get('optimize-autoloader'); $authoritative = $input->getOption('classmap-authoritative') || $composer->getConfig()->get('classmap-authoritative'); $install->setVerbose($input->getOption('verbose'))->setDevMode($updateDevMode)->setOptimizeAutoloader($optimize)->setClassMapAuthoritative($authoritative)->setUpdate(true)->setUpdateWhitelist($packages)->setWhitelistDependencies(!$input->getOption('no-update-with-dependencies'))->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs')); $exception = null; try { $status = $install->run(); } catch (\Exception $exception) { $status = 1; } if ($status !== 0) { $io->writeError("\n" . '<error>Removal failed, reverting ' . $file . ' to its original content.</error>'); file_put_contents($jsonFile->getPath(), $composerBackup); } if ($exception) { throw $exception; } return $status; }
/** * Remove packages from the root install. * * @param $packages array Indexed array of package names to remove * * @throws \Bolt\Exception\PackageManagerException * * @return int 0 on success or a positive error code on failure */ public function execute(array $packages) { if (empty($packages)) { throw new PackageManagerException('No package specified for removal'); } $io = $this->app['extend.manager']->getIO(); $options = $this->app['extend.manager']->getOptions(); $jsonFile = new JsonFile($options['composerjson']); $composerDefinition = $jsonFile->read(); $composerBackup = file_get_contents($jsonFile->getPath()); $json = new JsonConfigSource($jsonFile); $type = $options['dev'] ? 'require-dev' : 'require'; // Remove packages from JSON foreach ($packages as $package) { if (isset($composerDefinition[$type][$package])) { $json->removeLink($type, $package); } } // Reload Composer config $composer = $this->app['extend.manager']->getFactory()->resetComposer(); $install = Installer::create($io, $composer); try { $install->setVerbose($options['verbose'])->setDevMode(!$options['updatenodev'])->setUpdate(true)->setUpdateWhitelist($packages)->setWhitelistDependencies($options['updatewithdependencies'])->setIgnorePlatformRequirements($options['ignoreplatformreqs']); $status = $install->run(); if ($status !== 0) { // Write out old JSON file file_put_contents($jsonFile->getPath(), $composerBackup); } } catch (\Exception $e) { $msg = __CLASS__ . '::' . __FUNCTION__ . ' recieved an error from Composer: ' . $e->getMessage() . ' in ' . $e->getFile() . '::' . $e->getLine(); $this->app['logger.system']->critical($msg, array('event' => 'exception', 'exception' => $e)); throw new PackageManagerException($e->getMessage(), $e->getCode(), $e); } return $status; }
protected function execute(InputInterface $input, OutputInterface $output) { $packages = $input->getArgument('packages'); $file = Factory::getComposerFile(); $jsonFile = new JsonFile($file); $composer = $jsonFile->read(); $composerBackup = file_get_contents($jsonFile->getPath()); $json = new JsonConfigSource($jsonFile); $type = $input->getOption('dev') ? 'require-dev' : 'require'; $altType = !$input->getOption('dev') ? 'require-dev' : 'require'; foreach ($packages as $package) { if (isset($composer[$type][$package])) { $json->removeLink($type, $package); } elseif (isset($composer[$altType][$package])) { $this->getIO()->writeError('<warning>' . $package . ' could not be found in ' . $type . ' but it is present in ' . $altType . '</warning>'); $dialog = $this->getHelperSet()->get('dialog'); if ($this->getIO()->isInteractive()) { if ($dialog->askConfirmation($output, $dialog->getQuestion('Do you want to remove it from ' . $altType, 'yes', '?'), true)) { $json->removeLink($altType, $package); } } } else { $this->getIO()->writeError('<warning>' . $package . ' is not required in your composer.json and has not been removed</warning>'); } } if ($input->getOption('no-update')) { return 0; } // Update packages $composer = $this->getComposer(); $composer->getDownloadManager()->setOutputProgress(!$input->getOption('no-progress')); $io = $this->getIO(); $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'remove', $input, $output); $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent); $install = Installer::create($io, $composer); $updateDevMode = !$input->getOption('update-no-dev'); $install->setVerbose($input->getOption('verbose'))->setDevMode($updateDevMode)->setUpdate(true)->setUpdateWhitelist($packages)->setWhitelistDependencies($input->getOption('update-with-dependencies'))->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs')); $status = $install->run(); if ($status !== 0) { $this->getIO()->writeError("\n" . '<error>Removal failed, reverting ' . $file . ' to its original content.</error>'); file_put_contents($jsonFile->getPath(), $composerBackup); } return $status; }
/** * Test removeLink() * * @param string $sourceFile Source file * @param string $type Type (require, require-dev, provide, suggest, replace, conflict) * @param string $name Name * @param string $compareAgainst File to compare against after making changes * * @dataProvider provideRemoveLinkData */ public function testRemoveLink($sourceFile, $type, $name, $compareAgainst) { $composerJson = $this->workingDir . '/composer.json'; copy($sourceFile, $composerJson); $jsonConfigSource = new JsonConfigSource(new JsonFile($composerJson)); $jsonConfigSource->removeLink($type, $name); $this->assertFileEquals($compareAgainst, $composerJson); }