From ec71674826de35a8bed8642a1b49d0acef1d43d4 Mon Sep 17 00:00:00 2001 From: Joshua Estes Date: Mon, 1 Oct 2012 09:19:20 -0500 Subject: [PATCH 01/12] added empty configuration command and updated the application class to pull it in for display --- src/Composer/Command/ConfigCommand.php | 35 ++++++++++++++++++++++++++ src/Composer/Console/Application.php | 1 + 2 files changed, 36 insertions(+) create mode 100644 src/Composer/Command/ConfigCommand.php diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php new file mode 100644 index 000000000..7c188ebb9 --- /dev/null +++ b/src/Composer/Command/ConfigCommand.php @@ -0,0 +1,35 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Command; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class ConfigCommand extends Command +{ + protected function configure() + { + $this + ->setName('config') + ->setDescription('Manage config settings') + ->setHelp(<< Date: Mon, 1 Oct 2012 11:06:50 -0500 Subject: [PATCH 02/12] blah, don't need that --- src/Composer/Command/ConfigCommand.php | 35 -------------------------- 1 file changed, 35 deletions(-) delete mode 100644 src/Composer/Command/ConfigCommand.php diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php deleted file mode 100644 index 7c188ebb9..000000000 --- a/src/Composer/Command/ConfigCommand.php +++ /dev/null @@ -1,35 +0,0 @@ - - * Jordi Boggiano - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Composer\Command; - -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -class ConfigCommand extends Command -{ - protected function configure() - { - $this - ->setName('config') - ->setDescription('Manage config settings') - ->setHelp(<< Date: Mon, 1 Oct 2012 11:07:53 -0500 Subject: [PATCH 03/12] add a repository in either the global config or the local composer.json file --- .../Command/ConfigRepositoriesAddCommand.php | 101 ++++++++++++++++++ src/Composer/Console/Application.php | 2 +- 2 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 src/Composer/Command/ConfigRepositoriesAddCommand.php diff --git a/src/Composer/Command/ConfigRepositoriesAddCommand.php b/src/Composer/Command/ConfigRepositoriesAddCommand.php new file mode 100644 index 000000000..26cf198ee --- /dev/null +++ b/src/Composer/Command/ConfigRepositoriesAddCommand.php @@ -0,0 +1,101 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Command; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Composer\Factory; +use Composer\Installer; +use Composer\Json\JsonFile; +use Composer\Json\JsonManipulator; + +class ConfigRepositoriesAddCommand extends Command +{ + protected $repositories = array(); + + protected function configure() + { + $this + ->setName('config:repositories:add') + ->setDescription('Add a repository') + ->setDefinition(array( + new InputOption('global', null, InputOption::VALUE_NONE, 'Set this as a global config settings.') + )) + ->setHelp(<<get('home') . '/config.json'); + if (!$globalConfig->exists()) { + touch($globalConfig->getPath()); + $globalConfig->write(array()); + } + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $configFile = $input->getOption('global') + ? (Factory::createConfig()->get('home') . '/config.json') + : 'composer.json'; + + $configFile = new JsonFile($configFile); + + if (count($this->repositories)) { + $config = $configFile->read(); + foreach ($this->repositories as $repo) { + $config['repositories'][] = array( + 'type' => $repo['type'], + 'url' => $repo['url'], + ); + } + $configFile->write($config); + } + } + + protected function interact(InputInterface $input, OutputInterface $output) + { + $dialog = $this->getHelperSet()->get('dialog'); + + /** + * @todo Update this with more info + */ + $output->writeln(array( + '', + 'Add a repository', + '', + )); + + /** + * @todo put this into a loop so user can add many repositories at + * the same time. + */ + $type = $dialog->ask($output, $dialog->getQuestion('Repository Type')); + $repo = $dialog->ask($output, $dialog->getQuestion('Repository URL')); + if (null !== $type && null !== $repo) { + $this->repositories[] = array( + 'type' => $type, + 'url' => $repo, + ); + } + } +} + diff --git a/src/Composer/Console/Application.php b/src/Composer/Console/Application.php index 856ea5583..aee57a865 100755 --- a/src/Composer/Console/Application.php +++ b/src/Composer/Console/Application.php @@ -155,7 +155,7 @@ class Application extends BaseApplication { $commands = parent::getDefaultCommands(); $commands[] = new Command\AboutCommand(); - $commands[] = new Command\ConfigCommand(); + $commands[] = new Command\ConfigRepositoriesAddCommand(); $commands[] = new Command\DependsCommand(); $commands[] = new Command\InitCommand(); $commands[] = new Command\InstallCommand(); From 457d0aac94f8ad76e058c6411c0108cdb0e5181e Mon Sep 17 00:00:00 2001 From: Joshua Estes Date: Mon, 1 Oct 2012 15:27:30 -0500 Subject: [PATCH 04/12] cleaned up and added more comments --- .../Command/ConfigRepositoriesAddCommand.php | 82 +++++++++++++------ 1 file changed, 55 insertions(+), 27 deletions(-) diff --git a/src/Composer/Command/ConfigRepositoriesAddCommand.php b/src/Composer/Command/ConfigRepositoriesAddCommand.php index 26cf198ee..eae0abd24 100644 --- a/src/Composer/Command/ConfigRepositoriesAddCommand.php +++ b/src/Composer/Command/ConfigRepositoriesAddCommand.php @@ -19,47 +19,56 @@ use Symfony\Component\Console\Output\OutputInterface; use Composer\Factory; use Composer\Installer; use Composer\Json\JsonFile; -use Composer\Json\JsonManipulator; class ConfigRepositoriesAddCommand extends Command { + /** + * @var array + */ protected $repositories = array(); + /** + * {@inheritDoc} + */ protected function configure() { + // @todo Make it so the user can pass into this command an array $this ->setName('config:repositories:add') ->setDescription('Add a repository') ->setDefinition(array( - new InputOption('global', null, InputOption::VALUE_NONE, 'Set this as a global config settings.') + new InputOption('global', 'g', InputOption::VALUE_NONE, 'Set this as a global config settings.') )) ->setHelp(<<get('home') . '/config.json'); - if (!$globalConfig->exists()) { - touch($globalConfig->getPath()); - $globalConfig->write(array()); - } - } - + /** + * {@inheritDoc} + */ protected function execute(InputInterface $input, OutputInterface $output) { + // Get the local composer.json or the global config.json $configFile = $input->getOption('global') ? (Factory::createConfig()->get('home') . '/config.json') : 'composer.json'; $configFile = new JsonFile($configFile); - + if (!$configFile->exists()) { + touch($globalConfig->getPath()); + // If you read an empty file, Composer throws an error + $globalConfig->write(array()); + } + + // Make sure we have something to add if (count($this->repositories)) { + // @todo Check and make sure the type/url combo does not + // alredy exist. $config = $configFile->read(); foreach ($this->repositories as $repo) { $config['repositories'][] = array( @@ -67,35 +76,54 @@ EOT 'url' => $repo['url'], ); } + + if ($input->isInteractive()) { + $output->writeln(array( + '', + JsonFile::encode($config), + '', + )); + $dialog = $this->getHelperSet()->get('dialog'); + if (!$dialog->askConfirmation($output, $dialog->getQuestion('Do you want to continuw and save the repositories', 'yes', '?'), true)) { + $output->writeln('Command aborted by the user.'); + return 1; + } + } $configFile->write($config); + } else { + $output->writeln('No repositories have been added.'); } } + /** + * {@inheritDoc} + */ protected function interact(InputInterface $input, OutputInterface $output) { $dialog = $this->getHelperSet()->get('dialog'); - /** - * @todo Update this with more info - */ $output->writeln(array( '', - 'Add a repository', + 'With this command you can add as many repositories to either the', + 'local composer.json file or the global composer config file.', + '', + 'Type can be any of the following: composer, vcs, pear, package', + '', + 'For more information see docs: http://getcomposer.org/doc/05-repositories.md', '', )); - /** - * @todo put this into a loop so user can add many repositories at - * the same time. - */ - $type = $dialog->ask($output, $dialog->getQuestion('Repository Type')); - $repo = $dialog->ask($output, $dialog->getQuestion('Repository URL')); - if (null !== $type && null !== $repo) { + do { + $type = $dialog->ask($output, $dialog->getQuestion('Repository Type')); + $repo = $dialog->ask($output, $dialog->getQuestion('Repository URL')); + if (null === $type && null === $repo) { + break; + } $this->repositories[] = array( 'type' => $type, - 'url' => $repo, + 'url' => $repo, ); - } + } while(true); } } From 6386921f99f08189360faa288548924c14d6ceb1 Mon Sep 17 00:00:00 2001 From: Joshua Estes Date: Tue, 2 Oct 2012 10:42:48 -0500 Subject: [PATCH 05/12] deleted the repository, added a config command that current will just list the config for either file and open vim to edit the file --- src/Composer/Command/ConfigCommand.php | 133 ++++++++++++++++++ .../Command/ConfigRepositoriesAddCommand.php | 129 ----------------- src/Composer/Console/Application.php | 2 +- 3 files changed, 134 insertions(+), 130 deletions(-) create mode 100644 src/Composer/Command/ConfigCommand.php delete mode 100644 src/Composer/Command/ConfigRepositoriesAddCommand.php diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php new file mode 100644 index 000000000..f8f2f1292 --- /dev/null +++ b/src/Composer/Command/ConfigCommand.php @@ -0,0 +1,133 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Command; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Composer\Config; +use Composer\Factory; +use Composer\Json\JsonFile; + +class ConfigCommand extends Command +{ + /** + * @var array + */ + protected $repositories = array(); + + /** + * @var Composer\Json\JsonFile + */ + protected $configFile; + + /** + * {@inheritDoc} + */ + protected function configure() + { + $this + ->setName('config') + ->setDescription('Set config options') + ->setDefinition(array( + new InputOption('global', 'g', InputOption::VALUE_NONE, 'Set this as a global config settings.'), + new InputOption('editor', 'e', InputOption::VALUE_NONE, 'Open editor'), + new InputOption('list', 'l', InputOption::VALUE_NONE, 'List configuration settings'), + // @todo insert argument here + )) + ->setHelp(<<configFile = $input->getOption('global') + ? (Factory::createConfig()->get('home') . '/config.json') + : 'composer.json'; + + $this->configFile = new JsonFile($this->configFile); + if (!$this->configFile->exists()) { + touch($this->configFile->getPath()); + // If you read an empty file, Composer throws an error + // Toss some of the defaults in there + $defaults = Config::$defaultConfig; + $defaults['repositories'] = Config::$defaultRepositories; + $this->configFile->write($defaults); + } + } + + /** + * {@inheritDoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + // Open file in editor + if ($input->getOption('editor')) { + // @todo Find a way to use another editor + $editor = 'vim'; + system($editor . ' ' . $this->configFile->getPath() . ' > `tty`'); + return 0; + } + + // List the configuration of the file settings + if ($input->getOption('list')) { + $this->displayFileContents($this->configFile->read(), $output); + return 0; + } + } + + /** + * {@inheritDoc} + */ + protected function interact(InputInterface $input, OutputInterface $output) + { + } + + /** + * Display the contents of the file in a pretty formatted way + * + * @param array $contents + * @param OutputInterface $output + * @param integer $depth + * @param string|null $k + */ + protected function displayFileContents(array $contents, OutputInterface $output, &$depth = 0, $k = null) + { + // @todo Look into a way to refactor this code, as it is right now, I + // don't like it + foreach ($contents as $key => $value) { + if (is_array($value)) { + $depth++; + $k .= $key . '.'; + $this->displayFileContents($value, $output, $depth, $k); + if (substr_count($k,'.') > 1) { + $k = str_split($k,strrpos($k,'.',-2)); + $k = $k[0] . '.'; + } else { $k = null; } + $depth--; + continue; + } + $output->writeln('[' . $k . $key . '] ' . $value . ''); + } + } +} + + diff --git a/src/Composer/Command/ConfigRepositoriesAddCommand.php b/src/Composer/Command/ConfigRepositoriesAddCommand.php deleted file mode 100644 index eae0abd24..000000000 --- a/src/Composer/Command/ConfigRepositoriesAddCommand.php +++ /dev/null @@ -1,129 +0,0 @@ - - * Jordi Boggiano - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Composer\Command; - -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; -use Composer\Factory; -use Composer\Installer; -use Composer\Json\JsonFile; - -class ConfigRepositoriesAddCommand extends Command -{ - /** - * @var array - */ - protected $repositories = array(); - - /** - * {@inheritDoc} - */ - protected function configure() - { - // @todo Make it so the user can pass into this command an array - $this - ->setName('config:repositories:add') - ->setDescription('Add a repository') - ->setDefinition(array( - new InputOption('global', 'g', InputOption::VALUE_NONE, 'Set this as a global config settings.') - )) - ->setHelp(<<getOption('global') - ? (Factory::createConfig()->get('home') . '/config.json') - : 'composer.json'; - - $configFile = new JsonFile($configFile); - if (!$configFile->exists()) { - touch($globalConfig->getPath()); - // If you read an empty file, Composer throws an error - $globalConfig->write(array()); - } - - // Make sure we have something to add - if (count($this->repositories)) { - // @todo Check and make sure the type/url combo does not - // alredy exist. - $config = $configFile->read(); - foreach ($this->repositories as $repo) { - $config['repositories'][] = array( - 'type' => $repo['type'], - 'url' => $repo['url'], - ); - } - - if ($input->isInteractive()) { - $output->writeln(array( - '', - JsonFile::encode($config), - '', - )); - $dialog = $this->getHelperSet()->get('dialog'); - if (!$dialog->askConfirmation($output, $dialog->getQuestion('Do you want to continuw and save the repositories', 'yes', '?'), true)) { - $output->writeln('Command aborted by the user.'); - return 1; - } - } - $configFile->write($config); - } else { - $output->writeln('No repositories have been added.'); - } - } - - /** - * {@inheritDoc} - */ - protected function interact(InputInterface $input, OutputInterface $output) - { - $dialog = $this->getHelperSet()->get('dialog'); - - $output->writeln(array( - '', - 'With this command you can add as many repositories to either the', - 'local composer.json file or the global composer config file.', - '', - 'Type can be any of the following: composer, vcs, pear, package', - '', - 'For more information see docs: http://getcomposer.org/doc/05-repositories.md', - '', - )); - - do { - $type = $dialog->ask($output, $dialog->getQuestion('Repository Type')); - $repo = $dialog->ask($output, $dialog->getQuestion('Repository URL')); - if (null === $type && null === $repo) { - break; - } - $this->repositories[] = array( - 'type' => $type, - 'url' => $repo, - ); - } while(true); - } -} - diff --git a/src/Composer/Console/Application.php b/src/Composer/Console/Application.php index aee57a865..856ea5583 100755 --- a/src/Composer/Console/Application.php +++ b/src/Composer/Console/Application.php @@ -155,7 +155,7 @@ class Application extends BaseApplication { $commands = parent::getDefaultCommands(); $commands[] = new Command\AboutCommand(); - $commands[] = new Command\ConfigRepositoriesAddCommand(); + $commands[] = new Command\ConfigCommand(); $commands[] = new Command\DependsCommand(); $commands[] = new Command\InitCommand(); $commands[] = new Command\InstallCommand(); From 3c5500aa950c54db75cca1a6d9aec5823060823e Mon Sep 17 00:00:00 2001 From: Joshua Estes Date: Tue, 2 Oct 2012 13:33:08 -0500 Subject: [PATCH 06/12] updated a few things, works a little nicer, but still not yet to the point where it should be --- src/Composer/Command/ConfigCommand.php | 56 ++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php index f8f2f1292..1ccfa8b86 100644 --- a/src/Composer/Command/ConfigCommand.php +++ b/src/Composer/Command/ConfigCommand.php @@ -22,11 +22,6 @@ use Composer\Json\JsonFile; class ConfigCommand extends Command { - /** - * @var array - */ - protected $repositories = array(); - /** * @var Composer\Json\JsonFile */ @@ -44,8 +39,10 @@ class ConfigCommand extends Command new InputOption('global', 'g', InputOption::VALUE_NONE, 'Set this as a global config settings.'), new InputOption('editor', 'e', InputOption::VALUE_NONE, 'Open editor'), new InputOption('list', 'l', InputOption::VALUE_NONE, 'List configuration settings'), - // @todo insert argument here + new InputArgument('setting-key', null, 'Setting key'), + new InputArgument('setting-value', null, 'Setting value'), )) + // @todo Document ->setHelp(<<getOption('editor')) { // @todo Find a way to use another editor - $editor = 'vim'; + $editor = system("bash -cl 'echo \$EDITOR'"); system($editor . ' ' . $this->configFile->getPath() . ' > `tty`'); return 0; } @@ -92,6 +89,28 @@ EOT $this->displayFileContents($this->configFile->read(), $output); return 0; } + + // If the user enters in a config variable, parse it and save to file + if ($input->getArgument('setting-key')) { + if (null === $input->getArgument('setting-value')) { + throw new \RuntimeException('You must include a setting value.'); + } + $setting = $this->parseSetting($input->getArgument('setting-key'), $input->getArgument('setting-value')); + $configSettings = $this->configFile->read(); + $settings = array_merge($configSettings, $setting); + + // Make confirmation + if ($input->isInteractive()) { + $dialog = $this->getHelperSet()->get('dialog'); + $output->writeln(JsonFile::encode($settings)); + if (!$dialog->askConfirmation($output, $dialog->getQuestion('Do you confirm?', 'yes', '?'), true)) { + $output->writeln('Command Aborted by User'); + return 1; + } + } + + $this->configFile->write($settings); + } } /** @@ -112,7 +131,7 @@ EOT protected function displayFileContents(array $contents, OutputInterface $output, &$depth = 0, $k = null) { // @todo Look into a way to refactor this code, as it is right now, I - // don't like it + // don't like it, also the name of the function could be better foreach ($contents as $key => $value) { if (is_array($value)) { $depth++; @@ -128,6 +147,27 @@ EOT $output->writeln('[' . $k . $key . '] ' . $value . ''); } } + + /** + * This function will take a setting key (a.b.c) and return an + * array that matches this + * + * @param string $key + * @param string $value + * @return array + */ + protected function parseSetting($key, $value) + { + $parts = array_reverse(explode('.', $key)); + $tmp = array(); + for($i=0;$i Date: Wed, 3 Oct 2012 08:11:18 -0500 Subject: [PATCH 07/12] updated value argument to be array --- src/Composer/Command/ConfigCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php index 1ccfa8b86..17ee47251 100644 --- a/src/Composer/Command/ConfigCommand.php +++ b/src/Composer/Command/ConfigCommand.php @@ -40,7 +40,7 @@ class ConfigCommand extends Command new InputOption('editor', 'e', InputOption::VALUE_NONE, 'Open editor'), new InputOption('list', 'l', InputOption::VALUE_NONE, 'List configuration settings'), new InputArgument('setting-key', null, 'Setting key'), - new InputArgument('setting-value', null, 'Setting value'), + new InputArgument('setting-value', InputArgument::IS_ARRAY, 'Setting value'), )) // @todo Document ->setHelp(<< Date: Wed, 3 Oct 2012 08:12:04 -0500 Subject: [PATCH 08/12] added a validate schema function to make sure the user does not enter vomit into the config files --- src/Composer/Command/ConfigCommand.php | 37 ++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php index 17ee47251..0370d8f96 100644 --- a/src/Composer/Command/ConfigCommand.php +++ b/src/Composer/Command/ConfigCommand.php @@ -16,9 +16,11 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use JsonSchema\Validator; use Composer\Config; use Composer\Factory; use Composer\Json\JsonFile; +use Composer\Json\JsonValidationException; class ConfigCommand extends Command { @@ -168,6 +170,41 @@ EOT } return $tmp; } + + /** + * After the command sets a new config value, this will parse it writes + * it to disk to make sure that it is valid according the the composer.json + * schema. + * + * @param array $data + * @throws JsonValidationException + * @return boolean + */ + protected function validateSchema(array $data) + { + // @todo Figure out what should be excluded from the validation check + // @todo validation should vary based on if it's global or local + $schemaFile = __DIR__ . '/../../../res/composer-schema.json'; + $schemaData = json_decode(file_get_contents($schemaFile)); + //die(var_dump($schemaData)); + unset( + $schemaData->properties->name, + $schemaData->properties->description + ); + + $validator = new Validator(); + $validator->check(json_decode(json_encode($data)), $schemaData); + + if (!$validator->isValid()) { + $errors = array(); + foreach ((array) $validator->getErrors() as $error) { + $errors[] = ($error['property'] ? $error['property'].' : ' : '').$error['message']; + } + throw new JsonValidationException('"'.$this->configFile->getPath().'" does not match the expected JSON schema'."\n". implode("\n",$errors)); + } + + return true; + } } From 2e34ada3f02a682fadd0848e2754da6ef955c838 Mon Sep 17 00:00:00 2001 From: Joshua Estes Date: Wed, 3 Oct 2012 08:12:39 -0500 Subject: [PATCH 09/12] updated some of the core functionality, only supports process timeout and repositories --- src/Composer/Command/ConfigCommand.php | 48 ++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php index 0370d8f96..5c82040f4 100644 --- a/src/Composer/Command/ConfigCommand.php +++ b/src/Composer/Command/ConfigCommand.php @@ -97,9 +97,51 @@ EOT if (null === $input->getArgument('setting-value')) { throw new \RuntimeException('You must include a setting value.'); } - $setting = $this->parseSetting($input->getArgument('setting-key'), $input->getArgument('setting-value')); - $configSettings = $this->configFile->read(); - $settings = array_merge($configSettings, $setting); + /** + * The user needs the ability to add a repository with one command. + * For example "config -g repository.foo 'vcs http://example.com' + */ + $configSettings = $this->configFile->read(); // what is current in the config + $settings = array(); // This will what will be merged into the above + $values = $input->getArgument('setting-value'); // what the user is trying to add/change + + // Checking for each known config value is going to make this method very large + // what is a better way to do this? + + // repositories.foo + if (preg_match('/^repositories\.(.+)/', $input->getArgument('setting-key'), $matches)) { + if (2 !== count($values)) { + throw new \RuntimeException('You must pass the type and a url. Example: php composer.phar config repositories.foo vcs http://bar.com'); + } + $setting = $this->parseSetting($input->getArgument('setting-key'), array( + 'type' => $values[0], + 'url' => $values[1], + )); + + // Could there be a better way to do this? + $settings = array_merge_recursive($configSettings, $setting); + $this->validateSchema($settings); + } + // process-timeout + elseif (preg_match('/^process-timeout/', $input->getArgument('setting-key'))) { + if (1 !== count($values)) { + throw new \RuntimeException('You can only pass one value. Example: php composer.phar config process-timeout 300'); + } + + if (!is_numeric($values[0])) { + throw new \RuntimeException(sprintf('"%s" is not a number.', $values[0])); + } + + $setting = $this->parseSetting('config.'.$input->getArgument('setting-key'), (integer) $values[0]); + $settings = array_merge($configSettings, $setting); + $this->validateSchema($settings); + } + + // Make sure we have something to write to disk + if (!count($settings)) { + $output->writeln('Trying to update a setting that is supported with this command.'); + return 0; + } // Make confirmation if ($input->isInteractive()) { From ebc67f31910262040d594564f650c53a2549ab13 Mon Sep 17 00:00:00 2001 From: Joshua Estes Date: Wed, 3 Oct 2012 08:23:56 -0500 Subject: [PATCH 10/12] added the ablity to allow users the option of telling where the file they want to edit/update is --- src/Composer/Command/ConfigCommand.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php index 5c82040f4..cc05cd945 100644 --- a/src/Composer/Command/ConfigCommand.php +++ b/src/Composer/Command/ConfigCommand.php @@ -41,6 +41,7 @@ class ConfigCommand extends Command new InputOption('global', 'g', InputOption::VALUE_NONE, 'Set this as a global config settings.'), new InputOption('editor', 'e', InputOption::VALUE_NONE, 'Open editor'), new InputOption('list', 'l', InputOption::VALUE_NONE, 'List configuration settings'), + new InputOption('file', 'f', InputOption::VALUE_REQUIRED, 'If you want to choose a different composer.json or config.json'), new InputArgument('setting-key', null, 'Setting key'), new InputArgument('setting-value', InputArgument::IS_ARRAY, 'Setting value'), )) @@ -57,10 +58,17 @@ EOT */ protected function initialize(InputInterface $input, OutputInterface $output) { - // Get the local composer.json or the global config.json + if ($input->getOption('global') && $input->getOption('file')) { + throw new \RuntimeException('Cannot use both, you must pick to edit either the global config or path to composer.json'); + } + + // Get the local composer.json, global config.json, or if the user + // passed in a file to use $this->configFile = $input->getOption('global') ? (Factory::createConfig()->get('home') . '/config.json') - : 'composer.json'; + : (null !== $input->getOption('file') + ? $input->getOption('file') + : 'composer.json'); $this->configFile = new JsonFile($this->configFile); if (!$this->configFile->exists()) { From 41bc8fd1b62c7d9884a2642482698b26602df43c Mon Sep 17 00:00:00 2001 From: Joshua Estes Date: Wed, 3 Oct 2012 08:38:29 -0500 Subject: [PATCH 11/12] updated the help for the command --- src/Composer/Command/ConfigCommand.php | 34 +++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php index cc05cd945..9dbb6cea2 100644 --- a/src/Composer/Command/ConfigCommand.php +++ b/src/Composer/Command/ConfigCommand.php @@ -45,8 +45,40 @@ class ConfigCommand extends Command new InputArgument('setting-key', null, 'Setting key'), new InputArgument('setting-value', InputArgument::IS_ARRAY, 'Setting value'), )) - // @todo Document ->setHelp(<<USAGE: + +To edit the global config.json file: + + php composer.phar --global + +To add a repository: + + php composer.phar repositories.foo vcs http://bar.com + +You can add a repository to the global config.json file by passing in the +--global option. + +If you want to launch your editor with the composer.json file you must have +\$EDITOR set. + + php composer.phar --edit + +To get a list of configuration values in the file, pass the --list option. + + php composer.phar --list + +You can always pass more than one option. As an example, if you want to edit the +global config.json file. + + php composer.phar --edit --global + +LIMITATIONS + +The command only supports repositories and process-timeout right now. EOT ) From 74c344ffe44ae4b3b243ab32cf895b4ed1d390e2 Mon Sep 17 00:00:00 2001 From: Joshua Estes Date: Wed, 3 Oct 2012 08:41:07 -0500 Subject: [PATCH 12/12] bug fix --- src/Composer/Command/ConfigCommand.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Composer/Command/ConfigCommand.php b/src/Composer/Command/ConfigCommand.php index 9dbb6cea2..114954606 100644 --- a/src/Composer/Command/ConfigCommand.php +++ b/src/Composer/Command/ConfigCommand.php @@ -60,10 +60,9 @@ To add a repository: php composer.phar repositories.foo vcs http://bar.com You can add a repository to the global config.json file by passing in the ---global option. +--global option. -If you want to launch your editor with the composer.json file you must have -\$EDITOR set. +If you want to launch your editor with the composer.json file you must have "EDITOR" set. php composer.phar --edit