/** * Merge repositories and requirements from a separate composer-local.json. * * This allows static development dependencies to be shipped with Vanilla, but can be customized with a * composer-local.json file that specifies additional dependencies such as plugins or compatibility libraries. * * @param Event $event The event being fired. */ public static function preUpdate(Event $event) { self::clearAddonManagerCache(); // Check for a composer-local.json. $composerLocalPath = './composer-local.json'; if (!file_exists($composerLocalPath)) { return; } $composer = $event->getComposer(); $factory = new Factory(); $localComposer = $factory->createComposer($event->getIO(), $composerLocalPath, true, null, false); // Merge repositories. $localRepositories = $localComposer->getRepositoryManager()->getRepositories(); foreach ($localRepositories as $repository) { /* @var \Composer\Repository\RepositoryInterface $repository */ if (method_exists($repository, 'getRepoConfig')) { $config = $repository->getRepoConfig(); } else { $config = ['url' => '']; } // Skip the packagist repo. if (strpos($config['url'], 'packagist.org') !== false) { continue; } $composer->getRepositoryManager()->addRepository($repository); } // Merge requirements. $requires = array_merge($composer->getPackage()->getRequires(), $localComposer->getPackage()->getRequires()); $composer->getPackage()->setRequires($requires); $devRequires = array_merge($composer->getPackage()->getDevRequires(), $localComposer->getPackage()->getDevRequires()); $composer->getPackage()->setDevRequires($devRequires); }
/** * Builds the archives of the repository. * * @param array $packages List of packages to dump */ public function dump(array $packages) { $helper = new ArchiveBuilderHelper($this->output, $this->config['archive']); $directory = $helper->getDirectory($this->outputDir); $this->output->writeln(sprintf("<info>Creating local downloads in '%s'</info>", $directory)); $format = isset($this->config['archive']['format']) ? $this->config['archive']['format'] : 'zip'; $endpoint = isset($this->config['archive']['prefix-url']) ? $this->config['archive']['prefix-url'] : $this->config['homepage']; $includeArchiveChecksum = isset($this->config['archive']['checksum']) ? (bool) $this->config['archive']['checksum'] : true; $composerConfig = Factory::createConfig(); $factory = new Factory(); $io = new ConsoleIO($this->input, $this->output, $this->helperSet); $io->loadConfiguration($composerConfig); /* @var \Composer\Downloader\DownloadManager $downloadManager */ $downloadManager = $factory->createDownloadManager($io, $composerConfig); /* @var \Composer\Package\Archiver\ArchiveManager $archiveManager */ $archiveManager = $factory->createArchiveManager($composerConfig, $downloadManager); $archiveManager->setOverwriteFiles(false); shuffle($packages); /* @var \Composer\Package\CompletePackage $package */ foreach ($packages as $package) { if ($helper->isSkippable($package)) { continue; } $this->output->writeln(sprintf("<info>Dumping '%s'.</info>", $package->getName())); try { if ('pear-library' === $package->getType()) { // PEAR packages are archives already $filesystem = new Filesystem(); $packageName = $archiveManager->getPackageFilename($package); $path = realpath($directory) . '/' . $packageName . '.' . pathinfo($package->getDistUrl(), PATHINFO_EXTENSION); if (!file_exists($path)) { $downloadDir = sys_get_temp_dir() . '/composer_archiver/' . $packageName; $filesystem->ensureDirectoryExists($downloadDir); $downloadManager->download($package, $downloadDir, false); $filesystem->ensureDirectoryExists($directory); $filesystem->rename($downloadDir . '/' . pathinfo($package->getDistUrl(), PATHINFO_BASENAME), $path); $filesystem->removeDirectory($downloadDir); } // Set archive format to `file` to tell composer to download it as is $archiveFormat = 'file'; } else { $path = $archiveManager->archive($package, $format, $directory); $archiveFormat = $format; } $archive = basename($path); $distUrl = sprintf('%s/%s/%s', $endpoint, $this->config['archive']['directory'], $archive); $package->setDistType($archiveFormat); $package->setDistUrl($distUrl); if ($includeArchiveChecksum) { $package->setDistSha1Checksum(hash_file('sha1', $path)); } $package->setDistReference($package->getSourceReference()); } catch (\Exception $exception) { if (!$this->skipErrors) { throw $exception; } $this->output->writeln(sprintf("<error>Skipping Exception '%s'.</error>", $exception->getMessage())); } } }
/** * Test that the core bundles get correctly injected. * * @return void */ public function testInjectCoreBundles() { $inOut = $this->getMock('Composer\\IO\\IOInterface'); $factory = new Factory(); $composer = $factory->createComposer($inOut, $this->config); $plugin = new Plugin(); $local = $composer->getRepositoryManager()->getLocalRepository(); if ($core = $local->findPackages('contao/core')) { $this->fail('Contao core has already been injected, found version ' . $core[0]->getVersion()); } $plugin->activate($composer, $inOut); if (!($core = $local->findPackages('contao/core'))) { $this->fail('Contao core has not been injected.'); } $core = $core[0]; $constraint = new Constraint('=', $core->getVersion()); $pool = new Pool('dev'); $pool->addRepository($local); $this->assertNotNull($core = $pool->whatProvides('contao/core', $constraint)); // bundle names + 'contao-community-alliance/composer-client' $this->assertCount(8, $core[0]->getRequires()); foreach (array('contao/calendar-bundle', 'contao/comments-bundle', 'contao/core-bundle', 'contao/faq-bundle', 'contao/listing-bundle', 'contao/news-bundle', 'contao/newsletter-bundle') as $bundleName) { $this->assertNotNull($matches = $pool->whatProvides($bundleName, $constraint)); $this->assertCount(1, $matches); $this->assertEquals('metapackage', $matches[0]->getType()); } }
protected function execute(InputInterface $input, OutputInterface $output) { $factory = new Factory(); $file = $factory->getComposerFile(); if (!file_exists($file)) { $output->writeln('<error>' . $file . ' not found.</error>'); return 1; } if (!is_readable($file)) { $output->writeln('<error>' . $file . ' is not readable.</error>'); return 1; } $dialog = $this->getHelperSet()->get('dialog'); $json = new JsonFile($file); $composer = $json->read(); $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>'); // Update packages $composer = $this->getComposer(); $io = $this->getIO(); $install = Installer::create($io, $composer); $install->setVerbose($input->getOption('verbose'))->setPreferSource($input->getOption('prefer-source'))->setDevMode($input->getOption('dev'))->setUpdate(true)->setUpdateWhitelist($requirements); return $install->run() ? 0 : 1; }
public function setUp() { parent::setUp(); $factory = new Factory(); $this->manager = $factory->createArchiveManager($factory->createConfig()); $this->targetDir = $this->testDir . '/composer_archiver_tests'; }
/** * @return Composer */ protected function getComposer() { $dir = Module::getRootDir(); $path = $dir . '/composer.json'; \Dotenv::setEnvironmentVariable('COMPOSER', $path); $factory = new Factory(); return $factory->createComposer(new NullIO(), $path, false, $dir); }
/** * @return \Composer\Composer */ public static function getComposer() { if (!self::$composer) { $factory = new Factory(); self::$composer = $factory->createComposer(new NullIO(), Yii::getAlias(self::$composerConfigFile), false, Yii::getAlias(self::$composerConfigFilePath)); } return self::$composer; }
/** * When the plugin is loaded, the event listeners are registered which require the Housekeeper. * * When the plugin gets uninstalled the housekeeper does not exist anymore and a "Housekeeper class not found" is * thrown. * * Test for https://github.com/contao-community-alliance/composer-plugin/issues/30 * * Situation: * - plugin is installed. * - plugin get uninstalled. * * Result: * - Housekeeper class not found. * * @return void */ public function testIssue30LoadHousekeeper() { $inOut = $this->getMock('Composer\\IO\\IOInterface'); $factory = new Factory(); $composer = $factory->createComposer($inOut); $plugin = new Plugin(); $plugin->activate($composer, $inOut); $this->assertTrue(class_exists('ContaoCommunityAlliance\\Composer\\Plugin\\Housekeeper', false)); }
private function getDownloadManager() { if (!$this->downloadManager) { $config = Factory::createConfig(); $factory = new Factory(); $this->downloadManager = $factory->createDownloadManager($this->getIO(), $config); } return $this->downloadManager; }
/** * Returns a list of directory paths in which scaffold files * are to be searched for, in order to build an index * * @return string[] */ public function directories() { $composerConfig = Factory::createConfig(null, getcwd()); $vendorDir = $composerConfig->get('vendor-dir'); $globalVendorDir = Factory::createConfig(null, $composerConfig->get('home'))->get('vendor-dir'); return [$globalVendorDir, $vendorDir, getcwd() . DIRECTORY_SEPARATOR]; }
protected function initialize(InputInterface $input, OutputInterface $output) { parent::initialize($input, $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()); $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); 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(sprintf('File "%s" cannot be found in the current directory', $configFile)); } }
protected function execute(InputInterface $input, OutputInterface $output) { $baseUrl = (extension_loaded('openssl') ? 'https' : 'http') . '://' . self::HOMEPAGE; $config = Factory::createConfig(); $remoteFilesystem = new RemoteFilesystem($this->getIO(), $config); $cacheDir = $config->get('cache-dir'); $rollbackDir = $config->get('home'); $localFilename = realpath($_SERVER['argv'][0]) ?: $_SERVER['argv'][0]; // check if current dir is writable and if not try the cache dir from settings $tmpDir = is_writable(dirname($localFilename)) ? dirname($localFilename) : $cacheDir; // check for permissions in local filesystem before start connection process if (!is_writable($tmpDir)) { throw new FilesystemException('Composer update failed: the "' . $tmpDir . '" directory used to download the temp file could not be written'); } if (!is_writable($localFilename)) { throw new FilesystemException('Composer update failed: the "' . $localFilename . '" file could not be written'); } if ($input->getOption('rollback')) { return $this->rollback($output, $rollbackDir, $localFilename); } $latestVersion = trim($remoteFilesystem->getContents(self::HOMEPAGE, $baseUrl . '/version', false)); $updateVersion = $input->getArgument('version') ?: $latestVersion; if (preg_match('{^[0-9a-f]{40}$}', $updateVersion) && $updateVersion !== $latestVersion) { $output->writeln('<error>You can not update to a specific SHA-1 as those phars are not available for download</error>'); return 1; } if (Composer::VERSION === $updateVersion) { $output->writeln('<info>You are already using composer version ' . $updateVersion . '.</info>'); return 0; } $tempFilename = $tmpDir . '/' . basename($localFilename, '.phar') . '-temp.phar'; $backupFile = sprintf('%s/%s-%s%s', $rollbackDir, strtr(Composer::RELEASE_DATE, ' :', '_-'), preg_replace('{^([0-9a-f]{7})[0-9a-f]{33}$}', '$1', Composer::VERSION), self::OLD_INSTALL_EXT); $output->writeln(sprintf("Updating to version <info>%s</info>.", $updateVersion)); $remoteFilename = $baseUrl . (preg_match('{^[0-9a-f]{40}$}', $updateVersion) ? '/composer.phar' : "/download/{$updateVersion}/composer.phar"); $remoteFilesystem->copy(self::HOMEPAGE, $remoteFilename, $tempFilename); if (!file_exists($tempFilename)) { $output->writeln('<error>The download of the new composer version failed for an unexpected reason</error>'); return 1; } // remove saved installations of composer if ($input->getOption('clean-backups')) { $finder = $this->getOldInstallationFinder($rollbackDir); $fs = new Filesystem(); foreach ($finder as $file) { $file = (string) $file; $output->writeln('<info>Removing: ' . $file . '</info>'); $fs->remove($file); } } if ($err = $this->setLocalPhar($localFilename, $tempFilename, $backupFile)) { $output->writeln('<error>The file is corrupted (' . $err->getMessage() . ').</error>'); $output->writeln('<error>Please re-run the self-update command to try again.</error>'); return 1; } if (file_exists($backupFile)) { $output->writeln('Use <info>composer self-update --rollback</info> to return to version ' . Composer::VERSION); } else { $output->writeln('<warning>A backup of the current version could not be written to ' . $backupFile . ', no rollback possible</warning>'); } }
/** * Search for packages. * * @param array $packages Indexed array of package names to search for * @param boolean $onlyname True for name only search, false for full text * * @throws PackageManagerException * * @return array List of matching packages */ public function execute($packages, $onlyname = true) { /** @var $composer \Composer\Composer */ $composer = $this->getComposer(); $io = $this->getIO(); $platformRepo = new PlatformRepository(); if ($composer) { $localRepo = $composer->getRepositoryManager()->getLocalRepository(); $installedRepo = new CompositeRepository([$localRepo, $platformRepo]); $repos = new CompositeRepository(array_merge([$installedRepo], $composer->getRepositoryManager()->getRepositories())); } else { $defaultRepos = Factory::createDefaultRepositories($io); //No composer.json found in the current directory, showing packages from local repo $installedRepo = $platformRepo; $repos = new CompositeRepository(array_merge([$installedRepo], $defaultRepos)); } $flags = $onlyname ? RepositoryInterface::SEARCH_NAME : RepositoryInterface::SEARCH_FULLTEXT; try { return $repos->search(implode(' ', $packages), $flags); } catch (\Exception $e) { $msg = __CLASS__ . '::' . __FUNCTION__ . ' recieved an error from Composer: ' . $e->getMessage() . ' in ' . $e->getFile() . '::' . $e->getLine(); $this->app['logger.system']->critical($msg, ['event' => 'exception', 'exception' => $e]); throw new PackageManagerException($e->getMessage(), $e->getCode(), $e); } }
/** * Constructor. * * @param IOInterface $io The IO instance * @param Config $config The composer configuration * @param ProcessExecutor $process Process instance, injectable for mocking * @param RemoteFilesystem $remoteFilesystem Remote Filesystem, injectable for mocking */ public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, RemoteFilesystem $remoteFilesystem = null) { $this->io = $io; $this->config = $config; $this->process = $process ?: new ProcessExecutor(); $this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config); }
/** * @param string $url * @param string $token * @param bool $cacheDir * @param null $bufferIO * * @throws \Exception */ public function __construct($url, $token = '', $cacheDir = false, $bufferIO = null) { $this->url = $url; $this->io = new NullIO(); $this->log = $bufferIO ? $bufferIO : new BufferIO(); $config = Factory::createConfig(); $cfg = ['config' => []]; if ($cacheDir) { $cfg['config']['cache-dir'] = $cacheDir; } if ($token) { $cfg['config']['github-oauth'] = ['github.com' => $token]; } $config->merge($cfg); $this->cacheDir = $cacheDir; $this->io->loadConfiguration($config); $this->repository = new Repository\VcsRepository(['url' => $url, 'no-api' => false], $this->io, $config); $driver = $this->vcsDriver = $this->repository->getDriver(); if (!$driver) { throw new \Exception('No driver found for <' . $url . '>'); } $this->driver = $driver; $composerInfoMaster = $this->driver->getComposerInformation($this->driver->getRootIdentifier()); if (!$composerInfoMaster) { throw new \Exception('master must have a valid composer.json'); } $this->name = $composerInfoMaster['name']; list($this->vendorName, $this->packageName) = explode('/', $this->name); preg_match('#^(?:(?:https?|git)://([^/]+)/|git@([^:]+):)([^/]+)/(.+?)(?:\\.git|/)?$#', $this->url, $match); $this->gitHubVendorName = $match[3]; $this->gitHubRepositoryName = $match[4]; $client = new \Github\Client(); $client->authenticate($token, null, \GitHub\Client::AUTH_URL_TOKEN); $this->client = $client; }
/** * Removes patched packages. */ public function main() { // Check if all required data is present. $this->checkRequirements(); $composer = Factory::create(new NullIO(), $this->composerJsonPath); // Force discarding of changes, these packages are patched after all. // @todo Make this configurable with a "force" flag. $config = $composer->getConfig(); $config->merge(['config' => ['discard-changes' => TRUE]]); // Get the list of patches. $extra = $composer->getPackage()->getExtra(); if (!empty($extra['patches'])) { $repository = $composer->getRepositoryManager()->getLocalRepository(); $installation_manager = $composer->getInstallationManager(); // Loop over the patched packages. foreach (array_keys($extra['patches']) as $package_name) { foreach ($repository->findPackages($package_name) as $package) { // Skip aliases, only remove the actual packages. if (!$package instanceof AliasPackage) { // Remove the package. $this->log("Removing patched package '{$package_name}'."); $operation = new UninstallOperation($package, 'Uninstalling patched package so it can be reinstalled.'); $installation_manager->uninstall($repository, $operation); } } } // Re-generate the autoloader to get rid of stale class definitions. $generator = $composer->getAutoloadGenerator(); $localRepo = $composer->getRepositoryManager()->getLocalRepository(); $package = $composer->getPackage(); $installationManager = $composer->getInstallationManager(); $generator->dump($config, $localRepo, $package, $installationManager, 'composer'); } }
protected function createRepositoryManager(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null) { $rm = parent::createRepositoryManager($io, $config, $eventDispatcher); $rm->setRepositoryClass('t3git', 'Helhum\\T3Satis\\Composer\\Repository\\Typo3ExtensionRepository'); $repoCollections = $config->get('repository-collections'); if ($repoCollections && is_array($repoCollections)) { foreach ($repoCollections as $repoCollection) { if (isset($repoCollection['type'])) { if (!isset($this->repoCollectionClasses[$repoCollection['type']])) { throw new \UnexpectedValueException('The collection type ' . $repoCollection['type'] . ' is unkown!', 1439304140); } $collectionClass = $this->repoCollectionClasses[$repoCollection['type']]; } elseif (isset($repoCollection['className'])) { $collectionClass = $repoCollection['className']; } else { throw new \UnexpectedValueException('The collection must either be specified with "type" or "className"!', 1439304139); } if (!in_array('Helhum\\T3Satis\\Composer\\Repository\\RepositoryCollectionInterface', class_implements($collectionClass))) { throw new \UnexpectedValueException('The collection class must be autoloadable and must implement the RepositoryCollectionInterface', 1439304139); } /** @var RepositoryCollectionInterface $collection */ $collection = new $collectionClass(); $repos = $collection->fetchRepositoryConfiguration(); $config->merge(array('repositories' => $repos)); } } return $rm; }
public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, RemoteFilesystem $rfs = null) { if (!preg_match('{^[\\w.]+\\??://}', $repoConfig['url'])) { // assume http as the default protocol $repoConfig['url'] = 'http://' . $repoConfig['url']; } $repoConfig['url'] = rtrim($repoConfig['url'], '/'); if ('https?' === substr($repoConfig['url'], 0, 6)) { $repoConfig['url'] = (extension_loaded('openssl') ? 'https' : 'http') . substr($repoConfig['url'], 6); } $urlBits = parse_url($repoConfig['url']); if ($urlBits === false || empty($urlBits['scheme'])) { throw new \UnexpectedValueException('Invalid url given for Composer repository: ' . $repoConfig['url']); } if (!isset($repoConfig['options'])) { $repoConfig['options'] = array(); } if (isset($repoConfig['allow_ssl_downgrade']) && true === $repoConfig['allow_ssl_downgrade']) { $this->allowSslDowngrade = true; } $this->config = $config; $this->options = $repoConfig['options']; $this->url = $repoConfig['url']; $this->baseUrl = rtrim(preg_replace('{^(.*)(?:/[^/\\]+.json)?(?:[?#].*)?$}', '$1', $this->url), '/'); $this->io = $io; $this->cache = new Cache($io, $config->get('cache-repo-dir') . '/' . preg_replace('{[^a-z0-9.]}i', '-', $this->url), 'a-z0-9.$'); $this->loader = new ArrayLoader(); $this->rfs = $rfs ?: Factory::createRemoteFilesystem($this->io, $this->config, $this->options); $this->eventDispatcher = $eventDispatcher; $this->repoConfig = $repoConfig; }
public function getComposer() { if ($this->composer === null) { $this->composer = Factory::create($this->io, null, false); } return $this->composer; }
/** * Create \Composer\Composer * * @return \Composer\Composer * @throws \Exception */ public function create() { if (!getenv('COMPOSER_HOME')) { putenv('COMPOSER_HOME=' . $this->directoryList->getPath(DirectoryList::COMPOSER_HOME)); } return \Composer\Factory::create(new BufferIO(), $this->composerJsonFinder->findComposerJson()); }
/** * {@inheritDoc} */ protected function prepareCommand() { RuntimeHelper::setupHome($this->file->get(self::SETTING_HOME)); $command = new UpdateCommand(); $command->setComposer(Factory::create($this->getIO())); return $command; }
protected function execute(InputInterface $input, OutputInterface $output) { // init repos $platformRepo = new PlatformRepository(); if ($composer = $this->getComposer(false)) { $localRepo = $composer->getRepositoryManager()->getLocalRepository(); $installedRepo = new CompositeRepository(array($localRepo, $platformRepo)); $repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories())); } else { $defaultRepos = Factory::createDefaultRepositories($this->getIO()); $output->writeln('No composer.json found in the current directory, showing packages from ' . implode(', ', array_keys($defaultRepos))); $installedRepo = $platformRepo; $repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos)); } if ($composer) { $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'search', $input, $output); $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent); } $onlyName = $input->getOption('only-name'); $flags = $onlyName ? RepositoryInterface::SEARCH_NAME : RepositoryInterface::SEARCH_FULLTEXT; $results = $repos->search(implode(' ', $input->getArgument('tokens')), $flags); foreach ($results as $result) { $output->writeln($result['name'] . (isset($result['description']) ? ' ' . $result['description'] : '')); } }
public function run(InputInterface $input, OutputInterface $output) { // extract real command name $tokens = preg_split('{\\s+}', $input->__toString()); $args = array(); foreach ($tokens as $token) { if ($token && $token[0] !== '-') { $args[] = $token; if (count($args) >= 2) { break; } } } // show help for this command if no command was found if (count($args) < 2) { return parent::run($input, $output); } // change to global dir $config = Factory::createConfig(); chdir($config->get('home')); $this->getIO()->writeError('<info>Changed current directory to ' . $config->get('home') . '</info>'); // create new input without "global" command prefix $input = new StringInput(preg_replace('{\\bg(?:l(?:o(?:b(?:a(?:l)?)?)?)?)?\\b}', '', $input->__toString(), 1)); $this->getApplication()->resetComposer(); return $this->getApplication()->run($input, $output); }
/** * Runs the project configurator. * * @return void */ public function run() { $namespace = $this->ask('Namespace', function ($namespace) { return $this->validateNamespace($namespace); }, 'App'); $packageName = $this->ask('Package name', function ($packageName) { return $this->validatePackageName($packageName); }, $this->suggestPackageName($namespace)); $license = $this->ask('License', function ($license) { return trim($license); }, 'proprietary'); $description = $this->ask('Description', function ($description) { return trim($description); }, ''); $file = new JsonFile('./composer.json'); $config = $file->read(); $config['name'] = $packageName; $config['license'] = $license; $config['description'] = $description; $config['autoload']['psr-4'] = [$namespace . '\\' => 'src/']; $config['autoload-dev']['psr-4'] = [$namespace . '\\Tests\\' => 'tests/']; unset($config['scripts']['post-root-package-install']); $config['extra']['branch-alias']['dev-master'] = '1.0-dev'; $file->write($config); $this->composer->setPackage(Factory::create($this->io, null, true)->getPackage()); // reload root package $filesystem = new Filesystem(); $filesystem->removeDirectory('./app/Distribution'); }
/** * {@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'); } }
protected function selectPackage(IOInterface $io, $packageName, $version = null) { $io->writeError('<info>Searching for the specified package.</info>'); if ($composer = $this->getComposer(false)) { $localRepo = $composer->getRepositoryManager()->getLocalRepository(); $repos = new CompositeRepository(array_merge(array($localRepo), $composer->getRepositoryManager()->getRepositories())); } else { $defaultRepos = Factory::createDefaultRepositories($this->getIO()); $io->writeError('No composer.json found in the current directory, searching packages from ' . implode(', ', array_keys($defaultRepos))); $repos = new CompositeRepository($defaultRepos); } $pool = new Pool(); $pool->addRepository($repos); $parser = new VersionParser(); $constraint = $version ? $parser->parseConstraints($version) : null; $packages = $pool->whatProvides($packageName, $constraint, true); if (count($packages) > 1) { $package = reset($packages); $io->writeError('<info>Found multiple matches, selected ' . $package->getPrettyString() . '.</info>'); $io->writeError('Alternatives were ' . implode(', ', array_map(function ($p) { return $p->getPrettyString(); }, $packages)) . '.'); $io->writeError('<comment>Please use a more specific constraint to pick a different package.</comment>'); } elseif ($packages) { $package = reset($packages); $io->writeError('<info>Found an exact match ' . $package->getPrettyString() . '.</info>'); } else { $io->writeError('<error>Could not find a package matching ' . $packageName . '.</error>'); return false; } return $package; }
/** * Executes composer for the extension. */ public function execute(InputInterface $input, OutputInterface $output) { $name = $this->argument('extension'); $update = $this->option('update'); if (!is_dir($path = $this->pagekit['path.extensions'] . "/{$name}") && file_exists("{$path}/extension.json")) { $this->error("Extension not exists '{$path}'"); exit; } $package = json_decode(file_get_contents("{$path}/extension.json"), true); if (!isset($package['composer']) || empty($package['composer'])) { $this->error("Composer not defined in '{$path}/extension.json'"); exit; } $this->loadComposer($path); $io = new ConsoleIO($input, $output, $this->getHelperSet()); $composer = Factory::create($io, $package['composer']); $lockFile = new JsonFile("{$path}/extension.lock"); $locker = new Locker($io, $lockFile, $composer->getRepositoryManager(), $composer->getInstallationManager(), md5(json_encode($package['composer']))); $composer->setLocker($locker); $installed = new JsonFile($this->pagekit['path'] . '/vendor/composer/installed.json'); $internal = new CompositeRepository([]); $internal->addRepository(new InstalledFilesystemRepository($installed)); $installer = Installer::create($io, $composer); $installer->setAdditionalInstalledRepository($internal); $installer->setUpdate($update); return $installer->run(); }
/** * Reload Composer. */ public function reload() { // update application components to the latest version if (file_exists($this->lock_file)) { unlink($this->lock_file); } $this->composer = $this->factory->createComposer($this->getIO()); }
/** * Retrieve a composer instance. * * @param null|IOInterface $inputOutput The input/output handler to use. * * @return Composer */ public function getComposer(IOInterface $inputOutput = null) { if (null === $inputOutput) { $inputOutput = $this->getInputOutput(); } RuntimeHelper::setupHome($this->getTensideHome()); return ComposerFactory::create($inputOutput); }
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; }