Ejemplo n.º 1
0
 /**
  * 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;
 }
Ejemplo n.º 2
0
 protected function manipulateJson($method, $args, $fallback)
 {
     $args = func_get_args();
     // remove method & fallback
     array_shift($args);
     $fallback = array_pop($args);
     if ($this->file->exists()) {
         $contents = file_get_contents($this->file->getPath());
     } else {
         $contents = "{\n    \"config\": {\n    }\n}\n";
     }
     $manipulator = new JsonManipulator($contents);
     $newFile = !$this->file->exists();
     // try to update cleanly
     if (call_user_func_array(array($manipulator, $method), $args)) {
         file_put_contents($this->file->getPath(), $manipulator->getContents());
     } else {
         // on failed clean update, call the fallback and rewrite the whole file
         $config = $this->file->read();
         $this->array_unshift_ref($args, $config);
         call_user_func_array($fallback, $args);
         $this->file->write($config);
     }
     if ($newFile) {
         @chmod($this->file->getPath(), 0600);
     }
 }
Ejemplo n.º 3
0
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $file = Factory::getComposerFile();
     if (!file_exists($file) && !file_put_contents($file, "{\n}\n")) {
         $output->writeln('<error>' . $file . ' could not be created.</error>');
         return 1;
     }
     if (!is_readable($file)) {
         $output->writeln('<error>' . $file . ' is not readable.</error>');
         return 1;
     }
     if (!is_writable($file)) {
         $output->writeln('<error>' . $file . ' is not writable.</error>');
         return 1;
     }
     $json = new JsonFile($file);
     $composer = $json->read();
     $composerBackup = file_get_contents($json->getPath());
     $requirements = $this->determineRequirements($input, $output, $input->getArgument('packages'));
     $requireKey = $input->getOption('dev') ? 'require-dev' : 'require';
     $removeKey = $input->getOption('dev') ? 'require' : 'require-dev';
     $baseRequirements = array_key_exists($requireKey, $composer) ? $composer[$requireKey] : array();
     $requirements = $this->formatRequirements($requirements);
     // validate requirements format
     $versionParser = new VersionParser();
     foreach ($requirements as $constraint) {
         $versionParser->parseConstraints($constraint);
     }
     if (!$this->updateFileCleanly($json, $baseRequirements, $requirements, $requireKey, $removeKey)) {
         foreach ($requirements as $package => $version) {
             $baseRequirements[$package] = $version;
             if (isset($composer[$removeKey][$package])) {
                 unset($composer[$removeKey][$package]);
             }
         }
         $composer[$requireKey] = $baseRequirements;
         $json->write($composer);
     }
     $output->writeln('<info>' . $file . ' has been updated</info>');
     if ($input->getOption('no-update')) {
         return 0;
     }
     $updateDevMode = !$input->getOption('update-no-dev');
     // Update packages
     $composer = $this->getComposer();
     $composer->getDownloadManager()->setOutputProgress(!$input->getOption('no-progress'));
     $io = $this->getIO();
     $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'require', $input, $output);
     $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
     $install = Installer::create($io, $composer);
     $install->setVerbose($input->getOption('verbose'))->setPreferSource($input->getOption('prefer-source'))->setPreferDist($input->getOption('prefer-dist'))->setDevMode($updateDevMode)->setUpdate(true)->setUpdateWhitelist(array_keys($requirements))->setWhitelistDependencies($input->getOption('update-with-dependencies'));
     $status = $install->run();
     if ($status !== 0) {
         $output->writeln("\n" . '<error>Installation failed, reverting ' . $file . ' to its original content.</error>');
         file_put_contents($json->getPath(), $composerBackup);
     }
     return $status;
 }
Ejemplo n.º 4
0
 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();
     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
     $composer = $this->getComposer();
     $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('update-with-dependencies'))->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs'));
     $status = $install->run();
     if ($status !== 0) {
         $io->writeError("\n" . '<error>Removal failed, reverting ' . $file . ' to its original content.</error>');
         file_put_contents($jsonFile->getPath(), $composerBackup);
     }
     return $status;
 }
Ejemplo n.º 5
0
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $file = Factory::getComposerFile();
     if (!file_exists($file) && !file_put_contents($file, "{\n}\n")) {
         $output->writeln('<error>' . $file . ' could not be created.</error>');
         return 1;
     }
     if (!is_readable($file)) {
         $output->writeln('<error>' . $file . ' is not readable.</error>');
         return 1;
     }
     if (!is_writable($file)) {
         $output->writeln('<error>' . $file . ' is not writable.</error>');
         return 1;
     }
     $dialog = $this->getHelperSet()->get('dialog');
     $json = new JsonFile($file);
     $composer = $json->read();
     $composerBackup = file_get_contents($json->getPath());
     $requirements = $this->determineRequirements($input, $output, $input->getArgument('packages'));
     $requireKey = $input->getOption('dev') ? 'require-dev' : 'require';
     $baseRequirements = array_key_exists($requireKey, $composer) ? $composer[$requireKey] : array();
     $requirements = $this->formatRequirements($requirements);
     if (!$this->updateFileCleanly($json, $baseRequirements, $requirements, $requireKey)) {
         foreach ($requirements as $package => $version) {
             $baseRequirements[$package] = $version;
         }
         $composer[$requireKey] = $baseRequirements;
         $json->write($composer);
     }
     $output->writeln('<info>' . $file . ' has been updated</info>');
     if ($input->getOption('no-update')) {
         return 0;
     }
     // Update packages
     $composer = $this->getComposer();
     $composer->getDownloadManager()->setOutputProgress(!$input->getOption('no-progress'));
     $io = $this->getIO();
     $install = Installer::create($io, $composer);
     $install->setVerbose($input->getOption('verbose'))->setPreferSource($input->getOption('prefer-source'))->setPreferDist($input->getOption('prefer-dist'))->setDevMode(true)->setUpdate(true)->setUpdateWhitelist(array_keys($requirements));
     if (!$install->run()) {
         $output->writeln("\n" . '<error>Installation failed, reverting ' . $file . ' to its original content.</error>');
         file_put_contents($json->getPath(), $composerBackup);
         return 1;
     }
     return 0;
 }
Ejemplo n.º 6
0
 protected function manipulateJson($method, $args, $fallback)
 {
     $args = func_get_args();
     // remove method & fallback
     array_shift($args);
     $fallback = array_pop($args);
     if ($this->file->exists()) {
         if (!is_writable($this->file->getPath())) {
             throw new \RuntimeException(sprintf('The file "%s" is not writable.', $this->file->getPath()));
         }
         if (!is_readable($this->file->getPath())) {
             throw new \RuntimeException(sprintf('The file "%s" is not readable.', $this->file->getPath()));
         }
         $contents = file_get_contents($this->file->getPath());
     } elseif ($this->authConfig) {
         $contents = "{\n}\n";
     } else {
         $contents = "{\n    \"config\": {\n    }\n}\n";
     }
     $manipulator = new JsonManipulator($contents);
     $newFile = !$this->file->exists();
     // override manipulator method for auth config files
     if ($this->authConfig && $method === 'addConfigSetting') {
         $method = 'addSubNode';
         list($mainNode, $name) = explode('.', $args[0], 2);
         $args = array($mainNode, $name, $args[1]);
     } elseif ($this->authConfig && $method === 'removeConfigSetting') {
         $method = 'removeSubNode';
         list($mainNode, $name) = explode('.', $args[0], 2);
         $args = array($mainNode, $name);
     }
     // try to update cleanly
     if (call_user_func_array(array($manipulator, $method), $args)) {
         file_put_contents($this->file->getPath(), $manipulator->getContents());
     } else {
         // on failed clean update, call the fallback and rewrite the whole file
         $config = $this->file->read();
         $this->arrayUnshiftRef($args, $config);
         call_user_func_array($fallback, $args);
         $this->file->write($config);
     }
     if ($newFile) {
         Silencer::call('chmod', $this->file->getPath(), 0600);
     }
 }
Ejemplo n.º 7
0
 /**
  * Creates a Composer instance
  *
  * @param  IOInterface               $io             IO instance
  * @param  array|string|null         $localConfig    either a configuration array or a filename to read from, if null it will
  *                                                   read from the default filename
  * @param  bool                      $disablePlugins Whether plugins should not be loaded
  * @throws \InvalidArgumentException
  * @throws \UnexpectedValueException
  * @return Composer
  */
 public function createComposer(IOInterface $io, $localConfig = null, $disablePlugins = false)
 {
     // load Composer configuration
     if (null === $localConfig) {
         $localConfig = static::getComposerFile();
     }
     if (is_string($localConfig)) {
         $composerFile = $localConfig;
         $file = new JsonFile($localConfig, new RemoteFilesystem($io));
         if (!$file->exists()) {
             if ($localConfig === './composer.json' || $localConfig === 'composer.json') {
                 $message = 'Composer could not find a composer.json file in ' . getcwd();
             } else {
                 $message = 'Composer could not find the config file: ' . $localConfig;
             }
             $instructions = 'To initialize a project, please create a composer.json file as described in the http://getcomposer.org/ "Getting Started" section';
             throw new \InvalidArgumentException($message . PHP_EOL . $instructions);
         }
         $file->validateSchema(JsonFile::LAX_SCHEMA);
         $localConfig = $file->read();
     }
     // Load config and override with local config/auth config
     $config = static::createConfig($io);
     $config->merge($localConfig);
     if (isset($composerFile)) {
         if ($io && $io->isDebug()) {
             $io->write('Loading config file ' . $composerFile);
         }
         $localAuthFile = new JsonFile(dirname(realpath($composerFile)) . '/auth.json');
         if ($localAuthFile->exists()) {
             if ($io && $io->isDebug()) {
                 $io->write('Loading config file ' . $localAuthFile->getPath());
             }
             $config->merge(array('config' => $localAuthFile->read()));
             $config->setAuthConfigSource(new JsonConfigSource($localAuthFile, true));
         }
     }
     // load auth configs into the IO instance
     $io->loadConfiguration($config);
     $vendorDir = $config->get('vendor-dir');
     $binDir = $config->get('bin-dir');
     // setup process timeout
     ProcessExecutor::setTimeout((int) $config->get('process-timeout'));
     // initialize composer
     $composer = new Composer();
     $composer->setConfig($config);
     // initialize event dispatcher
     $dispatcher = new EventDispatcher($composer, $io);
     // initialize repository manager
     $rm = $this->createRepositoryManager($io, $config, $dispatcher);
     // load local repository
     $this->addLocalRepository($rm, $vendorDir);
     // load package
     $parser = new VersionParser();
     $loader = new Package\Loader\RootPackageLoader($rm, $config, $parser, new ProcessExecutor($io));
     $package = $loader->load($localConfig);
     // initialize installation manager
     $im = $this->createInstallationManager();
     // Composer composition
     $composer->setPackage($package);
     $composer->setRepositoryManager($rm);
     $composer->setInstallationManager($im);
     // initialize download manager
     $dm = $this->createDownloadManager($io, $config, $dispatcher);
     $composer->setDownloadManager($dm);
     $composer->setEventDispatcher($dispatcher);
     // initialize autoload generator
     $generator = new AutoloadGenerator($dispatcher, $io);
     $composer->setAutoloadGenerator($generator);
     // add installers to the manager
     $this->createDefaultInstallers($im, $composer, $io);
     $globalRepository = $this->createGlobalRepository($config, $vendorDir);
     $pm = $this->createPluginManager($composer, $io, $globalRepository);
     $composer->setPluginManager($pm);
     if (!$disablePlugins) {
         $pm->loadInstalledPlugins();
     }
     // purge packages if they have been deleted on the filesystem
     $this->purgePackages($rm, $im);
     // init locker if possible
     if (isset($composerFile)) {
         $lockFile = "json" === pathinfo($composerFile, PATHINFO_EXTENSION) ? substr($composerFile, 0, -4) . 'lock' : $composerFile . '.lock';
         $locker = new Package\Locker($io, new JsonFile($lockFile, new RemoteFilesystem($io, $config)), $rm, $im, md5_file($composerFile));
         $composer->setLocker($locker);
     }
     return $composer;
 }
