/** * {@inheritdoc} * * @SuppressWarnings(PHPMD.LongVariable) */ public function handle(\Input $input) { $packageName = $input->get('install'); if ($packageName == 'contao/core') { $this->redirect('contao/main.php?do=composer'); } if ($input->post('version')) { $version = base64_decode(rawurldecode($input->post('version'))); // make a backup copy(TL_ROOT . '/' . $this->configPathname, TL_ROOT . '/' . $this->configPathname . '~'); // update requires $json = new JsonFile(TL_ROOT . '/' . $this->configPathname); $config = $json->read(); if (!array_key_exists('require', $config)) { $config['require'] = array(); } $config['require'][$packageName] = $version; ksort($config['require']); $json->write($config); Messages::addInfo(sprintf($GLOBALS['TL_LANG']['composer_client']['added_candidate'], $packageName, $version)); $_SESSION['COMPOSER_OUTPUT'] .= $this->io->getOutput(); $this->redirect('contao/main.php?do=composer'); } $installationCandidates = $this->searchPackage($packageName); if (empty($installationCandidates)) { Messages::addError(sprintf($GLOBALS['TL_LANG']['composer_client']['noInstallationCandidates'], $packageName)); $_SESSION['COMPOSER_OUTPUT'] .= $this->io->getOutput(); $this->redirect('contao/main.php?do=composer'); } $template = new \BackendTemplate('be_composer_client_install'); $template->composer = $this->composer; $template->packageName = $packageName; $template->candidates = $installationCandidates; return $template->parse(); }
/** * {@inheritdoc} */ public function handle(\Input $input) { if ($input->post('FORM_SUBMIT') == 'tl_composer_migrate_undo') { /** @var RootPackage $rootPackage */ $rootPackage = $this->composer->getPackage(); $requires = $rootPackage->getRequires(); foreach (array_keys($requires) as $package) { if ($package != 'contao-community-alliance/composer') { unset($requires[$package]); } } $rootPackage->setRequires($requires); $lockPathname = preg_replace('#\\.json$#', '.lock', $this->configPathname); /** @var DownloadManager $downloadManager */ $downloadManager = $this->composer->getDownloadManager(); $downloadManager->setOutputProgress(false); $installer = Installer::create($this->io, $this->composer); if (file_exists(TL_ROOT . '/' . $lockPathname)) { $installer->setUpdate(true); } if ($installer->run()) { $_SESSION['COMPOSER_OUTPUT'] .= $this->io->getOutput(); } else { $_SESSION['COMPOSER_OUTPUT'] .= $this->io->getOutput(); $this->redirect('contao/main.php?do=composer&migrate=undo'); } // load config $json = new JsonFile(TL_ROOT . '/' . $this->configPathname); $config = $json->read(); // remove migration status unset($config['extra']['contao']['migrated']); // write config $json->write($config); // disable composer client and enable repository client $inactiveModules = deserialize($GLOBALS['TL_CONFIG']['inactiveModules']); $inactiveModules[] = '!composer'; foreach (array('rep_base', 'rep_client', 'repository') as $module) { $pos = array_search($module, $inactiveModules); if ($pos !== false) { unset($inactiveModules[$pos]); } } if (version_compare(VERSION, '3', '>=')) { $skipFile = new \File('system/modules/!composer/.skip'); $skipFile->write('Remove this file to enable the module'); $skipFile->close(); } if (file_exists(TL_ROOT . '/system/modules/repository/.skip')) { $skipFile = new \File('system/modules/repository/.skip'); $skipFile->delete(); } $this->Config->update("\$GLOBALS['TL_CONFIG']['inactiveModules']", serialize($inactiveModules)); $this->redirect('contao/main.php?do=repository_manager'); } $template = new \BackendTemplate('be_composer_client_migrate_undo'); $template->composer = $this->composer; $template->output = $_SESSION['COMPOSER_OUTPUT']; unset($_SESSION['COMPOSER_OUTPUT']); return $template->parse(); }
/** * {@inheritdoc} */ public function handle(\Input $input) { $removeNames = $input->post('packages') ? explode(',', $input->post('packages')) : array($input->post('remove')); // filter undeletable packages $removeNames = array_filter($removeNames, function ($removeName) { return !in_array($removeName, InstalledController::$UNDELETABLE_PACKAGES); }); // skip empty if (empty($removeNames)) { $this->redirect('contao/main.php?do=composer'); } // make a backup copy(TL_ROOT . '/' . $this->configPathname, TL_ROOT . '/' . $this->configPathname . '~'); // update requires $json = new JsonFile(TL_ROOT . '/' . $this->configPathname); $config = $json->read(); if (!array_key_exists('require', $config)) { $config['require'] = array(); } foreach ($removeNames as $removeName) { unset($config['require'][$removeName]); } $json->write($config); $_SESSION['TL_INFO'][] = sprintf($GLOBALS['TL_LANG']['composer_client']['removeCandidate'], implode(', ', $removeNames)); $_SESSION['COMPOSER_OUTPUT'] .= $this->io->getOutput(); $this->redirect('contao/main.php?do=composer'); }
/** * {@inheritDoc} */ protected function initialize(InputInterface $input, OutputInterface $output) { parent::initialize($input, $output); if ($input->getOption('global') && null !== $input->getOption('file')) { throw new \RuntimeException('--file and --global can not be combined'); } $io = $this->getIO(); $this->config = Factory::createConfig($io); // 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') ?: trim(getenv('COMPOSER')) ?: 'composer.json'); // Create global composer.json if this was invoked using `composer global config` if ($configFile === 'composer.json' && !file_exists($configFile) && realpath(getcwd()) === realpath($this->config->get('home'))) { file_put_contents($configFile, "{\n}\n"); } $this->configFile = new JsonFile($configFile, null, $io); $this->configSource = new JsonConfigSource($this->configFile); $authConfigFile = $input->getOption('global') ? $this->config->get('home') . '/auth.json' : dirname(realpath($configFile)) . '/auth.json'; $this->authConfigFile = new JsonFile($authConfigFile, null, $io); $this->authConfigSource = new JsonConfigSource($this->authConfigFile, true); // Initialize the global file if it's not there, ignoring any warnings or notices if ($input->getOption('global') && !$this->configFile->exists()) { touch($this->configFile->getPath()); $this->configFile->write(array('config' => new \ArrayObject())); Silencer::call('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(), 'gitlab-oauth' => new \ArrayObject())); Silencer::call('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 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 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>'); } }
protected function execute(InputInterface $input, OutputInterface $output) { $dialog = $this->getHelperSet()->get('dialog'); $whitelist = array('name', 'description', 'author', 'require'); $options = array_filter(array_intersect_key($input->getOptions(), array_flip($whitelist))); if (isset($options['author'])) { $options['authors'] = $this->formatAuthors($options['author']); unset($options['author']); } $options['require'] = isset($options['require']) ? $this->formatRequirements($options['require']) : new \stdClass(); $file = new JsonFile('composer.json'); $json = $file->encode($options); if ($input->isInteractive()) { $output->writeln(array('', $json, '')); if (!$dialog->askConfirmation($output, $dialog->getQuestion('Do you confirm generation', 'yes', '?'), true)) { $output->writeln('<error>Command aborted</error>'); return 1; } } $file->write($options); if ($input->isInteractive()) { $ignoreFile = realpath('.gitignore'); if (false === $ignoreFile) { $ignoreFile = realpath('.') . '/.gitignore'; } if (!$this->hasVendorIgnore($ignoreFile)) { $question = 'Would you like the <info>vendor</info> directory added to your <info>.gitignore</info> [<comment>yes</comment>]?'; if ($dialog->askConfirmation($output, $question, true)) { $this->addVendorIgnore($ignoreFile); } } } }
/** * 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'); }
/** * Writes the packages.json of the repository. * * @param array $includes List of included JSON files. */ private function dumpPackagesJson($includes) { $repo = array('packages' => array(), 'includes' => $includes); $this->output->writeln('<info>Writing packages.json</info>'); $repoJson = new JsonFile($this->filename); $repoJson->write($repo); }
/** * {@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'); } }
/** * 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; }
public function modifyComposerJson() { $configFile = new JsonFile('composer.json'); $configJson = $configFile->read(); $configJson = $this->addInitThemeScript($configJson); $configJson = $this->addChangeThemeVersionScript($configJson); $configJson = $this->addChangeThemeNameScript($configJson); $configFile->write($configJson); }
public function flush() { if (null === $this->oauth) { if (isset($this->data['config']['github-oauth'])) { unset($this->data['config']['github-oauth']['github.com']); // Fix json schema. if (empty($this->data['config']['github-oauth'])) { $this->data['config']['github-oauth'] = new \stdClass(); } } } else { $this->data['config']['github-oauth']['github.com'] = $this->oauth; } $repositories = []; foreach ($this->repositories as $repo) { $repositories[] = ['type' => $repo->getType(), 'url' => $repo->getUrl()]; } $this->data['repositories'] = $repositories; $this->config->write($this->data); }
/** * @depends testInstall */ public function testUpdate($tempDir) { $composerJson = $tempDir . DIRECTORY_SEPARATOR . "composer.json"; $file = new JsonFile($composerJson); $json = $file->read(); $json['require']['nesbot/carbon'] = '1.0'; $file->write($json); $app = new ComposerUI($tempDir); $this->assertTrue($app->update($tempDir)); $this->assertTrue(is_dir($tempDir . DIRECTORY_SEPARATOR . 'vendor')); $this->assertTrue(is_dir($tempDir . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'seld' . DIRECTORY_SEPARATOR . 'jsonlint')); $this->assertTrue(is_dir($tempDir . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'monolog' . DIRECTORY_SEPARATOR . 'monolog')); $this->assertTrue(is_dir($tempDir . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'nesbot' . DIRECTORY_SEPARATOR . 'carbon')); }
public static function initialize(Event $event) { $io = $event->getIO(); $project_dirname = basename(getcwd()); $current_namespace = self::camelize($project_dirname); $io->write("Initialize {$current_namespace} ..."); $targets = self::globRecursive('app/*.php'); $targets = array_merge($targets, self::globRecursive('app/*.html.twig')); $targets = array_merge($targets, self::globRecursive('tests/*.php')); $targets[] = 'composer.json'; $targets[] = 'webroot/index.php'; foreach ($targets as $target) { $source_text = file_get_contents($target); $new_source = str_replace(self::PLACEHOLDER, $current_namespace, $source_text); file_put_contents($target, $new_source); } copy('app/config/config_development.php.sample', 'app/config/config_development.php'); chmod('tmp', 0777); // dumpautoload $composer = $event->getComposer(); $gen = $composer->getAutoloadGenerator(); $gen->setDevMode(true); // rename "autoload" $package = $composer->getPackage(); $autoload = $package->getAutoload(); $autoload['psr-4'][$current_namespace . '\\'] = $autoload['psr-4'][self::PLACEHOLDER . '\\']; unset($autoload['psr-4'][self::PLACEHOLDER . '\\']); unset($autoload['psr-4']['DietcubeInstaller\\']); $package->setAutoload($autoload); // rewrite json file $json = new JsonFile(Factory::getComposerFile()); $composer_definition = $json->read(); unset($composer_definition['autoload']['psr-4']['DietcubeInstaller\\']); unset($composer_definition['scripts']); $json->write($composer_definition); $gen->dump($composer->getConfig(), $composer->getRepositoryManager()->getLocalRepository(), $package, $composer->getInstallationManager(), 'composer', false); $io->write('-------------------------------------------------------------------------'); $io->write(''); $io->write('<comment>Dietcube setup completed.</comment>'); $io->write(''); $io->write('Try now with built-in server:'); $io->write("\$ cd {$project_dirname}"); $io->write('$ DIET_ENV=development php -d variables_order=EGPCS -S 0:8999 -t webroot/'); $io->write(''); $io->write('-------------------------------------------------------------------------'); self::removeMe(); }
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); } }
/** * Run all configuration updates. * * @return void * * @throws ConfigUpdateException When the upgrade process did perform any action. The process should be restarted. */ public static function run() { $messages = array(); $configFile = new JsonFile('composer.json'); $configJson = $configFile->read(); $jsonModified = static::runUpdates($configJson, $messages); if ($jsonModified) { copy('composer.json', 'composer.json~'); $configFile->write($configJson); } if (count($messages)) { $exception = null; foreach (array_reverse($messages) as $message) { $exception = new ConfigUpdateException($message, 0, $exception); } throw $exception; } }
/** * 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; }
protected function updateSatisConfig($package) { $satisConfig = $this->config->satisconfig; $satisUrl = $this->config->satisurl; if ($satisConfig) { $file = new JsonFile($satisConfig); $config = $file->read(); if ($satisUrl) { $url = $package . '.git'; $repo = array('type' => 'git', 'url' => $satisUrl . '/' . $url); } else { $url = ltrim(realpath($this->config->repodir . '/' . $package . '.git'), '/'); $repo = array('type' => 'git', 'url' => 'file:///' . $url); } $config['repositories'][] = $repo; $config['repositories'] = $this->deduplicate($config['repositories']); $file->write($config); } }
/** * {@inheritdoc} */ public function handle(\Input $input) { $packageName = $input->post('pin'); $json = new JsonFile(TL_ROOT . '/' . $this->configPathname); $config = $json->read(); $versionLocks = isset($config['extra']['contao']['version-locks']) ? (array) $config['extra']['contao']['version-locks'] : array(); if (array_key_exists($packageName, $versionLocks)) { if ($versionLocks[$packageName] === null) { unset($config['require'][$packageName]); } else { $config['require'][$packageName] = $versionLocks[$packageName]; } unset($versionLocks[$packageName]); } else { /** @var RepositoryInterface $localRepository */ $localRepository = $this->getRepositoryManager()->getLocalRepository(); /** @var PackageInterface[] $packages */ $packages = $localRepository->findPackages($packageName); while (count($packages) && $packages[0] instanceof AliasPackage) { array_shift($packages); } if (empty($packages)) { $this->redirect('contao/main.php?do=composer'); } if (isset($config['require'][$packageName])) { $versionLocks[$packageName] = $config['require'][$packageName]; } else { $versionLocks[$packageName] = null; } $config['require'][$packageName] = $packages[0]->getVersion(); } if (empty($versionLocks)) { unset($config['extra']['contao']['version-locks']); } else { $config['extra']['contao']['version-locks'] = $versionLocks; } // make a backup copy(TL_ROOT . '/' . $this->configPathname, TL_ROOT . '/' . $this->configPathname . '~'); // update config file $json->write($config); $this->redirect('contao/main.php?do=composer'); }
/** * Merge the current config with the updated data * @param Event $event * @param array $info */ public static function mergeConfig(Event $event, array $info) { // start $io = $event->getIO(); $options = array("name" => $info['package'], "description" => $info['description'], "license" => $info['license'], "keywords" => array(), "type" => "wordpress-plugin", "authors" => array(array("name" => $info['author'], "email" => $info['author_email']) + (!empty($info['author_url']) ? array("homepage" => $info['author_url']) : array())), "scripts" => array("publish" => "Jumpstart\\Deploy::publish"), "minimum-stability" => "dev", "prefer-stable" => true, "require" => array("composer/installers" => "~1.0", "mrgrain/jumpstart-battery" => "~1.0"), "require-dev" => array("mrgrain/jumpstart-deploy" => "@stable"), "autoload" => array("psr-4" => array($info['namespace'] . "\\" => "src/"))); $file = new JsonFile('composer.json'); $json = $file->encode($options); $writeFile = true; $io->write('Jumpstart has generated a composer.json file for you.'); if ($io->askConfirmation('Do you want to check it before writing to disk? [yes]' . "\t")) { $writeFile = false; $io->write($json); if ($io->askConfirmation('Write the generated composer.json to disk? [yes]' . "\t")) { $writeFile = true; } } if ($writeFile) { $file->write($options); } }
/** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { $whitelist = array('name', 'description', 'author', 'type', 'homepage', 'require', 'require-dev', 'stability', 'license'); $options = array_filter(array_intersect_key($input->getOptions(), array_flip($whitelist))); if (isset($options['author'])) { $options['authors'] = $this->formatAuthors($options['author']); unset($options['author']); } if (isset($options['stability'])) { $options['minimum-stability'] = $options['stability']; unset($options['stability']); } $options['require'] = isset($options['require']) ? $this->formatRequirements($options['require']) : new \stdClass(); if (array() === $options['require']) { $options['require'] = new \stdClass(); } if (isset($options['require-dev'])) { $options['require-dev'] = $this->formatRequirements($options['require-dev']); if (array() === $options['require-dev']) { $options['require-dev'] = new \stdClass(); } } $file = new JsonFile('composer.json'); $json = $file->encode($options); $io = $this->getIO(); if ($input->isInteractive()) { $io->writeError(array('', $json, '')); if (!$io->askConfirmation('Do you confirm generation [<comment>yes</comment>]? ', true)) { $io->writeError('<error>Command aborted</error>'); return 1; } } $file->write($options); if ($input->isInteractive() && is_dir('.git')) { $ignoreFile = realpath('.gitignore'); if (false === $ignoreFile) { $ignoreFile = realpath('.') . '/.gitignore'; } if (!$this->hasVendorIgnore($ignoreFile)) { $question = 'Would you like the <info>vendor</info> directory added to your <info>.gitignore</info> [<comment>yes</comment>]? '; if ($io->askConfirmation($question, true)) { $this->addVendorIgnore($ignoreFile); } } } }
/** * {@inheritdoc} * * @SuppressWarnings(PHPMD.LongVariable) */ public function handle(\Input $input) { $packageName = $input->get('solve'); $version = base64_decode(rawurldecode($input->get('version'))); if ($input->post('mark') || $input->post('install')) { // make a backup copy(TL_ROOT . '/' . $this->configPathname, TL_ROOT . '/' . $this->configPathname . '~'); // update requires $json = new JsonFile(TL_ROOT . '/' . $this->configPathname); $config = $json->read(); if (!array_key_exists('require', $config)) { $config['require'] = array(); } $config['require'][$packageName] = $version; $json->write($config); Messages::addInfo(sprintf($GLOBALS['TL_LANG']['composer_client']['added_candidate'], $packageName, $version)); $_SESSION['COMPOSER_OUTPUT'] .= $this->io->getOutput(); if ($input->post('install')) { $this->redirect('contao/main.php?do=composer&update=packages'); } $this->redirect('contao/main.php?do=composer'); } /** @var RootPackage $rootPackage */ $rootPackage = $this->composer->getPackage(); $installedRootPackage = clone $rootPackage; $installedRootPackage->setRequires(array()); $installedRootPackage->setDevRequires(array()); $repositoryManager = $this->getRepositoryManager(); $localRepository = $repositoryManager->getLocalRepository(); $platformRepo = new PlatformRepository(); $installedRepository = new CompositeRepository(array($localRepository, new InstalledArrayRepository(array($installedRootPackage)), $platformRepo)); $versionParser = new VersionParser(); $constraint = $versionParser->parseConstraints($version); $stability = $versionParser->parseStability($version); $aliases = $this->getRootAliases($rootPackage); $this->aliasPlatformPackages($platformRepo, $aliases); $stabilityFlags = $rootPackage->getStabilityFlags(); $stabilityFlags[$packageName] = BasePackage::$stabilities[$stability]; $pool = $this->getPool($rootPackage->getMinimumStability(), $stabilityFlags); $pool->addRepository($installedRepository, $aliases); $policy = new DefaultPolicy($rootPackage->getPreferStable()); $request = new Request($pool); // add root package $rootPackageConstraint = $this->createConstraint('=', $rootPackage->getVersion()); $rootPackageConstraint->setPrettyString($rootPackage->getPrettyVersion()); $request->install($rootPackage->getName(), $rootPackageConstraint); // add requirements $links = $rootPackage->getRequires(); /** @var Link $link */ foreach ($links as $link) { if ($link->getTarget() != $packageName) { $request->install($link->getTarget(), $link->getConstraint()); } } /** @var PackageInterface $package */ foreach ($installedRepository->getPackages() as $package) { $request->install($package->getName(), $this->createConstraint('=', $package->getVersion())); } $operations = array(); try { $solver = new Solver($policy, $pool, $installedRepository); $beforeOperations = $solver->solve($request); $request->install($packageName, $constraint); $operations = $solver->solve($request); /** @var \Composer\DependencyResolver\Operation\SolverOperation $beforeOperation */ foreach ($beforeOperations as $beforeOperation) { /** @var \Composer\DependencyResolver\Operation\InstallOperation $operation */ foreach ($operations as $index => $operation) { if ($operation->getPackage()->getName() != $packageName && $beforeOperation->__toString() == $operation->__toString()) { unset($operations[$index]); } } } } catch (SolverProblemsException $e) { Messages::addError(sprintf('<span style="white-space: pre-line">%s</span>', trim($e->getMessage()))); } $template = new \BackendTemplate('be_composer_client_solve'); $template->composer = $this->composer; $template->packageName = $packageName; $template->packageVersion = $version; $template->operations = $operations; return $template->parse(); }
private function dumpJson(array $packages, OutputInterface $output, $filename) { $repo = array('packages' => array()); $dumper = new ArrayDumper(); foreach ($packages as $package) { $repo['packages'][$package->getPrettyName()][$package->getPrettyVersion()] = $dumper->dump($package); } $output->writeln('<info>Writing packages.json</info>'); $repoJson = new JsonFile($filename); $repoJson->write($repo); }
/** * Writes the packages.json of the repository. * * @param array $repo Repository information */ private function dumpPackagesJson($repo) { if (isset($this->config['notify-batch'])) { $repo['notify-batch'] = $this->config['notify-batch']; } $this->output->writeln('<info>Writing packages.json</info>'); $repoJson = new JsonFile($this->filename); $repoJson->write($repo); }
/** * Install command: choose packages and provide configuration. * * Prompts users for package selections, and copies in package-specific * configuration when known. * * Updates the composer.json with the package selections, and removes the * install and update commands on completion. * * @param Event $event */ public static function install(Event $event) { $io = $event->getIO(); $composer = $event->getComposer(); // Get composer.json $composerFile = Factory::getComposerFile(); $json = new JsonFile($composerFile); self::$composerDefinition = $json->read(); $projectRoot = realpath(dirname($composerFile)); $io->write("<info>Setup data and cache dir</info>"); if (!is_dir($projectRoot . '/data/cache')) { mkdir($projectRoot . '/data/cache', 0775, true); chmod($projectRoot . '/data', 0775); } $io->write("<info>Setting up optional packages</info>"); // Get root package $rootPackage = $composer->getPackage(); while ($rootPackage instanceof AliasPackage) { $rootPackage = $rootPackage->getAliasOf(); } // Get required packages self::$composerRequires = $rootPackage->getRequires(); self::$composerDevRequires = $rootPackage->getDevRequires(); // Get stability flags self::$stabilityFlags = $rootPackage->getStabilityFlags(); // Minimal? $minimal = self::requestMinimal($io); $copyFilesKey = $minimal ? 'minimal-files' : 'copy-files'; self::$config = (require __DIR__ . '/config.php'); foreach (self::$config['questions'] as $questionName => $question) { $defaultOption = isset($question['default']) ? $question['default'] : 1; if (isset(self::$composerDefinition['extra']['optional-packages'][$questionName])) { // Skip question, it's already answered continue; } // Get answer $answer = self::askQuestion($composer, $io, $question, $defaultOption); // Save user selected option self::$composerDefinition['extra']['optional-packages'][$questionName] = $answer; if (is_numeric($answer)) { // Add packages to install if (isset($question['options'][$answer]['packages'])) { foreach ($question['options'][$answer]['packages'] as $packageName) { self::addPackage($io, $packageName, self::$config['packages'][$packageName]); } } // Copy files if (isset($question['options'][$answer][$copyFilesKey])) { foreach ($question['options'][$answer][$copyFilesKey] as $source => $target) { self::copyFile($io, $projectRoot, $source, $target); } } } elseif ($question['custom-package'] === true && preg_match(self::PACKAGE_REGEX, $answer, $match)) { self::addPackage($io, $match['name'], $match['version']); if (isset($question['custom-package-warning'])) { $io->write(sprintf(" <warning>%s</warning>", $question['custom-package-warning'])); } } // Update composer definition $json->write(self::$composerDefinition); } // Set required packages $rootPackage->setRequires(self::$composerRequires); $rootPackage->setDevRequires(self::$composerDevRequires); // Set stability flags $rootPackage->setStabilityFlags(self::$stabilityFlags); // House keeping $io->write("<info>Remove installer</info>"); // Remove composer source unset(self::$composerDefinition['require-dev']['composer/composer']); // Remove installer data unset(self::$composerDefinition['extra']['optional-packages']); if (empty(self::$composerDefinition['extra'])) { unset(self::$composerDefinition['extra']); } // Remove installer scripts, only need to do this once unset(self::$composerDefinition['scripts']['pre-update-cmd']); unset(self::$composerDefinition['scripts']['pre-install-cmd']); if (empty(self::$composerDefinition['scripts'])) { unset(self::$composerDefinition['scripts']); } // Remove installer script autoloading rules unset(self::$composerDefinition['autoload']['psr-4']['ExpressiveInstaller\\']); // Update composer definition $json->write(self::$composerDefinition); // Minimal install? Remove default middleware if ($minimal) { self::removeDefaultMiddleware($io, $projectRoot); } self::cleanUp($io); }
/** * Write the PSR-4 data to the extensions/composer.json file. * * @param Finder $finder */ private function setLocalExtensionPsr4(Finder $finder) { // Get Bolt's extension JSON $composerOptions = $this->app['extend.action.options']; $composerJsonFile = new JsonFile($composerOptions['composerjson']); $boltJson = $composerJsonFile->read(); $boltPsr4 = isset($boltJson['autoload']['psr-4']) ? $boltJson['autoload']['psr-4'] : []; foreach ($finder as $file) { try { $extensionJsonFile = new JsonFile($file->getRealpath()); $json = $extensionJsonFile->read(); } catch (\Exception $e) { $this->logInitFailure('Reading local extension composer.json file failed', $file->getRealpath(), $e, Logger::ERROR); } if (isset($json['autoload']['psr-4'])) { $basePath = str_replace($this->app['resources']->getPath('extensions/local'), 'local', dirname($file->getRealpath())); $psr4 = $this->getLocalExtensionPsr4($basePath, $json['autoload']['psr-4']); $boltPsr4 = array_merge($boltPsr4, $psr4); } } // Modify Bolt's extension JSON and write out changes $boltJson['autoload']['psr-4'] = $boltPsr4; $composerJsonFile->write($boltJson); $this->app['extend.manager']->dumpautoload(); $this->app['filesystem']->put('app://cache/.local.autoload.built', time()); }
/** * Create a default composer.json, should one not already exist * * @param string $composer_path Where the composer.json should be created * @return true|WP_Error */ private function create_default_composer_json($composer_path) { $composer_dir = pathinfo($composer_path, PATHINFO_DIRNAME); if (!is_dir($composer_dir)) { \WP_CLI\Process::create(WP_CLI\Utils\esc_cmd('mkdir -p %s', $composer_dir))->run(); } if (!is_dir($composer_dir)) { WP_CLI::error("Composer directory for packages couldn't be created."); } $json_file = new JsonFile($composer_path); $author = (object) array('name' => 'WP-CLI', 'email' => '*****@*****.**'); $repositories = (object) array('wp-cli' => (object) array('type' => 'composer', 'url' => self::PACKAGE_INDEX_URL)); $options = array('name' => 'wp-cli/wp-cli', 'description' => 'Installed community packages used by WP-CLI', 'version' => self::get_wp_cli_version_composer(), 'authors' => array($author), 'homepage' => self::PACKAGE_INDEX_URL, 'require' => new stdClass(), 'require-dev' => new stdClass(), 'minimum-stability' => 'dev', 'license' => 'MIT', 'repositories' => $repositories); try { $json_file->write($options); } catch (Exception $e) { WP_CLI::error($e->getMessage()); } return true; }
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; }