Fix config/create-project handling of repositories to prepend them by default as this is most likely the goal, fixes #9371

main
Jordi Boggiano 4 years ago
parent ffc0f86fc0
commit f2f3b03fec
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC

@ -75,6 +75,7 @@ class ConfigCommand extends BaseCommand
new InputOption('absolute', null, InputOption::VALUE_NONE, 'Returns absolute paths when fetching *-dir config values instead of relative'), new InputOption('absolute', null, InputOption::VALUE_NONE, 'Returns absolute paths when fetching *-dir config values instead of relative'),
new InputOption('json', 'j', InputOption::VALUE_NONE, 'JSON decode the setting value, to be used with extra.* keys'), new InputOption('json', 'j', InputOption::VALUE_NONE, 'JSON decode the setting value, to be used with extra.* keys'),
new InputOption('merge', 'm', InputOption::VALUE_NONE, 'Merge the setting value with the current value, to be used with extra.* keys in combination with --json'), new InputOption('merge', 'm', InputOption::VALUE_NONE, 'Merge the setting value with the current value, to be used with extra.* keys in combination with --json'),
new InputOption('append', null, InputOption::VALUE_NONE, 'When adding a repository, append it (lowest priority) to the existing ones instead of prepending it (highest priority)'),
new InputArgument('setting-key', null, 'Setting key'), new InputArgument('setting-key', null, 'Setting key'),
new InputArgument('setting-value', InputArgument::IS_ARRAY, 'Setting value'), new InputArgument('setting-value', InputArgument::IS_ARRAY, 'Setting value'),
)) ))
@ -596,7 +597,7 @@ EOT
$this->configSource->addRepository($matches[1], array( $this->configSource->addRepository($matches[1], array(
'type' => $values[0], 'type' => $values[0],
'url' => $values[1], 'url' => $values[1],
)); ), $input->getOption('append'));
return 0; return 0;
} }
@ -605,13 +606,13 @@ EOT
$value = strtolower($values[0]); $value = strtolower($values[0]);
if (true === $booleanValidator($value)) { if (true === $booleanValidator($value)) {
if (false === $booleanNormalizer($value)) { if (false === $booleanNormalizer($value)) {
$this->configSource->addRepository($matches[1], false); $this->configSource->addRepository($matches[1], false, $input->getOption('append'));
return 0; return 0;
} }
} else { } else {
$value = JsonFile::parseJson($values[0]); $value = JsonFile::parseJson($values[0]);
$this->configSource->addRepository($matches[1], $value); $this->configSource->addRepository($matches[1], $value, $input->getOption('append'));
return 0; return 0;
} }

@ -199,7 +199,7 @@ EOT
) { ) {
$configSource->addRepository('packagist.org', false); $configSource->addRepository('packagist.org', false);
} else { } else {
$configSource->addRepository($name, $repoConfig); $configSource->addRepository($name, $repoConfig, false);
} }
$composer = Factory::create($io, null, $disablePlugins); $composer = Factory::create($io, null, $disablePlugins);