Ejemplo n.º 8
0
 /**
  * @return Config
  *
  * @throws \Exception
  */
 protected function getConfig()
 {
     if (!isset($this->config)) {
         $configFilePath = $this->configPathFromInput ?: ConfigFactory::getHomeDir() . '/config.json';
         $this->config = ConfigFactory::createConfig($configFilePath);
         $configFile = new JsonFile($configFilePath);
         $this->configPath = $configFile->getPath();
         $this->configSource = new JsonConfigSource($configFile);
         // initialize the global file if it's not there
         if (!$configFile->exists()) {
             $path = $configFile->getPath();
             $dir = dirname($path);
             if (!is_dir($dir)) {
                 mkdir($dir, 0777, true);
             }
             touch($configFile->getPath());
             $configFile->write(['config' => new \ArrayObject()]);
             @chmod($configFile->getPath(), 0600);
         }
         if (!$configFile->exists()) {
             throw new \RuntimeException('No config.json found in the current directory');
         }
     }
     return $this->config;
 }
Ejemplo n.º 9
0
 protected function updateFileCleanly(JsonFile $json, array $base, array $new, $requireKey, $removeKey, $sortPackages)
 {
     $extra = $this->extra;
     $contents = file_get_contents($json->getPath());
     $manipulator = new JsonManipulator($contents);
     foreach ($new as $package => $constraint) {
         if (!$manipulator->addLink($requireKey, $package, $constraint, $sortPackages)) {
             return false;
         }
         if (!$manipulator->removeSubNode($removeKey, $package)) {
             return false;
         }
     }
     if (isset($extra['installer-modules']) && is_array($extra['installer-modules'])) {
         $manipulator->addSubNode('extra', 'installer-modules', $extra['installer-modules']);
     }
     $paths = $this->getComposer()->getPackage()->getExtra();
     $paths = $paths['installer-paths'];
     if (isset($extra['installer-paths']) && is_array($extra['installer-paths'])) {
         foreach ($extra['installer-paths'] as $path => $list) {
             if (!is_array($list)) {
                 continue;
             }
             if (isset($paths[$path])) {
                 $result = array_merge($paths[$path], $list);
                 $result = array_keys(array_flip($result));
                 $paths[$path] = $result;
             } else {
                 $paths[$path] = $list;
             }
         }
     }
     if (isset($extra['system-modules']) && is_array($extra['system-modules'])) {
         $modules = $extra['system-modules'];
         foreach ($modules as &$module) {
             if (strpos($module, '/') === false) {
                 $module = 'opis-colibri/' . $module;
             }
         }
         $path = 'system/modules/{$name}/';
         if (isset($paths[$path])) {
             $result = array_merge($paths[$path], $modules);
             $result = array_keys(array_flip($result));
             $paths[$path] = $result;
         }
     }
     $manipulator->addSubNode('extra', 'installer-paths', $paths);
     file_put_contents($json->getPath(), $manipulator->getContents());
     return true;
 }
