Merge branch 'master' into 2.0
commit
411dd51f20
|
@ -21,6 +21,11 @@ If your issue involves installing, updating or resolving dependencies, the
|
|||
chance of us being able to reproduce your issue will be much higher if you
|
||||
share your `composer.json` with us.
|
||||
|
||||
Coding Style Fixes
|
||||
------------------
|
||||
|
||||
We do not accept CS fixes pull requests. Fixes are done by the project maintainers when appropriate to avoid causing too many unnecessary conflicts between branches and pull requests.
|
||||
|
||||
Security Reports
|
||||
----------------
|
||||
|
||||
|
|
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -1,3 +1,16 @@
|
|||
### [1.8.0] 2018-12-03
|
||||
|
||||
* Changed `post-package-install` / `post-package-update` event to be fired *after* the lock file has been updated as opposed to before
|
||||
* Added support for removing packages using a wildcard with the `remove` command, e.g. `composer remove foo/*`
|
||||
* Added `chat` to the list of `support` channels you can list in composer.json
|
||||
* Added signal handling on require command to restore the composer.json in case of abort
|
||||
* Added `--ignore` to `outdated` command to pass one or more packages that you do not want to be listed
|
||||
* Added `--no-dev` to `check-platform-reqs` command to skip dev requirements even if they are installed
|
||||
* Added support for running plugin commands from sub-directories within a project much like other Composer commands
|
||||
* Added support for running Composer via phpdbg
|
||||
* Added `lib-imagick` platform package
|
||||
* Fixed validate command always checking for disabled checks when used with `--strict`
|
||||
|
||||
### [1.7.3] 2018-11-01
|
||||
|
||||
* Fixed handling of replace/conflict rules. This may affect dependency resolution in some edge cases.
|
||||
|
@ -696,6 +709,7 @@
|
|||
|
||||
* Initial release
|
||||
|
||||
[1.8.0]: https://github.com/composer/composer/compare/1.7.3...1.8.0
|
||||
[1.7.3]: https://github.com/composer/composer/compare/1.7.2...1.7.3
|
||||
[1.7.2]: https://github.com/composer/composer/compare/1.7.1...1.7.2
|
||||
[1.7.1]: https://github.com/composer/composer/compare/1.7.0...1.7.1
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
if (PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg') {
|
||||
echo 'Warning: Composer should be invoked via the CLI version of PHP, not the '.PHP_SAPI.' SAPI'.PHP_EOL;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.8-dev"
|
||||
"dev-master": "1.9-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
|
@ -126,16 +126,16 @@
|
|||
},
|
||||
{
|
||||
"name": "composer/spdx-licenses",
|
||||
"version": "1.4.0",
|
||||
"version": "1.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/spdx-licenses.git",
|
||||
"reference": "cb17687e9f936acd7e7245ad3890f953770dec1b"
|
||||
"reference": "7a9556b22bd9d4df7cad89876b00af58ef20d3a2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/spdx-licenses/zipball/cb17687e9f936acd7e7245ad3890f953770dec1b",
|
||||
"reference": "cb17687e9f936acd7e7245ad3890f953770dec1b",
|
||||
"url": "https://api.github.com/repos/composer/spdx-licenses/zipball/7a9556b22bd9d4df7cad89876b00af58ef20d3a2",
|
||||
"reference": "7a9556b22bd9d4df7cad89876b00af58ef20d3a2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -183,20 +183,20 @@
|
|||
"spdx",
|
||||
"validator"
|
||||
],
|
||||
"time": "2018-04-30T10:33:04+00:00"
|
||||
"time": "2018-11-01T09:45:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/xdebug-handler",
|
||||
"version": "1.3.0",
|
||||
"version": "1.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/xdebug-handler.git",
|
||||
"reference": "b8e9745fb9b06ea6664d8872c4505fb16df4611c"
|
||||
"reference": "dc523135366eb68f22268d069ea7749486458562"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/xdebug-handler/zipball/b8e9745fb9b06ea6664d8872c4505fb16df4611c",
|
||||
"reference": "b8e9745fb9b06ea6664d8872c4505fb16df4611c",
|
||||
"url": "https://api.github.com/repos/composer/xdebug-handler/zipball/dc523135366eb68f22268d069ea7749486458562",
|
||||
"reference": "dc523135366eb68f22268d069ea7749486458562",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -227,7 +227,7 @@
|
|||
"Xdebug",
|
||||
"performance"
|
||||
],
|
||||
"time": "2018-08-31T19:20:00+00:00"
|
||||
"time": "2018-11-29T10:59:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "justinrainbow/json-schema",
|
||||
|
@ -297,16 +297,16 @@
|
|||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
"version": "1.0.2",
|
||||
"version": "1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/log.git",
|
||||
"reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
|
||||
"reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
|
||||
"reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
|
||||
"reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -340,7 +340,7 @@
|
|||
"psr",
|
||||
"psr-3"
|
||||
],
|
||||
"time": "2016-10-10T12:19:37+00:00"
|
||||
"time": "2018-11-20T15:27:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "seld/jsonlint",
|
||||
|
@ -437,16 +437,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v2.8.45",
|
||||
"version": "v2.8.48",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "0c1fcbb9afb5cff992c982ff99c0434f0146dcfc"
|
||||
"reference": "cbcf4b5e233af15cd2bbd50dee1ccc9b7927dc12"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/0c1fcbb9afb5cff992c982ff99c0434f0146dcfc",
|
||||
"reference": "0c1fcbb9afb5cff992c982ff99c0434f0146dcfc",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/cbcf4b5e233af15cd2bbd50dee1ccc9b7927dc12",
|
||||
"reference": "cbcf4b5e233af15cd2bbd50dee1ccc9b7927dc12",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -494,20 +494,20 @@
|
|||
],
|
||||
"description": "Symfony Console Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T11:13:39+00:00"
|
||||
"time": "2018-11-20T15:55:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/debug",
|
||||
"version": "v2.8.45",
|
||||
"version": "v2.8.48",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/debug.git",
|
||||
"reference": "cbb8a5f212148964efbc414838c527229f9951b7"
|
||||
"reference": "74251c8d50dd3be7c4ce0c7b862497cdc641a5d0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/debug/zipball/cbb8a5f212148964efbc414838c527229f9951b7",
|
||||
"reference": "cbb8a5f212148964efbc414838c527229f9951b7",
|
||||
"url": "https://api.github.com/repos/symfony/debug/zipball/74251c8d50dd3be7c4ce0c7b862497cdc641a5d0",
|
||||
"reference": "74251c8d50dd3be7c4ce0c7b862497cdc641a5d0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -551,20 +551,20 @@
|
|||
],
|
||||
"description": "Symfony Debug Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-08-03T09:45:57+00:00"
|
||||
"time": "2018-11-11T11:18:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v2.8.45",
|
||||
"version": "v2.8.48",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/filesystem.git",
|
||||
"reference": "0b252f4e25b7da17abb5a98eb60755b71d082c9c"
|
||||
"reference": "7ae46872dad09dffb7fe1e93a0937097339d0080"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/0b252f4e25b7da17abb5a98eb60755b71d082c9c",
|
||||
"reference": "0b252f4e25b7da17abb5a98eb60755b71d082c9c",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/7ae46872dad09dffb7fe1e93a0937097339d0080",
|
||||
"reference": "7ae46872dad09dffb7fe1e93a0937097339d0080",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -601,20 +601,20 @@
|
|||
],
|
||||
"description": "Symfony Filesystem Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-08-07T09:12:42+00:00"
|
||||
"time": "2018-11-11T11:18:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v2.8.45",
|
||||
"version": "v2.8.48",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "f0de0b51913eb2caab7dfed6413b87e14fca780e"
|
||||
"reference": "1444eac52273e345d9b95129bf914639305a9ba4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/f0de0b51913eb2caab7dfed6413b87e14fca780e",
|
||||
"reference": "f0de0b51913eb2caab7dfed6413b87e14fca780e",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/1444eac52273e345d9b95129bf914639305a9ba4",
|
||||
"reference": "1444eac52273e345d9b95129bf914639305a9ba4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -650,11 +650,11 @@
|
|||
],
|
||||
"description": "Symfony Finder Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T11:13:39+00:00"
|
||||
"time": "2018-11-11T11:18:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.9.0",
|
||||
"version": "v1.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
|
@ -712,16 +712,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.9.0",
|
||||
"version": "v1.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8"
|
||||
"reference": "c79c051f5b3a46be09205c73b80b346e4153e494"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8",
|
||||
"reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494",
|
||||
"reference": "c79c051f5b3a46be09205c73b80b346e4153e494",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -767,20 +767,20 @@
|
|||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2018-08-06T14:22:27+00:00"
|
||||
"time": "2018-09-21T13:07:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v2.8.45",
|
||||
"version": "v2.8.48",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "4be278e19064c3492095de50c9e375caae569ae1"
|
||||
"reference": "c3591a09c78639822b0b290d44edb69bf9f05dc8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/4be278e19064c3492095de50c9e375caae569ae1",
|
||||
"reference": "4be278e19064c3492095de50c9e375caae569ae1",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/c3591a09c78639822b0b290d44edb69bf9f05dc8",
|
||||
"reference": "c3591a09c78639822b0b290d44edb69bf9f05dc8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -816,7 +816,7 @@
|
|||
],
|
||||
"description": "Symfony Process Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-08-03T09:45:57+00:00"
|
||||
"time": "2018-11-11T11:18:13+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
@ -1736,16 +1736,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v2.8.45",
|
||||
"version": "v2.8.48",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
"reference": "fbf876678e29dc634430dcf0096e216eb0004467"
|
||||
"reference": "02c1859112aa779d9ab394ae4f3381911d84052b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/fbf876678e29dc634430dcf0096e216eb0004467",
|
||||
"reference": "fbf876678e29dc634430dcf0096e216eb0004467",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/02c1859112aa779d9ab394ae4f3381911d84052b",
|
||||
"reference": "02c1859112aa779d9ab394ae4f3381911d84052b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1782,7 +1782,7 @@
|
|||
],
|
||||
"description": "Symfony Yaml Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2018-07-26T09:03:18+00:00"
|
||||
"time": "2018-11-11T11:18:13+00:00"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
|
|
|
@ -243,6 +243,7 @@ Support information includes the following:
|
|||
* **source:** URL to browse or download the sources.
|
||||
* **docs:** URL to the documentation.
|
||||
* **rss:** URL to the RSS feed.
|
||||
* **chat:** URL to the chat channel.
|
||||
|
||||
An example:
|
||||
|
||||
|
|
|
@ -238,6 +238,17 @@ one by prefixing the command name with `@`:
|
|||
}
|
||||
```
|
||||
|
||||
You can also refer a script and pass it new arguments:
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"tests": "phpunit",
|
||||
"testsVerbose": "@tests -vvv"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Calling Composer commands
|
||||
|
||||
To call Composer commands, you can use `@composer` which will automatically
|
||||
|
|
|
@ -490,6 +490,11 @@
|
|||
"description": "IRC channel for support, as irc://server/channel.",
|
||||
"format": "uri"
|
||||
},
|
||||
"chat": {
|
||||
"type": "string",
|
||||
"description": "URL to the support chat.",
|
||||
"format": "uri"
|
||||
},
|
||||
"source": {
|
||||
"type": "string",
|
||||
"description": "URL to browse or download the sources.",
|
||||
|
|
|
@ -22,6 +22,7 @@ use Composer\Repository\PlatformRepository;
|
|||
use Composer\Repository\RepositoryFactory;
|
||||
use Composer\Repository\RepositorySet;
|
||||
use Composer\Util\ProcessExecutor;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
@ -145,6 +146,11 @@ EOT
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
$question = 'Would you like to install dependencies now [<comment>yes</comment>]? ';
|
||||
if ($input->isInteractive() && $this->hasDependencies($options) && $io->askConfirmation($question, true)) {
|
||||
$this->installDependencies($output);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -208,7 +214,7 @@ EOT
|
|||
}
|
||||
$name = strtolower($name);
|
||||
} else {
|
||||
if (!preg_match('{^[a-z0-9_.-]+/[a-z0-9_.-]+$}', $name)) {
|
||||
if (!preg_match('{^[a-z0-9_.-]+/[a-z0-9_.-]+$}D', $name)) {
|
||||
throw new \InvalidArgumentException(
|
||||
'The package name '.$name.' is invalid, it should be lowercase and have a vendor name, a forward slash, and a package name, matching: [a-z0-9_.-]+/[a-z0-9_.-]+'
|
||||
);
|
||||
|
@ -222,7 +228,7 @@ EOT
|
|||
return $name;
|
||||
}
|
||||
|
||||
if (!preg_match('{^[a-z0-9_.-]+/[a-z0-9_.-]+$}', $value)) {
|
||||
if (!preg_match('{^[a-z0-9_.-]+/[a-z0-9_.-]+$}D', $value)) {
|
||||
throw new \InvalidArgumentException(
|
||||
'The package name '.$value.' is invalid, it should be lowercase and have a vendor name, a forward slash, and a package name, matching: [a-z0-9_.-]+/[a-z0-9_.-]+'
|
||||
);
|
||||
|
@ -381,7 +387,7 @@ EOT
|
|||
return $this->repos;
|
||||
}
|
||||
|
||||
protected function determineRequirements(InputInterface $input, OutputInterface $output, $requires = array(), $phpVersion = null, $preferredStability = 'stable')
|
||||
protected function determineRequirements(InputInterface $input, OutputInterface $output, $requires = array(), $phpVersion = null, $preferredStability = 'stable', $checkProvidedVersions = true)
|
||||
{
|
||||
if ($requires) {
|
||||
$requires = $this->normalizeRequirements($requires);
|
||||
|
@ -404,7 +410,7 @@ EOT
|
|||
));
|
||||
} else {
|
||||
// check that the specified version/constraint exists before we proceed
|
||||
list($name, $version) = $this->findBestVersionAndNameForPackage($input, $requirement['name'], $phpVersion, $preferredStability, $requirement['version'], 'dev');
|
||||
list($name, $version) = $this->findBestVersionAndNameForPackage($input, $requirement['name'], $phpVersion, $preferredStability, $checkProvidedVersions ? $requirement['version'] : null, 'dev');
|
||||
|
||||
// replace package name from packagist.org
|
||||
$requirement['name'] = $name;
|
||||
|
@ -767,4 +773,23 @@ EOT
|
|||
|
||||
return array_keys(array_slice($similarPackages, 0, 5));
|
||||
}
|
||||
|
||||
private function installDependencies($output)
|
||||
{
|
||||
try {
|
||||
$installCommand = $this->getApplication()->find('install');
|
||||
$installCommand->run(new ArrayInput(array()), $output);
|
||||
} catch (\Exception $e) {
|
||||
$this->getIO()->writeError('Could not install dependencies. Run `composer install` to see more information.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function hasDependencies($options)
|
||||
{
|
||||
$requires = (array) $options['require'];
|
||||
$devRequires = isset($options['require-dev']) ? (array) $options['require-dev'] : array();
|
||||
|
||||
return !empty($requires) || !empty($devRequires);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ use Symfony\Component\Console\Input\InputInterface;
|
|||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Composer\Package\BasePackage;
|
||||
|
||||
/**
|
||||
* @author Pierre du Plessis <pdples@gmail.com>
|
||||
|
@ -94,12 +95,25 @@ EOT
|
|||
if (isset($composer[$type][$package])) {
|
||||
$json->removeLink($type, $composer[$type][$package]);
|
||||
} elseif (isset($composer[$altType][$package])) {
|
||||
$io->writeError('<warning>'.$composer[$altType][$package].' could not be found in '.$type.' but it is present in '.$altType.'</warning>');
|
||||
$io->writeError('<warning>' . $composer[$altType][$package] . ' could not be found in ' . $type . ' but it is present in ' . $altType . '</warning>');
|
||||
if ($io->isInteractive()) {
|
||||
if ($io->askConfirmation('Do you want to remove it from '.$altType.' [<comment>yes</comment>]? ', true)) {
|
||||
if ($io->askConfirmation('Do you want to remove it from ' . $altType . ' [<comment>yes</comment>]? ', true)) {
|
||||
$json->removeLink($altType, $composer[$altType][$package]);
|
||||
}
|
||||
}
|
||||
} elseif (isset($composer[$type]) && $matches = preg_grep(BasePackage::packageNameToRegexp($package), array_keys($composer[$type]))) {
|
||||
foreach ($matches as $matchedPackage) {
|
||||
$json->removeLink($type, $matchedPackage);
|
||||
}
|
||||
} elseif (isset($composer[$altType]) && $matches = preg_grep(BasePackage::packageNameToRegexp($package), array_keys($composer[$altType]))) {
|
||||
foreach ($matches as $matchedPackage) {
|
||||
$io->writeError('<warning>' . $matchedPackage . ' could not be found in ' . $type . ' but it is present in ' . $altType . '</warning>');
|
||||
if ($io->isInteractive()) {
|
||||
if ($io->askConfirmation('Do you want to remove it from ' . $altType . ' [<comment>yes</comment>]? ', true)) {
|
||||
$json->removeLink($altType, $matchedPackage);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$io->writeError('<warning>'.$package.' is not required in your composer.json and has not been removed</warning>');
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ class RequireCommand extends InitCommand
|
|||
<<<EOT
|
||||
The require command adds required packages to your composer.json and installs them.
|
||||
|
||||
If you do not specify a package, composer will prompt you to search for a package, and given results, provide a list of
|
||||
If you do not specify a package, composer will prompt you to search for a package, and given results, provide a list of
|
||||
matches to require.
|
||||
|
||||
If you do not specify a version constraint, composer will choose a suitable one based on the available package versions.
|
||||
|
@ -131,7 +131,7 @@ EOT
|
|||
}
|
||||
|
||||
$phpVersion = $this->repos->findPackage('php', '*')->getPrettyVersion();
|
||||
$requirements = $this->determineRequirements($input, $output, $input->getArgument('packages'), $phpVersion, $preferredStability);
|
||||
$requirements = $this->determineRequirements($input, $output, $input->getArgument('packages'), $phpVersion, $preferredStability, !$input->getOption('no-update'));
|
||||
|
||||
$requireKey = $input->getOption('dev') ? 'require-dev' : 'require';
|
||||
$removeKey = $input->getOption('dev') ? 'require' : 'require-dev';
|
||||
|
|
|
@ -95,9 +95,10 @@ EOT
|
|||
$lockErrors[] = 'The lock file is not up to date with the latest changes in composer.json, it is recommended that you run `composer update`.';
|
||||
}
|
||||
|
||||
$this->outputResult($io, $file, $errors, $warnings, $checkPublish, $publishErrors, $checkLock, $lockErrors, true);
|
||||
$this->outputResult($io, $file, $errors, $warnings, $checkPublish, $publishErrors, $checkLock, $lockErrors, true, $isStrict);
|
||||
|
||||
$exitCode = $errors || ($publishErrors && $checkPublish) || ($lockErrors && $checkLock) ? 2 : ($isStrict && $warnings ? 1 : 0);
|
||||
// $errors include publish and lock errors when exists
|
||||
$exitCode = $errors ? 2 : ($isStrict && $warnings ? 1 : 0);
|
||||
|
||||
if ($input->getOption('with-dependencies')) {
|
||||
$localRepo = $composer->getRepositoryManager()->getLocalRepository();
|
||||
|
@ -108,7 +109,7 @@ EOT
|
|||
list($errors, $publishErrors, $warnings) = $validator->validate($file, $checkAll);
|
||||
$this->outputResult($io, $package->getPrettyName(), $errors, $warnings, $checkPublish, $publishErrors);
|
||||
|
||||
$depCode = $errors || ($publishErrors && $checkPublish) ? 2 : ($isStrict && $warnings ? 1 : 0);
|
||||
$depCode = $errors ? 2 : ($isStrict && $warnings ? 1 : 0);
|
||||
$exitCode = max($depCode, $exitCode);
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +122,7 @@ EOT
|
|||
return $exitCode;
|
||||
}
|
||||
|
||||
private function outputResult($io, $name, &$errors, &$warnings, $checkPublish = false, $publishErrors = array(), $checkLock = false, $lockErrors = array(), $printSchemaUrl = false)
|
||||
private function outputResult($io, $name, &$errors, &$warnings, $checkPublish = false, $publishErrors = array(), $checkLock = false, $lockErrors = array(), $printSchemaUrl = false, $isStrict = false)
|
||||
{
|
||||
if (!$errors && !$publishErrors && !$warnings) {
|
||||
$io->write('<info>' . $name . ' is valid</info>');
|
||||
|
@ -141,16 +142,18 @@ EOT
|
|||
}
|
||||
|
||||
// If checking publish errors, display them as errors, otherwise just show them as warnings
|
||||
// Skip when it is a strict check and we don't want to check publish errors
|
||||
if ($checkPublish) {
|
||||
$errors = array_merge($errors, $publishErrors);
|
||||
} else {
|
||||
} elseif (!$isStrict) {
|
||||
$warnings = array_merge($warnings, $publishErrors);
|
||||
}
|
||||
|
||||
// If checking lock errors, display them as errors, otherwise just show them as warnings
|
||||
// Skip when it is a strict check and we don't want to check lock errors
|
||||
if ($checkLock) {
|
||||
$errors = array_merge($errors, $lockErrors);
|
||||
} else {
|
||||
} elseif (!$isStrict) {
|
||||
$warnings = array_merge($warnings, $lockErrors);
|
||||
}
|
||||
|
||||
|
|
|
@ -176,8 +176,12 @@ class EventDispatcher
|
|||
$return = false === call_user_func($callable, $event) ? 1 : 0;
|
||||
} elseif ($this->isComposerScript($callable)) {
|
||||
$this->io->writeError(sprintf('> %s: %s', $event->getName(), $callable), true, IOInterface::VERBOSE);
|
||||
$scriptName = substr($callable, 1);
|
||||
$args = $event->getArguments();
|
||||
|
||||
$script = explode(' ', substr($callable, 1));
|
||||
$scriptName = $script[0];
|
||||
unset($script[0]);
|
||||
|
||||
$args = array_merge($script, $event->getArguments());
|
||||
$flags = $event->getFlags();
|
||||
if (substr($callable, 0, 10) === '@composer ') {
|
||||
$exec = $this->getPhpExecCommand() . ' ' . ProcessExecutor::escape(getenv('COMPOSER_BINARY')) . substr($callable, 9);
|
||||
|
@ -262,16 +266,17 @@ class EventDispatcher
|
|||
protected function getPhpExecCommand()
|
||||
{
|
||||
$finder = new PhpExecutableFinder();
|
||||
$phpPath = $finder->find();
|
||||
$phpPath = $finder->find(false);
|
||||
if (!$phpPath) {
|
||||
throw new \RuntimeException('Failed to locate PHP binary to execute '.$phpPath);
|
||||
}
|
||||
|
||||
$phpArgs = $finder->findArguments();
|
||||
$phpArgs = $phpArgs ? ' ' . implode(' ', $phpArgs) : '';
|
||||
$allowUrlFOpenFlag = ' -d allow_url_fopen=' . ProcessExecutor::escape(ini_get('allow_url_fopen'));
|
||||
$disableFunctionsFlag = ' -d disable_functions=' . ProcessExecutor::escape(ini_get('disable_functions'));
|
||||
$memoryLimitFlag = ' -d memory_limit=' . ProcessExecutor::escape(ini_get('memory_limit'));
|
||||
|
||||
return ProcessExecutor::escape($phpPath) . $allowUrlFOpenFlag . $disableFunctionsFlag . $memoryLimitFlag;
|
||||
return ProcessExecutor::escape($phpPath) . $phpArgs . $allowUrlFOpenFlag . $disableFunctionsFlag . $memoryLimitFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,6 +33,7 @@ use Composer\Installer\NoopInstaller;
|
|||
use Composer\Installer\SuggestedPackagesReporter;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Package\AliasPackage;
|
||||
use Composer\Package\BasePackage;
|
||||
use Composer\Package\CompletePackage;
|
||||
use Composer\Package\Link;
|
||||
use Composer\Package\Loader\ArrayLoader;
|
||||
|
@ -1247,7 +1248,7 @@ class Installer
|
|||
}
|
||||
|
||||
foreach ($this->updateWhitelist as $whiteListedPattern => $void) {
|
||||
$patternRegexp = $this->packageNameToRegexp($whiteListedPattern);
|
||||
$patternRegexp = BasePackage::packageNameToRegexp($whiteListedPattern);
|
||||
if (preg_match($patternRegexp, $package->getName())) {
|
||||
return true;
|
||||
}
|
||||
|
@ -1256,19 +1257,6 @@ class Installer
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a regexp from a package name, expanding * globs as required
|
||||
*
|
||||
* @param string $whiteListedPattern
|
||||
* @return string
|
||||
*/
|
||||
private function packageNameToRegexp($whiteListedPattern)
|
||||
{
|
||||
$cleanedWhiteListedPattern = str_replace('\\*', '.*', preg_quote($whiteListedPattern));
|
||||
|
||||
return "{^" . $cleanedWhiteListedPattern . "$}i";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $links
|
||||
* @return array
|
||||
|
@ -1334,7 +1322,7 @@ class Installer
|
|||
|
||||
// check if the name is a glob pattern that did not match directly
|
||||
if (!$nameMatchesRequiredPackage) {
|
||||
$whitelistPatternRegexp = $this->packageNameToRegexp($packageName);
|
||||
$whitelistPatternRegexp = BasePackage::packageNameToRegexp($packageName);
|
||||
foreach ($rootRequiredPackageNames as $rootRequiredPackageName) {
|
||||
if (preg_match($whitelistPatternRegexp, $rootRequiredPackageName)) {
|
||||
$nameMatchesRequiredPackage = true;
|
||||
|
|
|
@ -234,4 +234,17 @@ abstract class BasePackage implements PackageInterface
|
|||
$this->repository = null;
|
||||
$this->id = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a regexp from a package name, expanding * globs as required
|
||||
*
|
||||
* @param string $whiteListedPattern
|
||||
* @return string
|
||||
*/
|
||||
public static function packageNameToRegexp($whiteListedPattern)
|
||||
{
|
||||
$cleanedWhiteListedPattern = str_replace('\\*', '.*', preg_quote($whiteListedPattern));
|
||||
|
||||
return "{^" . $cleanedWhiteListedPattern . "$}i";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -161,7 +161,7 @@ class ValidatingArrayLoader implements LoaderInterface
|
|||
}
|
||||
|
||||
if ($this->validateArray('support') && !empty($this->config['support'])) {
|
||||
foreach (array('issues', 'forum', 'wiki', 'source', 'email', 'irc', 'docs', 'rss') as $key) {
|
||||
foreach (array('issues', 'forum', 'wiki', 'source', 'email', 'irc', 'docs', 'rss', 'chat') as $key) {
|
||||
if (isset($this->config['support'][$key]) && !is_string($this->config['support'][$key])) {
|
||||
$this->errors[] = 'support.'.$key.' : invalid value, must be a string';
|
||||
unset($this->config['support'][$key]);
|
||||
|
@ -178,7 +178,7 @@ class ValidatingArrayLoader implements LoaderInterface
|
|||
unset($this->config['support']['irc']);
|
||||
}
|
||||
|
||||
foreach (array('issues', 'forum', 'wiki', 'source', 'docs') as $key) {
|
||||
foreach (array('issues', 'forum', 'wiki', 'source', 'docs', 'chat') as $key) {
|
||||
if (isset($this->config['support'][$key]) && !$this->filterUrl($this->config['support'][$key])) {
|
||||
$this->warnings[] = 'support.'.$key.' : invalid value ('.$this->config['support'][$key].'), must be an http/https URL';
|
||||
unset($this->config['support'][$key]);
|
||||
|
|
|
@ -157,6 +157,13 @@ class PlatformRepository extends ArrayRepository
|
|||
|
||||
break;
|
||||
|
||||
case 'imagick':
|
||||
$imagick = new \Imagick();
|
||||
$imageMagickVersion = $imagick->getVersion();
|
||||
preg_match('/^ImageMagick ([\d.]+)-(\d+)/', $imageMagickVersion['versionString'], $matches);
|
||||
$prettyVersion = "{$matches[1]}.{$matches[2]}";
|
||||
break;
|
||||
|
||||
case 'libxml':
|
||||
$prettyVersion = LIBXML_DOTTED_VERSION;
|
||||
break;
|
||||
|
|
|
@ -40,7 +40,7 @@ final class StreamContextFactory
|
|||
));
|
||||
|
||||
// Handle HTTP_PROXY/http_proxy on CLI only for security reasons
|
||||
if (PHP_SAPI === 'cli' && (!empty($_SERVER['HTTP_PROXY']) || !empty($_SERVER['http_proxy']))) {
|
||||
if ((PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') && (!empty($_SERVER['HTTP_PROXY']) || !empty($_SERVER['http_proxy']))) {
|
||||
$proxy = parse_url(!empty($_SERVER['http_proxy']) ? $_SERVER['http_proxy'] : $_SERVER['HTTP_PROXY']);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace Composer\Test\EventDispatcher;
|
|||
|
||||
use Composer\EventDispatcher\Event;
|
||||
use Composer\EventDispatcher\EventDispatcher;
|
||||
use Composer\EventDispatcher\ScriptExecutionException;
|
||||
use Composer\Installer\InstallerEvents;
|
||||
use Composer\Config;
|
||||
use Composer\Composer;
|
||||
|
@ -251,6 +252,45 @@ class EventDispatcherTest extends TestCase
|
|||
$this->assertEquals($expected, $io->getOutput());
|
||||
}
|
||||
|
||||
public function testRecursionInScriptsNames()
|
||||
{
|
||||
$process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
$dispatcher = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')
|
||||
->setConstructorArgs(array(
|
||||
$composer = $this->createComposerInstance(),
|
||||
$io = new BufferIO('', OutputInterface::VERBOSITY_VERBOSE),
|
||||
$process
|
||||
))
|
||||
->setMethods(array(
|
||||
'getListeners'
|
||||
))
|
||||
->getMock();
|
||||
|
||||
$process->expects($this->exactly(1))
|
||||
->method('execute')
|
||||
->will($this->returnValue(0));
|
||||
|
||||
$dispatcher->expects($this->atLeastOnce())
|
||||
->method('getListeners')
|
||||
->will($this->returnCallback(function (Event $event) {
|
||||
if($event->getName() === 'hello') {
|
||||
return array('echo Hello');
|
||||
}
|
||||
|
||||
if($event->getName() === 'helloWorld') {
|
||||
return array('@hello World');
|
||||
}
|
||||
|
||||
return array();
|
||||
}));
|
||||
|
||||
$dispatcher->dispatch('helloWorld', new CommandEvent('helloWorld', $composer, $io));
|
||||
$expected = "> helloWorld: @hello World".PHP_EOL.
|
||||
"> hello: echo Hello " .escapeshellarg('World').PHP_EOL;
|
||||
|
||||
$this->assertEquals($expected, $io->getOutput());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException RuntimeException
|
||||
*/
|
||||
|
|
|
@ -71,6 +71,7 @@ class ValidatingArrayLoaderTest extends TestCase
|
|||
'source' => 'http://example.org/',
|
||||
'irc' => 'irc://example.org/example',
|
||||
'rss' => 'http://example.org/rss',
|
||||
'chat' => 'http://example.org/chat',
|
||||
),
|
||||
'require' => array(
|
||||
'a/b' => '1.*',
|
||||
|
@ -305,6 +306,7 @@ class ValidatingArrayLoaderTest extends TestCase
|
|||
'forum' => 'foo:bar',
|
||||
'issues' => 'foo:bar',
|
||||
'wiki' => 'foo:bar',
|
||||
'chat' => 'foo:bar',
|
||||
),
|
||||
),
|
||||
array(
|
||||
|
@ -312,6 +314,7 @@ class ValidatingArrayLoaderTest extends TestCase
|
|||
'support.forum : invalid value (foo:bar), must be an http/https URL',
|
||||
'support.issues : invalid value (foo:bar), must be an http/https URL',
|
||||
'support.wiki : invalid value (foo:bar), must be an http/https URL',
|
||||
'support.chat : invalid value (foo:bar), must be an http/https URL',
|
||||
),
|
||||
),
|
||||
array(
|
||||
|
|
Loading…
Reference in New Issue