@ -26,7 +26,7 @@ interface ConfigSourceInterface
* @param string $name Name * @param string $name Name
* @param array|false $config Configuration * @param array|false $config Configuration
*/ */
public function addRepository($name, $config); public function addRepository($name, $config/* , $append = true */);
/** /**
* Remove a repository * Remove a repository

@ -57,9 +57,9 @@ class JsonConfigSource implements ConfigSourceInterface
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function addRepository($name, $config) public function addRepository($name, $config, $append = true)
{ {
$this->manipulateJson('addRepository', $name, $config, function (&$config, $repo, $repoConfig) { $this->manipulateJson('addRepository', $name, $config, $append, function (&$config, $repo, $repoConfig) use ($append) {
// if converting from an array format to hashmap format, and there is a {"packagist.org":false} repo, we have // if converting from an array format to hashmap format, and there is a {"packagist.org":false} repo, we have
// to convert it to "packagist.org": false key on the hashmap otherwise it fails schema validation // to convert it to "packagist.org": false key on the hashmap otherwise it fails schema validation
if (isset($config['repositories'])) { if (isset($config['repositories'])) {
@ -75,7 +75,11 @@ class JsonConfigSource implements ConfigSourceInterface
} }
} }
$config['repositories'][$repo] = $repoConfig; if ($append) {
$config['repositories'][$repo] = $repoConfig;
} else {
$config['repositories'] = array($repo => $repoConfig) + $config['repositories'];
}
}); });
} }

@ -145,9 +145,9 @@ class JsonManipulator
}); });
} }
public function addRepository($name, $config) public function addRepository($name, $config, $append = true)
{ {
return $this->addSubNode('repositories', $name, $config); return $this->addSubNode('repositories', $name, $config, $append);
} }
public function removeRepository($name) public function removeRepository($name)
@ -199,7 +199,7 @@ class JsonManipulator
return $this->removeMainKey($name); return $this->removeMainKey($name);
} }
public function addSubNode($mainNode, $name, $value) public function addSubNode($mainNode, $name, $value, $append = true)
{ {
$decoded = JsonFile::parseJson($this->contents); $decoded = JsonFile::parseJson($this->contents);
@ -258,7 +258,7 @@ class JsonManipulator
return $matches['start'] . $that->format($value, 1) . $matches['end']; return $matches['start'] . $that->format($value, 1) . $matches['end'];
}, $children); }, $children);
} else { } else {
$this->pregMatch('#^{ \s*? (?P<content>\S+.*?)? (?P<trailingspace>\s*) }$#sx', $children, $match); $this->pregMatch('#^{ (?P<leadingspace>\s*?) (?P<content>\S+.*?)? (?P<trailingspace>\s*) }$#sx', $children, $match);
$whitespace = ''; $whitespace = '';
if (!empty($match['trailingspace'])) { if (!empty($match['trailingspace'])) {
@ -271,11 +271,24 @@ class JsonManipulator
} }
// child missing but non empty children // child missing but non empty children
$children = preg_replace( if ($append) {
'#'.$whitespace.'}$#', $children = preg_replace(
addcslashes(',' . $this->newline . $this->indent . $this->indent . JsonFile::encode($name).': '.$this->format($value, 1) . $whitespace . '}', '\\$'), '#'.$whitespace.'}$#',
$children addcslashes(',' . $this->newline . $this->indent . $this->indent . JsonFile::encode($name).': '.$this->format($value, 1) . $whitespace . '}', '\\$'),
); $children
);
} else {
$whitespace = '';
if (!empty($match['leadingspace'])) {
$whitespace = $match['leadingspace'];
}
$children = preg_replace(
'#^{'.$whitespace.'#',
addcslashes('{' . $whitespace . JsonFile::encode($name).': '.$this->format($value, 1) . ',' . $this->newline . $this->indent . $this->indent, '\\$'),
$children
);
}
} else { } else {
if ($subName !== null) { if ($subName !== null) {
$value = array($subName => $value); $value = array($subName => $value);

@ -1935,7 +1935,7 @@ class JsonManipulatorTest extends TestCase
", $manipulator->getContents()); ", $manipulator->getContents());
} }
public function testAddRepositoryCanAdd() public function testAddRepositoryCanAppend()
{ {
$manipulator = new JsonManipulator('{ $manipulator = new JsonManipulator('{
"repositories": { "repositories": {
@ -1946,7 +1946,7 @@ class JsonManipulatorTest extends TestCase
} }
}'); }');
$this->assertTrue($manipulator->addRepository('bar', array('type' => 'composer'))); $this->assertTrue($manipulator->addRepository('bar', array('type' => 'composer'), true));
$this->assertEquals('{ $this->assertEquals('{
"repositories": { "repositories": {
"foo": { "foo": {
@ -1961,6 +1961,32 @@ class JsonManipulatorTest extends TestCase
', $manipulator->getContents()); ', $manipulator->getContents());
} }
public function testAddRepositoryCanPrepend()
{
$manipulator = new JsonManipulator('{
"repositories": {
"foo": {
"type": "vcs",
"url": "lala"
}
}
}');
$this->assertTrue($manipulator->addRepository('bar', array('type' => 'composer'), false));
$this->assertEquals('{
"repositories": {
"bar": {
"type": "composer"
},
"foo": {
"type": "vcs",
"url": "lala"
}
}
}
', $manipulator->getContents());
}
public function testAddRepositoryCanOverrideDeepRepos() public function testAddRepositoryCanOverrideDeepRepos()
{ {
$manipulator = new JsonManipulator('{ $manipulator = new JsonManipulator('{

Loading…
Cancel
Save