Ejemplo n.º 10
0
 /**
  * Creates a Composer instance
  *
  * @param  IOInterface               $io             IO instance
  * @param  array|string|null         $localConfig    either a configuration array or a filename to read from, if null it will
  *                                                   read from the default filename
  * @param  bool                      $disablePlugins Whether plugins should not be loaded
  * @param  bool                      $fullLoad       Whether to initialize everything or only main project stuff (used when loading the global composer)
  * @throws \InvalidArgumentException
  * @throws \UnexpectedValueException
  * @return Composer
  */
 public function createComposer(IOInterface $io, $localConfig = null, $disablePlugins = false, $cwd = null, $fullLoad = true)
 {
     $cwd = $cwd ?: getcwd();
     // load Composer configuration
     if (null === $localConfig) {
         $localConfig = static::getComposerFile();
     }
     if (is_string($localConfig)) {
         $composerFile = $localConfig;
         $file = new JsonFile($localConfig, null, $io);
         if (!$file->exists()) {
             if ($localConfig === './composer.json' || $localConfig === 'composer.json') {
                 $message = 'Composer could not find a composer.json file in ' . $cwd;
             } else {
                 $message = 'Composer could not find the config file: ' . $localConfig;
             }
             $instructions = 'To initialize a project, please create a composer.json file as described in the https://getcomposer.org/ "Getting Started" section';
             throw new \InvalidArgumentException($message . PHP_EOL . $instructions);
         }
         $file->validateSchema(JsonFile::LAX_SCHEMA);
         $jsonParser = new JsonParser();
         try {
             $jsonParser->parse(file_get_contents($localConfig), JsonParser::DETECT_KEY_CONFLICTS);
         } catch (\Seld\JsonLint\DuplicateKeyException $e) {
             $details = $e->getDetails();
             $io->writeError('<warning>Key ' . $details['key'] . ' is a duplicate in ' . $localConfig . ' at line ' . $details['line'] . '</warning>');
         }
         $localConfig = $file->read();
     }
     // Load config and override with local config/auth config
     $config = static::createConfig($io, $cwd);
     $config->merge($localConfig);
     if (isset($composerFile)) {
         $io->writeError('Loading config file ' . $composerFile, true, IOInterface::DEBUG);
         $localAuthFile = new JsonFile(dirname(realpath($composerFile)) . '/auth.json');
         if ($localAuthFile->exists()) {
             $io->writeError('Loading config file ' . $localAuthFile->getPath(), true, IOInterface::DEBUG);
             $config->merge(array('config' => $localAuthFile->read()));
             $config->setAuthConfigSource(new JsonConfigSource($localAuthFile, true));
         }
     }
     $vendorDir = $config->get('vendor-dir');
     $binDir = $config->get('bin-dir');
     // initialize composer
     $composer = new Composer();
     $composer->setConfig($config);
     if ($fullLoad) {
         // load auth configs into the IO instance
         $io->loadConfiguration($config);
     }
     $rfs = self::createRemoteFilesystem($io, $config);
     // initialize event dispatcher
     $dispatcher = new EventDispatcher($composer, $io);
     $composer->setEventDispatcher($dispatcher);
     // initialize repository manager
     $rm = $this->createRepositoryManager($io, $config, $dispatcher, $rfs);
     $composer->setRepositoryManager($rm);
     // load local repository
     $this->addLocalRepository($io, $rm, $vendorDir);
     // force-set the version of the global package if not defined as
     // guessing it adds no value and only takes time
     if (!$fullLoad && !isset($localConfig['version'])) {
         $localConfig['version'] = '1.0.0';
     }
     // load package
     $parser = new VersionParser();
     $guesser = new VersionGuesser($config, new ProcessExecutor($io), $parser);
     $loader = new Package\Loader\RootPackageLoader($rm, $config, $parser, $guesser);
     $package = $loader->load($localConfig, 'Composer\\Package\\RootPackage', $cwd);
     $composer->setPackage($package);
     // initialize installation manager
     $im = $this->createInstallationManager();
     $composer->setInstallationManager($im);
     if ($fullLoad) {
         // initialize download manager
         $dm = $this->createDownloadManager($io, $config, $dispatcher, $rfs);
         $composer->setDownloadManager($dm);
         // initialize autoload generator
         $generator = new AutoloadGenerator($dispatcher, $io);
         $composer->setAutoloadGenerator($generator);
     }
     // add installers to the manager (must happen after download manager is created since they read it out of $composer)
     $this->createDefaultInstallers($im, $composer, $io);
     if ($fullLoad) {
         $globalComposer = $this->createGlobalComposer($io, $config, $disablePlugins);
         $pm = $this->createPluginManager($io, $composer, $globalComposer, $disablePlugins);
         $composer->setPluginManager($pm);
         $pm->loadInstalledPlugins();
         // once we have plugins and custom installers we can
         // purge packages from local repos if they have been deleted on the filesystem
         if ($rm->getLocalRepository()) {
             $this->purgePackages($rm->getLocalRepository(), $im);
         }
     }
     // init locker if possible
     if ($fullLoad && isset($composerFile)) {
         $lockFile = "json" === pathinfo($composerFile, PATHINFO_EXTENSION) ? substr($composerFile, 0, -4) . 'lock' : $composerFile . '.lock';
         $locker = new Package\Locker($io, new JsonFile($lockFile, null, $io), $rm, $im, file_get_contents($composerFile));
         $composer->setLocker($locker);
     }
     return $composer;
 }
Ejemplo n.º 11
0
 /**
  * Cleanly update a Composer JSON file.
  *
  * @param JsonFile $json
  * @param array    $new
  * @param string   $requireKey
  * @param string   $removeKey
  * @param boolean  $sortPackages
  * @param boolean  $postreset
  *
  * @return boolean
  */
 private function updateFileCleanly(JsonFile $json, array $new, $requireKey, $removeKey, $sortPackages, $postreset)
 {
     $contents = file_get_contents($json->getPath());
     $manipulator = new JsonManipulator($contents);
     foreach ($new as $package => $constraint) {
         if ($postreset) {
             $constraint = $this->findBestVersionForPackage($package);
         }
         if (!$manipulator->addLink($requireKey, $package, $constraint, $sortPackages)) {
             return false;
         }
         if (!$manipulator->removeSubNode($removeKey, $package)) {
             return false;
         }
     }
     file_put_contents($json->getPath(), $manipulator->getContents());
     return true;
 }
