/** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $composer = $this->getComposer(); $config = $composer->getConfig(); $isInitDone = true; // Init packages.json $directory = $this->getRepositoryDirectory(); $file = new JsonFile($directory . '/packages.json'); if (!$file->exists()) { $output->writeln('<info>Initializing composer repository in</info> <comment>' . $directory . '</comment>'); $file->write(array('packages' => (object) array())); $isInitDone = false; } // Init ~/composer/config.json $file = new JsonFile($this->getComposerHome() . '/config.json'); $config = $file->exists() ? $file->read() : array(); if (!isset($config['repositories'])) { $config['repositories'] = array(); } $isRepoActived = false; foreach ($config['repositories'] as $repo) { if ($repo['type'] === 'composer' && $repo['url'] === 'file://' . $directory) { $isRepoActived = true; } } if (!$isRepoActived) { $output->writeln('<info>Writing stone repository in global configuration</info>'); $config['repositories'][] = array('type' => 'composer', 'url' => 'file://' . $directory); $file->write($config); $isInitDone = false; } if ($isInitDone) { $output->writeln('<info>It seems stone is already configured</info>'); } }
/** * @param InputInterface $input The input instance * @param OutputInterface $output The output instance */ protected function execute(InputInterface $input, OutputInterface $output) { $verbose = $input->getOption('verbose'); $file = new JsonFile($input->getArgument('file')); if (!$file->exists()) { $output->writeln('<error>File not found: ' . $input->getArgument('file') . '</error>'); return 1; } $config = $file->read(); // disable packagist by default unset(Config::$defaultRepositories['packagist']); // fetch options $requireAll = isset($config['require-all']) && true === $config['require-all']; if (!$requireAll && !isset($config['require'])) { $output->writeln('No explicit requires defined, enabling require-all'); $requireAll = true; } $composer = $this->getApplication()->getComposer(true, $config); $packages = $this->selectPackages($composer, $output, $verbose, $requireAll); if (!($outputDir = $input->getArgument('output-dir'))) { $outputDir = isset($config['output-dir']) ? $config['output-dir'] : null; } if ($htmlView = !$input->getOption('no-html-output')) { $htmlView = !isset($config['output-html']) || $config['output-html']; } $filename = $outputDir . '/packages.json'; $this->dumpJson($packages, $output, $filename); if ($htmlView) { $rootPackage = $composer->getPackage(); $this->dumpWeb($packages, $output, $rootPackage, $outputDir); } }
/** * Set up Composer JSON file. * * @return array|null */ public function updateJson() { if (!is_file($this->getOption('composerjson'))) { $this->initJson($this->getOption('composerjson')); } $jsonFile = new JsonFile($this->getOption('composerjson')); if ($jsonFile->exists()) { $json = $jsonorig = $jsonFile->read(); // Workaround Bolt 2.0 installs with "require": [] if (isset($json['require']) && empty($json['require'])) { unset($json['require']); } $json = $this->setJsonDefaults($json); } else { // Error $this->messages[] = Trans::__("The Bolt extensions file '%composerjson%' isn't readable.", ['%composerjson%' => $this->getOption('composerjson')]); $this->app['extend.writeable'] = false; $this->app['extend.online'] = false; return null; } // Write out the file, but only if it's actually changed, and if it's writable. if ($json != $jsonorig) { try { umask(00); $jsonFile->write($json); } catch (\Exception $e) { $this->messages[] = Trans::__('The Bolt extensions Repo at %repository% is currently unavailable. Check your connection and try again shortly.', ['%repository%' => $this->app['extend.site']]); } } return $json; }
/** * Search for a given package version. * * Usage examples : Composition::has('php', '5.3.*') // PHP version * Composition::has('ext-memcache') // PHP extension * Composition::has('vendor/package', '>2.1') // Package version * * @param type $packageName The package name * @param type $prettyString An optional version constraint * * @return boolean Wether or not the package has been found. */ public static function has($packageName, $prettyString = '*') { if (null === self::$pool) { if (null === self::$rootDir) { self::$rootDir = getcwd(); if (!file_exists(self::$rootDir . '/composer.json')) { throw new \RuntimeException('Unable to guess the project root dir, please specify it manually using the Composition::setRootDir method.'); } } $minimumStability = 'dev'; $config = new Config(); $file = new JsonFile(self::$rootDir . '/composer.json'); if ($file->exists()) { $projectConfig = $file->read(); $config->merge($projectConfig); if (isset($projectConfig['minimum-stability'])) { $minimumStability = $projectConfig['minimum-stability']; } } $vendorDir = self::$rootDir . '/' . $config->get('vendor-dir'); $pool = new Pool($minimumStability); $pool->addRepository(new PlatformRepository()); $pool->addRepository(new InstalledFilesystemRepository(new JsonFile($vendorDir . '/composer/installed.json'))); $pool->addRepository(new InstalledFilesystemRepository(new JsonFile($vendorDir . '/composer/installed_dev.json'))); self::$pool = $pool; } $parser = new VersionParser(); $constraint = $parser->parseConstraints($prettyString); $packages = self::$pool->whatProvides($packageName, $constraint); return empty($packages) ? false : true; }
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); } }
/** * @param InputInterface $input The input instance * @param OutputInterface $output The output instance * * @return int */ protected function execute(InputInterface $input, OutputInterface $output) { /** @var FormatterHelper $formatter */ $formatter = $this->getHelper('formatter'); $configFile = $input->getArgument('file'); $repositoryUrl = $input->getArgument('url'); if (preg_match('{^https?://}i', $configFile)) { $output->writeln('<error>Unable to write to remote file ' . $configFile . '</error>'); return 2; } $file = new JsonFile($configFile); if (!$file->exists()) { $output->writeln('<error>File not found: ' . $configFile . '</error>'); return 1; } if (!$this->isRepositoryValid($repositoryUrl)) { $output->writeln('<error>Invalid Repository URL: ' . $repositoryUrl . '</error>'); return 3; } $config = $file->read(); if (!isset($config['repositories']) || !is_array($config['repositories'])) { $config['repositories'] = []; } foreach ($config['repositories'] as $repository) { if (isset($repository['url']) && $repository['url'] == $repositoryUrl) { $output->writeln('<error>Repository already added to the file</error>'); return 4; } } $config['repositories'][] = ['type' => 'vcs', 'url' => $repositoryUrl]; $file->write($config); $output->writeln(['', $formatter->formatBlock('Your configuration file successfully updated! It\'s time to rebuild your repository', 'bg=blue;fg=white', true), '']); return 0; }
/** * {@inheritDoc} */ protected function initialize(InputInterface $input, OutputInterface $output) { if ($input->getOption('global') && 'composer.json' !== $input->getOption('file')) { throw new \RuntimeException('--file and --global can not be combined'); } $this->config = Factory::createConfig($this->getIO()); // Get the local composer.json, global config.json, or if the user // passed in a file to use $configFile = $input->getOption('global') ? $this->config->get('home') . '/config.json' : $input->getOption('file'); $this->configFile = new JsonFile($configFile); $this->configSource = new JsonConfigSource($this->configFile); $authConfigFile = $input->getOption('global') ? $this->config->get('home') . '/auth.json' : dirname(realpath($input->getOption('file'))) . '/auth.json'; $this->authConfigFile = new JsonFile($authConfigFile); $this->authConfigSource = new JsonConfigSource($this->authConfigFile, true); // initialize the global file if it's not there if ($input->getOption('global') && !$this->configFile->exists()) { touch($this->configFile->getPath()); $this->configFile->write(array('config' => new \ArrayObject())); @chmod($this->configFile->getPath(), 0600); } if ($input->getOption('global') && !$this->authConfigFile->exists()) { touch($this->authConfigFile->getPath()); $this->authConfigFile->write(array('http-basic' => new \ArrayObject(), 'github-oauth' => new \ArrayObject())); @chmod($this->authConfigFile->getPath(), 0600); } if (!$this->configFile->exists()) { throw new \RuntimeException('No composer.json found in the current directory'); } }
/** * Creates a Composer instance * * @param IOInterface $io IO instance * @param mixed $localConfig either a configuration array or a filename to read from, if null it will read from the default filename * @return Composer */ public function createComposer(IOInterface $io, $localConfig = null) { // load Composer configuration if (null === $localConfig) { $localConfig = $this->getComposerFile(); } if (is_string($localConfig)) { $composerFile = $localConfig; $file = new JsonFile($localConfig, new RemoteFilesystem($io)); if (!$file->exists()) { if ($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(); } // Configuration defaults $config = static::createConfig(); $config->merge($localConfig); $vendorDir = $config->get('vendor-dir'); $binDir = $config->get('bin-dir'); // setup process timeout ProcessExecutor::setTimeout((int) $config->get('process-timeout')); // initialize repository manager $rm = $this->createRepositoryManager($io, $config); // load default repository unless it's explicitly disabled $localConfig = $this->addPackagistRepository($localConfig); // load local repository $this->addLocalRepository($rm, $vendorDir); // load package $loader = new Package\Loader\RootPackageLoader($rm); $package = $loader->load($localConfig); // initialize download manager $dm = $this->createDownloadManager($io); // initialize installation manager $im = $this->createInstallationManager($rm, $dm, $vendorDir, $binDir, $io); // purge packages if they have been deleted on the filesystem $this->purgePackages($rm, $im); // initialize composer $composer = new Composer(); $composer->setConfig($config); $composer->setPackage($package); $composer->setRepositoryManager($rm); $composer->setDownloadManager($dm); $composer->setInstallationManager($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(new JsonFile($lockFile, new RemoteFilesystem($io)), $rm, md5_file($composerFile)); $composer->setLocker($locker); } return $composer; }
public function getExtensionConfig() { $json = new JsonFile($this->getBasepath() . '/composer.json'); if ($json->exists()) { $composerjson = $json->read(); return array(strtolower($composerjson['name']) => array('name' => $this->getName(), 'json' => $composerjson)); } else { return array($this->getName() => array('name' => $extension->getName(), 'json' => array())); } }
/** * Reads auth config from given json file path and returns it. * * @param string $authFilePath * @return array * @throws \Seld\JsonLint\ParsingException */ private function readAuthConfig($authFilePath) { $file = new JsonFile($authFilePath); if ($file->exists()) { $auth = $file->read(); if (isset($auth['config']) && isset($auth['config']['basic-auth'])) { return $auth['config']['basic-auth']; } } return array(); }
/** * @param string $path * * @return Config */ public static function createConfig($path) { $config = new Config(); // load global config $file = new JsonFile($path); if ($file->exists()) { $config->merge($file->read()); } $config->setConfigSource(new JsonConfigSource($file)); return $config; }
/** * Get the contents of the extension's composer.json file, lazy-loading * as needed. */ public function getComposerJSON() { if (!$this->composerJsonLoaded && !$this->composerJson) { $this->composerJsonLoaded = true; $this->composerJson = null; $jsonFile = new JsonFile(__DIR__ . '/composer.json'); if ($jsonFile->exists()) { $this->composerJson = $jsonFile->read(); } } return $this->composerJson; }
protected function execute(InputInterface $input, OutputInterface $output) { $configFile = $input->getArgument('file'); $file = new JsonFile($configFile); if (!$file->exists()) { $output->writeln('<error>File not found: ' . $configFile . '</error>'); return 1; } $config = $file->read(); /** * Check whether archive is defined */ if (!isset($config['archive']) || !isset($config['archive']['directory'])) { $output->writeln('<error>You must define "archive" parameter in your ' . $configFile . '</error>'); return 1; } if (!($outputDir = $input->getArgument('output-dir'))) { throw new \InvalidArgumentException('The output dir must be specified as second argument'); } $files = glob($outputDir . "/include/*.json"); if (empty($files)) { $output->writeln('<info>No log file</info>'); return 1; } $files = array_combine($files, array_map("filemtime", $files)); arsort($files); $file = file_get_contents(key($files)); $json = json_decode($file, true); $needed = null; foreach ($json['packages'] as $key => $value) { $needed[] = str_replace("/", "-", $key); } /** * Packages in output-dir */ $files = scandir($outputDir . "/" . $config['archive']['directory'], 1); if (empty($files)) { $output->writeln('<info>No archived files</info>'); return 1; } /** * Get vendor-package of archived files */ $regex = "/^(.+)-(?:[^-]+)-(?:[^-]+)\\.(?:.+)\$/"; foreach ($files as $file) { preg_match($regex, $file, $matches); if (isset($matches[1]) && !in_array($matches[1], $needed)) { $output->writeln("<info>" . $matches[1] . " :: deleted</info>"); unlink($outputDir . "/" . $config['archive']['directory'] . "/" . $file); } } $output->writeln("<info>Purge :: finished</info>"); }
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); } }
/** * Generate configuration file * * @param InputInterface $input The input instance * @param OutputInterface $output The output instance * @return int */ protected function execute(InputInterface $input, OutputInterface $output) { $formatter = $this->getHelperSet()->get('formatter'); $configFile = $input->getArgument('file'); if (preg_match('{^https?://}i', $configFile)) { $output->writeln('<error>Unable to write to remote file ' . $configFile . '</error>'); return 2; } $file = new JsonFile($configFile); if ($file->exists()) { $output->writeln('<error>Configuration file already exists</error>'); return 1; } $config = array('name' => $input->getOption('name'), 'homepage' => $input->getOption('homepage'), 'repositories' => array(), 'require-all' => true); $file->write($config); $output->writeln(array('', $formatter->formatBlock('Your configuration file successfully created!', 'bg=blue;fg=white', true), '')); $output->writeln(array('', 'You are ready to add your package repositories', 'Use <comment>satis add repository-url</comment> to add them.', '')); return 0; }
/** * Set up Composer JSON file. * * @param Application $app * * @return array|null */ public function updateJson(Application $app) { if (!is_file($this->options['composerjson'])) { $this->initJson($this->options['composerjson']); } $jsonFile = new JsonFile($this->options['composerjson']); if ($jsonFile->exists()) { $json = $jsonorig = $jsonFile->read(); // Workaround Bolt 2.0 installs with "require": [] if (isset($json['require']) && empty($json['require'])) { unset($json['require']); } } else { // Error $this->messages[] = Trans::__("The Bolt extensions file '%composerjson%' isn't readable.", array('%composerjson%' => $this->options['composerjson'])); $app['extend.writeable'] = false; $app['extend.online'] = false; return null; } $pathToWeb = $app['resources']->findRelativePath($app['resources']->getPath('extensions'), $app['resources']->getPath('web')); // Enforce standard settings $json['repositories']['packagist'] = false; $json['repositories']['bolt'] = array('type' => 'composer', 'url' => $app['extend.site'] . 'satis/'); $json['minimum-stability'] = $app['config']->get('general/extensions/stability', 'stable'); $json['prefer-stable'] = true; $json['config'] = array('discard-changes' => true, 'preferred-install' => 'dist'); $json['provide']['bolt/bolt'] = $app['bolt_version']; $json['extra']['bolt-web-path'] = $pathToWeb; $json['autoload']['psr-4']['Bolt\\Composer\\'] = ''; $json['scripts'] = array('post-package-install' => 'Bolt\\Composer\\ExtensionInstaller::handle', 'post-package-update' => 'Bolt\\Composer\\ExtensionInstaller::handle'); // Write out the file, but only if it's actually changed, and if it's writable. if ($json != $jsonorig) { try { umask(00); $jsonFile->write($json); } catch (\Exception $e) { $this->messages[] = Trans::__('The Bolt extensions Repo at %repository% is currently unavailable. Check your connection and try again shortly.', array('%repository%' => $app['extend.site'])); } } return $json; }
private function _installBower($requires, $overrides, $resolutions) { $out = []; $retVar = null; exec("bower --version 2>&1", $out, $retVar); if ($retVar) { throw new \Exception("Bower isn't installed."); } else { $bowerBin = 'bower'; } $jsonFile = new JsonFile('bower.json'); if ($jsonFile->exists()) { $packageJson = $jsonFile->read(); if (!isset($packageJson['name']) || $packageJson['name'] != 'temp-composer-bower-plugin') { //assume we can overwrite our own temp one throw new \Exception("Can't install Bower dependencies as there is already a bower.json"); } } else { $packageJson = ['name' => 'temp-composer-bower-plugin', 'description' => "This file is auto-generated by 'php-kit/composer-bower-plugin'. " . "Warning: do NOT edit this file."]; } $packageJson['dependencies'] = $requires; if ($overrides) { $packageJson['overrides'] = $overrides; } if ($resolutions) { $packageJson['resolutions'] = $resolutions; } $jsonFile->write($packageJson); if (!file_exists('.bowerrc')) { $vd = $this->composer->getConfig()->get('vendor-dir'); if (substr($vd, 0, strlen(getcwd())) == getcwd()) { //make vendor-dir relative go cwd $vd = substr($vd, strlen(getcwd()) + 1); } $config = ['directory' => $vd . '/bower_components']; file_put_contents('.bowerrc', json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); } $this->write($requires ? "Installing/updating Bower packages" : "Removing Bower packages (if any)"); $cmd = "{$bowerBin} --allow-root install"; passthru($cmd, $retVar); if ($retVar) { throw new \RuntimeException('bower install failed'); } $cmd = "{$bowerBin} --allow-root prune"; passthru($cmd, $retVar); if ($retVar) { throw new \RuntimeException('bower prune failed'); } $config = json_decode(file_get_contents('.bowerrc'), true); $installedBowerFiles = glob($config['directory'] . '/*/.bower.json'); //detect actually installed versions $ret = []; foreach ($installedBowerFiles as $installedBowerFile) { $installedBower = json_decode(file_get_contents($installedBowerFile), true); $dep = $installedBower['_source'] . '#' . $installedBower['_release']; $ret[$installedBower['name']] = $dep; } return $ret; }
private function _installNpmDependencies($path, $dependencies, $shrinkwrapDependencies) { $prevCwd = getcwd(); chdir($path); if (file_exists('node_modules/.composer-extra-assets-installed.json')) { $installed = json_decode(file_get_contents('node_modules/.composer-extra-assets-installed.json'), true); if ($installed == $shrinkwrapDependencies) { $this->io->write("npm dependencies in '{$path}' are up to date..."); chdir($prevCwd); return; } } if (file_exists('node_modules')) { //recursively delete node_modules //this is done to support shrinkwrap properly foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator('node_modules', \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::CHILD_FIRST) as $i) { $i->isDir() && !$i->isLink() ? rmdir($i->getPathname()) : unlink($i->getPathname()); } } $jsonFile = new JsonFile('package.json'); if ($jsonFile->exists()) { $packageJson = $jsonFile->read(); if (!isset($packageJson['name']) || $packageJson['name'] != 'composer-extra-asssets') { //assume we can overwrite our own temp one throw new \Exception("Can't install npm dependencies as there is already a package.json"); } } else { $packageJson = array('name' => 'composer-extra-asssets', 'description' => "This file is auto-generated by 'koala-framework/composer-extra-assets'. You can " . "modify this file but the 'dependencies' section will be overwritten each time you run " . "composer install or composer update. You must not change the 'name' section.", 'readme' => ' ', 'license' => 'UNLICENSED', 'repository' => array('type' => 'git')); } $packageJson['dependencies'] = $dependencies; $jsonFile->write($packageJson); $shrinkwrapJsonFile = new JsonFile('npm-shrinkwrap.json'); if ($shrinkwrapDependencies) { $shrinkwrapJson = array('name' => 'composer-extra-asssets', 'dependencies' => $shrinkwrapDependencies); $shrinkwrapJsonFile->write($shrinkwrapJson); } else { if ($shrinkwrapJsonFile->exists()) { unlink('npm-shrinkwrap.json'); } } $this->io->write(""); $this->io->write("installing npm dependencies in '{$path}'..."); $npm = $this->composer->getConfig()->get('bin-dir') . '/npm'; $cmd = escapeshellarg($npm) . " install"; $descriptorspec = array(); $pipes = array(); $p = proc_open($cmd, $descriptorspec, $pipes); $retVar = proc_close($p); if ($retVar) { throw new \RuntimeException('npm install failed with ' . $retVar); } $ret = null; if (!$shrinkwrapDependencies) { $cmd = escapeshellarg($npm) . " shrinkwrap"; $descriptorspec = array(); $pipes = array(); $p = proc_open($cmd, $descriptorspec, $pipes); $retVar = proc_close($p); if ($retVar) { throw new \RuntimeException('npm shrinkwrap failed'); } $shrinkwrap = json_decode(file_get_contents('npm-shrinkwrap.json'), true); $ret = $shrinkwrap['dependencies']; } if ($path != '.') { unlink('package.json'); } unlink('npm-shrinkwrap.json'); $installed = $shrinkwrapDependencies; if (!$installed) { $installed = $ret; } file_put_contents('node_modules/.composer-extra-assets-installed.json', json_encode($installed)); chdir($prevCwd); return $ret; }
/** * @param string $repoFile * @param bool $filter * * @return InstalledFilesystemRepository */ private function openRepository($repoFile, $filter = true) { $json = new JsonFile($repoFile); if (!$json->exists()) { throw new \RuntimeException("Repository file '{$repoFile}' doesn't exist", 123); } $repo = new InstalledFilesystemRepository($json); if ($filter) { foreach ($repo->getPackages() as $package) { if ($package->getType() !== 'claroline-core' && $package->getType() !== 'claroline-plugin') { $repo->removePackage($package); } } } return $repo; }
/** * Creates a Composer instance * * @return Composer */ public function createComposer(IOInterface $io, $composerFile = null) { // load Composer configuration if (null === $composerFile) { $composerFile = getenv('COMPOSER') ?: 'composer.json'; } $file = new JsonFile($composerFile); if (!$file->exists()) { if ($composerFile === 'composer.json') { $message = 'Composer could not find a composer.json file in ' . getcwd(); } else { $message = 'Composer could not find the config file: ' . $composerFile; } $instructions = 'To initialize a project, please create a composer.json file as described on the http://packagist.org/ "Getting Started" section'; throw new \InvalidArgumentException($message . PHP_EOL . $instructions); } // Configuration defaults $composerConfig = array('vendor-dir' => 'vendor', 'process-timeout' => 300); $packageConfig = $file->read(); if (isset($packageConfig['config']) && is_array($packageConfig['config'])) { $packageConfig['config'] = array_merge($composerConfig, $packageConfig['config']); } else { $packageConfig['config'] = $composerConfig; } $vendorDir = getenv('COMPOSER_VENDOR_DIR') ?: $packageConfig['config']['vendor-dir']; if (!isset($packageConfig['config']['bin-dir'])) { $packageConfig['config']['bin-dir'] = $vendorDir . '/bin'; } $binDir = getenv('COMPOSER_BIN_DIR') ?: $packageConfig['config']['bin-dir']; // setup process timeout $processTimeout = getenv('COMPOSER_PROCESS_TIMEOUT') ?: $packageConfig['config']['process-timeout']; ProcessExecutor::setTimeout((int) $processTimeout); // initialize repository manager $rm = $this->createRepositoryManager($io); // load default repository unless it's explicitly disabled $loadPackagist = true; if (isset($packageConfig['repositories'])) { foreach ($packageConfig['repositories'] as $repo) { if (isset($repo['packagist']) && $repo['packagist'] === false) { $loadPackagist = false; } } } if ($loadPackagist) { $this->addPackagistRepository($rm); } // load local repository $this->addLocalRepository($rm, $vendorDir); // load package $loader = new Package\Loader\RootPackageLoader($rm); $package = $loader->load($packageConfig); // initialize download manager $dm = $this->createDownloadManager($io); // initialize installation manager $im = $this->createInstallationManager($rm, $dm, $vendorDir, $binDir, $io); // init locker $lockFile = substr($composerFile, -5) === '.json' ? substr($composerFile, 0, -4) . 'lock' : $composerFile . '.lock'; $locker = new Package\Locker(new JsonFile($lockFile), $rm, md5_file($composerFile)); // initialize composer $composer = new Composer(); $composer->setPackage($package); $composer->setLocker($locker); $composer->setRepositoryManager($rm); $composer->setDownloadManager($dm); $composer->setInstallationManager($im); return $composer; }
/** * 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; }
/** * @return Config */ private function getConfiguration() { $config = new Config(); // add dir to the config $config->merge(array('config' => array('home' => $this->getComposerHome()))); // load global auth file $file = new JsonFile($config->get('home') . '/auth.json'); if ($file->exists()) { $config->merge(array('config' => $file->read())); } $config->setAuthConfigSource(new JsonConfigSource($file, true)); return $config; }
/** * @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; }
/** * 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 * @throws \InvalidArgumentException * @return Composer */ public function createComposer(IOInterface $io, $localConfig = null) { // 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') { $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(); } // Configuration defaults $config = static::createConfig(); $config->merge($localConfig); // reload oauth token from config if available if ($tokens = $config->get('github-oauth')) { foreach ($tokens as $domain => $token) { if (!preg_match('{^[a-z0-9]+$}', $token)) { throw new \UnexpectedValueException('Your github oauth token for ' . $domain . ' contains invalid characters: "' . $token . '"'); } $io->setAuthentication($domain, $token, 'x-oauth-basic'); } } $vendorDir = $config->get('vendor-dir'); $binDir = $config->get('bin-dir'); // setup process timeout ProcessExecutor::setTimeout((int) $config->get('process-timeout')); // initialize repository manager $rm = $this->createRepositoryManager($io, $config); // load local repository $this->addLocalRepository($rm, $vendorDir); // load package $loader = new Package\Loader\RootPackageLoader($rm, $config); $package = $loader->load($localConfig); // initialize download manager $dm = $this->createDownloadManager($io, $config); // initialize installation manager $im = $this->createInstallationManager(); // initialize composer $composer = new Composer(); $composer->setConfig($config); $composer->setPackage($package); $composer->setRepositoryManager($rm); $composer->setDownloadManager($dm); $composer->setInstallationManager($im); // initialize event dispatcher $dispatcher = new EventDispatcher($composer, $io); $composer->setEventDispatcher($dispatcher); // initialize autoload generator $generator = new AutoloadGenerator($dispatcher); $composer->setAutoloadGenerator($generator); // add installers to the manager $this->createDefaultInstallers($im, $composer, $io); // 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(new JsonFile($lockFile, new RemoteFilesystem($io)), $rm, $im, md5_file($composerFile)); $composer->setLocker($locker); } return $composer; }
private function createConfig() { $config = Factory::createConfig(); $file = new JsonFile(Factory::getComposerFile()); if (!$file->exists()) { return $config; } $file->validateSchema(JsonFile::LAX_SCHEMA); $config->merge($file->read()); return $config; }
/** * Dump packages.json file used by composer repository. * * @param Composer $composer The Composer model * @param array $repositories The repositories to scan * @param string $directory The output directory */ protected function dumpPackagesJson(Composer $composer, array $repositories, $directory) { $repoJson = new JsonFile($directory . '/packages.json'); $manager = $composer->getRepositoryManager(); $packages = array(); foreach ($repositories as $config) { $repository = $manager->createRepository($config['type'], $config); foreach ($repository->getPackages() as $package) { // skip aliases if ($package instanceof AliasPackage) { continue; } $packages[] = $package; } } $repo = array('packages' => array()); $dumper = new ArrayDumper(); foreach ($packages as $package) { $name = $package->getPrettyName(); $version = $package->getPrettyVersion(); $repo['packages'][$name][$version] = $dumper->dump($package); } // Keep previous packages information if ($repoJson->exists()) { $data = $repoJson->read(); foreach ($data['packages'] as $name => $info) { if (!isset($repo['packages'][$name])) { $repo['packages'][$name] = $info; } } } $repoJson->write($repo); }
/** * 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; }
/** * Writes the assets database in a JSON file * * @param array $full_db * @return false|string */ public function writeJsonDatabase(array $full_db) { $assets_file = $this->assets_installer->getVendorDir() . '/' . $this->assets_installer->getAssetsDbFilename(); $this->assets_installer->getIo()->write(sprintf('Writing assets json DB to <info>%s</info>', str_replace(dirname($this->assets_installer->getVendorDir()) . '/', '', $assets_file))); try { $json = new JsonFile($assets_file); if ($json->exists()) { unlink($assets_file); } $json->write($full_db); return $assets_file; } catch (\Exception $e) { if (file_put_contents($assets_file, json_encode($full_db, version_compare(PHP_VERSION, '5.4') > 0 ? JSON_PRETTY_PRINT : 0))) { return $assets_file; } } return false; }
/** * {@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'); }
/** * 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; }