Ejemplo n.º 12
0
 /**
  * Loads previously dumped Packages in order to merge with updates.
  *
  * @return PackageInterface[]
  */
 public function load()
 {
     $packages = [];
     $repoJson = new JsonFile($this->filename);
     $dirName = dirname($this->filename);
     if ($repoJson->exists()) {
         $loader = new ArrayLoader();
         $packagesJson = $repoJson->read();
         $jsonIncludes = isset($packagesJson['includes']) && is_array($packagesJson['includes']) ? $packagesJson['includes'] : [];
         if (isset($packagesJson['providers']) && is_array($packagesJson['providers']) && isset($packagesJson['providers-url'])) {
             $baseUrl = $this->homepage ? parse_url(rtrim($this->homepage, '/'), PHP_URL_PATH) . '/' : null;
             $baseUrlLength = strlen($baseUrl);
             foreach ($packagesJson['providers'] as $packageName => $provider) {
                 $file = str_replace(['%package%', '%hash%'], [$packageName, $provider['sha256']], $packagesJson['providers-url']);
                 if ($baseUrl && substr($file, 0, $baseUrlLength) === $baseUrl) {
                     $file = substr($file, $baseUrlLength);
                 }
                 $jsonIncludes[$file] = $provider;
             }
         }
         foreach ($jsonIncludes as $includeFile => $includeConfig) {
             $includeJson = new JsonFile($dirName . '/' . $includeFile);
             if (!$includeJson->exists()) {
                 $this->output->writeln(sprintf('<error>File \'%s\' does not exist, defined in "includes" in \'%s\'</error>', $includeJson->getPath(), $repoJson->getPath()));
                 continue;
             }
             $jsonPackages = $includeJson->read();
             $jsonPackages = isset($jsonPackages['packages']) && is_array($jsonPackages['packages']) ? $jsonPackages['packages'] : [];
             foreach ($jsonPackages as $jsonPackage) {
                 if (is_array($jsonPackage)) {
                     foreach ($jsonPackage as $jsonVersion) {
                         if (is_array($jsonVersion)) {
                             if (isset($jsonVersion['name']) && in_array($jsonVersion['name'], $this->packagesFilter)) {
                                 continue;
                             }
                             $package = $loader->load($jsonVersion);
                             $packages[$package->getUniqueName()] = $package;
                         }
                     }
                 }
             }
         }
     }
     return $packages;
 }
Ejemplo n.º 13
0
 protected function updateFileCleanly(JsonFile $json, array $base, array $new, $requireKey, $removeKey, $sortPackages)
 {
     $contents = file_get_contents($json->getPath());
     $manipulator = new JsonManipulator($contents);
     foreach ($new as $package => $constraint) {
         if (!$manipulator->addLink($requireKey, $package, $constraint, $sortPackages)) {
             return false;
         }
         if (!$manipulator->removeSubNode($removeKey, $package)) {
             return false;
         }
     }
     file_put_contents($json->getPath(), $manipulator->getContents());
     return true;
 }
Ejemplo n.º 14
0
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $packages = $input->getArgument('packages');
     $packages = array_map('strtolower', $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>');
     }
     // make sure name checks are done case insensitively
     foreach (array('require', 'require-dev') as $linkType) {
         if (isset($composer[$linkType])) {
             foreach ($composer[$linkType] as $name => $version) {
                 $composer[$linkType][strtolower($name)] = $version;
             }
         }
     }
     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'))->setRunScripts(!$input->getOption('no-scripts'));
     $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;
 }
Ejemplo n.º 15
0
 /**
  * Loads previously dumped Packages in order to merge with updates.
  *
  * @return PackageInterface[]
  */
 public function load()
 {
     $packages = array();
     $repoJson = new JsonFile($this->filename);
     $dirName = dirname($this->filename);
     if ($repoJson->exists()) {
         $loader = new ArrayLoader();
         $jsonIncludes = $repoJson->read();
         $jsonIncludes = isset($jsonIncludes['includes']) && is_array($jsonIncludes['includes']) ? $jsonIncludes['includes'] : array();
         foreach ($jsonIncludes as $includeFile => $includeConfig) {
             $includeJson = new JsonFile($dirName . '/' . $includeFile);
             if (!$includeJson->exists()) {
                 $this->output->writeln(sprintf('<error>File \'%s\' does not exist, defined in "includes" in \'%s\'</error>', $includeJson->getPath(), $repoJson->getPath()));
                 continue;
             }
             $jsonPackages = $includeJson->read();
             $jsonPackages = isset($jsonPackages['packages']) && is_array($jsonPackages['packages']) ? $jsonPackages['packages'] : array();
             foreach ($jsonPackages as $jsonPackage) {
                 if (is_array($jsonPackage)) {
                     foreach ($jsonPackage as $jsonVersion) {
                         if (is_array($jsonVersion)) {
                             if (isset($jsonVersion['name']) && in_array($jsonVersion['name'], $this->packagesFilter)) {
                                 continue;
                             }
                             $package = $loader->load($jsonVersion);
                             $packages[$package->getUniqueName()] = $package;
                         }
                     }
                 }
             }
         }
     }
     return $packages;
 }
 /**
  * @param JsonFile $json
  * @param array    $base
  * @param array    $new
  * @param          $rootKey
  *
  * @return bool
  */
 private function updateFileCleanly(JsonFile $json, array $base, array $new, $rootKey)
 {
     $contents = file_get_contents($json->getPath());
     $manipulator = new JsonManipulator($contents);
     foreach ($new as $childKey => $childValue) {
         if (!$manipulator->addLink($rootKey, $childKey, $childValue)) {
             return false;
         }
     }
     file_put_contents($json->getPath(), $manipulator->getContents());
     return true;
 }
Ejemplo n.º 17
0
 private function loadProviderIncludes($dirName, $providerIncludes)
 {
     $loader = new ArrayLoader();
     foreach ($providerIncludes as $key => $hash) {
         $includeFile = strtr($key, array('%hash%' => $hash['sha256']));
         $includeJson = new JsonFile($dirName . '/' . $includeFile);
         if (!$includeJson->exists()) {
             $this->output->writeln(sprintf('<error>File \'%s\' does not exist, defined in "includes" in \'%s\'</error>', $includeJson->getPath(), $dirName));
             continue;
         }
         $providers = $includeJson->read();
         foreach ($providers['providers'] as $package => $hash) {
             $file = strtr($path, array('%package%' => $package, '%hash%' => $hash));
             $json = new JsonFile($dirName . $file);
             if (!$json->exists()) {
                 $this->output->writeln(sprintf('<error>File \'%s\' does not exist, defined in "includes" in \'%s\'</error>', $json->getPath(), $includeFile));
                 continue;
             }
             $packages = array_merge($packages, $this->loadPackages($loader, $json->read()));
         }
     }
     return $packages;
 }
Ejemplo n.º 18
0
 /**
  *
  * @param array $extra
  * @param \Composer\IO\IOInterface $io
  * @return int
  */
 private function updateJsonExtra($extra, $io)
 {
     $file = Factory::getComposerFile();
     if (!file_exists($file) && !file_put_contents($file, "{\n}\n")) {
         $io->write('<error>' . $file . ' could not be created.</error>');
         return 1;
     }
     if (!is_readable($file)) {
         $io->write('<error>' . $file . ' is not readable.</error>');
         return 1;
     }
     if (!is_writable($file)) {
         $io->write('<error>' . $file . ' is not writable.</error>');
         return 1;
     }
     $json = new JsonFile($file);
     $composer = $json->read();
     $composerBackup = file_get_contents($json->getPath());
     $extraKey = 'extra';
     $baseExtra = array_key_exists($extraKey, $composer) ? $composer[$extraKey] : array();
     if (!$this->updateFileCleanly($json, $baseExtra, $extra, $extraKey)) {
         foreach ($extra as $key => $value) {
             $baseExtra[$key] = $value;
         }
         $composer[$extraKey] = $baseExtra;
         $json->write($composer);
     }
 }
Ejemplo n.º 19
0
 public function createComposer()
 {
     $cwd = sprintf('%s/%s', getcwd(), '.eva');
     $factory = new Factory();
     if (false) {
         $composer = $factory->createComposer($this->io, $config, true, $cwd);
     }
     //  -----------------
     //  -----------------
     //  -----------------
     $fullLoad = true;
     $composerFile = $cwd . '/manifest.composer.json';
     $file = new JsonFile($composerFile);
     $file->validateSchema(JsonFile::LAX_SCHEMA);
     $localConfig = $file->read();
     //  -----------------
     //  -----------------
     //  -----------------
     // Load config and override with local config/auth config
     //        $config = Factory::createConfig($this->io, $cwd);
     $vendorDir = $cwd . '/manifests/vendor';
     $config = $factory::createConfig($this->io, $cwd);
     $config->merge($localConfig);
     $config->merge(['config' => ['vendor-dir' => $vendorDir]]);
     $localAuthFile = new JsonFile(dirname(realpath($composerFile)) . '/auth.json');
     if ($localAuthFile->exists()) {
         if ($this->io && $this->io->isDebug()) {
             $this->io->writeError('Loading config file ' . $localAuthFile->getPath());
         }
         $config->merge(array('config' => $localAuthFile->read()));
         $config->setAuthConfigSource(new JsonConfigSource($localAuthFile, true));
     }
     // initialize composer
     $composer = new Composer();
     $composer->setConfig($config);
     // initialize event dispatcher
     $dispatcher = new EventDispatcher($composer, $this->io);
     $composer->setEventDispatcher($dispatcher);
     // initialize repository manager
     //        $rm = $this->createRepositoryManager($io, $config, $dispatcher);
     //        $composer->setRepositoryManager($rm);
     $rm = new RepositoryManager($this->io, $config, $dispatcher);
     $rm->setRepositoryClass('composer', ComposerRepository::class);
     $composer->setRepositoryManager($rm);
     // load local repository
     $rm->setLocalRepository(new InstalledFilesystemRepository(new JsonFile($vendorDir . '/composer/installed.json')));
     // load package
     $parser = new VersionParser();
     $guesser = new VersionGuesser($config, new ProcessExecutor($this->io), $parser);
     $loader = new RootPackageLoader($rm, $config, $parser, $guesser);
     $package = $loader->load($localConfig);
     $composer->setPackage($package);
     // initialize installation manager
     $im = new InstallationManager();
     $composer->setInstallationManager($im);
     if ($fullLoad) {
         // initialize download manager
         $dm = $factory->createDownloadManager($this->io, $config, $dispatcher);
         $composer->setDownloadManager($dm);
         // initialize autoload generator
         $generator = new AutoloadGenerator($dispatcher, $this->io);
         $composer->setAutoloadGenerator($generator);
     }
     // add installers to the manager (must happen after download manager is created since they read it out of $composer)
     $im->addInstaller(new Installer\LibraryInstaller($this->io, $composer, null));
     $im->addInstaller(new Installer\PearInstaller($this->io, $composer, 'pear-library'));
     $im->addInstaller(new Installer\PluginInstaller($this->io, $composer));
     $im->addInstaller(new Installer\MetapackageInstaller($this->io));
     //        if ($fullLoad) {
     //            $globalComposer = $this->createGlobalComposer($io, $config, $disablePlugins);
     //            $pm = $this->createPluginManager($io, $composer, $globalComposer);
     //            $composer->setPluginManager($pm);
     //
     //            if (!$disablePlugins) {
     //                $pm->loadInstalledPlugins();
     //            }
     //
     //            // once we have plugins and custom installers we can
     //            // purge packages from local repos if they have been deleted on the filesystem
     //            if ($rm->getLocalRepository()) {
     //                $this->purgePackages($rm->getLocalRepository(), $im);
     //            }
     //        }
     // init locker if possible
     if ($fullLoad && isset($composerFile)) {
         $lockFile = "json" === pathinfo($composerFile, PATHINFO_EXTENSION) ? substr($composerFile, 0, -4) . 'lock' : $composerFile . '.lock';
         $locker = new Locker($this->io, new JsonFile($lockFile, new RemoteFilesystem($this->io, $config)), $rm, $im, file_get_contents($composerFile));
         $composer->setLocker($locker);
     }
     //  -----------------
     //  -----------------
     //  -----------------
     return $composer;
 }
Ejemplo n.º 20
0
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $file = Factory::getComposerFile();
     $io = $this->getIO();
     $newlyCreated = !file_exists($file);
     if (!file_exists($file) && !file_put_contents($file, "{\n}\n")) {
         $io->writeError('<error>' . $file . ' could not be created.</error>');
         return 1;
     }
     if (!is_readable($file)) {
         $io->writeError('<error>' . $file . ' is not readable.</error>');
         return 1;
     }
     if (!is_writable($file)) {
         $io->writeError('<error>' . $file . ' is not writable.</error>');
         return 1;
     }
     if (filesize($file) === 0) {
         file_put_contents($file, "{\n}\n");
     }
     $json = new JsonFile($file);
     $composerDefinition = $json->read();
     $composerBackup = file_get_contents($json->getPath());
     $composer = $this->getComposer(true, $input->getOption('no-plugins'));
     $repos = $composer->getRepositoryManager()->getRepositories();
     $platformOverrides = $composer->getConfig()->get('platform') ?: array();
     // initialize $this->repos as it is used by the parent InitCommand
     $this->repos = new CompositeRepository(array_merge(array(new PlatformRepository(array(), $platformOverrides)), $repos));
     $phpVersion = $this->repos->findPackage('php', '*')->getVersion();
     $requirements = $this->determineRequirements($input, $output, $input->getArgument('packages'), $phpVersion);
     $requireKey = $input->getOption('dev') ? 'require-dev' : 'require';
     $removeKey = $input->getOption('dev') ? 'require' : 'require-dev';
     $baseRequirements = array_key_exists($requireKey, $composerDefinition) ? $composerDefinition[$requireKey] : array();
     $requirements = $this->formatRequirements($requirements);
     // validate requirements format
     $versionParser = new VersionParser();
     foreach ($requirements as $constraint) {
         $versionParser->parseConstraints($constraint);
     }
     $sortPackages = $input->getOption('sort-packages') || $composer->getConfig()->get('sort-packages');
     if (!$this->updateFileCleanly($json, $baseRequirements, $requirements, $requireKey, $removeKey, $sortPackages)) {
         foreach ($requirements as $package => $version) {
             $baseRequirements[$package] = $version;
             if (isset($composerDefinition[$removeKey][$package])) {
                 unset($composerDefinition[$removeKey][$package]);
             }
         }
         $composerDefinition[$requireKey] = $baseRequirements;
         $json->write($composerDefinition);
     }
     $io->writeError('<info>' . $file . ' has been ' . ($newlyCreated ? 'created' : 'updated') . '</info>');
     if ($input->getOption('no-update')) {
         return 0;
     }
     $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');
     // Update packages
     $this->resetComposer();
     $composer = $this->getComposer(true, $input->getOption('no-plugins'));
     $composer->getDownloadManager()->setOutputProgress(!$input->getOption('no-progress'));
     $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'require', $input, $output);
     $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
     $install = Installer::create($io, $composer);
     $install->setVerbose($input->getOption('verbose'))->setPreferSource($input->getOption('prefer-source'))->setPreferDist($input->getOption('prefer-dist'))->setDevMode($updateDevMode)->setOptimizeAutoloader($optimize)->setClassMapAuthoritative($authoritative)->setUpdate(true)->setUpdateWhitelist(array_keys($requirements))->setWhitelistDependencies($input->getOption('update-with-dependencies'))->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs'))->setPreferStable($input->getOption('prefer-stable'))->setPreferLowest($input->getOption('prefer-lowest'));
     $exception = null;
     try {
         $status = $install->run();
     } catch (\Exception $exception) {
         $status = 1;
     }
     if ($status !== 0) {
         if ($newlyCreated) {
             $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);
         }
     }
     if ($exception) {
         throw $exception;
     }
     return $status;
 }
Ejemplo n.º 21
0
 /**
  * {@inheritDoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     // Open file in editor
     if ($input->getOption('editor')) {
         $editor = getenv('EDITOR');
         if (!$editor) {
             if (defined('PHP_WINDOWS_VERSION_BUILD')) {
                 $editor = 'notepad';
             } else {
                 foreach (array('vim', 'vi', 'nano', 'pico', 'ed') as $candidate) {
                     if (exec('which ' . $candidate)) {
                         $editor = $candidate;
                         break;
                     }
                 }
             }
         }
         system($editor . ' ' . $this->configFile->getPath() . (defined('PHP_WINDOWS_VERSION_BUILD') ? '' : ' > `tty`'));
         return 0;
     }
     if (!$input->getOption('global')) {
         $this->config->merge($this->configFile->read());
     }
     // List the configuration of the file settings
     if ($input->getOption('list')) {
         $this->listConfiguration($this->config->all(), $this->config->raw(), $output);
         return 0;
     }
     $settingKey = $input->getArgument('setting-key');
     if (!$settingKey) {
         return 0;
     }
     // If the user enters in a config variable, parse it and save to file
     if (array() !== $input->getArgument('setting-value') && $input->getOption('unset')) {
         throw new \RuntimeException('You can not combine a setting value with --unset');
     }
     // show the value if no value is provided
     if (array() === $input->getArgument('setting-value') && !$input->getOption('unset')) {
         $data = $this->config->all();
         if (preg_match('/^repos?(?:itories)?(?:\\.(.+))?/', $settingKey, $matches)) {
             if (empty($matches[1])) {
                 $value = isset($data['repositories']) ? $data['repositories'] : array();
             } else {
                 if (!isset($data['repositories'][$matches[1]])) {
                     throw new \InvalidArgumentException('There is no ' . $matches[1] . ' repository defined');
                 }
                 $value = $data['repositories'][$matches[1]];
             }
         } elseif (strpos($settingKey, '.')) {
             $bits = explode('.', $settingKey);
             $data = $data['config'];
             foreach ($bits as $bit) {
                 if (isset($data[$bit])) {
                     $data = $data[$bit];
                 } elseif (isset($data[implode('.', $bits)])) {
                     // last bit can contain domain names and such so try to join whatever is left if it exists
                     $data = $data[implode('.', $bits)];
                     break;
                 } else {
                     throw new \RuntimeException($settingKey . ' is not defined');
                 }
                 array_shift($bits);
             }
             $value = $data;
         } elseif (isset($data['config'][$settingKey])) {
             $value = $data['config'][$settingKey];
         } else {
             throw new \RuntimeException($settingKey . ' is not defined');
         }
         if (is_array($value)) {
             $value = json_encode($value);
         }
         $output->writeln($value);
         return 0;
     }
     $values = $input->getArgument('setting-value');
     // what the user is trying to add/change
     // handle repositories
     if (preg_match('/^repos?(?:itories)?\\.(.+)/', $settingKey, $matches)) {
         if ($input->getOption('unset')) {
             return $this->configSource->removeRepository($matches[1]);
         }
         if (2 !== count($values)) {
             throw new \RuntimeException('You must pass the type and a url. Example: php composer.phar config repositories.foo vcs http://bar.com');
         }
         return $this->configSource->addRepository($matches[1], array('type' => $values[0], 'url' => $values[1]));
     }
     // handle github-oauth
     if (preg_match('/^github-oauth\\.(.+)/', $settingKey, $matches)) {
         if ($input->getOption('unset')) {
             return $this->configSource->removeConfigSetting('github-oauth.' . $matches[1]);
         }
         if (1 !== count($values)) {
             throw new \RuntimeException('Too many arguments, expected only one token');
         }
         return $this->configSource->addConfigSetting('github-oauth.' . $matches[1], $values[0]);
     }
     $booleanValidator = function ($val) {
         return in_array($val, array('true', 'false', '1', '0'), true);
     };
     $booleanNormalizer = function ($val) {
         return $val !== 'false' && (bool) $val;
     };
     // handle config values
     $uniqueConfigValues = array('process-timeout' => array('is_numeric', 'intval'), 'use-include-path' => array($booleanValidator, $booleanNormalizer), 'preferred-install' => array(function ($val) {
         return in_array($val, array('auto', 'source', 'dist'), true);
     }, function ($val) {
         return $val;
     }), 'notify-on-install' => array($booleanValidator, $booleanNormalizer), 'vendor-dir' => array('is_string', function ($val) {
         return $val;
     }), 'bin-dir' => array('is_string', function ($val) {
         return $val;
     }), 'cache-dir' => array('is_string', function ($val) {
         return $val;
     }), 'cache-files-dir' => array('is_string', function ($val) {
         return $val;
     }), 'cache-repo-dir' => array('is_string', function ($val) {
         return $val;
     }), 'cache-vcs-dir' => array('is_string', function ($val) {
         return $val;
     }), 'cache-ttl' => array('is_numeric', 'intval'), 'cache-files-ttl' => array('is_numeric', 'intval'), 'cache-files-maxsize' => array(function ($val) {
         return preg_match('/^\\s*([0-9.]+)\\s*(?:([kmg])(?:i?b)?)?\\s*$/i', $val) > 0;
     }, function ($val) {
         return $val;
     }), 'discard-changes' => array(function ($val) {
         return in_array($val, array('stash', 'true', 'false', '1', '0'), true);
     }, function ($val) {
         if ('stash' === $val) {
             return 'stash';
         }
         return $val !== 'false' && (bool) $val;
     }));
     $multiConfigValues = array('github-protocols' => array(function ($vals) {
         if (!is_array($vals)) {
             return 'array expected';
         }
         foreach ($vals as $val) {
             if (!in_array($val, array('git', 'https', 'http'))) {
                 return 'valid protocols include: git, https, http';
             }
         }
         return true;
     }, function ($vals) {
         return $vals;
     }));
     foreach ($uniqueConfigValues as $name => $callbacks) {
         if ($settingKey === $name) {
             if ($input->getOption('unset')) {
                 return $this->configSource->removeConfigSetting($settingKey);
             }
             list($validator, $normalizer) = $callbacks;
             if (1 !== count($values)) {
                 throw new \RuntimeException('You can only pass one value. Example: php composer.phar config process-timeout 300');
             }
             if (true !== ($validation = $validator($values[0]))) {
                 throw new \RuntimeException(sprintf('"%s" is an invalid value' . ($validation ? ' (' . $validation . ')' : ''), $values[0]));
             }
             return $this->configSource->addConfigSetting($settingKey, $normalizer($values[0]));
         }
     }
     foreach ($multiConfigValues as $name => $callbacks) {
         if ($settingKey === $name) {
             if ($input->getOption('unset')) {
                 return $this->configSource->removeConfigSetting($settingKey);
             }
             list($validator, $normalizer) = $callbacks;
             if (true !== ($validation = $validator($values))) {
                 throw new \RuntimeException(sprintf('%s is an invalid value' . ($validation ? ' (' . $validation . ')' : ''), json_encode($values)));
             }
             return $this->configSource->addConfigSetting($settingKey, $normalizer($values));
         }
     }
     throw new \InvalidArgumentException('Setting ' . $settingKey . ' does not exist or is not supported by this command');
 }
Ejemplo n.º 22
0
 /**
  * {@inheritDoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     // Open file in editor
     if ($input->getOption('editor')) {
         $editor = escapeshellcmd(getenv('EDITOR'));
         if (!$editor) {
             if (Platform::isWindows()) {
                 $editor = 'notepad';
             } else {
                 foreach (array('editor', 'vim', 'vi', 'nano', 'pico', 'ed') as $candidate) {
                     if (exec('which ' . $candidate)) {
                         $editor = $candidate;
                         break;
                     }
                 }
             }
         }
         $file = $input->getOption('auth') ? $this->authConfigFile->getPath() : $this->configFile->getPath();
         system($editor . ' ' . $file . (Platform::isWindows() ? '' : ' > `tty`'));
         return 0;
     }
     if (!$input->getOption('global')) {
         $this->config->merge($this->configFile->read());
         $this->config->merge(array('config' => $this->authConfigFile->exists() ? $this->authConfigFile->read() : array()));
     }
     // List the configuration of the file settings
     if ($input->getOption('list')) {
         $this->listConfiguration($this->config->all(), $this->config->raw(), $output);
         return 0;
     }
     $settingKey = $input->getArgument('setting-key');
     if (!$settingKey) {
         return 0;
     }
     // If the user enters in a config variable, parse it and save to file
     if (array() !== $input->getArgument('setting-value') && $input->getOption('unset')) {
         throw new \RuntimeException('You can not combine a setting value with --unset');
     }
     // show the value if no value is provided
     if (array() === $input->getArgument('setting-value') && !$input->getOption('unset')) {
         $data = $this->config->all();
         if (preg_match('/^repos?(?:itories)?(?:\\.(.+))?/', $settingKey, $matches)) {
             if (empty($matches[1])) {
                 $value = isset($data['repositories']) ? $data['repositories'] : array();
             } else {
                 if (!isset($data['repositories'][$matches[1]])) {
                     throw new \InvalidArgumentException('There is no ' . $matches[1] . ' repository defined');
                 }
                 $value = $data['repositories'][$matches[1]];
             }
         } elseif (strpos($settingKey, '.')) {
             $bits = explode('.', $settingKey);
             $data = $data['config'];
             $match = false;
             foreach ($bits as $bit) {
                 $key = isset($key) ? $key . '.' . $bit : $bit;
                 $match = false;
                 if (isset($data[$key])) {
                     $match = true;
                     $data = $data[$key];
                     unset($key);
                 }
             }
             if (!$match) {
                 throw new \RuntimeException($settingKey . ' is not defined.');
             }
             $value = $data;
         } elseif (isset($data['config'][$settingKey])) {
             $value = $this->config->get($settingKey, $input->getOption('absolute') ? 0 : Config::RELATIVE_PATHS);
         } else {
             throw new \RuntimeException($settingKey . ' is not defined');
         }
         if (is_array($value)) {
             $value = json_encode($value);
         }
         $this->getIO()->write($value);
         return 0;
     }
     $values = $input->getArgument('setting-value');
     // what the user is trying to add/change
     $booleanValidator = function ($val) {
         return in_array($val, array('true', 'false', '1', '0'), true);
     };
     $booleanNormalizer = function ($val) {
         return $val !== 'false' && (bool) $val;
     };
     // handle config values
     $uniqueConfigValues = array('process-timeout' => array('is_numeric', 'intval'), 'use-include-path' => array($booleanValidator, $booleanNormalizer), 'preferred-install' => array(function ($val) {
         return in_array($val, array('auto', 'source', 'dist'), true);
     }, function ($val) {
         return $val;
     }), 'store-auths' => array(function ($val) {
         return in_array($val, array('true', 'false', 'prompt'), true);
     }, function ($val) {
         if ('prompt' === $val) {
             return 'prompt';
         }
         return $val !== 'false' && (bool) $val;
     }), 'notify-on-install' => array($booleanValidator, $booleanNormalizer), 'vendor-dir' => array('is_string', function ($val) {
         return $val;
     }), 'bin-dir' => array('is_string', function ($val) {
         return $val;
     }), 'archive-dir' => array('is_string', function ($val) {
         return $val;
     }), 'archive-format' => array('is_string', function ($val) {
         return $val;
     }), 'data-dir' => array('is_string', function ($val) {
         return $val;
     }), 'cache-dir' => array('is_string', function ($val) {
         return $val;
     }), 'cache-files-dir' => array('is_string', function ($val) {
         return $val;
     }), 'cache-repo-dir' => array('is_string', function ($val) {
         return $val;
     }), 'cache-vcs-dir' => array('is_string', function ($val) {
         return $val;
     }), 'cache-ttl' => array('is_numeric', 'intval'), 'cache-files-ttl' => array('is_numeric', 'intval'), 'cache-files-maxsize' => array(function ($val) {
         return preg_match('/^\\s*([0-9.]+)\\s*(?:([kmg])(?:i?b)?)?\\s*$/i', $val) > 0;
     }, function ($val) {
         return $val;
     }), 'bin-compat' => array(function ($val) {
         return in_array($val, array('auto', 'full'));
     }, function ($val) {
         return $val;
     }), 'discard-changes' => array(function ($val) {
         return in_array($val, array('stash', 'true', 'false', '1', '0'), true);
     }, function ($val) {
         if ('stash' === $val) {
             return 'stash';
         }
         return $val !== 'false' && (bool) $val;
     }), 'autoloader-suffix' => array('is_string', function ($val) {
         return $val === 'null' ? null : $val;
     }), 'sort-packages' => array($booleanValidator, $booleanNormalizer), 'optimize-autoloader' => array($booleanValidator, $booleanNormalizer), 'classmap-authoritative' => array($booleanValidator, $booleanNormalizer), 'prepend-autoloader' => array($booleanValidator, $booleanNormalizer), 'disable-tls' => array($booleanValidator, $booleanNormalizer), 'secure-http' => array($booleanValidator, $booleanNormalizer), 'cafile' => array(function ($val) {
         return file_exists($val) && is_readable($val);
     }, function ($val) {
         return $val === 'null' ? null : $val;
     }), 'capath' => array(function ($val) {
         return is_dir($val) && is_readable($val);
     }, function ($val) {
         return $val === 'null' ? null : $val;
     }), 'github-expose-hostname' => array($booleanValidator, $booleanNormalizer));
     $multiConfigValues = array('github-protocols' => array(function ($vals) {
         if (!is_array($vals)) {
             return 'array expected';
         }
         foreach ($vals as $val) {
             if (!in_array($val, array('git', 'https', 'ssh'))) {
                 return 'valid protocols include: git, https, ssh';
             }
         }
         return true;
     }, function ($vals) {
         return $vals;
     }), 'github-domains' => array(function ($vals) {
         if (!is_array($vals)) {
             return 'array expected';
         }
         return true;
     }, function ($vals) {
         return $vals;
     }), 'gitlab-domains' => array(function ($vals) {
         if (!is_array($vals)) {
             return 'array expected';
         }
         return true;
     }, function ($vals) {
         return $vals;
     }));
     foreach ($uniqueConfigValues as $name => $callbacks) {
         if ($settingKey === $name) {
             if ($input->getOption('unset')) {
                 return $this->configSource->removeConfigSetting($settingKey);
             }
             list($validator, $normalizer) = $callbacks;
             if (1 !== count($values)) {
                 throw new \RuntimeException('You can only pass one value. Example: php composer.phar config process-timeout 300');
             }
             if (true !== ($validation = $validator($values[0]))) {
                 throw new \RuntimeException(sprintf('"%s" is an invalid value' . ($validation ? ' (' . $validation . ')' : ''), $values[0]));
             }
             return $this->configSource->addConfigSetting($settingKey, $normalizer($values[0]));
         }
     }
     foreach ($multiConfigValues as $name => $callbacks) {
         if ($settingKey === $name) {
             if ($input->getOption('unset')) {
                 return $this->configSource->removeConfigSetting($settingKey);
             }
             list($validator, $normalizer) = $callbacks;
             if (true !== ($validation = $validator($values))) {
                 throw new \RuntimeException(sprintf('%s is an invalid value' . ($validation ? ' (' . $validation . ')' : ''), json_encode($values)));
             }
             return $this->configSource->addConfigSetting($settingKey, $normalizer($values));
         }
     }
     // handle repositories
     if (preg_match('/^repos?(?:itories)?\\.(.+)/', $settingKey, $matches)) {
         if ($input->getOption('unset')) {
             return $this->configSource->removeRepository($matches[1]);
         }
         if (2 === count($values)) {
             return $this->configSource->addRepository($matches[1], array('type' => $values[0], 'url' => $values[1]));
         }
         if (1 === count($values)) {
             $value = strtolower($values[0]);
             if (true === $booleanValidator($value)) {
                 if (false === $booleanNormalizer($value)) {
                     return $this->configSource->addRepository($matches[1], false);
                 }
             } else {
                 $value = JsonFile::parseJson($values[0]);
                 return $this->configSource->addRepository($matches[1], $value);
             }
         }
         throw new \RuntimeException('You must pass the type and a url. Example: php composer.phar config repositories.foo vcs https://bar.com');
     }
     // handle platform
     if (preg_match('/^platform\\.(.+)/', $settingKey, $matches)) {
         if ($input->getOption('unset')) {
             return $this->configSource->removeConfigSetting($settingKey);
         }
         return $this->configSource->addConfigSetting($settingKey, $values[0]);
     }
     // handle github-oauth
     if (preg_match('/^(github-oauth|gitlab-oauth|http-basic)\\.(.+)/', $settingKey, $matches)) {
         if ($input->getOption('unset')) {
             $this->authConfigSource->removeConfigSetting($matches[1] . '.' . $matches[2]);
             $this->configSource->removeConfigSetting($matches[1] . '.' . $matches[2]);
             return;
         }
         if ($matches[1] === 'github-oauth' || $matches[1] === 'gitlab-oauth') {
             if (1 !== count($values)) {
                 throw new \RuntimeException('Too many arguments, expected only one token');
             }
             $this->configSource->removeConfigSetting($matches[1] . '.' . $matches[2]);
             $this->authConfigSource->addConfigSetting($matches[1] . '.' . $matches[2], $values[0]);
         } elseif ($matches[1] === 'http-basic') {
             if (2 !== count($values)) {
                 throw new \RuntimeException('Expected two arguments (username, password), got ' . count($values));
             }
             $this->configSource->removeConfigSetting($matches[1] . '.' . $matches[2]);
             $this->authConfigSource->addConfigSetting($matches[1] . '.' . $matches[2], array('username' => $values[0], 'password' => $values[1]));
         }
         return;
     }
     throw new \InvalidArgumentException('Setting ' . $settingKey . ' does not exist or is not supported by this command');
 }
Ejemplo n.º 23
0
 public function execute()
 {
     $io = $this->getIO();
     if (empty($this->arguments)) {
         $io->writeError('<error>No module was specified</error>');
         return 1;
     }
     $modules = array_map(function ($value) {
         if (strpos($value, '/') === false) {
             $value = 'opis-colibri/' . $value;
         }
         if (strpos($value, ':') === false) {
             $value .= ':*';
         }
         return $value;
     }, $this->arguments);
     $file = Factory::getComposerFile();
     $json = new JsonFile($file);
     $composerDefinition = $json->read();
     $composerBackup = file_get_contents($json->getPath());
     $composer = $this->getComposer();
     $repos = $composer->getRepositoryManager()->getRepositories();
     $this->repos = new CompositeRepository(array_merge(array(new PlatformRepository()), $repos));
     $requirements = $this->determineRequirements($modules);
     $requireKey = !$this->devMode ? 'require-dev' : 'require';
     $removeKey = !$this->devMode ? 'require' : 'require-dev';
     $baseRequirements = array_key_exists($requireKey, $composerDefinition) ? $composerDefinition[$requireKey] : array();
     $requirements = $this->formatRequirements($requirements);
     $this->validateRequirements($requirements);
     $manager = $this->getComposer()->getRepositoryManager();
     $io->write('Searching for modules..');
     foreach ($requirements as $name => $version) {
         $pack = $manager->findPackage($name, $version);
         if ($pack == null) {
             $io->writeError('<error>Module ' . $name . ' doesn\'t exist</error>');
             return 1;
         }
         if ($pack->getType() !== 'opis-colibri-module') {
             $io->writeError('<error>' . $name . ' is not a valid module</error>');
             return 1;
         }
         $io->write('Found module ' . $pack->getName());
     }
     $sortPackages = false;
     if (!$this->updateFileCleanly($json, $baseRequirements, $requirements, $requireKey, $removeKey, $sortPackages)) {
         foreach ($requirements as $package => $version) {
             $baseRequirements[$package] = $version;
             if (isset($composerDefinition[$removeKey][$package])) {
                 unset($composerDefinition[$removeKey][$package]);
             }
         }
         $composerDefinition[$requireKey] = $baseRequirements;
         $json->write($composerDefinition);
     }
     $this->resetComposer();
     $composer = $this->getComposer();
     $install = Installer::create($io, $composer);
     $status = $install->setDevMode($this->devMode)->setUpdate(true)->setUpdateWhitelist(array_keys($requirements))->run();
     if ($status !== 0) {
         $io->writeError('<error>Installation failed, reverting ' . $file . ' to its original content.</error>');
         file_put_contents($json->getPath(), $composerBackup);
     }
     return $status;
 }