Merge branch 'master' of https://github.com/composer/composer into add_exclude
# By Jordi Boggiano (30) and others
# Via Jordi Boggiano (37) and Morgan Campbell (1)
* 'master' of https://github.com/composer/composer: (83 commits)
Update 01-basic-usage.md
Revert 331425bcb3
as well, fixes #3612
Revert "Disable overwrites when no-ansi is present, fixes #3612"
Update deps
Use justinrainbow/json-schema 1.4
Improved wording
Fix docs basic-auth => http-basic
Add test for Generics class
Single variable for traits and enums
Use HHVM_VERSION instead of HPHP_VERSION
Add support for using classmap to autoload Hack enums
Re-use existing autoloader suffix if available, fixes #3701
Report Travis CI build success early
Test on HHVM nightly releases. Allow to fail.
Make parseJson safer
Use get home from Config instead of factory
Fix env override regression, fixes #3820
[create-project] Used no progress value for dependencies
Add docBlock and fix CS
Fix output of first line of progress when output is not decorated, refs #3818
...
pull/1607/head
commit
7522a33079
22
.travis.yml
22
.travis.yml
|
@ -1,18 +1,34 @@
|
||||||
language: php
|
language: php
|
||||||
|
|
||||||
|
sudo: false
|
||||||
|
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- $HOME/.composer/cache
|
||||||
|
|
||||||
|
addons:
|
||||||
|
apt_packages:
|
||||||
|
- parallel
|
||||||
|
|
||||||
php:
|
php:
|
||||||
- 5.3.3
|
- 5.3.3
|
||||||
- 5.3
|
- 5.3
|
||||||
- 5.4
|
- 5.4
|
||||||
- 5.5
|
- 5.5
|
||||||
- 5.6
|
- 5.6
|
||||||
|
- 7.0
|
||||||
- hhvm
|
- hhvm
|
||||||
|
- hhvm-nightly
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
fast_finish: true
|
||||||
|
allow_failures:
|
||||||
|
- php: hhvm-nightly
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- sudo apt-get install parallel
|
|
||||||
- rm -f ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini
|
- rm -f ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini
|
||||||
- composer install --prefer-source
|
- composer install
|
||||||
- bin/composer install --prefer-source
|
- bin/composer install
|
||||||
- git config --global user.name travis-ci
|
- git config --global user.name travis-ci
|
||||||
- git config --global user.email travis@example.com
|
- git config --global user.email travis@example.com
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,9 @@ if (function_exists('ini_set')) {
|
||||||
};
|
};
|
||||||
|
|
||||||
$memoryLimit = trim(ini_get('memory_limit'));
|
$memoryLimit = trim(ini_get('memory_limit'));
|
||||||
// Increase memory_limit if it is lower than 512M
|
// Increase memory_limit if it is lower than 1GB
|
||||||
if ($memoryLimit != -1 && $memoryInBytes($memoryLimit) < 512 * 1024 * 1024) {
|
if ($memoryLimit != -1 && $memoryInBytes($memoryLimit) < 1024 * 1024 * 1024) {
|
||||||
@ini_set('memory_limit', '512M');
|
@ini_set('memory_limit', '1G');
|
||||||
}
|
}
|
||||||
unset($memoryInBytes, $memoryLimit);
|
unset($memoryInBytes, $memoryLimit);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,14 +23,14 @@
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.2",
|
"php": ">=5.3.2",
|
||||||
"justinrainbow/json-schema": "~1.3",
|
"justinrainbow/json-schema": "~1.4",
|
||||||
"seld/jsonlint": "~1.0",
|
"seld/jsonlint": "~1.0",
|
||||||
"symfony/console": "~2.3",
|
"symfony/console": "~2.5",
|
||||||
"symfony/finder": "~2.2",
|
"symfony/finder": "~2.2",
|
||||||
"symfony/process": "~2.1"
|
"symfony/process": "~2.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "~4.0"
|
"phpunit/phpunit": "~4.5"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"ext-zip": "Enabling the zip extension allows you to unzip archives, and allows gzip compression of all internet traffic",
|
"ext-zip": "Enabling the zip extension allows you to unzip archives, and allows gzip compression of all internet traffic",
|
||||||
|
|
|
@ -4,20 +4,20 @@
|
||||||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"hash": "2bc9cc8aa706b68d611d7058e4eb8de7",
|
"hash": "8317ca3b690ea80633fe3fb2b0d440cb",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "justinrainbow/json-schema",
|
"name": "justinrainbow/json-schema",
|
||||||
"version": "1.3.7",
|
"version": "1.4.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/justinrainbow/json-schema.git",
|
"url": "https://github.com/justinrainbow/json-schema.git",
|
||||||
"reference": "87b54b460febed69726c781ab67462084e97a105"
|
"reference": "680d026082c3aa234b2d8617c50e9c73999913ba"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/87b54b460febed69726c781ab67462084e97a105",
|
"url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/680d026082c3aa234b2d8617c50e9c73999913ba",
|
||||||
"reference": "87b54b460febed69726c781ab67462084e97a105",
|
"reference": "680d026082c3aa234b2d8617c50e9c73999913ba",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -70,20 +70,20 @@
|
||||||
"json",
|
"json",
|
||||||
"schema"
|
"schema"
|
||||||
],
|
],
|
||||||
"time": "2014-08-25 02:48:14"
|
"time": "2015-03-23 20:38:38"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "seld/jsonlint",
|
"name": "seld/jsonlint",
|
||||||
"version": "1.3.0",
|
"version": "1.3.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/Seldaek/jsonlint.git",
|
"url": "https://github.com/Seldaek/jsonlint.git",
|
||||||
"reference": "a7bc2ec9520ad15382292591b617c43bdb1fec35"
|
"reference": "863ae85c6d3ef60ca49cb12bd051c4a0648c40c4"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/a7bc2ec9520ad15382292591b617c43bdb1fec35",
|
"url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/863ae85c6d3ef60ca49cb12bd051c4a0648c40c4",
|
||||||
"reference": "a7bc2ec9520ad15382292591b617c43bdb1fec35",
|
"reference": "863ae85c6d3ef60ca49cb12bd051c4a0648c40c4",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -116,21 +116,21 @@
|
||||||
"parser",
|
"parser",
|
||||||
"validator"
|
"validator"
|
||||||
],
|
],
|
||||||
"time": "2014-09-05 15:36:20"
|
"time": "2015-01-04 21:18:15"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/console",
|
"name": "symfony/console",
|
||||||
"version": "v2.6.1",
|
"version": "v2.6.5",
|
||||||
"target-dir": "Symfony/Component/Console",
|
"target-dir": "Symfony/Component/Console",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/Console.git",
|
"url": "https://github.com/symfony/Console.git",
|
||||||
"reference": "ef825fd9f809d275926547c9e57cbf14968793e8"
|
"reference": "53f86497ccd01677e22435cfb7262599450a90d1"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/Console/zipball/ef825fd9f809d275926547c9e57cbf14968793e8",
|
"url": "https://api.github.com/repos/symfony/Console/zipball/53f86497ccd01677e22435cfb7262599450a90d1",
|
||||||
"reference": "ef825fd9f809d275926547c9e57cbf14968793e8",
|
"reference": "53f86497ccd01677e22435cfb7262599450a90d1",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -139,6 +139,7 @@
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"psr/log": "~1.0",
|
"psr/log": "~1.0",
|
||||||
"symfony/event-dispatcher": "~2.1",
|
"symfony/event-dispatcher": "~2.1",
|
||||||
|
"symfony/phpunit-bridge": "~2.7",
|
||||||
"symfony/process": "~2.1"
|
"symfony/process": "~2.1"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
|
@ -173,26 +174,29 @@
|
||||||
],
|
],
|
||||||
"description": "Symfony Console Component",
|
"description": "Symfony Console Component",
|
||||||
"homepage": "http://symfony.com",
|
"homepage": "http://symfony.com",
|
||||||
"time": "2014-12-02 20:19:20"
|
"time": "2015-03-13 17:37:22"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/finder",
|
"name": "symfony/finder",
|
||||||
"version": "v2.6.1",
|
"version": "v2.6.5",
|
||||||
"target-dir": "Symfony/Component/Finder",
|
"target-dir": "Symfony/Component/Finder",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/Finder.git",
|
"url": "https://github.com/symfony/Finder.git",
|
||||||
"reference": "0d3ef7f6ec55a7af5eca7914eaa0dacc04ccc721"
|
"reference": "bebc7479c566fa4f14b9bcef9e32e719eabec74e"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/Finder/zipball/0d3ef7f6ec55a7af5eca7914eaa0dacc04ccc721",
|
"url": "https://api.github.com/repos/symfony/Finder/zipball/bebc7479c566fa4f14b9bcef9e32e719eabec74e",
|
||||||
"reference": "0d3ef7f6ec55a7af5eca7914eaa0dacc04ccc721",
|
"reference": "bebc7479c566fa4f14b9bcef9e32e719eabec74e",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.3"
|
"php": ">=5.3.3"
|
||||||
},
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/phpunit-bridge": "~2.7"
|
||||||
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
|
@ -220,26 +224,29 @@
|
||||||
],
|
],
|
||||||
"description": "Symfony Finder Component",
|
"description": "Symfony Finder Component",
|
||||||
"homepage": "http://symfony.com",
|
"homepage": "http://symfony.com",
|
||||||
"time": "2014-12-02 20:19:20"
|
"time": "2015-03-12 10:28:44"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/process",
|
"name": "symfony/process",
|
||||||
"version": "v2.6.1",
|
"version": "v2.6.5",
|
||||||
"target-dir": "Symfony/Component/Process",
|
"target-dir": "Symfony/Component/Process",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/Process.git",
|
"url": "https://github.com/symfony/Process.git",
|
||||||
"reference": "bf0c9bd625f13b0b0bbe39919225cf145dfb935a"
|
"reference": "4d717f34f3d1d6ab30fbe79f7132960a27f4a0dc"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/Process/zipball/bf0c9bd625f13b0b0bbe39919225cf145dfb935a",
|
"url": "https://api.github.com/repos/symfony/Process/zipball/4d717f34f3d1d6ab30fbe79f7132960a27f4a0dc",
|
||||||
"reference": "bf0c9bd625f13b0b0bbe39919225cf145dfb935a",
|
"reference": "4d717f34f3d1d6ab30fbe79f7132960a27f4a0dc",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.3"
|
"php": ">=5.3.3"
|
||||||
},
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/phpunit-bridge": "~2.7"
|
||||||
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
|
@ -267,7 +274,7 @@
|
||||||
],
|
],
|
||||||
"description": "Symfony Process Component",
|
"description": "Symfony Process Component",
|
||||||
"homepage": "http://symfony.com",
|
"homepage": "http://symfony.com",
|
||||||
"time": "2014-12-02 20:19:20"
|
"time": "2015-03-12 10:28:44"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packages-dev": [
|
"packages-dev": [
|
||||||
|
@ -326,17 +333,125 @@
|
||||||
"time": "2014-10-13 12:58:55"
|
"time": "2014-10-13 12:58:55"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/php-code-coverage",
|
"name": "phpdocumentor/reflection-docblock",
|
||||||
"version": "2.0.14",
|
"version": "2.0.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
|
||||||
"reference": "ca158276c1200cc27f5409a5e338486bc0b4fc94"
|
"reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca158276c1200cc27f5409a5e338486bc0b4fc94",
|
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
|
||||||
"reference": "ca158276c1200cc27f5409a5e338486bc0b4fc94",
|
"reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.3"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "~4.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"dflydev/markdown": "~1.0",
|
||||||
|
"erusev/parsedown": "~1.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "2.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-0": {
|
||||||
|
"phpDocumentor": [
|
||||||
|
"src/"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Mike van Riel",
|
||||||
|
"email": "mike.vanriel@naenius.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2015-02-03 12:10:50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "phpspec/prophecy",
|
||||||
|
"version": "v1.3.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/phpspec/prophecy.git",
|
||||||
|
"reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/9ca52329bcdd1500de24427542577ebf3fc2f1c9",
|
||||||
|
"reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"doctrine/instantiator": "~1.0,>=1.0.2",
|
||||||
|
"phpdocumentor/reflection-docblock": "~2.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpspec/phpspec": "~2.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.2.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-0": {
|
||||||
|
"Prophecy\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Konstantin Kudryashov",
|
||||||
|
"email": "ever.zet@gmail.com",
|
||||||
|
"homepage": "http://everzet.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Marcello Duarte",
|
||||||
|
"email": "marcello.duarte@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Highly opinionated mocking framework for PHP 5.3+",
|
||||||
|
"homepage": "http://phpspec.org",
|
||||||
|
"keywords": [
|
||||||
|
"Double",
|
||||||
|
"Dummy",
|
||||||
|
"fake",
|
||||||
|
"mock",
|
||||||
|
"spy",
|
||||||
|
"stub"
|
||||||
|
],
|
||||||
|
"time": "2014-11-17 16:23:49"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "phpunit/php-code-coverage",
|
||||||
|
"version": "2.0.15",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||||
|
"reference": "34cc484af1ca149188d0d9e91412191e398e0b67"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/34cc484af1ca149188d0d9e91412191e398e0b67",
|
||||||
|
"reference": "34cc484af1ca149188d0d9e91412191e398e0b67",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -349,7 +464,7 @@
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"ext-xdebug": ">=2.1.4",
|
"ext-xdebug": ">=2.1.4",
|
||||||
"phpunit/phpunit": "~4.1"
|
"phpunit/phpunit": "~4"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"ext-dom": "*",
|
"ext-dom": "*",
|
||||||
|
@ -368,9 +483,6 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
"include-path": [
|
|
||||||
""
|
|
||||||
],
|
|
||||||
"license": [
|
"license": [
|
||||||
"BSD-3-Clause"
|
"BSD-3-Clause"
|
||||||
],
|
],
|
||||||
|
@ -388,7 +500,7 @@
|
||||||
"testing",
|
"testing",
|
||||||
"xunit"
|
"xunit"
|
||||||
],
|
],
|
||||||
"time": "2014-12-26 13:28:33"
|
"time": "2015-01-24 10:06:35"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/php-file-iterator",
|
"name": "phpunit/php-file-iterator",
|
||||||
|
@ -525,16 +637,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/php-token-stream",
|
"name": "phpunit/php-token-stream",
|
||||||
"version": "1.3.0",
|
"version": "1.4.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
|
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
|
||||||
"reference": "f8d5d08c56de5cfd592b3340424a81733259a876"
|
"reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/f8d5d08c56de5cfd592b3340424a81733259a876",
|
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/db32c18eba00b121c145575fcbcd4d4d24e6db74",
|
||||||
"reference": "f8d5d08c56de5cfd592b3340424a81733259a876",
|
"reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -547,7 +659,7 @@
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "1.3-dev"
|
"dev-master": "1.4-dev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -570,20 +682,20 @@
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"tokenizer"
|
"tokenizer"
|
||||||
],
|
],
|
||||||
"time": "2014-08-31 06:12:13"
|
"time": "2015-01-17 09:51:32"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/phpunit",
|
"name": "phpunit/phpunit",
|
||||||
"version": "4.4.1",
|
"version": "4.5.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||||
"reference": "6a5e49a86ce5e33b8d0657abe145057fc513543a"
|
"reference": "5b578d3865a9128b9c209b011fda6539ec06e7a5"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6a5e49a86ce5e33b8d0657abe145057fc513543a",
|
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5b578d3865a9128b9c209b011fda6539ec06e7a5",
|
||||||
"reference": "6a5e49a86ce5e33b8d0657abe145057fc513543a",
|
"reference": "5b578d3865a9128b9c209b011fda6539ec06e7a5",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -593,15 +705,16 @@
|
||||||
"ext-reflection": "*",
|
"ext-reflection": "*",
|
||||||
"ext-spl": "*",
|
"ext-spl": "*",
|
||||||
"php": ">=5.3.3",
|
"php": ">=5.3.3",
|
||||||
|
"phpspec/prophecy": "~1.3.1",
|
||||||
"phpunit/php-code-coverage": "~2.0",
|
"phpunit/php-code-coverage": "~2.0",
|
||||||
"phpunit/php-file-iterator": "~1.3.2",
|
"phpunit/php-file-iterator": "~1.3.2",
|
||||||
"phpunit/php-text-template": "~1.2",
|
"phpunit/php-text-template": "~1.2",
|
||||||
"phpunit/php-timer": "~1.0.2",
|
"phpunit/php-timer": "~1.0.2",
|
||||||
"phpunit/phpunit-mock-objects": "~2.3",
|
"phpunit/phpunit-mock-objects": "~2.3",
|
||||||
"sebastian/comparator": "~1.0",
|
"sebastian/comparator": "~1.1",
|
||||||
"sebastian/diff": "~1.1",
|
"sebastian/diff": "~1.1",
|
||||||
"sebastian/environment": "~1.1",
|
"sebastian/environment": "~1.2",
|
||||||
"sebastian/exporter": "~1.0",
|
"sebastian/exporter": "~1.2",
|
||||||
"sebastian/global-state": "~1.0",
|
"sebastian/global-state": "~1.0",
|
||||||
"sebastian/version": "~1.0",
|
"sebastian/version": "~1.0",
|
||||||
"symfony/yaml": "~2.0"
|
"symfony/yaml": "~2.0"
|
||||||
|
@ -615,7 +728,7 @@
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "4.4.x-dev"
|
"dev-master": "4.5.x-dev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -641,7 +754,7 @@
|
||||||
"testing",
|
"testing",
|
||||||
"xunit"
|
"xunit"
|
||||||
],
|
],
|
||||||
"time": "2014-12-28 07:57:05"
|
"time": "2015-02-05 15:51:19"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/phpunit-mock-objects",
|
"name": "phpunit/phpunit-mock-objects",
|
||||||
|
@ -700,25 +813,25 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sebastian/comparator",
|
"name": "sebastian/comparator",
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/comparator.git",
|
"url": "https://github.com/sebastianbergmann/comparator.git",
|
||||||
"reference": "c484a80f97573ab934e37826dba0135a3301b26a"
|
"reference": "1dd8869519a225f7f2b9eb663e225298fade819e"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/c484a80f97573ab934e37826dba0135a3301b26a",
|
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dd8869519a225f7f2b9eb663e225298fade819e",
|
||||||
"reference": "c484a80f97573ab934e37826dba0135a3301b26a",
|
"reference": "1dd8869519a225f7f2b9eb663e225298fade819e",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.3",
|
"php": ">=5.3.3",
|
||||||
"sebastian/diff": "~1.1",
|
"sebastian/diff": "~1.2",
|
||||||
"sebastian/exporter": "~1.0"
|
"sebastian/exporter": "~1.2"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "~4.1"
|
"phpunit/phpunit": "~4.4"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
|
@ -760,7 +873,7 @@
|
||||||
"compare",
|
"compare",
|
||||||
"equality"
|
"equality"
|
||||||
],
|
],
|
||||||
"time": "2014-11-16 21:32:38"
|
"time": "2015-01-29 16:28:08"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sebastian/diff",
|
"name": "sebastian/diff",
|
||||||
|
@ -866,28 +979,29 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sebastian/exporter",
|
"name": "sebastian/exporter",
|
||||||
"version": "1.0.2",
|
"version": "1.2.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/exporter.git",
|
"url": "https://github.com/sebastianbergmann/exporter.git",
|
||||||
"reference": "c7d59948d6e82818e1bdff7cadb6c34710eb7dc0"
|
"reference": "84839970d05254c73cde183a721c7af13aede943"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c7d59948d6e82818e1bdff7cadb6c34710eb7dc0",
|
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/84839970d05254c73cde183a721c7af13aede943",
|
||||||
"reference": "c7d59948d6e82818e1bdff7cadb6c34710eb7dc0",
|
"reference": "84839970d05254c73cde183a721c7af13aede943",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.3"
|
"php": ">=5.3.3",
|
||||||
|
"sebastian/recursion-context": "~1.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "~4.0"
|
"phpunit/phpunit": "~4.4"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "1.0.x-dev"
|
"dev-master": "1.2.x-dev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -927,7 +1041,7 @@
|
||||||
"export",
|
"export",
|
||||||
"exporter"
|
"exporter"
|
||||||
],
|
],
|
||||||
"time": "2014-09-10 00:51:36"
|
"time": "2015-01-27 07:23:06"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sebastian/global-state",
|
"name": "sebastian/global-state",
|
||||||
|
@ -980,6 +1094,59 @@
|
||||||
],
|
],
|
||||||
"time": "2014-10-06 09:23:50"
|
"time": "2014-10-06 09:23:50"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "sebastian/recursion-context",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/sebastianbergmann/recursion-context.git",
|
||||||
|
"reference": "3989662bbb30a29d20d9faa04a846af79b276252"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/3989662bbb30a29d20d9faa04a846af79b276252",
|
||||||
|
"reference": "3989662bbb30a29d20d9faa04a846af79b276252",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.3"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "~4.4"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"classmap": [
|
||||||
|
"src/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"BSD-3-Clause"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jeff Welch",
|
||||||
|
"email": "whatthejeff@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Sebastian Bergmann",
|
||||||
|
"email": "sebastian@phpunit.de"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Adam Harvey",
|
||||||
|
"email": "aharvey@php.net"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Provides functionality to recursively process PHP variables",
|
||||||
|
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
|
||||||
|
"time": "2015-01-24 09:48:32"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "sebastian/version",
|
"name": "sebastian/version",
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
|
@ -1017,22 +1184,25 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/yaml",
|
"name": "symfony/yaml",
|
||||||
"version": "v2.6.1",
|
"version": "v2.6.5",
|
||||||
"target-dir": "Symfony/Component/Yaml",
|
"target-dir": "Symfony/Component/Yaml",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/Yaml.git",
|
"url": "https://github.com/symfony/Yaml.git",
|
||||||
"reference": "3346fc090a3eb6b53d408db2903b241af51dcb20"
|
"reference": "0cd8e72071e46e15fc072270ae39ea1b66b10a9d"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/Yaml/zipball/3346fc090a3eb6b53d408db2903b241af51dcb20",
|
"url": "https://api.github.com/repos/symfony/Yaml/zipball/0cd8e72071e46e15fc072270ae39ea1b66b10a9d",
|
||||||
"reference": "3346fc090a3eb6b53d408db2903b241af51dcb20",
|
"reference": "0cd8e72071e46e15fc072270ae39ea1b66b10a9d",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.3"
|
"php": ">=5.3.3"
|
||||||
},
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/phpunit-bridge": "~2.7"
|
||||||
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
|
@ -1060,7 +1230,7 @@
|
||||||
],
|
],
|
||||||
"description": "Symfony Yaml Component",
|
"description": "Symfony Yaml Component",
|
||||||
"homepage": "http://symfony.com",
|
"homepage": "http://symfony.com",
|
||||||
"time": "2014-12-02 20:19:20"
|
"time": "2015-03-12 10:28:44"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
|
|
|
@ -140,7 +140,7 @@ versions from `composer.json` and create the lock file after executing the `upd
|
||||||
command.
|
command.
|
||||||
|
|
||||||
This means that if any of the dependencies get a new version, you won't get the updates
|
This means that if any of the dependencies get a new version, you won't get the updates
|
||||||
automatically. To update to the new version, use `update` command. This will fetch
|
automatically. To update to the new version, use the `update` command. This will fetch
|
||||||
the latest matching versions (according to your `composer.json` file) and also update
|
the latest matching versions (according to your `composer.json` file) and also update
|
||||||
the lock file with the new version.
|
the lock file with the new version.
|
||||||
|
|
||||||
|
|
|
@ -507,8 +507,13 @@ Lists the name, version and license of every package installed. Use
|
||||||
|
|
||||||
## run-script
|
## run-script
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
* **--no-dev:** Disable dev mode
|
||||||
|
* **--list:** List user defined scripts
|
||||||
|
|
||||||
To run [scripts](articles/scripts.md) manually you can use this command,
|
To run [scripts](articles/scripts.md) manually you can use this command,
|
||||||
just give it the script name and optionally --no-dev to disable the dev mode.
|
just give it the script name and optionally any required arguments.
|
||||||
|
|
||||||
## diagnose
|
## diagnose
|
||||||
|
|
||||||
|
|
|
@ -894,4 +894,36 @@ The example will include `/dir/foo/bar/file`, `/foo/bar/baz`, `/file.php`,
|
||||||
|
|
||||||
Optional.
|
Optional.
|
||||||
|
|
||||||
← [Command-line interface](03-cli.md) | [Repositories](05-repositories.md) →
|
### non-feature-branches
|
||||||
|
|
||||||
|
A list of regex patterns of branch names that are non-numeric (e.g. "latest" or something), that will NOT be handled as feature branches. This is an array of string.
|
||||||
|
|
||||||
|
If you have non-numeric branch names, for example like "latest", "current", "latest-stable"
|
||||||
|
or something, that do not look like a version number, then composer handles such branches
|
||||||
|
as feature branches. This means it searches for parent branches, that look like a version
|
||||||
|
or ends at special branches (like master) and the root package version number becomes the
|
||||||
|
version of the parent branch or at least master or something.
|
||||||
|
|
||||||
|
To handle non-numeric named branches as versions instead of searching for a parent branch
|
||||||
|
with a valid version or special branch name like master, you can set patterns for branch
|
||||||
|
names, that should be handled as dev version branches.
|
||||||
|
|
||||||
|
This is really helpful when you have dependencies using "self.version", so that not dev-master,
|
||||||
|
but the same branch is installed (in the example: latest-testing).
|
||||||
|
|
||||||
|
An example:
|
||||||
|
|
||||||
|
If you have a testing branch, that is heavily maintained during a testing phase and is
|
||||||
|
deployed to your staging environment, normally "composer show -s" will give you `versions : * dev-master`.
|
||||||
|
|
||||||
|
If you configure latest-.* as a pattern for non-feature-branches like this:
|
||||||
|
|
||||||
|
{
|
||||||
|
"non-feature-branches": ["latest-.*"]
|
||||||
|
}
|
||||||
|
|
||||||
|
Then "composer show -s" will give you `versions : * dev-latest-testing`.
|
||||||
|
|
||||||
|
Optional.
|
||||||
|
|
||||||
|
← [Command-line interface](03-cli.md) | [Repositories](05-repositories.md) →
|
|
@ -234,7 +234,7 @@ project to use the patched version. If the library is on GitHub (this is the
|
||||||
case most of the time), you can simply fork it there and push your changes to
|
case most of the time), you can simply fork it there and push your changes to
|
||||||
your fork. After that you update the project's `composer.json`. All you have
|
your fork. After that you update the project's `composer.json`. All you have
|
||||||
to do is add your fork as a repository and update the version constraint to
|
to do is add your fork as a repository and update the version constraint to
|
||||||
point to your custom branch. For version constraint naming conventions see
|
point to your custom branch. Your custom branch name must be prefixed with `"dev-"`. For version constraint naming conventions see
|
||||||
[Libraries](02-libraries.md) for more information.
|
[Libraries](02-libraries.md) for more information.
|
||||||
|
|
||||||
Example assuming you patched monolog to fix a bug in the `bugfix` branch:
|
Example assuming you patched monolog to fix a bug in the `bugfix` branch:
|
||||||
|
@ -533,10 +533,9 @@ There are a few tools that can help you create a `composer` repository.
|
||||||
### Packagist
|
### Packagist
|
||||||
|
|
||||||
The underlying application used by packagist is open source. This means that you
|
The underlying application used by packagist is open source. This means that you
|
||||||
can just install your own copy of packagist, re-brand, and use it. It's really
|
can technically install your own copy of packagist. However it is not a
|
||||||
quite straight-forward to do. However due to its size and complexity, for most
|
supported use case and changes will happen without caring for third parties
|
||||||
small and medium sized companies willing to track a few packages will be better
|
using the code.
|
||||||
off using Satis.
|
|
||||||
|
|
||||||
Packagist is a Symfony2 application, and it is [available on
|
Packagist is a Symfony2 application, and it is [available on
|
||||||
GitHub](https://github.com/composer/packagist). It uses composer internally and
|
GitHub](https://github.com/composer/packagist). It uses composer internally and
|
||||||
|
@ -544,8 +543,11 @@ acts as a proxy between VCS repositories and the composer users. It holds a list
|
||||||
of all VCS packages, periodically re-crawls them, and exposes them as a composer
|
of all VCS packages, periodically re-crawls them, and exposes them as a composer
|
||||||
repository.
|
repository.
|
||||||
|
|
||||||
To set your own copy, simply follow the instructions from the [packagist
|
### Toran Proxy
|
||||||
github repository](https://github.com/composer/packagist).
|
|
||||||
|
[Toran Proxy](https://toranproxy.com/) is a web app much like Packagist but
|
||||||
|
providing private package hosting as well as mirroring/proxying of GitHub and packagist.org. Check its homepage and the [Satis/Toran Proxy article](articles/handling-private-packages-with-satis.md)
|
||||||
|
for more information.
|
||||||
|
|
||||||
### Satis
|
### Satis
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,15 @@
|
||||||
|
|
||||||
# Toran Proxy
|
# Toran Proxy
|
||||||
|
|
||||||
[Toran Proxy](https://toranproxy.com/) is a commercial alternative to Satis offering professional support as well as a web UI to manage everything and a better integration with Composer.
|
[Toran Proxy](https://toranproxy.com/) is a commercial alternative to Satis
|
||||||
|
offering professional support as well as a web UI to manage everything and a
|
||||||
|
better integration with Composer. It also provides proxying/mirroring for git
|
||||||
|
repos and package zip files which makes installs faster and independent from
|
||||||
|
third party systems.
|
||||||
|
|
||||||
Toran's revenue is also used to pay for Composer and Packagist development and hosting so using it is a good way to support open source financially. You can find more information about how to set it up and use it on the [Toran Proxy](https://toranproxy.com/) website.
|
Toran's revenue is also used to pay for Composer and Packagist development and
|
||||||
|
hosting so using it is a good way to support open source financially. You can
|
||||||
|
find more information about how to set it up and use it on the [Toran Proxy](https://toranproxy.com/) website.
|
||||||
|
|
||||||
# Satis
|
# Satis
|
||||||
|
|
||||||
|
@ -151,6 +157,24 @@ Example using HTTP over SSL using a client certificate:
|
||||||
|
|
||||||
> **Tip:** See [ssl context options](http://www.php.net/manual/en/context.ssl.php) for more information.
|
> **Tip:** See [ssl context options](http://www.php.net/manual/en/context.ssl.php) for more information.
|
||||||
|
|
||||||
|
### Authentification
|
||||||
|
|
||||||
|
When your private repositories are password protected, you can store the authentification details permanently.
|
||||||
|
The first time Composer needs to authenticate against some domain it will prompt you for a username/password
|
||||||
|
and then you will be asked whether you want to store it.
|
||||||
|
|
||||||
|
The storage can be done either globally in the `COMPOSER_HOME/auth.json` file (`COMPOSER_HOME` defaults to
|
||||||
|
`~/.composer` or `%APPDATA%/Composer` on Windows) or also in the project directory directly sitting besides your
|
||||||
|
composer.json.
|
||||||
|
|
||||||
|
You can also configure these by hand using the config command if you need to configure a production machine
|
||||||
|
to be able to run non-interactive installs. For example to enter credentials for example.org one could type:
|
||||||
|
|
||||||
|
composer config http-basic.example.org username password
|
||||||
|
|
||||||
|
That will store it in the current directory's auth.json, but if you want it available globally you can use the
|
||||||
|
`--global` (`-g`) flag.
|
||||||
|
|
||||||
### Downloads
|
### Downloads
|
||||||
|
|
||||||
When GitHub or BitBucket repositories are mirrored on your local satis, the build process will include
|
When GitHub or BitBucket repositories are mirrored on your local satis, the build process will include
|
||||||
|
|
|
@ -40,7 +40,7 @@ username/password pairs, for example:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"basic-auth": {
|
"http-basic": {
|
||||||
"repo.example1.org": {
|
"repo.example1.org": {
|
||||||
"username": "my-username1",
|
"username": "my-username1",
|
||||||
"password": "my-secret-password1"
|
"password": "my-secret-password1"
|
||||||
|
|
|
@ -82,15 +82,7 @@ Furthermore plugins may implement the
|
||||||
event handlers automatically registered with the `EventDispatcher` when the
|
event handlers automatically registered with the `EventDispatcher` when the
|
||||||
plugin is loaded.
|
plugin is loaded.
|
||||||
|
|
||||||
The events available for plugins are:
|
Plugin can subscribe to any of the available [script events](scripts.md#event-names).
|
||||||
|
|
||||||
* **COMMAND**, is called at the beginning of all commands that load plugins.
|
|
||||||
It provides you with access to the input and output objects of the program.
|
|
||||||
* **PRE_FILE_DOWNLOAD**, is triggered before files are downloaded and allows
|
|
||||||
you to manipulate the `RemoteFilesystem` object prior to downloading files
|
|
||||||
based on the URL to be downloaded.
|
|
||||||
|
|
||||||
> A plugin can also subscribe to [script events][7].
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
@ -148,7 +140,7 @@ list of installed packages. Additionally all plugin packages installed in the
|
||||||
local project plugins are loaded.
|
local project plugins are loaded.
|
||||||
|
|
||||||
> You may pass the `--no-plugins` option to composer commands to disable all
|
> You may pass the `--no-plugins` option to composer commands to disable all
|
||||||
> installed commands. This may be particularly helpful if any of the plugins
|
> installed plugins. This may be particularly helpful if any of the plugins
|
||||||
> causes errors and you wish to update or uninstall it.
|
> causes errors and you wish to update or uninstall it.
|
||||||
|
|
||||||
[1]: ../04-schema.md#type
|
[1]: ../04-schema.md#type
|
||||||
|
@ -157,4 +149,3 @@ local project plugins are loaded.
|
||||||
[4]: https://github.com/composer/composer/blob/master/src/Composer/Composer.php
|
[4]: https://github.com/composer/composer/blob/master/src/Composer/Composer.php
|
||||||
[5]: https://github.com/composer/composer/blob/master/src/Composer/IO/IOInterface.php
|
[5]: https://github.com/composer/composer/blob/master/src/Composer/IO/IOInterface.php
|
||||||
[6]: https://github.com/composer/composer/blob/master/src/Composer/EventDispatcher/EventSubscriberInterface.php
|
[6]: https://github.com/composer/composer/blob/master/src/Composer/EventDispatcher/EventSubscriberInterface.php
|
||||||
[7]: ./scripts.md#event-names
|
|
||||||
|
|
|
@ -20,20 +20,16 @@ the Composer execution process.
|
||||||
|
|
||||||
Composer fires the following named events during its execution process:
|
Composer fires the following named events during its execution process:
|
||||||
|
|
||||||
|
### Command Events
|
||||||
|
|
||||||
- **pre-install-cmd**: occurs before the `install` command is executed.
|
- **pre-install-cmd**: occurs before the `install` command is executed.
|
||||||
- **post-install-cmd**: occurs after the `install` command is executed.
|
- **post-install-cmd**: occurs after the `install` command is executed.
|
||||||
- **pre-update-cmd**: occurs before the `update` command is executed.
|
- **pre-update-cmd**: occurs before the `update` command is executed.
|
||||||
- **post-update-cmd**: occurs after the `update` command is executed.
|
- **post-update-cmd**: occurs after the `update` command is executed.
|
||||||
- **pre-status-cmd**: occurs before the `status` command is executed.
|
- **pre-status-cmd**: occurs before the `status` command is executed.
|
||||||
- **post-status-cmd**: occurs after the `status` command is executed.
|
- **post-status-cmd**: occurs after the `status` command is executed.
|
||||||
- **pre-dependencies-solving**: occurs before the dependencies are resolved.
|
- **pre-archive-cmd**: occurs before the `archive` command is executed.
|
||||||
- **post-dependencies-solving**: occurs after the dependencies are resolved.
|
- **post-archive-cmd**: occurs after the `archive` command is executed.
|
||||||
- **pre-package-install**: occurs before a package is installed.
|
|
||||||
- **post-package-install**: occurs after a package is installed.
|
|
||||||
- **pre-package-update**: occurs before a package is updated.
|
|
||||||
- **post-package-update**: occurs after a package is updated.
|
|
||||||
- **pre-package-uninstall**: occurs before a package has been uninstalled.
|
|
||||||
- **post-package-uninstall**: occurs after a package has been uninstalled.
|
|
||||||
- **pre-autoload-dump**: occurs before the autoloader is dumped, either
|
- **pre-autoload-dump**: occurs before the autoloader is dumped, either
|
||||||
during `install`/`update`, or via the `dump-autoload` command.
|
during `install`/`update`, or via the `dump-autoload` command.
|
||||||
- **post-autoload-dump**: occurs after the autoloader is dumped, either
|
- **post-autoload-dump**: occurs after the autoloader is dumped, either
|
||||||
|
@ -42,8 +38,28 @@ Composer fires the following named events during its execution process:
|
||||||
installed, during the `create-project` command.
|
installed, during the `create-project` command.
|
||||||
- **post-create-project-cmd**: occurs after the `create-project` command is
|
- **post-create-project-cmd**: occurs after the `create-project` command is
|
||||||
executed.
|
executed.
|
||||||
- **pre-archive-cmd**: occurs before the `archive` command is executed.
|
|
||||||
- **post-archive-cmd**: occurs after the `archive` command is executed.
|
### Installer Events
|
||||||
|
|
||||||
|
- **pre-dependencies-solving**: occurs before the dependencies are resolved.
|
||||||
|
- **post-dependencies-solving**: occurs after the dependencies are resolved.
|
||||||
|
|
||||||
|
### Package Events
|
||||||
|
|
||||||
|
- **pre-package-install**: occurs before a package is installed.
|
||||||
|
- **post-package-install**: occurs after a package is installed.
|
||||||
|
- **pre-package-update**: occurs before a package is updated.
|
||||||
|
- **post-package-update**: occurs after a package is updated.
|
||||||
|
- **pre-package-uninstall**: occurs before a package has been uninstalled.
|
||||||
|
- **post-package-uninstall**: occurs after a package has been uninstalled.
|
||||||
|
|
||||||
|
### Plugin Events
|
||||||
|
|
||||||
|
- **command**: occurs before any Composer Command is executed on the CLI. It
|
||||||
|
provides you with access to the input and output objects of the program.
|
||||||
|
- **pre-file-download**: occurs before files are downloaded and allows
|
||||||
|
you to manipulate the `RemoteFilesystem` object prior to downloading files
|
||||||
|
based on the URL to be downloaded.
|
||||||
|
|
||||||
> **Note:** Composer makes no assumptions about the state of your dependencies
|
> **Note:** Composer makes no assumptions about the state of your dependencies
|
||||||
> prior to `install` or `update`. Therefore, you should not specify scripts
|
> prior to `install` or `update`. Therefore, you should not specify scripts
|
||||||
|
@ -96,6 +112,7 @@ that might be used to execute the PHP callbacks:
|
||||||
namespace MyVendor;
|
namespace MyVendor;
|
||||||
|
|
||||||
use Composer\Script\Event;
|
use Composer\Script\Event;
|
||||||
|
use Composer\Installer\PackageEvent;
|
||||||
|
|
||||||
class MyClass
|
class MyClass
|
||||||
{
|
{
|
||||||
|
@ -105,7 +122,7 @@ class MyClass
|
||||||
// do stuff
|
// do stuff
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function postPackageInstall(Event $event)
|
public static function postPackageInstall(PackageEvent $event)
|
||||||
{
|
{
|
||||||
$installedPackage = $event->getOperation()->getPackage();
|
$installedPackage = $event->getOperation()->getPackage();
|
||||||
// do stuff
|
// do stuff
|
||||||
|
@ -118,14 +135,21 @@ class MyClass
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
When an event is fired, Composer's internal event handler receives a
|
When an event is fired, your PHP callback receives as first argument an
|
||||||
`Composer\Script\Event` object, which is passed as the first argument to your
|
`Composer\EventDispatcher\Event` object. This object has a `getName()` method
|
||||||
PHP callback. This `Event` object has getters for other contextual objects:
|
that lets you retrieve event name.
|
||||||
|
|
||||||
- `getComposer()`: returns the current instance of `Composer\Composer`
|
Depending on the script types (see list above) you will get various event
|
||||||
- `getName()`: returns the name of the event being fired as a string
|
subclasses containing various getters with relevant data and associated
|
||||||
- `getIO()`: returns the current input/output stream which implements
|
objects:
|
||||||
`Composer\IO\IOInterface` for writing to the console
|
|
||||||
|
- Base class: [`Composer\EventDispatcher\Event`](https://getcomposer.org/apidoc/master/Composer/EventDispatcher/Event.html)
|
||||||
|
- Command Events: [`Composer\Script\Event`](https://getcomposer.org/apidoc/master/Composer/Script/Event.html)
|
||||||
|
- Installer Events: [`Composer\Installer\InstallerEvent`](https://getcomposer.org/apidoc/master/Composer/Installer/InstallerEvent.html)
|
||||||
|
- Package Events: [`Composer\Installer\PackageEvent`](https://getcomposer.org/apidoc/master/Composer/Installer/PackageEvent.html)
|
||||||
|
- Plugin Events:
|
||||||
|
- command: [`Composer\Plugin\CommandEvent`](https://getcomposer.org/apidoc/master/Composer/Plugin/CommandEvent.html)
|
||||||
|
- pre-file-download: [`Composer\Plugin\PreFileDownloadEvent`](https://getcomposer.org/apidoc/master/Composer/Plugin/PreFileDownloadEvent.html)
|
||||||
|
|
||||||
## Running scripts manually
|
## Running scripts manually
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ compatible with the new major version of your dependency.
|
||||||
|
|
||||||
For example instead of using `>=3.4` you should use `~3.4` which allows all
|
For example instead of using `>=3.4` you should use `~3.4` which allows all
|
||||||
versions up to `3.999` but does not include `4.0` and above. The `~` operator
|
versions up to `3.999` but does not include `4.0` and above. The `~` operator
|
||||||
works very well with libraries follow [semantic versioning](http://semver.org).
|
works very well with libraries following [semantic versioning](http://semver.org).
|
||||||
|
|
||||||
**Note:** As a package maintainer, you can make the life of your users easier
|
**Note:** As a package maintainer, you can make the life of your users easier
|
||||||
by providing an [alias version](../articles/aliases.md) for your development
|
by providing an [alias version](../articles/aliases.md) for your development
|
||||||
|
|
|
@ -413,6 +413,13 @@
|
||||||
"format": "uri"
|
"format": "uri"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"non-feature-branches": {
|
||||||
|
"type": ["array"],
|
||||||
|
"description": "A set of string or regex patterns for non-numeric branch names that will not be handles as feature branches.",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,7 +216,16 @@ EOF;
|
||||||
$classmapFile .= ");\n";
|
$classmapFile .= ");\n";
|
||||||
|
|
||||||
if (!$suffix) {
|
if (!$suffix) {
|
||||||
$suffix = $config->get('autoloader-suffix') ?: md5(uniqid('', true));
|
if (is_readable($vendorPath.'/autoload.php')) {
|
||||||
|
$content = file_get_contents($vendorPath.'/autoload.php');
|
||||||
|
if (preg_match('{ComposerAutoloaderInit([^:\s]+)::}', $content, $match)) {
|
||||||
|
$suffix = $match[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$suffix) {
|
||||||
|
$suffix = $config->get('autoloader-suffix') ?: md5(uniqid('', true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file_put_contents($targetDir.'/autoload_namespaces.php', $namespacesFile);
|
file_put_contents($targetDir.'/autoload_namespaces.php', $namespacesFile);
|
||||||
|
@ -393,7 +402,7 @@ EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$filesCode) {
|
if (!$filesCode) {
|
||||||
return FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <<<EOF
|
return <<<EOF
|
||||||
|
|
|
@ -92,7 +92,7 @@ class ClassMapGenerator
|
||||||
if (!isset($map[$class])) {
|
if (!isset($map[$class])) {
|
||||||
$map[$class] = $filePath;
|
$map[$class] = $filePath;
|
||||||
} elseif ($io && $map[$class] !== $filePath && !preg_match('{/(test|fixture|example)s?/}i', strtr($map[$class].' '.$filePath, '\\', '/'))) {
|
} elseif ($io && $map[$class] !== $filePath && !preg_match('{/(test|fixture|example)s?/}i', strtr($map[$class].' '.$filePath, '\\', '/'))) {
|
||||||
$io->write(
|
$io->writeError(
|
||||||
'<warning>Warning: Ambiguous class resolution, "'.$class.'"'.
|
'<warning>Warning: Ambiguous class resolution, "'.$class.'"'.
|
||||||
' was found in both "'.$map[$class].'" and "'.$filePath.'", the first will be used.</warning>'
|
' was found in both "'.$map[$class].'" and "'.$filePath.'", the first will be used.</warning>'
|
||||||
);
|
);
|
||||||
|
@ -112,7 +112,10 @@ class ClassMapGenerator
|
||||||
*/
|
*/
|
||||||
private static function findClasses($path)
|
private static function findClasses($path)
|
||||||
{
|
{
|
||||||
$traits = version_compare(PHP_VERSION, '5.4', '<') ? '' : '|trait';
|
$extraTypes = version_compare(PHP_VERSION, '5.4', '<') ? '' : '|trait';
|
||||||
|
if (defined('HHVM_VERSION') && version_compare(HHVM_VERSION, '3.3', '>=')) {
|
||||||
|
$extraTypes .= '|enum';
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$contents = @php_strip_whitespace($path);
|
$contents = @php_strip_whitespace($path);
|
||||||
|
@ -129,7 +132,7 @@ class ClassMapGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
// return early if there is no chance of matching anything in this file
|
// return early if there is no chance of matching anything in this file
|
||||||
if (!preg_match('{\b(?:class|interface'.$traits.')\s}i', $contents)) {
|
if (!preg_match('{\b(?:class|interface'.$extraTypes.')\s}i', $contents)) {
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +157,7 @@ class ClassMapGenerator
|
||||||
|
|
||||||
preg_match_all('{
|
preg_match_all('{
|
||||||
(?:
|
(?:
|
||||||
\b(?<![\$:>])(?P<type>class|interface'.$traits.') \s+ (?P<name>[a-zA-Z_\x7f-\xff:][a-zA-Z0-9_\x7f-\xff:\-]*)
|
\b(?<![\$:>])(?P<type>class|interface'.$extraTypes.') \s+ (?P<name>[a-zA-Z_\x7f-\xff:][a-zA-Z0-9_\x7f-\xff:\-]*)
|
||||||
| \b(?<![\$:>])(?P<ns>namespace) (?P<nsname>\s+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?:\s*\\\\\s*[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*)? \s*[\{;]
|
| \b(?<![\$:>])(?P<ns>namespace) (?P<nsname>\s+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?:\s*\\\\\s*[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*)? \s*[\{;]
|
||||||
)
|
)
|
||||||
}ix', $contents, $matches);
|
}ix', $contents, $matches);
|
||||||
|
@ -170,6 +173,12 @@ class ClassMapGenerator
|
||||||
if ($name[0] === ':') {
|
if ($name[0] === ':') {
|
||||||
// This is an XHP class, https://github.com/facebook/xhp
|
// This is an XHP class, https://github.com/facebook/xhp
|
||||||
$name = 'xhp'.substr(str_replace(array('-', ':'), array('_', '__'), $name), 1);
|
$name = 'xhp'.substr(str_replace(array('-', ':'), array('_', '__'), $name), 1);
|
||||||
|
} else if ($matches['type'][$i] === 'enum') {
|
||||||
|
// In Hack, something like:
|
||||||
|
// enum Foo: int { HERP = '123'; }
|
||||||
|
// The regex above captures the colon, which isn't part of
|
||||||
|
// the class name.
|
||||||
|
$name = rtrim($name, ':');
|
||||||
}
|
}
|
||||||
$classes[] = ltrim($namespace . $name, '\\');
|
$classes[] = ltrim($namespace . $name, '\\');
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ class Cache
|
||||||
$file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file);
|
$file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file);
|
||||||
if ($this->enabled && file_exists($this->root . $file)) {
|
if ($this->enabled && file_exists($this->root . $file)) {
|
||||||
if ($this->io->isDebug()) {
|
if ($this->io->isDebug()) {
|
||||||
$this->io->write('Reading '.$this->root . $file.' from cache');
|
$this->io->writeError('Reading '.$this->root . $file.' from cache');
|
||||||
}
|
}
|
||||||
|
|
||||||
return file_get_contents($this->root . $file);
|
return file_get_contents($this->root . $file);
|
||||||
|
@ -80,7 +80,7 @@ class Cache
|
||||||
$file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file);
|
$file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file);
|
||||||
|
|
||||||
if ($this->io->isDebug()) {
|
if ($this->io->isDebug()) {
|
||||||
$this->io->write('Writing '.$this->root . $file.' into cache');
|
$this->io->writeError('Writing '.$this->root . $file.' into cache');
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -98,7 +98,7 @@ class Cache
|
||||||
@disk_free_space($this->root . dirname($file))
|
@disk_free_space($this->root . dirname($file))
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->io->write($message);
|
$this->io->writeError($message);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ class Cache
|
||||||
$this->filesystem->ensureDirectoryExists(dirname($this->root . $file));
|
$this->filesystem->ensureDirectoryExists(dirname($this->root . $file));
|
||||||
|
|
||||||
if ($this->io->isDebug()) {
|
if ($this->io->isDebug()) {
|
||||||
$this->io->write('Writing '.$this->root . $file.' into cache');
|
$this->io->writeError('Writing '.$this->root . $file.' into cache');
|
||||||
}
|
}
|
||||||
|
|
||||||
return copy($source, $this->root . $file);
|
return copy($source, $this->root . $file);
|
||||||
|
@ -139,7 +139,7 @@ class Cache
|
||||||
touch($this->root . $file);
|
touch($this->root . $file);
|
||||||
|
|
||||||
if ($this->io->isDebug()) {
|
if ($this->io->isDebug()) {
|
||||||
$this->io->write('Reading '.$this->root . $file.' from cache');
|
$this->io->writeError('Reading '.$this->root . $file.' from cache');
|
||||||
}
|
}
|
||||||
|
|
||||||
return copy($this->root . $file, $target);
|
return copy($this->root . $file, $target);
|
||||||
|
|
|
@ -34,7 +34,7 @@ EOT
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output)
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
{
|
{
|
||||||
$output->writeln(<<<EOT
|
$this->getIO()->write(<<<EOT
|
||||||
<info>Composer - Package Management for PHP</info>
|
<info>Composer - Package Management for PHP</info>
|
||||||
<comment>Composer is a dependency manager tracking local dependencies of your projects and libraries.
|
<comment>Composer is a dependency manager tracking local dependencies of your projects and libraries.
|
||||||
See http://getcomposer.org/ for more information.</comment>
|
See http://getcomposer.org/ for more information.</comment>
|
||||||
|
|
|
@ -97,7 +97,7 @@ EOT
|
||||||
$package = $this->getComposer()->getPackage();
|
$package = $this->getComposer()->getPackage();
|
||||||
}
|
}
|
||||||
|
|
||||||
$io->write('<info>Creating the archive.</info>');
|
$io->writeError('<info>Creating the archive.</info>');
|
||||||
$archiveManager->archive($package, $format, $dest);
|
$archiveManager->archive($package, $format, $dest);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -105,14 +105,14 @@ EOT
|
||||||
|
|
||||||
protected function selectPackage(IOInterface $io, $packageName, $version = null)
|
protected function selectPackage(IOInterface $io, $packageName, $version = null)
|
||||||
{
|
{
|
||||||
$io->write('<info>Searching for the specified package.</info>');
|
$io->writeError('<info>Searching for the specified package.</info>');
|
||||||
|
|
||||||
if ($composer = $this->getComposer(false)) {
|
if ($composer = $this->getComposer(false)) {
|
||||||
$localRepo = $composer->getRepositoryManager()->getLocalRepository();
|
$localRepo = $composer->getRepositoryManager()->getLocalRepository();
|
||||||
$repos = new CompositeRepository(array_merge(array($localRepo), $composer->getRepositoryManager()->getRepositories()));
|
$repos = new CompositeRepository(array_merge(array($localRepo), $composer->getRepositoryManager()->getRepositories()));
|
||||||
} else {
|
} else {
|
||||||
$defaultRepos = Factory::createDefaultRepositories($this->getIO());
|
$defaultRepos = Factory::createDefaultRepositories($this->getIO());
|
||||||
$io->write('No composer.json found in the current directory, searching packages from ' . implode(', ', array_keys($defaultRepos)));
|
$io->writeError('No composer.json found in the current directory, searching packages from ' . implode(', ', array_keys($defaultRepos)));
|
||||||
$repos = new CompositeRepository($defaultRepos);
|
$repos = new CompositeRepository($defaultRepos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,14 +125,14 @@ EOT
|
||||||
|
|
||||||
if (count($packages) > 1) {
|
if (count($packages) > 1) {
|
||||||
$package = reset($packages);
|
$package = reset($packages);
|
||||||
$io->write('<info>Found multiple matches, selected '.$package->getPrettyString().'.</info>');
|
$io->writeError('<info>Found multiple matches, selected '.$package->getPrettyString().'.</info>');
|
||||||
$io->write('Alternatives were '.implode(', ', array_map(function ($p) { return $p->getPrettyString(); }, $packages)).'.');
|
$io->writeError('Alternatives were '.implode(', ', array_map(function ($p) { return $p->getPrettyString(); }, $packages)).'.');
|
||||||
$io->write('<comment>Please use a more specific constraint to pick a different package.</comment>');
|
$io->writeError('<comment>Please use a more specific constraint to pick a different package.</comment>');
|
||||||
} elseif ($packages) {
|
} elseif ($packages) {
|
||||||
$package = reset($packages);
|
$package = reset($packages);
|
||||||
$io->write('<info>Found an exact match '.$package->getPrettyString().'.</info>');
|
$io->writeError('<info>Found an exact match '.$package->getPrettyString().'.</info>');
|
||||||
} else {
|
} else {
|
||||||
$io->write('<error>Could not find a package matching '.$packageName.'.</error>');
|
$io->writeError('<error>Could not find a package matching '.$packageName.'.</error>');
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,21 +51,21 @@ EOT
|
||||||
foreach ($cachePaths as $key => $cachePath) {
|
foreach ($cachePaths as $key => $cachePath) {
|
||||||
$cachePath = realpath($cachePath);
|
$cachePath = realpath($cachePath);
|
||||||
if (!$cachePath) {
|
if (!$cachePath) {
|
||||||
$io->write("<info>Cache directory does not exist ($key): $cachePath</info>");
|
$io->writeError("<info>Cache directory does not exist ($key): $cachePath</info>");
|
||||||
|
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
$cache = new Cache($io, $cachePath);
|
$cache = new Cache($io, $cachePath);
|
||||||
if (!$cache->isEnabled()) {
|
if (!$cache->isEnabled()) {
|
||||||
$io->write("<info>Cache is not enabled ($key): $cachePath</info>");
|
$io->writeError("<info>Cache is not enabled ($key): $cachePath</info>");
|
||||||
|
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$io->write("<info>Clearing cache ($key): $cachePath</info>");
|
$io->writeError("<info>Clearing cache ($key): $cachePath</info>");
|
||||||
$cache->gc(0, 0);
|
$cache->gc(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
$io->write('<info>All caches cleared.</info>');
|
$io->writeError('<info>All caches cleared.</info>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,15 +33,25 @@ class ConfigCommand extends Command
|
||||||
protected $config;
|
protected $config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Composer\Json\JsonFile
|
* @var JsonFile
|
||||||
*/
|
*/
|
||||||
protected $configFile;
|
protected $configFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Composer\Config\JsonConfigSource
|
* @var JsonConfigSource
|
||||||
*/
|
*/
|
||||||
protected $configSource;
|
protected $configSource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var JsonFile
|
||||||
|
*/
|
||||||
|
protected $authConfigFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var JsonConfigSource
|
||||||
|
*/
|
||||||
|
protected $authConfigSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -65,6 +75,15 @@ class ConfigCommand extends Command
|
||||||
This command allows you to edit some basic composer settings in either the
|
This command allows you to edit some basic composer settings in either the
|
||||||
local composer.json file or the global config.json file.
|
local composer.json file or the global config.json file.
|
||||||
|
|
||||||
|
To set a config setting:
|
||||||
|
|
||||||
|
<comment>%command.full_name% bin-dir bin/</comment>
|
||||||
|
|
||||||
|
To read a config setting:
|
||||||
|
|
||||||
|
<comment>%command.full_name% bin-dir</comment>
|
||||||
|
Outputs: <info>bin</info>
|
||||||
|
|
||||||
To edit the global config.json file:
|
To edit the global config.json file:
|
||||||
|
|
||||||
<comment>%command.full_name% --global</comment>
|
<comment>%command.full_name% --global</comment>
|
||||||
|
@ -73,7 +92,15 @@ To add a repository:
|
||||||
|
|
||||||
<comment>%command.full_name% repositories.foo vcs http://bar.com</comment>
|
<comment>%command.full_name% repositories.foo vcs http://bar.com</comment>
|
||||||
|
|
||||||
You can add a repository to the global config.json file by passing in the
|
To remove a repository (repo is a short alias for repositories):
|
||||||
|
|
||||||
|
<comment>%command.full_name% --unset repo.foo</comment>
|
||||||
|
|
||||||
|
To disable packagist:
|
||||||
|
|
||||||
|
<comment>%command.full_name% repo.packagist false</comment>
|
||||||
|
|
||||||
|
You can alter repositories in the global config.json file by passing in the
|
||||||
<info>--global</info> option.
|
<info>--global</info> option.
|
||||||
|
|
||||||
To edit the file in an external editor:
|
To edit the file in an external editor:
|
||||||
|
@ -230,55 +257,13 @@ EOT
|
||||||
$value = json_encode($value);
|
$value = json_encode($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
$output->writeln($value);
|
$this->getIO()->write($value);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$values = $input->getArgument('setting-value'); // what the user is trying to add/change
|
$values = $input->getArgument('setting-value'); // what the user is trying to add/change
|
||||||
|
|
||||||
// handle repositories
|
|
||||||
if (preg_match('/^repos?(?:itories)?\.(.+)/', $settingKey, $matches)) {
|
|
||||||
if ($input->getOption('unset')) {
|
|
||||||
return $this->configSource->removeRepository($matches[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
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');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->configSource->addRepository($matches[1], array(
|
|
||||||
'type' => $values[0],
|
|
||||||
'url' => $values[1],
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle github-oauth
|
|
||||||
if (preg_match('/^(github-oauth|http-basic)\.(.+)/', $settingKey, $matches)) {
|
|
||||||
if ($input->getOption('unset')) {
|
|
||||||
$this->authConfigSource->removeConfigSetting($matches[1].'.'.$matches[2]);
|
|
||||||
$this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($matches[1] === 'github-oauth') {
|
|
||||||
if (1 !== count($values)) {
|
|
||||||
throw new \RuntimeException('Too many arguments, expected only one token');
|
|
||||||
}
|
|
||||||
$this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
|
|
||||||
$this->authConfigSource->addConfigSetting($matches[1].'.'.$matches[2], $values[0]);
|
|
||||||
} elseif ($matches[1] === 'http-basic') {
|
|
||||||
if (2 !== count($values)) {
|
|
||||||
throw new \RuntimeException('Expected two arguments (username, password), got '.count($values));
|
|
||||||
}
|
|
||||||
$this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
|
|
||||||
$this->authConfigSource->addConfigSetting($matches[1].'.'.$matches[2], array('username' => $values[0], 'password' => $values[1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$booleanValidator = function ($val) { return in_array($val, array('true', 'false', '1', '0'), true); };
|
$booleanValidator = function ($val) { return in_array($val, array('true', 'false', '1', '0'), true); };
|
||||||
$booleanNormalizer = function ($val) { return $val !== 'false' && (bool) $val; };
|
$booleanNormalizer = function ($val) { return $val !== 'false' && (bool) $val; };
|
||||||
|
|
||||||
|
@ -402,6 +387,55 @@ EOT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handle repositories
|
||||||
|
if (preg_match('/^repos?(?:itories)?\.(.+)/', $settingKey, $matches)) {
|
||||||
|
if ($input->getOption('unset')) {
|
||||||
|
return $this->configSource->removeRepository($matches[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (2 === count($values)) {
|
||||||
|
return $this->configSource->addRepository($matches[1], array(
|
||||||
|
'type' => $values[0],
|
||||||
|
'url' => $values[1],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (1 === count($values)) {
|
||||||
|
$bool = strtolower($values[0]);
|
||||||
|
if (true === $booleanValidator($bool) && false === $booleanNormalizer($bool)) {
|
||||||
|
return $this->configSource->addRepository($matches[1], false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \RuntimeException('You must pass the type and a url. Example: php composer.phar config repositories.foo vcs http://bar.com');
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle github-oauth
|
||||||
|
if (preg_match('/^(github-oauth|http-basic)\.(.+)/', $settingKey, $matches)) {
|
||||||
|
if ($input->getOption('unset')) {
|
||||||
|
$this->authConfigSource->removeConfigSetting($matches[1].'.'.$matches[2]);
|
||||||
|
$this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($matches[1] === 'github-oauth') {
|
||||||
|
if (1 !== count($values)) {
|
||||||
|
throw new \RuntimeException('Too many arguments, expected only one token');
|
||||||
|
}
|
||||||
|
$this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
|
||||||
|
$this->authConfigSource->addConfigSetting($matches[1].'.'.$matches[2], $values[0]);
|
||||||
|
} elseif ($matches[1] === 'http-basic') {
|
||||||
|
if (2 !== count($values)) {
|
||||||
|
throw new \RuntimeException('Expected two arguments (username, password), got '.count($values));
|
||||||
|
}
|
||||||
|
$this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
|
||||||
|
$this->authConfigSource->addConfigSetting($matches[1].'.'.$matches[2], array('username' => $values[0], 'password' => $values[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
throw new \InvalidArgumentException('Setting '.$settingKey.' does not exist or is not supported by this command');
|
throw new \InvalidArgumentException('Setting '.$settingKey.' does not exist or is not supported by this command');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,9 +484,9 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_string($rawVal) && $rawVal != $value) {
|
if (is_string($rawVal) && $rawVal != $value) {
|
||||||
$output->writeln('[<comment>' . $k . $key . '</comment>] <info>' . $rawVal . ' (' . $value . ')</info>');
|
$this->getIO()->write('[<comment>' . $k . $key . '</comment>] <info>' . $rawVal . ' (' . $value . ')</info>');
|
||||||
} else {
|
} else {
|
||||||
$output->writeln('[<comment>' . $k . $key . '</comment>] <info>' . $value . '</info>');
|
$this->getIO()->write('[<comment>' . $k . $key . '</comment>] <info>' . $value . '</info>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ EOT
|
||||||
$this->updatePreferredOptions($config, $input, $preferSource, $preferDist);
|
$this->updatePreferredOptions($config, $input, $preferSource, $preferDist);
|
||||||
|
|
||||||
if ($input->getOption('no-custom-installers')) {
|
if ($input->getOption('no-custom-installers')) {
|
||||||
$output->writeln('<warning>You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.</warning>');
|
$this->getIO()->writeError('<warning>You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.</warning>');
|
||||||
$input->setOption('no-plugins', true);
|
$input->setOption('no-plugins', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,11 +145,13 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
$composer = Factory::create($io, null, $disablePlugins);
|
$composer = Factory::create($io, null, $disablePlugins);
|
||||||
|
$composer->getDownloadManager()->setOutputProgress(!$noProgress);
|
||||||
|
|
||||||
$fs = new Filesystem();
|
$fs = new Filesystem();
|
||||||
|
|
||||||
if ($noScripts === false) {
|
if ($noScripts === false) {
|
||||||
// dispatch event
|
// dispatch event
|
||||||
$composer->getEventDispatcher()->dispatchCommandEvent(ScriptEvents::POST_ROOT_PACKAGE_INSTALL, $installDevPackages);
|
$composer->getEventDispatcher()->dispatchScript(ScriptEvents::POST_ROOT_PACKAGE_INSTALL, $installDevPackages);
|
||||||
}
|
}
|
||||||
|
|
||||||
$rootPackageConfig = $composer->getConfig();
|
$rootPackageConfig = $composer->getConfig();
|
||||||
|
@ -196,7 +198,7 @@ EOT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$io->write('<error>An error occurred while removing the VCS metadata: '.$e->getMessage().'</error>');
|
$io->writeError('<error>An error occurred while removing the VCS metadata: '.$e->getMessage().'</error>');
|
||||||
}
|
}
|
||||||
|
|
||||||
$hasVcs = false;
|
$hasVcs = false;
|
||||||
|
@ -217,7 +219,7 @@ EOT
|
||||||
|
|
||||||
if ($noScripts === false) {
|
if ($noScripts === false) {
|
||||||
// dispatch event
|
// dispatch event
|
||||||
$composer->getEventDispatcher()->dispatchCommandEvent(ScriptEvents::POST_CREATE_PROJECT_CMD, $installDevPackages);
|
$composer->getEventDispatcher()->dispatchScript(ScriptEvents::POST_CREATE_PROJECT_CMD, $installDevPackages);
|
||||||
}
|
}
|
||||||
|
|
||||||
chdir($oldCwd);
|
chdir($oldCwd);
|
||||||
|
@ -288,10 +290,10 @@ EOT
|
||||||
$directory = getcwd() . DIRECTORY_SEPARATOR . array_pop($parts);
|
$directory = getcwd() . DIRECTORY_SEPARATOR . array_pop($parts);
|
||||||
}
|
}
|
||||||
|
|
||||||
$io->write('<info>Installing ' . $package->getName() . ' (' . VersionParser::formatVersion($package, false) . ')</info>');
|
$io->writeError('<info>Installing ' . $package->getName() . ' (' . VersionParser::formatVersion($package, false) . ')</info>');
|
||||||
|
|
||||||
if ($disablePlugins) {
|
if ($disablePlugins) {
|
||||||
$io->write('<info>Plugins have been disabled.</info>');
|
$io->writeError('<info>Plugins have been disabled.</info>');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 === strpos($package->getPrettyVersion(), 'dev-') && in_array($package->getSourceType(), array('git', 'hg'))) {
|
if (0 === strpos($package->getPrettyVersion(), 'dev-') && in_array($package->getSourceType(), array('git', 'hg'))) {
|
||||||
|
@ -311,10 +313,11 @@ EOT
|
||||||
|
|
||||||
$installedFromVcs = 'source' === $package->getInstallationSource();
|
$installedFromVcs = 'source' === $package->getInstallationSource();
|
||||||
|
|
||||||
$io->write('<info>Created project in ' . $directory . '</info>');
|
$io->writeError('<info>Created project in ' . $directory . '</info>');
|
||||||
chdir($directory);
|
chdir($directory);
|
||||||
|
|
||||||
putenv('COMPOSER_ROOT_VERSION='.$package->getPrettyVersion());
|
$_SERVER['COMPOSER_ROOT_VERSION'] = $package->getPrettyVersion();
|
||||||
|
putenv('COMPOSER_ROOT_VERSION='.$_SERVER['COMPOSER_ROOT_VERSION']);
|
||||||
|
|
||||||
return $installedFromVcs;
|
return $installedFromVcs;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,9 +96,9 @@ EOT
|
||||||
|
|
||||||
if ($messages) {
|
if ($messages) {
|
||||||
sort($messages);
|
sort($messages);
|
||||||
$output->writeln($messages);
|
$this->getIO()->write($messages);
|
||||||
} else {
|
} else {
|
||||||
$output->writeln('<info>There is no installed package depending on "'.$needle.'".</info>');
|
$this->getIO()->writeError('<info>There is no installed package depending on "'.$needle.'".</info>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,8 +59,8 @@ EOT
|
||||||
$commandEvent = new CommandEvent(PluginEvents::COMMAND, 'diagnose', $input, $output);
|
$commandEvent = new CommandEvent(PluginEvents::COMMAND, 'diagnose', $input, $output);
|
||||||
$composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
|
$composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
|
||||||
|
|
||||||
$output->write('Checking composer.json: ');
|
$this->getIO()->write('Checking composer.json: ', false);
|
||||||
$this->outputResult($output, $this->checkComposerSchema());
|
$this->outputResult($this->checkComposerSchema());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($composer) {
|
if ($composer) {
|
||||||
|
@ -72,37 +72,37 @@ EOT
|
||||||
$this->rfs = new RemoteFilesystem($this->getIO(), $config);
|
$this->rfs = new RemoteFilesystem($this->getIO(), $config);
|
||||||
$this->process = new ProcessExecutor($this->getIO());
|
$this->process = new ProcessExecutor($this->getIO());
|
||||||
|
|
||||||
$output->write('Checking platform settings: ');
|
$this->getIO()->write('Checking platform settings: ', false);
|
||||||
$this->outputResult($output, $this->checkPlatform());
|
$this->outputResult($this->checkPlatform());
|
||||||
|
|
||||||
$output->write('Checking git settings: ');
|
$this->getIO()->write('Checking git settings: ', false);
|
||||||
$this->outputResult($output, $this->checkGit());
|
$this->outputResult($this->checkGit());
|
||||||
|
|
||||||
$output->write('Checking http connectivity: ');
|
$this->getIO()->write('Checking http connectivity: ', false);
|
||||||
$this->outputResult($output, $this->checkHttp());
|
$this->outputResult($this->checkHttp());
|
||||||
|
|
||||||
$opts = stream_context_get_options(StreamContextFactory::getContext('http://example.org'));
|
$opts = stream_context_get_options(StreamContextFactory::getContext('http://example.org'));
|
||||||
if (!empty($opts['http']['proxy'])) {
|
if (!empty($opts['http']['proxy'])) {
|
||||||
$output->write('Checking HTTP proxy: ');
|
$this->getIO()->write('Checking HTTP proxy: ', false);
|
||||||
$this->outputResult($output, $this->checkHttpProxy());
|
$this->outputResult($this->checkHttpProxy());
|
||||||
$output->write('Checking HTTP proxy support for request_fulluri: ');
|
$this->getIO()->write('Checking HTTP proxy support for request_fulluri: ', false);
|
||||||
$this->outputResult($output, $this->checkHttpProxyFullUriRequestParam());
|
$this->outputResult($this->checkHttpProxyFullUriRequestParam());
|
||||||
$output->write('Checking HTTPS proxy support for request_fulluri: ');
|
$this->getIO()->write('Checking HTTPS proxy support for request_fulluri: ', false);
|
||||||
$this->outputResult($output, $this->checkHttpsProxyFullUriRequestParam());
|
$this->outputResult($this->checkHttpsProxyFullUriRequestParam());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($oauth = $config->get('github-oauth')) {
|
if ($oauth = $config->get('github-oauth')) {
|
||||||
foreach ($oauth as $domain => $token) {
|
foreach ($oauth as $domain => $token) {
|
||||||
$output->write('Checking '.$domain.' oauth access: ');
|
$this->getIO()->write('Checking '.$domain.' oauth access: ', false);
|
||||||
$this->outputResult($output, $this->checkGithubOauth($domain, $token));
|
$this->outputResult($this->checkGithubOauth($domain, $token));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$output->write('Checking github.com rate limit: ');
|
$this->getIO()->write('Checking github.com rate limit: ', false);
|
||||||
$rate = $this->getGithubRateLimit('github.com');
|
$rate = $this->getGithubRateLimit('github.com');
|
||||||
|
|
||||||
if (10 > $rate['remaining']) {
|
if (10 > $rate['remaining']) {
|
||||||
$output->writeln('<warning>WARNING</warning>');
|
$this->getIO()->write('<warning>WARNING</warning>');
|
||||||
$output->writeln(sprintf(
|
$this->getIO()->write(sprintf(
|
||||||
'<comment>Github has a rate limit on their API. '
|
'<comment>Github has a rate limit on their API. '
|
||||||
. 'You currently have <options=bold>%u</options=bold> '
|
. 'You currently have <options=bold>%u</options=bold> '
|
||||||
. 'out of <options=bold>%u</options=bold> requests left.' . PHP_EOL
|
. 'out of <options=bold>%u</options=bold> requests left.' . PHP_EOL
|
||||||
|
@ -112,15 +112,15 @@ EOT
|
||||||
$rate['limit']
|
$rate['limit']
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
$output->writeln('<info>OK</info>');
|
$this->getIO()->write('<info>OK</info>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$output->write('Checking disk free space: ');
|
$this->getIO()->write('Checking disk free space: ', false);
|
||||||
$this->outputResult($output, $this->checkDiskSpace($config));
|
$this->outputResult($this->checkDiskSpace($config));
|
||||||
|
|
||||||
$output->write('Checking composer version: ');
|
$this->getIO()->write('Checking composer version: ', false);
|
||||||
$this->outputResult($output, $this->checkVersion());
|
$this->outputResult($this->checkVersion());
|
||||||
|
|
||||||
return $this->failures;
|
return $this->failures;
|
||||||
}
|
}
|
||||||
|
@ -308,17 +308,17 @@ EOT
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function outputResult(OutputInterface $output, $result)
|
private function outputResult($result)
|
||||||
{
|
{
|
||||||
if (true === $result) {
|
if (true === $result) {
|
||||||
$output->writeln('<info>OK</info>');
|
$this->getIO()->write('<info>OK</info>');
|
||||||
} else {
|
} else {
|
||||||
$this->failures++;
|
$this->failures++;
|
||||||
$output->writeln('<error>FAIL</error>');
|
$this->getIO()->write('<error>FAIL</error>');
|
||||||
if ($result instanceof \Exception) {
|
if ($result instanceof \Exception) {
|
||||||
$output->writeln('['.get_class($result).'] '.$result->getMessage());
|
$this->getIO()->write('['.get_class($result).'] '.$result->getMessage());
|
||||||
} elseif ($result) {
|
} elseif ($result) {
|
||||||
$output->writeln(trim($result));
|
$this->getIO()->write(trim($result));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -343,10 +343,34 @@ EOT
|
||||||
}
|
}
|
||||||
$iniMessage .= PHP_EOL.'If you can not modify the ini file, you can also run `php -d option=value` to modify ini values on the fly. You can use -d multiple times.';
|
$iniMessage .= PHP_EOL.'If you can not modify the ini file, you can also run `php -d option=value` to modify ini values on the fly. You can use -d multiple times.';
|
||||||
|
|
||||||
|
if (!function_exists('json_decode')) {
|
||||||
|
$errors['json'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!extension_loaded('Phar')) {
|
||||||
|
$errors['phar'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!extension_loaded('filter')) {
|
||||||
|
$errors['filter'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!extension_loaded('hash')) {
|
||||||
|
$errors['hash'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!extension_loaded('ctype')) {
|
||||||
|
$errors['ctype'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ini_get('allow_url_fopen')) {
|
if (!ini_get('allow_url_fopen')) {
|
||||||
$errors['allow_url_fopen'] = true;
|
$errors['allow_url_fopen'] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (extension_loaded('ionCube Loader') && ioncube_loader_iversion() < 40009) {
|
||||||
|
$errors['ioncube'] = ioncube_loader_version();
|
||||||
|
}
|
||||||
|
|
||||||
if (version_compare(PHP_VERSION, '5.3.2', '<')) {
|
if (version_compare(PHP_VERSION, '5.3.2', '<')) {
|
||||||
$errors['php'] = PHP_VERSION;
|
$errors['php'] = PHP_VERSION;
|
||||||
}
|
}
|
||||||
|
@ -356,19 +380,13 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!extension_loaded('openssl')) {
|
if (!extension_loaded('openssl')) {
|
||||||
$warnings['openssl'] = true;
|
$errors['openssl'] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!defined('HHVM_VERSION') && !extension_loaded('apcu') && ini_get('apc.enable_cli')) {
|
if (!defined('HHVM_VERSION') && !extension_loaded('apcu') && ini_get('apc.enable_cli')) {
|
||||||
$warnings['apc_cli'] = true;
|
$warnings['apc_cli'] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ini_get('xdebug.profiler_enabled')) {
|
|
||||||
$warnings['xdebug_profile'] = true;
|
|
||||||
} elseif (extension_loaded('xdebug')) {
|
|
||||||
$warnings['xdebug_loaded'] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
phpinfo(INFO_GENERAL);
|
phpinfo(INFO_GENERAL);
|
||||||
$phpinfo = ob_get_clean();
|
$phpinfo = ob_get_clean();
|
||||||
|
@ -384,19 +402,76 @@ EOT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ini_get('xdebug.profiler_enabled')) {
|
||||||
|
$warnings['xdebug_profile'] = true;
|
||||||
|
} elseif (extension_loaded('xdebug')) {
|
||||||
|
$warnings['xdebug_loaded'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty($errors)) {
|
if (!empty($errors)) {
|
||||||
foreach ($errors as $error => $current) {
|
foreach ($errors as $error => $current) {
|
||||||
switch ($error) {
|
switch ($error) {
|
||||||
|
case 'json':
|
||||||
|
$text = PHP_EOL."The json extension is missing.".PHP_EOL;
|
||||||
|
$text .= "Install it or recompile php without --disable-json";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'phar':
|
||||||
|
$text = PHP_EOL."The phar extension is missing.".PHP_EOL;
|
||||||
|
$text .= "Install it or recompile php without --disable-phar";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'filter':
|
||||||
|
$text = PHP_EOL."The filter extension is missing.".PHP_EOL;
|
||||||
|
$text .= "Install it or recompile php without --disable-filter";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'hash':
|
||||||
|
$text = PHP_EOL."The hash extension is missing.".PHP_EOL;
|
||||||
|
$text .= "Install it or recompile php without --disable-hash";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'ctype':
|
||||||
|
$text = PHP_EOL."The ctype extension is missing.".PHP_EOL;
|
||||||
|
$text .= "Install it or recompile php without --disable-ctype";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'unicode':
|
||||||
|
$text = PHP_EOL."The detect_unicode setting must be disabled.".PHP_EOL;
|
||||||
|
$text .= "Add the following to the end of your `php.ini`:".PHP_EOL;
|
||||||
|
$text .= " detect_unicode = Off";
|
||||||
|
$displayIniMessage = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'suhosin':
|
||||||
|
$text = PHP_EOL."The suhosin.executor.include.whitelist setting is incorrect.".PHP_EOL;
|
||||||
|
$text .= "Add the following to the end of your `php.ini` or suhosin.ini (Example path [for Debian]: /etc/php5/cli/conf.d/suhosin.ini):".PHP_EOL;
|
||||||
|
$text .= " suhosin.executor.include.whitelist = phar ".$current;
|
||||||
|
$displayIniMessage = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'php':
|
case 'php':
|
||||||
$text = "Your PHP ({$current}) is too old, you must upgrade to PHP 5.3.2 or higher.";
|
$text = PHP_EOL."Your PHP ({$current}) is too old, you must upgrade to PHP 5.3.2 or higher.";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'allow_url_fopen':
|
case 'allow_url_fopen':
|
||||||
$text = "The allow_url_fopen setting is incorrect.".PHP_EOL;
|
$text = PHP_EOL."The allow_url_fopen setting is incorrect.".PHP_EOL;
|
||||||
$text .= "Add the following to the end of your `php.ini`:".PHP_EOL;
|
$text .= "Add the following to the end of your `php.ini`:".PHP_EOL;
|
||||||
$text .= " allow_url_fopen = On";
|
$text .= " allow_url_fopen = On";
|
||||||
$displayIniMessage = true;
|
$displayIniMessage = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'ioncube':
|
||||||
|
$text = PHP_EOL."Your ionCube Loader extension ($current) is incompatible with Phar files.".PHP_EOL;
|
||||||
|
$text .= "Upgrade to ionCube 4.0.9 or higher or remove this line (path may be different) from your `php.ini` to disable it:".PHP_EOL;
|
||||||
|
$text .= " zend_extension = /usr/lib/php5/20090626+lfs/ioncube_loader_lin_5.3.so";
|
||||||
|
$displayIniMessage = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'openssl':
|
||||||
|
$text = PHP_EOL."The openssl extension is missing, which means that secure HTTPS transfers are impossible.".PHP_EOL;
|
||||||
|
$text .= "If possible you should enable it or recompile php with --with-openssl";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
$out($text, 'error');
|
$out($text, 'error');
|
||||||
}
|
}
|
||||||
|
@ -425,11 +500,6 @@ EOT
|
||||||
$text .= " Recompile it without this flag if possible";
|
$text .= " Recompile it without this flag if possible";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'openssl':
|
|
||||||
$text = "The openssl extension is missing, which will reduce the security and stability of Composer.".PHP_EOL;
|
|
||||||
$text .= " If possible you should enable it or recompile php with --with-openssl";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'php':
|
case 'php':
|
||||||
$text = "Your PHP ({$current}) is quite old, upgrading to PHP 5.3.4 or higher is recommended.".PHP_EOL;
|
$text = "Your PHP ({$current}) is quite old, upgrading to PHP 5.3.4 or higher is recommended.".PHP_EOL;
|
||||||
$text .= " Composer works with 5.3.2+ for most people, but there might be edge case issues.";
|
$text .= " Composer works with 5.3.2+ for most people, but there might be edge case issues.";
|
||||||
|
|
|
@ -55,9 +55,9 @@ EOT
|
||||||
$optimize = $input->getOption('optimize') || $config->get('optimize-autoloader') || $config->get('classmap-authoritative');
|
$optimize = $input->getOption('optimize') || $config->get('optimize-autoloader') || $config->get('classmap-authoritative');
|
||||||
|
|
||||||
if ($optimize) {
|
if ($optimize) {
|
||||||
$output->writeln('<info>Generating optimized autoload files</info>');
|
$this->getIO()->writeError('<info>Generating optimized autoload files</info>');
|
||||||
} else {
|
} else {
|
||||||
$output->writeln('<info>Generating autoload files</info>');
|
$this->getIO()->writeError('<info>Generating autoload files</info>');
|
||||||
}
|
}
|
||||||
|
|
||||||
$generator = $composer->getAutoloadGenerator();
|
$generator = $composer->getAutoloadGenerator();
|
||||||
|
|
|
@ -72,7 +72,7 @@ EOT
|
||||||
// change to global dir
|
// change to global dir
|
||||||
$config = Factory::createConfig();
|
$config = Factory::createConfig();
|
||||||
chdir($config->get('home'));
|
chdir($config->get('home'));
|
||||||
$output->writeln('<info>Changed current directory to '.$config->get('home').'</info>');
|
$this->getIO()->writeError('<info>Changed current directory to '.$config->get('home').'</info>');
|
||||||
|
|
||||||
// create new input without "global" command prefix
|
// create new input without "global" command prefix
|
||||||
$input = new StringInput(preg_replace('{\bg(?:l(?:o(?:b(?:a(?:l)?)?)?)?)?\b}', '', $input->__toString(), 1));
|
$input = new StringInput(preg_replace('{\bg(?:l(?:o(?:b(?:a(?:l)?)?)?)?)?\b}', '', $input->__toString(), 1));
|
||||||
|
|
|
@ -57,15 +57,21 @@ EOT
|
||||||
*/
|
*/
|
||||||
protected function execute(InputInterface $input, OutputInterface $output)
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
{
|
{
|
||||||
$repo = $this->initializeRepo();
|
$repos = $this->initializeRepos();
|
||||||
$return = 0;
|
$return = 0;
|
||||||
|
|
||||||
foreach ($input->getArgument('packages') as $packageName) {
|
foreach ($input->getArgument('packages') as $packageName) {
|
||||||
|
foreach ($repos as $repo) {
|
||||||
|
$package = $this->getPackage($repo, $packageName);
|
||||||
|
if ($package instanceof CompletePackageInterface) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
$package = $this->getPackage($repo, $packageName);
|
$package = $this->getPackage($repo, $packageName);
|
||||||
|
|
||||||
if (!$package instanceof CompletePackageInterface) {
|
if (!$package instanceof CompletePackageInterface) {
|
||||||
$return = 1;
|
$return = 1;
|
||||||
$output->writeln('<warning>Package '.$packageName.' not found</warning>');
|
$this->getIO()->writeError('<warning>Package '.$packageName.' not found</warning>');
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -78,13 +84,13 @@ EOT
|
||||||
|
|
||||||
if (!filter_var($url, FILTER_VALIDATE_URL)) {
|
if (!filter_var($url, FILTER_VALIDATE_URL)) {
|
||||||
$return = 1;
|
$return = 1;
|
||||||
$output->writeln('<warning>'.($input->getOption('homepage') ? 'Invalid or missing homepage' : 'Invalid or missing repository URL').' for '.$packageName.'</warning>');
|
$this->getIO()->writeError('<warning>'.($input->getOption('homepage') ? 'Invalid or missing homepage' : 'Invalid or missing repository URL').' for '.$packageName.'</warning>');
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($input->getOption('show')) {
|
if ($input->getOption('show')) {
|
||||||
$output->writeln(sprintf('<info>%s</info>', $url));
|
$this->getIO()->write(sprintf('<info>%s</info>', $url));
|
||||||
} else {
|
} else {
|
||||||
$this->openBrowser($url);
|
$this->openBrowser($url);
|
||||||
}
|
}
|
||||||
|
@ -139,26 +145,30 @@ EOT
|
||||||
} elseif (0 === $osx) {
|
} elseif (0 === $osx) {
|
||||||
passthru('open ' . $url);
|
passthru('open ' . $url);
|
||||||
} else {
|
} else {
|
||||||
$this->getIO()->write('no suitable browser opening command found, open yourself: ' . $url);
|
$this->getIO()->writeError('no suitable browser opening command found, open yourself: ' . $url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the repo
|
* Initializes repositories
|
||||||
*
|
*
|
||||||
* @return CompositeRepository
|
* Returns an array of repos in order they should be checked in
|
||||||
|
*
|
||||||
|
* @return RepositoryInterface[]
|
||||||
*/
|
*/
|
||||||
private function initializeRepo()
|
private function initializeRepos()
|
||||||
{
|
{
|
||||||
$composer = $this->getComposer(false);
|
$composer = $this->getComposer(false);
|
||||||
|
|
||||||
if ($composer) {
|
if ($composer) {
|
||||||
$repo = new CompositeRepository($composer->getRepositoryManager()->getRepositories());
|
return array(
|
||||||
} else {
|
$composer->getRepositoryManager()->getLocalRepository(),
|
||||||
$defaultRepos = Factory::createDefaultRepositories($this->getIO());
|
new CompositeRepository($composer->getRepositoryManager()->getRepositories())
|
||||||
$repo = new CompositeRepository($defaultRepos);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $repo;
|
$defaultRepos = Factory::createDefaultRepositories($this->getIO());
|
||||||
|
|
||||||
|
return array(new CompositeRepository($defaultRepos));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,13 +117,13 @@ EOT
|
||||||
$json = $file->encode($options);
|
$json = $file->encode($options);
|
||||||
|
|
||||||
if ($input->isInteractive()) {
|
if ($input->isInteractive()) {
|
||||||
$output->writeln(array(
|
$this->getIO()->writeError(array(
|
||||||
'',
|
'',
|
||||||
$json,
|
$json,
|
||||||
''
|
''
|
||||||
));
|
));
|
||||||
if (!$dialog->askConfirmation($output, $dialog->getQuestion('Do you confirm generation', 'yes', '?'), true)) {
|
if (!$dialog->askConfirmation($output, $dialog->getQuestion('Do you confirm generation', 'yes', '?'), true)) {
|
||||||
$output->writeln('<error>Command aborted</error>');
|
$this->getIO()->writeError('<error>Command aborted</error>');
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -154,14 +154,14 @@ EOT
|
||||||
|
|
||||||
$dialog = $this->getHelperSet()->get('dialog');
|
$dialog = $this->getHelperSet()->get('dialog');
|
||||||
$formatter = $this->getHelperSet()->get('formatter');
|
$formatter = $this->getHelperSet()->get('formatter');
|
||||||
$output->writeln(array(
|
$this->getIO()->writeError(array(
|
||||||
'',
|
'',
|
||||||
$formatter->formatBlock('Welcome to the Composer config generator', 'bg=blue;fg=white', true),
|
$formatter->formatBlock('Welcome to the Composer config generator', 'bg=blue;fg=white', true),
|
||||||
''
|
''
|
||||||
));
|
));
|
||||||
|
|
||||||
// namespace
|
// namespace
|
||||||
$output->writeln(array(
|
$this->getIO()->writeError(array(
|
||||||
'',
|
'',
|
||||||
'This command will guide you through creating your composer.json config.',
|
'This command will guide you through creating your composer.json config.',
|
||||||
'',
|
'',
|
||||||
|
@ -266,7 +266,7 @@ EOT
|
||||||
);
|
);
|
||||||
$input->setOption('license', $license);
|
$input->setOption('license', $license);
|
||||||
|
|
||||||
$output->writeln(array(
|
$this->getIO()->writeError(array(
|
||||||
'',
|
'',
|
||||||
'Define your dependencies.',
|
'Define your dependencies.',
|
||||||
''
|
''
|
||||||
|
@ -316,7 +316,7 @@ EOT
|
||||||
$version = $this->findBestVersionForPackage($input, $requirement['name']);
|
$version = $this->findBestVersionForPackage($input, $requirement['name']);
|
||||||
$requirement['version'] = $version;
|
$requirement['version'] = $version;
|
||||||
|
|
||||||
$output->writeln(sprintf(
|
$this->getIO()->writeError(sprintf(
|
||||||
'Using version <info>%s</info> for <info>%s</info>',
|
'Using version <info>%s</info> for <info>%s</info>',
|
||||||
$requirement['version'],
|
$requirement['version'],
|
||||||
$requirement['name']
|
$requirement['name']
|
||||||
|
@ -329,6 +329,7 @@ EOT
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$versionParser = new VersionParser();
|
||||||
while (null !== $package = $dialog->ask($output, $prompt)) {
|
while (null !== $package = $dialog->ask($output, $prompt)) {
|
||||||
$matches = $this->findPackages($package);
|
$matches = $this->findPackages($package);
|
||||||
|
|
||||||
|
@ -345,31 +346,41 @@ EOT
|
||||||
|
|
||||||
// no match, prompt which to pick
|
// no match, prompt which to pick
|
||||||
if (!$exactMatch) {
|
if (!$exactMatch) {
|
||||||
$output->writeln(array(
|
$this->getIO()->writeError(array(
|
||||||
'',
|
'',
|
||||||
sprintf('Found <info>%s</info> packages matching <info>%s</info>', count($matches), $package),
|
sprintf('Found <info>%s</info> packages matching <info>%s</info>', count($matches), $package),
|
||||||
''
|
''
|
||||||
));
|
));
|
||||||
|
|
||||||
$output->writeln($choices);
|
$this->getIO()->writeError($choices);
|
||||||
$output->writeln('');
|
$this->getIO()->writeError('');
|
||||||
|
|
||||||
$validator = function ($selection) use ($matches) {
|
$validator = function ($selection) use ($matches, $versionParser) {
|
||||||
if ('' === $selection) {
|
if ('' === $selection) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_numeric($selection) && preg_match('{^\s*(\S+)\s+(\S.*)\s*$}', $selection, $matches)) {
|
if (is_numeric($selection) && isset($matches[(int) $selection])) {
|
||||||
return $matches[1].' '.$matches[2];
|
$package = $matches[(int) $selection];
|
||||||
|
|
||||||
|
return $package['name'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($matches[(int) $selection])) {
|
if (preg_match('{^\s*(?P<name>[\S/]+)(?:\s+(?P<version>\S+))?\s*$}', $selection, $packageMatches)) {
|
||||||
throw new \Exception('Not a valid selection');
|
if (isset($packageMatches['version'])) {
|
||||||
|
// parsing `acme/example ~2.3`
|
||||||
|
|
||||||
|
// validate version constraint
|
||||||
|
$versionParser->parseConstraints($packageMatches['version']);
|
||||||
|
|
||||||
|
return $packageMatches['name'].' '.$packageMatches['version'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// parsing `acme/example`
|
||||||
|
return $packageMatches['name'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$package = $matches[(int) $selection];
|
throw new \Exception('Not a valid selection');
|
||||||
|
|
||||||
return $package['name'];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$package = $dialog->askAndValidate($output, $dialog->getQuestion('Enter package # to add, or the complete package name if it is not listed', false, ':'), $validator, 3);
|
$package = $dialog->askAndValidate($output, $dialog->getQuestion('Enter package # to add, or the complete package name if it is not listed', false, ':'), $validator, 3);
|
||||||
|
@ -392,7 +403,7 @@ EOT
|
||||||
if (false === $constraint) {
|
if (false === $constraint) {
|
||||||
$constraint = $this->findBestVersionForPackage($input, $package);
|
$constraint = $this->findBestVersionForPackage($input, $package);
|
||||||
|
|
||||||
$output->writeln(sprintf(
|
$this->getIO()->writeError(sprintf(
|
||||||
'Using version <info>%s</info> for <info>%s</info>',
|
'Using version <info>%s</info> for <info>%s</info>',
|
||||||
$constraint,
|
$constraint,
|
||||||
$package
|
$package
|
||||||
|
|
|
@ -65,18 +65,18 @@ EOT
|
||||||
protected function execute(InputInterface $input, OutputInterface $output)
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
{
|
{
|
||||||
if ($args = $input->getArgument('packages')) {
|
if ($args = $input->getArgument('packages')) {
|
||||||
$output->writeln('<error>Invalid argument '.implode(' ', $args).'. Use "composer require '.implode(' ', $args).'" instead to add packages to your composer.json.</error>');
|
$this->getIO()->writeError('<error>Invalid argument '.implode(' ', $args).'. Use "composer require '.implode(' ', $args).'" instead to add packages to your composer.json.</error>');
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($input->getOption('no-custom-installers')) {
|
if ($input->getOption('no-custom-installers')) {
|
||||||
$output->writeln('<warning>You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.</warning>');
|
$this->getIO()->writeError('<warning>You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.</warning>');
|
||||||
$input->setOption('no-plugins', true);
|
$input->setOption('no-plugins', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($input->getOption('dev')) {
|
if ($input->getOption('dev')) {
|
||||||
$output->writeln('<warning>You are using the deprecated option "dev". Dev packages are installed by default now.</warning>');
|
$this->getIO()->writeError('<warning>You are using the deprecated option "dev". Dev packages are installed by default now.</warning>');
|
||||||
}
|
}
|
||||||
|
|
||||||
$composer = $this->getComposer(true, $input->getOption('no-plugins'));
|
$composer = $this->getComposer(true, $input->getOption('no-plugins'));
|
||||||
|
|
|
@ -18,7 +18,8 @@ use Composer\Plugin\CommandEvent;
|
||||||
use Composer\Plugin\PluginEvents;
|
use Composer\Plugin\PluginEvents;
|
||||||
use Composer\Package\PackageInterface;
|
use Composer\Package\PackageInterface;
|
||||||
use Composer\Repository\RepositoryInterface;
|
use Composer\Repository\RepositoryInterface;
|
||||||
use Symfony\Component\Console\Helper\TableHelper;
|
use Symfony\Component\Console\Helper\Table;
|
||||||
|
use Symfony\Component\Console\Helper\TableStyle;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Input\InputOption;
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
@ -68,14 +69,17 @@ EOT
|
||||||
|
|
||||||
switch ($format = $input->getOption('format')) {
|
switch ($format = $input->getOption('format')) {
|
||||||
case 'text':
|
case 'text':
|
||||||
$output->writeln('Name: <comment>'.$root->getPrettyName().'</comment>');
|
$this->getIO()->write('Name: <comment>'.$root->getPrettyName().'</comment>');
|
||||||
$output->writeln('Version: <comment>'.$versionParser->formatVersion($root).'</comment>');
|
$this->getIO()->write('Version: <comment>'.$versionParser->formatVersion($root).'</comment>');
|
||||||
$output->writeln('Licenses: <comment>'.(implode(', ', $root->getLicense()) ?: 'none').'</comment>');
|
$this->getIO()->write('Licenses: <comment>'.(implode(', ', $root->getLicense()) ?: 'none').'</comment>');
|
||||||
$output->writeln('Dependencies:');
|
$this->getIO()->write('Dependencies:');
|
||||||
|
$this->getIO()->write('');
|
||||||
|
|
||||||
$table = $this->getHelperSet()->get('table');
|
$table = new Table($output);
|
||||||
$table->setLayout(TableHelper::LAYOUT_BORDERLESS);
|
$table->setStyle('compact');
|
||||||
$table->setHorizontalBorderChar('');
|
$table->getStyle()->setVerticalBorderChar('');
|
||||||
|
$table->getStyle()->setCellRowContentFormat('%s ');
|
||||||
|
$table->setHeaders(array('Name', 'Version', 'License'));
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
$table->addRow(array(
|
$table->addRow(array(
|
||||||
$package->getPrettyName(),
|
$package->getPrettyName(),
|
||||||
|
@ -83,7 +87,7 @@ EOT
|
||||||
implode(', ', $package->getLicense()) ?: 'none',
|
implode(', ', $package->getLicense()) ?: 'none',
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
$table->render($output);
|
$table->render();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'json':
|
case 'json':
|
||||||
|
@ -94,7 +98,7 @@ EOT
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$output->writeln(JsonFile::encode(array(
|
$this->getIO()->write(JsonFile::encode(array(
|
||||||
'name' => $root->getPrettyName(),
|
'name' => $root->getPrettyName(),
|
||||||
'version' => $versionParser->formatVersion($root),
|
'version' => $versionParser->formatVersion($root),
|
||||||
'license' => $root->getLicense(),
|
'license' => $root->getLicense(),
|
||||||
|
|
|
@ -73,7 +73,7 @@ EOT
|
||||||
if (isset($composer[$type][$package])) {
|
if (isset($composer[$type][$package])) {
|
||||||
$json->removeLink($type, $package);
|
$json->removeLink($type, $package);
|
||||||
} elseif (isset($composer[$altType][$package])) {
|
} elseif (isset($composer[$altType][$package])) {
|
||||||
$output->writeln('<warning>'.$package.' could not be found in '.$type.' but it is present in '.$altType.'</warning>');
|
$this->getIO()->writeError('<warning>'.$package.' could not be found in '.$type.' but it is present in '.$altType.'</warning>');
|
||||||
$dialog = $this->getHelperSet()->get('dialog');
|
$dialog = $this->getHelperSet()->get('dialog');
|
||||||
if ($this->getIO()->isInteractive()) {
|
if ($this->getIO()->isInteractive()) {
|
||||||
if ($dialog->askConfirmation($output, $dialog->getQuestion('Do you want to remove it from '.$altType, 'yes', '?'), true)) {
|
if ($dialog->askConfirmation($output, $dialog->getQuestion('Do you want to remove it from '.$altType, 'yes', '?'), true)) {
|
||||||
|
@ -81,7 +81,7 @@ EOT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$output->writeln('<warning>'.$package.' is not required in your composer.json and has not been removed</warning>');
|
$this->getIO()->writeError('<warning>'.$package.' is not required in your composer.json and has not been removed</warning>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ EOT
|
||||||
|
|
||||||
$status = $install->run();
|
$status = $install->run();
|
||||||
if ($status !== 0) {
|
if ($status !== 0) {
|
||||||
$output->writeln("\n".'<error>Removal failed, reverting '.$file.' to its original content.</error>');
|
$this->getIO()->writeError("\n".'<error>Removal failed, reverting '.$file.' to its original content.</error>');
|
||||||
file_put_contents($jsonFile->getPath(), $composerBackup);
|
file_put_contents($jsonFile->getPath(), $composerBackup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,17 +67,17 @@ EOT
|
||||||
|
|
||||||
$newlyCreated = !file_exists($file);
|
$newlyCreated = !file_exists($file);
|
||||||
if (!file_exists($file) && !file_put_contents($file, "{\n}\n")) {
|
if (!file_exists($file) && !file_put_contents($file, "{\n}\n")) {
|
||||||
$output->writeln('<error>'.$file.' could not be created.</error>');
|
$this->getIO()->writeError('<error>'.$file.' could not be created.</error>');
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!is_readable($file)) {
|
if (!is_readable($file)) {
|
||||||
$output->writeln('<error>'.$file.' is not readable.</error>');
|
$this->getIO()->writeError('<error>'.$file.' is not readable.</error>');
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!is_writable($file)) {
|
if (!is_writable($file)) {
|
||||||
$output->writeln('<error>'.$file.' is not writable.</error>');
|
$this->getIO()->writeError('<error>'.$file.' is not writable.</error>');
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ EOT
|
||||||
$json->write($composerDefinition);
|
$json->write($composerDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
$output->writeln('<info>'.$file.' has been '.($newlyCreated ? 'created' : 'updated').'</info>');
|
$this->getIO()->writeError('<info>'.$file.' has been '.($newlyCreated ? 'created' : 'updated').'</info>');
|
||||||
|
|
||||||
if ($input->getOption('no-update')) {
|
if ($input->getOption('no-update')) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -154,10 +154,10 @@ EOT
|
||||||
$status = $install->run();
|
$status = $install->run();
|
||||||
if ($status !== 0) {
|
if ($status !== 0) {
|
||||||
if ($newlyCreated) {
|
if ($newlyCreated) {
|
||||||
$output->writeln("\n".'<error>Installation failed, deleting '.$file.'.</error>');
|
$this->getIO()->writeError("\n".'<error>Installation failed, deleting '.$file.'.</error>');
|
||||||
unlink($json->getPath());
|
unlink($json->getPath());
|
||||||
} else {
|
} else {
|
||||||
$output->writeln("\n".'<error>Installation failed, reverting '.$file.' to its original content.</error>');
|
$this->getIO()->writeError("\n".'<error>Installation failed, reverting '.$file.' to its original content.</error>');
|
||||||
file_put_contents($json->getPath(), $composerBackup);
|
file_put_contents($json->getPath(), $composerBackup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ class RunScriptCommand extends Command
|
||||||
/**
|
/**
|
||||||
* @var array Array with command events
|
* @var array Array with command events
|
||||||
*/
|
*/
|
||||||
protected $commandEvents = array(
|
protected $scriptEvents = array(
|
||||||
ScriptEvents::PRE_INSTALL_CMD,
|
ScriptEvents::PRE_INSTALL_CMD,
|
||||||
ScriptEvents::POST_INSTALL_CMD,
|
ScriptEvents::POST_INSTALL_CMD,
|
||||||
ScriptEvents::PRE_UPDATE_CMD,
|
ScriptEvents::PRE_UPDATE_CMD,
|
||||||
|
@ -35,17 +35,11 @@ class RunScriptCommand extends Command
|
||||||
ScriptEvents::PRE_STATUS_CMD,
|
ScriptEvents::PRE_STATUS_CMD,
|
||||||
ScriptEvents::POST_STATUS_CMD,
|
ScriptEvents::POST_STATUS_CMD,
|
||||||
ScriptEvents::POST_ROOT_PACKAGE_INSTALL,
|
ScriptEvents::POST_ROOT_PACKAGE_INSTALL,
|
||||||
ScriptEvents::POST_CREATE_PROJECT_CMD
|
ScriptEvents::POST_CREATE_PROJECT_CMD,
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array Array with script events
|
|
||||||
*/
|
|
||||||
protected $scriptEvents = array(
|
|
||||||
ScriptEvents::PRE_ARCHIVE_CMD,
|
ScriptEvents::PRE_ARCHIVE_CMD,
|
||||||
ScriptEvents::POST_ARCHIVE_CMD,
|
ScriptEvents::POST_ARCHIVE_CMD,
|
||||||
ScriptEvents::PRE_AUTOLOAD_DUMP,
|
ScriptEvents::PRE_AUTOLOAD_DUMP,
|
||||||
ScriptEvents::POST_AUTOLOAD_DUMP
|
ScriptEvents::POST_AUTOLOAD_DUMP,
|
||||||
);
|
);
|
||||||
|
|
||||||
protected function configure()
|
protected function configure()
|
||||||
|
@ -54,10 +48,11 @@ class RunScriptCommand extends Command
|
||||||
->setName('run-script')
|
->setName('run-script')
|
||||||
->setDescription('Run the scripts defined in composer.json.')
|
->setDescription('Run the scripts defined in composer.json.')
|
||||||
->setDefinition(array(
|
->setDefinition(array(
|
||||||
new InputArgument('script', InputArgument::REQUIRED, 'Script name to run.'),
|
new InputArgument('script', InputArgument::OPTIONAL, 'Script name to run.'),
|
||||||
new InputArgument('args', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, ''),
|
new InputArgument('args', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, ''),
|
||||||
new InputOption('dev', null, InputOption::VALUE_NONE, 'Sets the dev mode.'),
|
new InputOption('dev', null, InputOption::VALUE_NONE, 'Sets the dev mode.'),
|
||||||
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables the dev mode.'),
|
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables the dev mode.'),
|
||||||
|
new InputOption('list', 'l', InputOption::VALUE_NONE, 'List scripts.'),
|
||||||
))
|
))
|
||||||
->setHelp(<<<EOT
|
->setHelp(<<<EOT
|
||||||
The <info>run-script</info> command runs scripts defined in composer.json:
|
The <info>run-script</info> command runs scripts defined in composer.json:
|
||||||
|
@ -70,8 +65,14 @@ EOT
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output)
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
{
|
{
|
||||||
|
if ($input->getOption('list')) {
|
||||||
|
return $this->listScripts();
|
||||||
|
} elseif (!$input->getArgument('script')) {
|
||||||
|
throw new \RunTimeException('Missing required argument "script"');
|
||||||
|
}
|
||||||
|
|
||||||
$script = $input->getArgument('script');
|
$script = $input->getArgument('script');
|
||||||
if (!in_array($script, $this->commandEvents) && !in_array($script, $this->scriptEvents)) {
|
if (!in_array($script, $this->scriptEvents)) {
|
||||||
if (defined('Composer\Script\ScriptEvents::'.str_replace('-', '_', strtoupper($script)))) {
|
if (defined('Composer\Script\ScriptEvents::'.str_replace('-', '_', strtoupper($script)))) {
|
||||||
throw new \InvalidArgumentException(sprintf('Script "%s" cannot be run with this command', $script));
|
throw new \InvalidArgumentException(sprintf('Script "%s" cannot be run with this command', $script));
|
||||||
}
|
}
|
||||||
|
@ -86,15 +87,28 @@ EOT
|
||||||
// add the bin dir to the PATH to make local binaries of deps usable in scripts
|
// add the bin dir to the PATH to make local binaries of deps usable in scripts
|
||||||
$binDir = $composer->getConfig()->get('bin-dir');
|
$binDir = $composer->getConfig()->get('bin-dir');
|
||||||
if (is_dir($binDir)) {
|
if (is_dir($binDir)) {
|
||||||
putenv('PATH='.realpath($binDir).PATH_SEPARATOR.getenv('PATH'));
|
$_SERVER['PATH'] = realpath($binDir).PATH_SEPARATOR.getenv('PATH');
|
||||||
|
putenv('PATH='.$_SERVER['PATH']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$args = $input->getArgument('args');
|
$args = $input->getArgument('args');
|
||||||
|
|
||||||
if (in_array($script, $this->commandEvents)) {
|
|
||||||
return $composer->getEventDispatcher()->dispatchCommandEvent($script, $input->getOption('dev') || !$input->getOption('no-dev'), $args);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $composer->getEventDispatcher()->dispatchScript($script, $input->getOption('dev') || !$input->getOption('no-dev'), $args);
|
return $composer->getEventDispatcher()->dispatchScript($script, $input->getOption('dev') || !$input->getOption('no-dev'), $args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function listScripts()
|
||||||
|
{
|
||||||
|
$scripts = $this->getComposer()->getPackage()->getScripts();
|
||||||
|
|
||||||
|
if (!count($scripts)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->getIO()->writeError('<info>scripts:</info>');
|
||||||
|
foreach ($scripts as $name => $script) {
|
||||||
|
$this->getIO()->write(' ' . $name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,8 @@ EOT
|
||||||
// add the bin dir to the PATH to make local binaries of deps usable in scripts
|
// add the bin dir to the PATH to make local binaries of deps usable in scripts
|
||||||
$binDir = $composer->getConfig()->get('bin-dir');
|
$binDir = $composer->getConfig()->get('bin-dir');
|
||||||
if (is_dir($binDir)) {
|
if (is_dir($binDir)) {
|
||||||
putenv('PATH='.realpath($binDir).PATH_SEPARATOR.getenv('PATH'));
|
$_SERVER['PATH'] = realpath($binDir).PATH_SEPARATOR.getenv('PATH');
|
||||||
|
putenv('PATH='.$_SERVER['PATH']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$args = $input->getArguments();
|
$args = $input->getArguments();
|
||||||
|
|
|
@ -62,7 +62,7 @@ EOT
|
||||||
$repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories()));
|
$repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories()));
|
||||||
} else {
|
} else {
|
||||||
$defaultRepos = Factory::createDefaultRepositories($this->getIO());
|
$defaultRepos = Factory::createDefaultRepositories($this->getIO());
|
||||||
$output->writeln('No composer.json found in the current directory, showing packages from ' . implode(', ', array_keys($defaultRepos)));
|
$this->getIO()->writeError('No composer.json found in the current directory, showing packages from ' . implode(', ', array_keys($defaultRepos)));
|
||||||
$installedRepo = $platformRepo;
|
$installedRepo = $platformRepo;
|
||||||
$repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos));
|
$repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos));
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ EOT
|
||||||
$results = $repos->search(implode(' ', $input->getArgument('tokens')), $flags);
|
$results = $repos->search(implode(' ', $input->getArgument('tokens')), $flags);
|
||||||
|
|
||||||
foreach ($results as $result) {
|
foreach ($results as $result) {
|
||||||
$output->writeln($result['name'] . (isset($result['description']) ? ' '. $result['description'] : ''));
|
$this->getIO()->write($result['name'] . (isset($result['description']) ? ' '. $result['description'] : ''));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,13 +84,13 @@ EOT
|
||||||
$updateVersion = $input->getArgument('version') ?: $latestVersion;
|
$updateVersion = $input->getArgument('version') ?: $latestVersion;
|
||||||
|
|
||||||
if (preg_match('{^[0-9a-f]{40}$}', $updateVersion) && $updateVersion !== $latestVersion) {
|
if (preg_match('{^[0-9a-f]{40}$}', $updateVersion) && $updateVersion !== $latestVersion) {
|
||||||
$output->writeln('<error>You can not update to a specific SHA-1 as those phars are not available for download</error>');
|
$this->getIO()->writeError('<error>You can not update to a specific SHA-1 as those phars are not available for download</error>');
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Composer::VERSION === $updateVersion) {
|
if (Composer::VERSION === $updateVersion) {
|
||||||
$output->writeln('<info>You are already using composer version '.$updateVersion.'.</info>');
|
$this->getIO()->writeError('<info>You are already using composer version '.$updateVersion.'.</info>');
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -104,11 +104,11 @@ EOT
|
||||||
self::OLD_INSTALL_EXT
|
self::OLD_INSTALL_EXT
|
||||||
);
|
);
|
||||||
|
|
||||||
$output->writeln(sprintf("Updating to version <info>%s</info>.", $updateVersion));
|
$this->getIO()->writeError(sprintf("Updating to version <info>%s</info>.", $updateVersion));
|
||||||
$remoteFilename = $baseUrl . (preg_match('{^[0-9a-f]{40}$}', $updateVersion) ? '/composer.phar' : "/download/{$updateVersion}/composer.phar");
|
$remoteFilename = $baseUrl . (preg_match('{^[0-9a-f]{40}$}', $updateVersion) ? '/composer.phar' : "/download/{$updateVersion}/composer.phar");
|
||||||
$remoteFilesystem->copy(self::HOMEPAGE, $remoteFilename, $tempFilename, !$input->getOption('no-progress'));
|
$remoteFilesystem->copy(self::HOMEPAGE, $remoteFilename, $tempFilename, !$input->getOption('no-progress'));
|
||||||
if (!file_exists($tempFilename)) {
|
if (!file_exists($tempFilename)) {
|
||||||
$output->writeln('<error>The download of the new composer version failed for an unexpected reason</error>');
|
$this->getIO()->writeError('<error>The download of the new composer version failed for an unexpected reason</error>');
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -120,22 +120,22 @@ EOT
|
||||||
$fs = new Filesystem;
|
$fs = new Filesystem;
|
||||||
foreach ($finder as $file) {
|
foreach ($finder as $file) {
|
||||||
$file = (string) $file;
|
$file = (string) $file;
|
||||||
$output->writeln('<info>Removing: '.$file.'</info>');
|
$this->getIO()->writeError('<info>Removing: '.$file.'</info>');
|
||||||
$fs->remove($file);
|
$fs->remove($file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($err = $this->setLocalPhar($localFilename, $tempFilename, $backupFile)) {
|
if ($err = $this->setLocalPhar($localFilename, $tempFilename, $backupFile)) {
|
||||||
$output->writeln('<error>The file is corrupted ('.$err->getMessage().').</error>');
|
$this->getIO()->writeError('<error>The file is corrupted ('.$err->getMessage().').</error>');
|
||||||
$output->writeln('<error>Please re-run the self-update command to try again.</error>');
|
$this->getIO()->writeError('<error>Please re-run the self-update command to try again.</error>');
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_exists($backupFile)) {
|
if (file_exists($backupFile)) {
|
||||||
$output->writeln('Use <info>composer self-update --rollback</info> to return to version '.Composer::VERSION);
|
$this->getIO()->writeError('Use <info>composer self-update --rollback</info> to return to version '.Composer::VERSION);
|
||||||
} else {
|
} else {
|
||||||
$output->writeln('<warning>A backup of the current version could not be written to '.$backupFile.', no rollback possible</warning>');
|
$this->getIO()->writeError('<warning>A backup of the current version could not be written to '.$backupFile.', no rollback possible</warning>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,9 +160,9 @@ EOT
|
||||||
}
|
}
|
||||||
|
|
||||||
$oldFile = $rollbackDir . "/{$rollbackVersion}" . self::OLD_INSTALL_EXT;
|
$oldFile = $rollbackDir . "/{$rollbackVersion}" . self::OLD_INSTALL_EXT;
|
||||||
$output->writeln(sprintf("Rolling back to version <info>%s</info>.", $rollbackVersion));
|
$this->getIO()->writeError(sprintf("Rolling back to version <info>%s</info>.", $rollbackVersion));
|
||||||
if ($err = $this->setLocalPhar($localFilename, $oldFile)) {
|
if ($err = $this->setLocalPhar($localFilename, $oldFile)) {
|
||||||
$output->writeln('<error>The backup file was corrupted ('.$err->getMessage().') and has been removed.</error>');
|
$this->getIO()->writeError('<error>The backup file was corrupted ('.$err->getMessage().') and has been removed.</error>');
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ EOT
|
||||||
} else {
|
} else {
|
||||||
$defaultRepos = Factory::createDefaultRepositories($this->getIO());
|
$defaultRepos = Factory::createDefaultRepositories($this->getIO());
|
||||||
$repos = new CompositeRepository($defaultRepos);
|
$repos = new CompositeRepository($defaultRepos);
|
||||||
$output->writeln('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos)));
|
$this->getIO()->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos)));
|
||||||
}
|
}
|
||||||
} elseif ($composer) {
|
} elseif ($composer) {
|
||||||
$localRepo = $composer->getRepositoryManager()->getLocalRepository();
|
$localRepo = $composer->getRepositoryManager()->getLocalRepository();
|
||||||
|
@ -92,7 +92,7 @@ EOT
|
||||||
$repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories()));
|
$repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories()));
|
||||||
} else {
|
} else {
|
||||||
$defaultRepos = Factory::createDefaultRepositories($this->getIO());
|
$defaultRepos = Factory::createDefaultRepositories($this->getIO());
|
||||||
$output->writeln('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos)));
|
$this->getIO()->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos)));
|
||||||
$installedRepo = $platformRepo;
|
$installedRepo = $platformRepo;
|
||||||
$repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos));
|
$repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos));
|
||||||
}
|
}
|
||||||
|
@ -119,9 +119,9 @@ EOT
|
||||||
$this->printLinks($input, $output, $package, 'requires');
|
$this->printLinks($input, $output, $package, 'requires');
|
||||||
$this->printLinks($input, $output, $package, 'devRequires', 'requires (dev)');
|
$this->printLinks($input, $output, $package, 'devRequires', 'requires (dev)');
|
||||||
if ($package->getSuggests()) {
|
if ($package->getSuggests()) {
|
||||||
$output->writeln("\n<info>suggests</info>");
|
$this->getIO()->write("\n<info>suggests</info>");
|
||||||
foreach ($package->getSuggests() as $suggested => $reason) {
|
foreach ($package->getSuggests() as $suggested => $reason) {
|
||||||
$output->writeln($suggested . ' <comment>' . $reason . '</comment>');
|
$this->getIO()->write($suggested . ' <comment>' . $reason . '</comment>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->printLinks($input, $output, $package, 'provides');
|
$this->printLinks($input, $output, $package, 'provides');
|
||||||
|
@ -172,7 +172,7 @@ EOT
|
||||||
foreach (array('<info>platform</info>:' => true, '<comment>available</comment>:' => false, '<info>installed</info>:' => true) as $type => $showVersion) {
|
foreach (array('<info>platform</info>:' => true, '<comment>available</comment>:' => false, '<info>installed</info>:' => true) as $type => $showVersion) {
|
||||||
if (isset($packages[$type])) {
|
if (isset($packages[$type])) {
|
||||||
if ($tree) {
|
if ($tree) {
|
||||||
$output->writeln($type);
|
$this->getIO()->write($type);
|
||||||
}
|
}
|
||||||
ksort($packages[$type]);
|
ksort($packages[$type]);
|
||||||
|
|
||||||
|
@ -222,10 +222,10 @@ EOT
|
||||||
} else {
|
} else {
|
||||||
$output->write($indent . $package);
|
$output->write($indent . $package);
|
||||||
}
|
}
|
||||||
$output->writeln('');
|
$this->getIO()->write('');
|
||||||
}
|
}
|
||||||
if ($tree) {
|
if ($tree) {
|
||||||
$output->writeln('');
|
$this->getIO()->write('');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -285,53 +285,53 @@ EOT
|
||||||
*/
|
*/
|
||||||
protected function printMeta(InputInterface $input, OutputInterface $output, CompletePackageInterface $package, array $versions, RepositoryInterface $installedRepo, RepositoryInterface $repos)
|
protected function printMeta(InputInterface $input, OutputInterface $output, CompletePackageInterface $package, array $versions, RepositoryInterface $installedRepo, RepositoryInterface $repos)
|
||||||
{
|
{
|
||||||
$output->writeln('<info>name</info> : ' . $package->getPrettyName());
|
$this->getIO()->write('<info>name</info> : ' . $package->getPrettyName());
|
||||||
$output->writeln('<info>descrip.</info> : ' . $package->getDescription());
|
$this->getIO()->write('<info>descrip.</info> : ' . $package->getDescription());
|
||||||
$output->writeln('<info>keywords</info> : ' . join(', ', $package->getKeywords() ?: array()));
|
$this->getIO()->write('<info>keywords</info> : ' . join(', ', $package->getKeywords() ?: array()));
|
||||||
$this->printVersions($input, $output, $package, $versions, $installedRepo, $repos);
|
$this->printVersions($input, $output, $package, $versions, $installedRepo, $repos);
|
||||||
$output->writeln('<info>type</info> : ' . $package->getType());
|
$this->getIO()->write('<info>type</info> : ' . $package->getType());
|
||||||
$output->writeln('<info>license</info> : ' . implode(', ', $package->getLicense()));
|
$this->getIO()->write('<info>license</info> : ' . implode(', ', $package->getLicense()));
|
||||||
$output->writeln('<info>source</info> : ' . sprintf('[%s] <comment>%s</comment> %s', $package->getSourceType(), $package->getSourceUrl(), $package->getSourceReference()));
|
$this->getIO()->write('<info>source</info> : ' . sprintf('[%s] <comment>%s</comment> %s', $package->getSourceType(), $package->getSourceUrl(), $package->getSourceReference()));
|
||||||
$output->writeln('<info>dist</info> : ' . sprintf('[%s] <comment>%s</comment> %s', $package->getDistType(), $package->getDistUrl(), $package->getDistReference()));
|
$this->getIO()->write('<info>dist</info> : ' . sprintf('[%s] <comment>%s</comment> %s', $package->getDistType(), $package->getDistUrl(), $package->getDistReference()));
|
||||||
$output->writeln('<info>names</info> : ' . implode(', ', $package->getNames()));
|
$this->getIO()->write('<info>names</info> : ' . implode(', ', $package->getNames()));
|
||||||
|
|
||||||
if ($package->isAbandoned()) {
|
if ($package->isAbandoned()) {
|
||||||
$replacement = ($package->getReplacementPackage() !== null)
|
$replacement = ($package->getReplacementPackage() !== null)
|
||||||
? ' The author suggests using the ' . $package->getReplacementPackage(). ' package instead.'
|
? ' The author suggests using the ' . $package->getReplacementPackage(). ' package instead.'
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
$output->writeln(
|
$this->getIO()->writeError(
|
||||||
sprintf('<error>Attention: This package is abandoned and no longer maintained.%s</error>', $replacement)
|
sprintf('<error>Attention: This package is abandoned and no longer maintained.%s</error>', $replacement)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($package->getSupport()) {
|
if ($package->getSupport()) {
|
||||||
$output->writeln("\n<info>support</info>");
|
$this->getIO()->write("\n<info>support</info>");
|
||||||
foreach ($package->getSupport() as $type => $value) {
|
foreach ($package->getSupport() as $type => $value) {
|
||||||
$output->writeln('<comment>' . $type . '</comment> : '.$value);
|
$this->getIO()->write('<comment>' . $type . '</comment> : '.$value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($package->getAutoload()) {
|
if ($package->getAutoload()) {
|
||||||
$output->writeln("\n<info>autoload</info>");
|
$this->getIO()->write("\n<info>autoload</info>");
|
||||||
foreach ($package->getAutoload() as $type => $autoloads) {
|
foreach ($package->getAutoload() as $type => $autoloads) {
|
||||||
$output->writeln('<comment>' . $type . '</comment>');
|
$this->getIO()->write('<comment>' . $type . '</comment>');
|
||||||
|
|
||||||
if ($type === 'psr-0') {
|
if ($type === 'psr-0') {
|
||||||
foreach ($autoloads as $name => $path) {
|
foreach ($autoloads as $name => $path) {
|
||||||
$output->writeln(($name ?: '*') . ' => ' . (is_array($path) ? implode(', ', $path) : ($path ?: '.')));
|
$this->getIO()->write(($name ?: '*') . ' => ' . (is_array($path) ? implode(', ', $path) : ($path ?: '.')));
|
||||||
}
|
}
|
||||||
} elseif ($type === 'psr-4') {
|
} elseif ($type === 'psr-4') {
|
||||||
foreach ($autoloads as $name => $path) {
|
foreach ($autoloads as $name => $path) {
|
||||||
$output->writeln(($name ?: '*') . ' => ' . (is_array($path) ? implode(', ', $path) : ($path ?: '.')));
|
$this->getIO()->write(($name ?: '*') . ' => ' . (is_array($path) ? implode(', ', $path) : ($path ?: '.')));
|
||||||
}
|
}
|
||||||
} elseif ($type === 'classmap') {
|
} elseif ($type === 'classmap') {
|
||||||
$output->writeln(implode(', ', $autoloads));
|
$this->getIO()->write(implode(', ', $autoloads));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($package->getIncludePaths()) {
|
if ($package->getIncludePaths()) {
|
||||||
$output->writeln('<comment>include-path</comment>');
|
$this->getIO()->write('<comment>include-path</comment>');
|
||||||
$output->writeln(implode(', ', $package->getIncludePaths()));
|
$this->getIO()->write(implode(', ', $package->getIncludePaths()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -355,7 +355,7 @@ EOT
|
||||||
|
|
||||||
$versions = implode(', ', $versions);
|
$versions = implode(', ', $versions);
|
||||||
|
|
||||||
$output->writeln('<info>versions</info> : ' . $versions);
|
$this->getIO()->write('<info>versions</info> : ' . $versions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -371,10 +371,10 @@ EOT
|
||||||
{
|
{
|
||||||
$title = $title ?: $linkType;
|
$title = $title ?: $linkType;
|
||||||
if ($links = $package->{'get'.ucfirst($linkType)}()) {
|
if ($links = $package->{'get'.ucfirst($linkType)}()) {
|
||||||
$output->writeln("\n<info>" . $title . "</info>");
|
$this->getIO()->write("\n<info>" . $title . "</info>");
|
||||||
|
|
||||||
foreach ($links as $link) {
|
foreach ($links as $link) {
|
||||||
$output->writeln($link->getTarget() . ' <comment>' . $link->getPrettyConstraint() . '</comment>');
|
$this->getIO()->write($link->getTarget() . ' <comment>' . $link->getPrettyConstraint() . '</comment>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ EOT
|
||||||
$im = $composer->getInstallationManager();
|
$im = $composer->getInstallationManager();
|
||||||
|
|
||||||
// Dispatch pre-status-command
|
// Dispatch pre-status-command
|
||||||
$composer->getEventDispatcher()->dispatchCommandEvent(ScriptEvents::PRE_STATUS_CMD, true);
|
$composer->getEventDispatcher()->dispatchScript(ScriptEvents::PRE_STATUS_CMD, true);
|
||||||
|
|
||||||
$errors = array();
|
$errors = array();
|
||||||
|
|
||||||
|
@ -76,9 +76,9 @@ EOT
|
||||||
|
|
||||||
// output errors/warnings
|
// output errors/warnings
|
||||||
if (!$errors) {
|
if (!$errors) {
|
||||||
$output->writeln('<info>No local changes</info>');
|
$this->getIO()->writeError('<info>No local changes</info>');
|
||||||
} else {
|
} else {
|
||||||
$output->writeln('<error>You have changes in the following dependencies:</error>');
|
$this->getIO()->writeError('<error>You have changes in the following dependencies:</error>');
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($errors as $path => $changes) {
|
foreach ($errors as $path => $changes) {
|
||||||
|
@ -86,19 +86,19 @@ EOT
|
||||||
$indentedChanges = implode("\n", array_map(function ($line) {
|
$indentedChanges = implode("\n", array_map(function ($line) {
|
||||||
return ' ' . ltrim($line);
|
return ' ' . ltrim($line);
|
||||||
}, explode("\n", $changes)));
|
}, explode("\n", $changes)));
|
||||||
$output->writeln('<info>'.$path.'</info>:');
|
$this->getIO()->write('<info>'.$path.'</info>:');
|
||||||
$output->writeln($indentedChanges);
|
$this->getIO()->write($indentedChanges);
|
||||||
} else {
|
} else {
|
||||||
$output->writeln($path);
|
$this->getIO()->write($path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($errors && !$input->getOption('verbose')) {
|
if ($errors && !$input->getOption('verbose')) {
|
||||||
$output->writeln('Use --verbose (-v) to see modified files');
|
$this->getIO()->writeError('Use --verbose (-v) to see modified files');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dispatch post-status-command
|
// Dispatch post-status-command
|
||||||
$composer->getEventDispatcher()->dispatchCommandEvent(ScriptEvents::POST_STATUS_CMD, true);
|
$composer->getEventDispatcher()->dispatchScript(ScriptEvents::POST_STATUS_CMD, true);
|
||||||
|
|
||||||
return $errors ? 1 : 0;
|
return $errors ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,12 +75,12 @@ EOT
|
||||||
protected function execute(InputInterface $input, OutputInterface $output)
|
protected function execute(InputInterface $input, OutputInterface $output)
|
||||||
{
|
{
|
||||||
if ($input->getOption('no-custom-installers')) {
|
if ($input->getOption('no-custom-installers')) {
|
||||||
$output->writeln('<warning>You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.</warning>');
|
$this->getIO()->writeError('<warning>You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.</warning>');
|
||||||
$input->setOption('no-plugins', true);
|
$input->setOption('no-plugins', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($input->getOption('dev')) {
|
if ($input->getOption('dev')) {
|
||||||
$output->writeln('<warning>You are using the deprecated option "dev". Dev packages are installed by default now.</warning>');
|
$this->getIO()->writeError('<warning>You are using the deprecated option "dev". Dev packages are installed by default now.</warning>');
|
||||||
}
|
}
|
||||||
|
|
||||||
$composer = $this->getComposer(true, $input->getOption('no-plugins'));
|
$composer = $this->getComposer(true, $input->getOption('no-plugins'));
|
||||||
|
|
|
@ -37,6 +37,7 @@ class ValidateCommand extends Command
|
||||||
->setDescription('Validates a composer.json')
|
->setDescription('Validates a composer.json')
|
||||||
->setDefinition(array(
|
->setDefinition(array(
|
||||||
new InputOption('no-check-all', null, InputOption::VALUE_NONE, 'Do not make a complete validation'),
|
new InputOption('no-check-all', null, InputOption::VALUE_NONE, 'Do not make a complete validation'),
|
||||||
|
new InputOption('no-check-publish', null, InputOption::VALUE_NONE, 'Do not check for publish errors'),
|
||||||
new InputArgument('file', InputArgument::OPTIONAL, 'path to composer.json file', './composer.json')
|
new InputArgument('file', InputArgument::OPTIONAL, 'path to composer.json file', './composer.json')
|
||||||
))
|
))
|
||||||
->setHelp(<<<EOT
|
->setHelp(<<<EOT
|
||||||
|
@ -57,45 +58,53 @@ EOT
|
||||||
$file = $input->getArgument('file');
|
$file = $input->getArgument('file');
|
||||||
|
|
||||||
if (!file_exists($file)) {
|
if (!file_exists($file)) {
|
||||||
$output->writeln('<error>' . $file . ' not found.</error>');
|
$this->getIO()->writeError('<error>' . $file . ' not found.</error>');
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!is_readable($file)) {
|
if (!is_readable($file)) {
|
||||||
$output->writeln('<error>' . $file . ' is not readable.</error>');
|
$this->getIO()->writeError('<error>' . $file . ' is not readable.</error>');
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$validator = new ConfigValidator($this->getIO());
|
$validator = new ConfigValidator($this->getIO());
|
||||||
$checkAll = $input->getOption('no-check-all') ? 0 : ValidatingArrayLoader::CHECK_ALL;
|
$checkAll = $input->getOption('no-check-all') ? 0 : ValidatingArrayLoader::CHECK_ALL;
|
||||||
|
$checkPublish = !$input->getOption('no-check-publish');
|
||||||
list($errors, $publishErrors, $warnings) = $validator->validate($file, $checkAll);
|
list($errors, $publishErrors, $warnings) = $validator->validate($file, $checkAll);
|
||||||
|
|
||||||
// output errors/warnings
|
// output errors/warnings
|
||||||
if (!$errors && !$publishErrors && !$warnings) {
|
if (!$errors && !$publishErrors && !$warnings) {
|
||||||
$output->writeln('<info>' . $file . ' is valid</info>');
|
$this->getIO()->write('<info>' . $file . ' is valid</info>');
|
||||||
} elseif (!$errors && !$publishErrors) {
|
} elseif (!$errors && !$publishErrors) {
|
||||||
$output->writeln('<info>' . $file . ' is valid, but with a few warnings</info>');
|
$this->getIO()->writeError('<info>' . $file . ' is valid, but with a few warnings</info>');
|
||||||
$output->writeln('<warning>See http://getcomposer.org/doc/04-schema.md for details on the schema</warning>');
|
$this->getIO()->writeError('<warning>See http://getcomposer.org/doc/04-schema.md for details on the schema</warning>');
|
||||||
} elseif (!$errors) {
|
} elseif (!$errors) {
|
||||||
$output->writeln('<info>' . $file . ' is valid for simple usage with composer but has</info>');
|
$this->getIO()->writeError('<info>' . $file . ' is valid for simple usage with composer but has</info>');
|
||||||
$output->writeln('<info>strict errors that make it unable to be published as a package:</info>');
|
$this->getIO()->writeError('<info>strict errors that make it unable to be published as a package:</info>');
|
||||||
$output->writeln('<warning>See http://getcomposer.org/doc/04-schema.md for details on the schema</warning>');
|
$this->getIO()->writeError('<warning>See http://getcomposer.org/doc/04-schema.md for details on the schema</warning>');
|
||||||
} else {
|
} else {
|
||||||
$output->writeln('<error>' . $file . ' is invalid, the following errors/warnings were found:</error>');
|
$this->getIO()->writeError('<error>' . $file . ' is invalid, the following errors/warnings were found:</error>');
|
||||||
}
|
}
|
||||||
|
|
||||||
$messages = array(
|
$messages = array(
|
||||||
'error' => array_merge($errors, $publishErrors),
|
'error' => $errors,
|
||||||
'warning' => $warnings,
|
'warning' => $warnings,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// If checking publish errors, display them errors, otherwise just show them as warnings
|
||||||
|
if ($checkPublish) {
|
||||||
|
$messages['error'] = array_merge($messages['error'], $publishErrors);
|
||||||
|
} else {
|
||||||
|
$messages['warning'] = array_merge($messages['warning'], $publishErrors);
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($messages as $style => $msgs) {
|
foreach ($messages as $style => $msgs) {
|
||||||
foreach ($msgs as $msg) {
|
foreach ($msgs as $msg) {
|
||||||
$output->writeln('<' . $style . '>' . $msg . '</' . $style . '>');
|
$this->getIO()->writeError('<' . $style . '>' . $msg . '</' . $style . '>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $errors || $publishErrors ? 1 : 0;
|
return $errors || ($publishErrors && $checkPublish) ? 1 : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,10 +102,13 @@ class Compiler
|
||||||
$finder->files()
|
$finder->files()
|
||||||
->ignoreVCS(true)
|
->ignoreVCS(true)
|
||||||
->name('*.php')
|
->name('*.php')
|
||||||
|
->name('LICENSE')
|
||||||
->exclude('Tests')
|
->exclude('Tests')
|
||||||
|
->exclude('tests')
|
||||||
|
->exclude('docs')
|
||||||
->in(__DIR__.'/../../vendor/symfony/')
|
->in(__DIR__.'/../../vendor/symfony/')
|
||||||
->in(__DIR__.'/../../vendor/seld/jsonlint/src/')
|
->in(__DIR__.'/../../vendor/seld/jsonlint/')
|
||||||
->in(__DIR__.'/../../vendor/justinrainbow/json-schema/src/')
|
->in(__DIR__.'/../../vendor/justinrainbow/json-schema/')
|
||||||
;
|
;
|
||||||
|
|
||||||
foreach ($finder as $file) {
|
foreach ($finder as $file) {
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace Composer\Console;
|
||||||
use Symfony\Component\Console\Application as BaseApplication;
|
use Symfony\Component\Console\Application as BaseApplication;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Input\InputOption;
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
use Symfony\Component\Console\Output\ConsoleOutputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
use Symfony\Component\Console\Output\ConsoleOutput;
|
use Symfony\Component\Console\Output\ConsoleOutput;
|
||||||
use Symfony\Component\Console\Formatter\OutputFormatter;
|
use Symfony\Component\Console\Formatter\OutputFormatter;
|
||||||
|
@ -91,7 +92,7 @@ class Application extends BaseApplication
|
||||||
$this->io = new ConsoleIO($input, $output, $this->getHelperSet());
|
$this->io = new ConsoleIO($input, $output, $this->getHelperSet());
|
||||||
|
|
||||||
if (version_compare(PHP_VERSION, '5.3.2', '<')) {
|
if (version_compare(PHP_VERSION, '5.3.2', '<')) {
|
||||||
$output->writeln('<warning>Composer only officially supports PHP 5.3.2 and above, you will most likely encounter problems with your PHP '.PHP_VERSION.', upgrading is strongly recommended.</warning>');
|
$this->getIO()->writeError('<warning>Composer only officially supports PHP 5.3.2 and above, you will most likely encounter problems with your PHP '.PHP_VERSION.', upgrading is strongly recommended.</warning>');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defined('COMPOSER_DEV_WARNING_TIME')) {
|
if (defined('COMPOSER_DEV_WARNING_TIME')) {
|
||||||
|
@ -104,7 +105,7 @@ class Application extends BaseApplication
|
||||||
}
|
}
|
||||||
if ($commandName !== 'self-update' && $commandName !== 'selfupdate') {
|
if ($commandName !== 'self-update' && $commandName !== 'selfupdate') {
|
||||||
if (time() > COMPOSER_DEV_WARNING_TIME) {
|
if (time() > COMPOSER_DEV_WARNING_TIME) {
|
||||||
$output->writeln(sprintf('<warning>Warning: This development build of composer is over 30 days old. It is recommended to update it by running "%s self-update" to get the latest version.</warning>', $_SERVER['PHP_SELF']));
|
$this->getIO()->writeError(sprintf('<warning>Warning: This development build of composer is over 30 days old. It is recommended to update it by running "%s self-update" to get the latest version.</warning>', $_SERVER['PHP_SELF']));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,8 +118,8 @@ class Application extends BaseApplication
|
||||||
if ($newWorkDir = $this->getNewWorkingDir($input)) {
|
if ($newWorkDir = $this->getNewWorkingDir($input)) {
|
||||||
$oldWorkingDir = getcwd();
|
$oldWorkingDir = getcwd();
|
||||||
chdir($newWorkDir);
|
chdir($newWorkDir);
|
||||||
if ($output->getVerbosity() >= 4) {
|
if ($this->getIO()->isDebug() >= 4) {
|
||||||
$output->writeln('Changed CWD to ' . getcwd());
|
$this->getIO()->writeError('Changed CWD to ' . getcwd());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +130,7 @@ class Application extends BaseApplication
|
||||||
foreach ($composer['scripts'] as $script => $dummy) {
|
foreach ($composer['scripts'] as $script => $dummy) {
|
||||||
if (!defined('Composer\Script\ScriptEvents::'.str_replace('-', '_', strtoupper($script)))) {
|
if (!defined('Composer\Script\ScriptEvents::'.str_replace('-', '_', strtoupper($script)))) {
|
||||||
if ($this->has($script)) {
|
if ($this->has($script)) {
|
||||||
$output->writeln('<warning>A script named '.$script.' would override a native Composer function and has been skipped</warning>');
|
$this->getIO()->writeError('<warning>A script named '.$script.' would override a native Composer function and has been skipped</warning>');
|
||||||
} else {
|
} else {
|
||||||
$this->add(new Command\ScriptAliasCommand($script));
|
$this->add(new Command\ScriptAliasCommand($script));
|
||||||
}
|
}
|
||||||
|
@ -150,7 +151,7 @@ class Application extends BaseApplication
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($startTime)) {
|
if (isset($startTime)) {
|
||||||
$output->writeln('<info>Memory usage: '.round(memory_get_usage() / 1024 / 1024, 2).'MB (peak: '.round(memory_get_peak_usage() / 1024 / 1024, 2).'MB), time: '.round(microtime(true) - $startTime, 2).'s');
|
$this->getIO()->writeError('<info>Memory usage: '.round(memory_get_usage() / 1024 / 1024, 2).'MB (peak: '.round(memory_get_peak_usage() / 1024 / 1024, 2).'MB), time: '.round(microtime(true) - $startTime, 2).'s');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
|
@ -186,23 +187,27 @@ class Application extends BaseApplication
|
||||||
|| (($df = @disk_free_space($dir = $config->get('vendor-dir'))) !== false && $df < $minSpaceFree)
|
|| (($df = @disk_free_space($dir = $config->get('vendor-dir'))) !== false && $df < $minSpaceFree)
|
||||||
|| (($df = @disk_free_space($dir = sys_get_temp_dir())) !== false && $df < $minSpaceFree)
|
|| (($df = @disk_free_space($dir = sys_get_temp_dir())) !== false && $df < $minSpaceFree)
|
||||||
) {
|
) {
|
||||||
$output->writeln('<error>The disk hosting '.$dir.' is full, this may be the cause of the following exception</error>');
|
$this->getIO()->writeError('<error>The disk hosting '.$dir.' is full, this may be the cause of the following exception</error>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defined('PHP_WINDOWS_VERSION_BUILD') && false !== strpos($exception->getMessage(), 'The system cannot find the path specified')) {
|
if (defined('PHP_WINDOWS_VERSION_BUILD') && false !== strpos($exception->getMessage(), 'The system cannot find the path specified')) {
|
||||||
$output->writeln('<error>The following exception may be caused by a stale entry in your cmd.exe AutoRun</error>');
|
$this->getIO()->writeError('<error>The following exception may be caused by a stale entry in your cmd.exe AutoRun</error>');
|
||||||
$output->writeln('<error>Check https://getcomposer.org/doc/articles/troubleshooting.md#-the-system-cannot-find-the-path-specified-windows- for details</error>');
|
$this->getIO()->writeError('<error>Check https://getcomposer.org/doc/articles/troubleshooting.md#-the-system-cannot-find-the-path-specified-windows- for details</error>');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (false !== strpos($exception->getMessage(), 'fork failed - Cannot allocate memory')) {
|
if (false !== strpos($exception->getMessage(), 'fork failed - Cannot allocate memory')) {
|
||||||
$output->writeln('<error>The following exception is caused by a lack of memory and not having swap configured</error>');
|
$this->getIO()->writeError('<error>The following exception is caused by a lack of memory and not having swap configured</error>');
|
||||||
$output->writeln('<error>Check https://getcomposer.org/doc/articles/troubleshooting.md#proc-open-fork-failed-errors for details</error>');
|
$this->getIO()->writeError('<error>Check https://getcomposer.org/doc/articles/troubleshooting.md#proc-open-fork-failed-errors for details</error>');
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::renderException($exception, $output);
|
if ($output instanceof ConsoleOutputInterface) {
|
||||||
|
parent::renderException($exception, $output->getErrorOutput());
|
||||||
|
} else {
|
||||||
|
parent::renderException($exception, $output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -218,7 +223,7 @@ class Application extends BaseApplication
|
||||||
$this->composer = Factory::create($this->io, null, $disablePlugins);
|
$this->composer = Factory::create($this->io, null, $disablePlugins);
|
||||||
} catch (\InvalidArgumentException $e) {
|
} catch (\InvalidArgumentException $e) {
|
||||||
if ($required) {
|
if ($required) {
|
||||||
$this->io->write($e->getMessage());
|
$this->io->writeError($e->getMessage());
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
} catch (JsonValidationException $e) {
|
} catch (JsonValidationException $e) {
|
||||||
|
@ -323,7 +328,6 @@ class Application extends BaseApplication
|
||||||
protected function getDefaultHelperSet()
|
protected function getDefaultHelperSet()
|
||||||
{
|
{
|
||||||
$helperSet = parent::getDefaultHelperSet();
|
$helperSet = parent::getDefaultHelperSet();
|
||||||
|
|
||||||
$helperSet->set(new DialogHelper());
|
$helperSet->set(new DialogHelper());
|
||||||
|
|
||||||
return $helperSet;
|
return $helperSet;
|
||||||
|
|
|
@ -83,6 +83,6 @@ class HtmlOutputFormatter extends OutputFormatter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $out . '">'.$matches[2].'</span>';
|
return $out.'">'.$matches[2].'</span>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,11 @@ class Pool
|
||||||
}
|
}
|
||||||
$this->stabilityFlags = $stabilityFlags;
|
$this->stabilityFlags = $stabilityFlags;
|
||||||
$this->filterRequires = $filterRequires;
|
$this->filterRequires = $filterRequires;
|
||||||
|
foreach ($filterRequires as $name => $constraint) {
|
||||||
|
if (preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name)) {
|
||||||
|
unset($this->filterRequires[$name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setWhitelist($whitelist)
|
public function setWhitelist($whitelist)
|
||||||
|
|
|
@ -87,6 +87,19 @@ class Problem
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($job && $job['cmd'] === 'install' && empty($packages)) {
|
if ($job && $job['cmd'] === 'install' && empty($packages)) {
|
||||||
|
// handle php/hhvm
|
||||||
|
if ($job['packageName'] === 'php' || $job['packageName'] === 'php-64bit' || $job['packageName'] === 'hhvm') {
|
||||||
|
$msg = "\n - This package requires ".$job['packageName'].$this->constraintToText($job['constraint']).' but ';
|
||||||
|
|
||||||
|
if (defined('HHVM_VERSION')) {
|
||||||
|
return $msg . 'your HHVM version does not satisfy that requirement.';
|
||||||
|
} elseif ($job['packageName'] === 'hhvm') {
|
||||||
|
return $msg . 'you are running this with PHP and not HHVM.';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $msg . 'your PHP version does not satisfy that requirement.';
|
||||||
|
}
|
||||||
|
|
||||||
// handle php extensions
|
// handle php extensions
|
||||||
if (0 === stripos($job['packageName'], 'ext-')) {
|
if (0 === stripos($job['packageName'], 'ext-')) {
|
||||||
$ext = substr($job['packageName'], 4);
|
$ext = substr($job['packageName'], 4);
|
||||||
|
|
|
@ -217,7 +217,15 @@ class Rule
|
||||||
$targetName = $this->reasonData->getTarget();
|
$targetName = $this->reasonData->getTarget();
|
||||||
|
|
||||||
// handle php extensions
|
// handle php extensions
|
||||||
if (0 === strpos($targetName, 'ext-')) {
|
if ($targetName === 'php' || $targetName === 'php-64bit' || $targetName === 'hhvm') {
|
||||||
|
if (defined('HHVM_VERSION')) {
|
||||||
|
$text .= ' -> your HHVM version does not satisfy that requirement.';
|
||||||
|
} elseif ($targetName === 'hhvm') {
|
||||||
|
$text .= ' -> you are running this with PHP and not HHVM.';
|
||||||
|
} else {
|
||||||
|
$text .= ' -> your PHP version does not satisfy that requirement.';
|
||||||
|
}
|
||||||
|
} elseif (0 === strpos($targetName, 'ext-')) {
|
||||||
$ext = substr($targetName, 4);
|
$ext = substr($targetName, 4);
|
||||||
$error = extension_loaded($ext) ? 'has the wrong version ('.(phpversion($ext) ?: '0').') installed' : 'is missing from your system';
|
$error = extension_loaded($ext) ? 'has the wrong version ('.(phpversion($ext) ?: '0').') installed' : 'is missing from your system';
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ class Solver
|
||||||
protected $branches = array();
|
protected $branches = array();
|
||||||
protected $problems = array();
|
protected $problems = array();
|
||||||
protected $learnedPool = array();
|
protected $learnedPool = array();
|
||||||
|
protected $learnedWhy = array();
|
||||||
|
|
||||||
public function __construct(PolicyInterface $policy, Pool $pool, RepositoryInterface $installed)
|
public function __construct(PolicyInterface $policy, Pool $pool, RepositoryInterface $installed)
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,7 +35,7 @@ abstract class ArchiveDownloader extends FileDownloader
|
||||||
$fileName = parent::download($package, $path);
|
$fileName = parent::download($package, $path);
|
||||||
|
|
||||||
if ($this->io->isVerbose()) {
|
if ($this->io->isVerbose()) {
|
||||||
$this->io->write(' Extracting archive');
|
$this->io->writeError(' Extracting archive');
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -77,7 +77,7 @@ abstract class ArchiveDownloader extends FileDownloader
|
||||||
|
|
||||||
// retry downloading if we have an invalid zip file
|
// retry downloading if we have an invalid zip file
|
||||||
if ($retries && $e instanceof \UnexpectedValueException && class_exists('ZipArchive') && $e->getCode() === \ZipArchive::ER_NOZIP) {
|
if ($retries && $e instanceof \UnexpectedValueException && class_exists('ZipArchive') && $e->getCode() === \ZipArchive::ER_NOZIP) {
|
||||||
$this->io->write(' Invalid zip file, retrying...');
|
$this->io->writeError(' Invalid zip file, retrying...');
|
||||||
usleep(500000);
|
usleep(500000);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ abstract class ArchiveDownloader extends FileDownloader
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->io->write('');
|
$this->io->writeError('');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -192,7 +192,7 @@ class DownloadManager
|
||||||
|
|
||||||
foreach ($sources as $i => $source) {
|
foreach ($sources as $i => $source) {
|
||||||
if (isset($e)) {
|
if (isset($e)) {
|
||||||
$this->io->write(' <warning>Now trying to download from ' . $source . '</warning>');
|
$this->io->writeError(' <warning>Now trying to download from ' . $source . '</warning>');
|
||||||
}
|
}
|
||||||
$package->setInstallationSource($source);
|
$package->setInstallationSource($source);
|
||||||
try {
|
try {
|
||||||
|
@ -206,7 +206,7 @@ class DownloadManager
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->io->write(
|
$this->io->writeError(
|
||||||
' <warning>Failed to download '.
|
' <warning>Failed to download '.
|
||||||
$package->getPrettyName().
|
$package->getPrettyName().
|
||||||
' from ' . $source . ': '.
|
' from ' . $source . ': '.
|
||||||
|
|
|
@ -81,7 +81,7 @@ class FileDownloader implements DownloaderInterface
|
||||||
throw new \InvalidArgumentException('The given package is missing url information');
|
throw new \InvalidArgumentException('The given package is missing url information');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->io->write(" - Installing <info>" . $package->getName() . "</info> (<comment>" . VersionParser::formatVersion($package) . "</comment>)");
|
$this->io->writeError(" - Installing <info>" . $package->getName() . "</info> (<comment>" . VersionParser::formatVersion($package) . "</comment>)");
|
||||||
|
|
||||||
$urls = $package->getDistUrls();
|
$urls = $package->getDistUrls();
|
||||||
while ($url = array_shift($urls)) {
|
while ($url = array_shift($urls)) {
|
||||||
|
@ -89,11 +89,11 @@ class FileDownloader implements DownloaderInterface
|
||||||
return $this->doDownload($package, $path, $url);
|
return $this->doDownload($package, $path, $url);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
if ($this->io->isDebug()) {
|
if ($this->io->isDebug()) {
|
||||||
$this->io->write('');
|
$this->io->writeError('');
|
||||||
$this->io->write('Failed: ['.get_class($e).'] '.$e->getCode().': '.$e->getMessage());
|
$this->io->writeError('Failed: ['.get_class($e).'] '.$e->getCode().': '.$e->getMessage());
|
||||||
} elseif (count($urls)) {
|
} elseif (count($urls)) {
|
||||||
$this->io->write('');
|
$this->io->writeError('');
|
||||||
$this->io->write(' Failed, trying the next URL ('.$e->getCode().': '.$e->getMessage().')');
|
$this->io->writeError(' Failed, trying the next URL ('.$e->getCode().': '.$e->getMessage().')');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!count($urls)) {
|
if (!count($urls)) {
|
||||||
|
@ -102,7 +102,7 @@ class FileDownloader implements DownloaderInterface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->io->write('');
|
$this->io->writeError('');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function doDownload(PackageInterface $package, $path, $url)
|
protected function doDownload(PackageInterface $package, $path, $url)
|
||||||
|
@ -127,7 +127,7 @@ class FileDownloader implements DownloaderInterface
|
||||||
// download if we don't have it in cache or the cache is invalidated
|
// download if we don't have it in cache or the cache is invalidated
|
||||||
if (!$this->cache || ($checksum && $checksum !== $this->cache->sha1($cacheKey)) || !$this->cache->copyTo($cacheKey, $fileName)) {
|
if (!$this->cache || ($checksum && $checksum !== $this->cache->sha1($cacheKey)) || !$this->cache->copyTo($cacheKey, $fileName)) {
|
||||||
if (!$this->outputProgress) {
|
if (!$this->outputProgress) {
|
||||||
$this->io->write(' Downloading');
|
$this->io->writeError(' Downloading');
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to download 3 times then fail hard
|
// try to download 3 times then fail hard
|
||||||
|
@ -142,7 +142,7 @@ class FileDownloader implements DownloaderInterface
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
if ($this->io->isVerbose()) {
|
if ($this->io->isVerbose()) {
|
||||||
$this->io->write(' Download failed, retrying...');
|
$this->io->writeError(' Download failed, retrying...');
|
||||||
}
|
}
|
||||||
usleep(500000);
|
usleep(500000);
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ class FileDownloader implements DownloaderInterface
|
||||||
$this->cache->copyFrom($cacheKey, $fileName);
|
$this->cache->copyFrom($cacheKey, $fileName);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$this->io->write(' Loading from cache');
|
$this->io->writeError(' Loading from cache');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!file_exists($fileName)) {
|
if (!file_exists($fileName)) {
|
||||||
|
@ -205,7 +205,7 @@ class FileDownloader implements DownloaderInterface
|
||||||
*/
|
*/
|
||||||
public function remove(PackageInterface $package, $path)
|
public function remove(PackageInterface $package, $path)
|
||||||
{
|
{
|
||||||
$this->io->write(" - Removing <info>" . $package->getName() . "</info> (<comment>" . VersionParser::formatVersion($package) . "</comment>)");
|
$this->io->writeError(" - Removing <info>" . $package->getName() . "</info> (<comment>" . VersionParser::formatVersion($package) . "</comment>)");
|
||||||
if (!$this->filesystem->removeDirectory($path)) {
|
if (!$this->filesystem->removeDirectory($path)) {
|
||||||
throw new \RuntimeException('Could not completely delete '.$path.', aborting.');
|
throw new \RuntimeException('Could not completely delete '.$path.', aborting.');
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ class GitDownloader extends VcsDownloader
|
||||||
$ref = $package->getSourceReference();
|
$ref = $package->getSourceReference();
|
||||||
$flag = defined('PHP_WINDOWS_VERSION_MAJOR') ? '/D ' : '';
|
$flag = defined('PHP_WINDOWS_VERSION_MAJOR') ? '/D ' : '';
|
||||||
$command = 'git clone --no-checkout %s %s && cd '.$flag.'%2$s && git remote add composer %1$s && git fetch composer';
|
$command = 'git clone --no-checkout %s %s && cd '.$flag.'%2$s && git remote add composer %1$s && git fetch composer';
|
||||||
$this->io->write(" Cloning ".$ref);
|
$this->io->writeError(" Cloning ".$ref);
|
||||||
|
|
||||||
$commandCallable = function ($url) use ($ref, $path, $command) {
|
$commandCallable = function ($url) use ($ref, $path, $command) {
|
||||||
return sprintf($command, ProcessExecutor::escape($url), ProcessExecutor::escape($path), ProcessExecutor::escape($ref));
|
return sprintf($command, ProcessExecutor::escape($url), ProcessExecutor::escape($path), ProcessExecutor::escape($ref));
|
||||||
|
@ -78,7 +78,7 @@ class GitDownloader extends VcsDownloader
|
||||||
}
|
}
|
||||||
|
|
||||||
$ref = $target->getSourceReference();
|
$ref = $target->getSourceReference();
|
||||||
$this->io->write(" Checking out ".$ref);
|
$this->io->writeError(" Checking out ".$ref);
|
||||||
$command = 'git remote set-url composer %s && git fetch composer && git fetch --tags composer';
|
$command = 'git remote set-url composer %s && git fetch composer && git fetch --tags composer';
|
||||||
|
|
||||||
$commandCallable = function ($url) use ($command) {
|
$commandCallable = function ($url) use ($command) {
|
||||||
|
@ -143,10 +143,10 @@ class GitDownloader extends VcsDownloader
|
||||||
$changes = array_map(function ($elem) {
|
$changes = array_map(function ($elem) {
|
||||||
return ' '.$elem;
|
return ' '.$elem;
|
||||||
}, preg_split('{\s*\r?\n\s*}', $changes));
|
}, preg_split('{\s*\r?\n\s*}', $changes));
|
||||||
$this->io->write(' <error>The package has modified files:</error>');
|
$this->io->writeError(' <error>The package has modified files:</error>');
|
||||||
$this->io->write(array_slice($changes, 0, 10));
|
$this->io->writeError(array_slice($changes, 0, 10));
|
||||||
if (count($changes) > 10) {
|
if (count($changes) > 10) {
|
||||||
$this->io->write(' <info>'.count($changes) - 10 . ' more files modified, choose "v" to view the full list</info>');
|
$this->io->writeError(' <info>'.count($changes) - 10 . ' more files modified, choose "v" to view the full list</info>');
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -167,21 +167,21 @@ class GitDownloader extends VcsDownloader
|
||||||
throw new \RuntimeException('Update aborted');
|
throw new \RuntimeException('Update aborted');
|
||||||
|
|
||||||
case 'v':
|
case 'v':
|
||||||
$this->io->write($changes);
|
$this->io->writeError($changes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
help:
|
help:
|
||||||
$this->io->write(array(
|
$this->io->writeError(array(
|
||||||
' y - discard changes and apply the '.($update ? 'update' : 'uninstall'),
|
' y - discard changes and apply the '.($update ? 'update' : 'uninstall'),
|
||||||
' n - abort the '.($update ? 'update' : 'uninstall').' and let you manually clean things up',
|
' n - abort the '.($update ? 'update' : 'uninstall').' and let you manually clean things up',
|
||||||
' v - view modified files',
|
' v - view modified files',
|
||||||
));
|
));
|
||||||
if ($update) {
|
if ($update) {
|
||||||
$this->io->write(' s - stash changes and try to reapply them after the update');
|
$this->io->writeError(' s - stash changes and try to reapply them after the update');
|
||||||
}
|
}
|
||||||
$this->io->write(' ? - print help');
|
$this->io->writeError(' ? - print help');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,7 +195,7 @@ class GitDownloader extends VcsDownloader
|
||||||
$path = $this->normalizePath($path);
|
$path = $this->normalizePath($path);
|
||||||
if ($this->hasStashedChanges) {
|
if ($this->hasStashedChanges) {
|
||||||
$this->hasStashedChanges = false;
|
$this->hasStashedChanges = false;
|
||||||
$this->io->write(' <info>Re-applying stashed changes</info>');
|
$this->io->writeError(' <info>Re-applying stashed changes</info>');
|
||||||
if (0 !== $this->process->execute('git stash pop', $output, $path)) {
|
if (0 !== $this->process->execute('git stash pop', $output, $path)) {
|
||||||
throw new \RuntimeException("Failed to apply stashed changes:\n\n".$this->process->getErrorOutput());
|
throw new \RuntimeException("Failed to apply stashed changes:\n\n".$this->process->getErrorOutput());
|
||||||
}
|
}
|
||||||
|
@ -261,7 +261,7 @@ class GitDownloader extends VcsDownloader
|
||||||
|
|
||||||
// reference was not found (prints "fatal: reference is not a tree: $ref")
|
// reference was not found (prints "fatal: reference is not a tree: $ref")
|
||||||
if (false !== strpos($this->process->getErrorOutput(), $reference)) {
|
if (false !== strpos($this->process->getErrorOutput(), $reference)) {
|
||||||
$this->io->write(' <warning>'.$reference.' is gone (history was rewritten?)</warning>');
|
$this->io->writeError(' <warning>'.$reference.' is gone (history was rewritten?)</warning>');
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new \RuntimeException('Failed to execute ' . GitUtil::sanitizeUrl($command) . "\n\n" . $this->process->getErrorOutput());
|
throw new \RuntimeException('Failed to execute ' . GitUtil::sanitizeUrl($command) . "\n\n" . $this->process->getErrorOutput());
|
||||||
|
|
|
@ -27,7 +27,7 @@ class HgDownloader extends VcsDownloader
|
||||||
{
|
{
|
||||||
$url = ProcessExecutor::escape($url);
|
$url = ProcessExecutor::escape($url);
|
||||||
$ref = ProcessExecutor::escape($package->getSourceReference());
|
$ref = ProcessExecutor::escape($package->getSourceReference());
|
||||||
$this->io->write(" Cloning ".$package->getSourceReference());
|
$this->io->writeError(" Cloning ".$package->getSourceReference());
|
||||||
$command = sprintf('hg clone %s %s', $url, ProcessExecutor::escape($path));
|
$command = sprintf('hg clone %s %s', $url, ProcessExecutor::escape($path));
|
||||||
if (0 !== $this->process->execute($command, $ignoredOutput)) {
|
if (0 !== $this->process->execute($command, $ignoredOutput)) {
|
||||||
throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
|
throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
|
||||||
|
@ -45,7 +45,7 @@ class HgDownloader extends VcsDownloader
|
||||||
{
|
{
|
||||||
$url = ProcessExecutor::escape($url);
|
$url = ProcessExecutor::escape($url);
|
||||||
$ref = ProcessExecutor::escape($target->getSourceReference());
|
$ref = ProcessExecutor::escape($target->getSourceReference());
|
||||||
$this->io->write(" Updating to ".$target->getSourceReference());
|
$this->io->writeError(" Updating to ".$target->getSourceReference());
|
||||||
|
|
||||||
if (!is_dir($path.'/.hg')) {
|
if (!is_dir($path.'/.hg')) {
|
||||||
throw new \RuntimeException('The .hg directory is missing from '.$path.', see http://getcomposer.org/commit-deps for more information');
|
throw new \RuntimeException('The .hg directory is missing from '.$path.', see http://getcomposer.org/commit-deps for more information');
|
||||||
|
|
|
@ -31,7 +31,7 @@ class PerforceDownloader extends VcsDownloader
|
||||||
$ref = $package->getSourceReference();
|
$ref = $package->getSourceReference();
|
||||||
$label = $this->getLabelFromSourceReference($ref);
|
$label = $this->getLabelFromSourceReference($ref);
|
||||||
|
|
||||||
$this->io->write(' Cloning ' . $ref);
|
$this->io->writeError(' Cloning ' . $ref);
|
||||||
$this->initPerforce($package, $path, $url);
|
$this->initPerforce($package, $path, $url);
|
||||||
$this->perforce->setStream($ref);
|
$this->perforce->setStream($ref);
|
||||||
$this->perforce->p4Login($this->io);
|
$this->perforce->p4Login($this->io);
|
||||||
|
@ -85,7 +85,7 @@ class PerforceDownloader extends VcsDownloader
|
||||||
*/
|
*/
|
||||||
public function getLocalChanges(PackageInterface $package, $path)
|
public function getLocalChanges(PackageInterface $package, $path)
|
||||||
{
|
{
|
||||||
$this->io->write('Perforce driver does not check for local changes before overriding', true);
|
$this->io->writeError('Perforce driver does not check for local changes before overriding', true);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ class SvnDownloader extends VcsDownloader
|
||||||
SvnUtil::cleanEnv();
|
SvnUtil::cleanEnv();
|
||||||
$ref = $package->getSourceReference();
|
$ref = $package->getSourceReference();
|
||||||
|
|
||||||
$this->io->write(" Checking out ".$package->getSourceReference());
|
$this->io->writeError(" Checking out ".$package->getSourceReference());
|
||||||
$this->execute($url, "svn co", sprintf("%s/%s", $url, $ref), null, $path);
|
$this->execute($url, "svn co", sprintf("%s/%s", $url, $ref), null, $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ class SvnDownloader extends VcsDownloader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->io->write(" Checking out " . $ref);
|
$this->io->writeError(" Checking out " . $ref);
|
||||||
$this->execute($url, "svn switch" . $flags, sprintf("%s/%s", $url, $ref), $path);
|
$this->execute($url, "svn switch" . $flags, sprintf("%s/%s", $url, $ref), $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,10 +114,10 @@ class SvnDownloader extends VcsDownloader
|
||||||
$changes = array_map(function ($elem) {
|
$changes = array_map(function ($elem) {
|
||||||
return ' '.$elem;
|
return ' '.$elem;
|
||||||
}, preg_split('{\s*\r?\n\s*}', $changes));
|
}, preg_split('{\s*\r?\n\s*}', $changes));
|
||||||
$this->io->write(' <error>The package has modified files:</error>');
|
$this->io->writeError(' <error>The package has modified files:</error>');
|
||||||
$this->io->write(array_slice($changes, 0, 10));
|
$this->io->writeError(array_slice($changes, 0, 10));
|
||||||
if (count($changes) > 10) {
|
if (count($changes) > 10) {
|
||||||
$this->io->write(' <info>'.count($changes) - 10 . ' more files modified, choose "v" to view the full list</info>');
|
$this->io->writeError(' <info>'.count($changes) - 10 . ' more files modified, choose "v" to view the full list</info>');
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -130,12 +130,12 @@ class SvnDownloader extends VcsDownloader
|
||||||
throw new \RuntimeException('Update aborted');
|
throw new \RuntimeException('Update aborted');
|
||||||
|
|
||||||
case 'v':
|
case 'v':
|
||||||
$this->io->write($changes);
|
$this->io->writeError($changes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
$this->io->write(array(
|
$this->io->writeError(array(
|
||||||
' y - discard changes and apply the '.($update ? 'update' : 'uninstall'),
|
' y - discard changes and apply the '.($update ? 'update' : 'uninstall'),
|
||||||
' n - abort the '.($update ? 'update' : 'uninstall').' and let you manually clean things up',
|
' n - abort the '.($update ? 'update' : 'uninstall').' and let you manually clean things up',
|
||||||
' v - view modified files',
|
' v - view modified files',
|
||||||
|
|
|
@ -54,7 +54,7 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
||||||
throw new \InvalidArgumentException('Package '.$package->getPrettyName().' is missing reference information');
|
throw new \InvalidArgumentException('Package '.$package->getPrettyName().' is missing reference information');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->io->write(" - Installing <info>" . $package->getName() . "</info> (<comment>" . VersionParser::formatVersion($package) . "</comment>)");
|
$this->io->writeError(" - Installing <info>" . $package->getName() . "</info> (<comment>" . VersionParser::formatVersion($package) . "</comment>)");
|
||||||
$this->filesystem->emptyDirectory($path);
|
$this->filesystem->emptyDirectory($path);
|
||||||
|
|
||||||
$urls = $package->getSourceUrls();
|
$urls = $package->getSourceUrls();
|
||||||
|
@ -67,9 +67,9 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
||||||
break;
|
break;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
if ($this->io->isDebug()) {
|
if ($this->io->isDebug()) {
|
||||||
$this->io->write('Failed: ['.get_class($e).'] '.$e->getMessage());
|
$this->io->writeError('Failed: ['.get_class($e).'] '.$e->getMessage());
|
||||||
} elseif (count($urls)) {
|
} elseif (count($urls)) {
|
||||||
$this->io->write(' Failed, trying the next URL');
|
$this->io->writeError(' Failed, trying the next URL');
|
||||||
}
|
}
|
||||||
if (!count($urls)) {
|
if (!count($urls)) {
|
||||||
throw $e;
|
throw $e;
|
||||||
|
@ -77,7 +77,7 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->io->write('');
|
$this->io->writeError('');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -104,7 +104,7 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
||||||
$to = VersionParser::formatVersion($target);
|
$to = VersionParser::formatVersion($target);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->io->write(" - Updating <info>" . $name . "</info> (<comment>" . $from . "</comment> => <comment>" . $to . "</comment>)");
|
$this->io->writeError(" - Updating <info>" . $name . "</info> (<comment>" . $from . "</comment> => <comment>" . $to . "</comment>)");
|
||||||
|
|
||||||
$this->cleanChanges($initial, $path, true);
|
$this->cleanChanges($initial, $path, true);
|
||||||
$urls = $target->getSourceUrls();
|
$urls = $target->getSourceUrls();
|
||||||
|
@ -117,9 +117,9 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
||||||
break;
|
break;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
if ($this->io->isDebug()) {
|
if ($this->io->isDebug()) {
|
||||||
$this->io->write('Failed: ['.get_class($e).'] '.$e->getMessage());
|
$this->io->writeError('Failed: ['.get_class($e).'] '.$e->getMessage());
|
||||||
} elseif (count($urls)) {
|
} elseif (count($urls)) {
|
||||||
$this->io->write(' Failed, trying the next URL');
|
$this->io->writeError(' Failed, trying the next URL');
|
||||||
} else {
|
} else {
|
||||||
// in case of failed update, try to reapply the changes before aborting
|
// in case of failed update, try to reapply the changes before aborting
|
||||||
$this->reapplyChanges($path);
|
$this->reapplyChanges($path);
|
||||||
|
@ -146,12 +146,12 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
||||||
return ' ' . $line;
|
return ' ' . $line;
|
||||||
}, explode("\n", $logs)));
|
}, explode("\n", $logs)));
|
||||||
|
|
||||||
$this->io->write(' '.$message);
|
$this->io->writeError(' '.$message);
|
||||||
$this->io->write($logs);
|
$this->io->writeError($logs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->io->write('');
|
$this->io->writeError('');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -159,7 +159,7 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
||||||
*/
|
*/
|
||||||
public function remove(PackageInterface $package, $path)
|
public function remove(PackageInterface $package, $path)
|
||||||
{
|
{
|
||||||
$this->io->write(" - Removing <info>" . $package->getName() . "</info> (<comment>" . $package->getPrettyVersion() . "</comment>)");
|
$this->io->writeError(" - Removing <info>" . $package->getName() . "</info> (<comment>" . $package->getPrettyVersion() . "</comment>)");
|
||||||
$this->cleanChanges($package, $path, false);
|
$this->cleanChanges($package, $path, false);
|
||||||
if (!$this->filesystem->removeDirectory($path)) {
|
if (!$this->filesystem->removeDirectory($path)) {
|
||||||
throw new \RuntimeException('Could not completely delete '.$path.', aborting.');
|
throw new \RuntimeException('Could not completely delete '.$path.', aborting.');
|
||||||
|
|
|
@ -21,7 +21,6 @@ use Composer\Composer;
|
||||||
use Composer\DependencyResolver\Operation\OperationInterface;
|
use Composer\DependencyResolver\Operation\OperationInterface;
|
||||||
use Composer\Repository\CompositeRepository;
|
use Composer\Repository\CompositeRepository;
|
||||||
use Composer\Script;
|
use Composer\Script;
|
||||||
use Composer\Script\CommandEvent;
|
|
||||||
use Composer\Script\PackageEvent;
|
use Composer\Script\PackageEvent;
|
||||||
use Composer\Util\ProcessExecutor;
|
use Composer\Util\ProcessExecutor;
|
||||||
|
|
||||||
|
@ -95,36 +94,28 @@ class EventDispatcher
|
||||||
/**
|
/**
|
||||||
* Dispatch a package event.
|
* Dispatch a package event.
|
||||||
*
|
*
|
||||||
* @param string $eventName The constant in ScriptEvents
|
* @param string $eventName The constant in PackageEvents
|
||||||
* @param boolean $devMode Whether or not we are in dev mode
|
* @param bool $devMode Whether or not we are in dev mode
|
||||||
* @param OperationInterface $operation The package being installed/updated/removed
|
* @param PolicyInterface $policy The policy
|
||||||
* @return int return code of the executed script if any, for php scripts a false return
|
* @param Pool $pool The pool
|
||||||
* value is changed to 1, anything else to 0
|
* @param CompositeRepository $installedRepo The installed repository
|
||||||
*/
|
* @param Request $request The request
|
||||||
public function dispatchPackageEvent($eventName, $devMode, OperationInterface $operation)
|
* @param array $operations The list of operations
|
||||||
{
|
* @param OperationInterface $operation The package being installed/updated/removed
|
||||||
return $this->doDispatch(new PackageEvent($eventName, $this->composer, $this->io, $devMode, $operation));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dispatch a command event.
|
|
||||||
*
|
*
|
||||||
* @param string $eventName The constant in ScriptEvents
|
* @return int return code of the executed script if any, for php scripts a false return
|
||||||
* @param boolean $devMode Whether or not we are in dev mode
|
* value is changed to 1, anything else to 0
|
||||||
* @param array $additionalArgs Arguments passed by the user
|
|
||||||
* @param array $flags Optional flags to pass data not as argument
|
|
||||||
* @return int return code of the executed script if any, for php scripts a false return
|
|
||||||
* value is changed to 1, anything else to 0
|
|
||||||
*/
|
*/
|
||||||
public function dispatchCommandEvent($eventName, $devMode, $additionalArgs = array(), $flags = array())
|
public function dispatchPackageEvent($eventName, $devMode, PolicyInterface $policy, Pool $pool, CompositeRepository $installedRepo, Request $request, array $operations, OperationInterface $operation)
|
||||||
{
|
{
|
||||||
return $this->doDispatch(new CommandEvent($eventName, $this->composer, $this->io, $devMode, $additionalArgs, $flags));
|
return $this->doDispatch(new PackageEvent($eventName, $this->composer, $this->io, $devMode, $policy, $pool, $installedRepo, $request, $operations, $operation));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatch a installer event.
|
* Dispatch a installer event.
|
||||||
*
|
*
|
||||||
* @param string $eventName The constant in InstallerEvents
|
* @param string $eventName The constant in InstallerEvents
|
||||||
|
* @param bool $devMode Whether or not we are in dev mode
|
||||||
* @param PolicyInterface $policy The policy
|
* @param PolicyInterface $policy The policy
|
||||||
* @param Pool $pool The pool
|
* @param Pool $pool The pool
|
||||||
* @param CompositeRepository $installedRepo The installed repository
|
* @param CompositeRepository $installedRepo The installed repository
|
||||||
|
@ -134,9 +125,9 @@ class EventDispatcher
|
||||||
* @return int return code of the executed script if any, for php scripts a false return
|
* @return int return code of the executed script if any, for php scripts a false return
|
||||||
* value is changed to 1, anything else to 0
|
* value is changed to 1, anything else to 0
|
||||||
*/
|
*/
|
||||||
public function dispatchInstallerEvent($eventName, PolicyInterface $policy, Pool $pool, CompositeRepository $installedRepo, Request $request, array $operations = array())
|
public function dispatchInstallerEvent($eventName, $devMode, PolicyInterface $policy, Pool $pool, CompositeRepository $installedRepo, Request $request, array $operations = array())
|
||||||
{
|
{
|
||||||
return $this->doDispatch(new InstallerEvent($eventName, $this->composer, $this->io, $policy, $pool, $installedRepo, $request, $operations));
|
return $this->doDispatch(new InstallerEvent($eventName, $this->composer, $this->io, $devMode, $policy, $pool, $installedRepo, $request, $operations));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -163,11 +154,11 @@ class EventDispatcher
|
||||||
$methodName = substr($callable, strpos($callable, '::') + 2);
|
$methodName = substr($callable, strpos($callable, '::') + 2);
|
||||||
|
|
||||||
if (!class_exists($className)) {
|
if (!class_exists($className)) {
|
||||||
$this->io->write('<warning>Class '.$className.' is not autoloadable, can not call '.$event->getName().' script</warning>');
|
$this->io->writeError('<warning>Class '.$className.' is not autoloadable, can not call '.$event->getName().' script</warning>');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!is_callable($callable)) {
|
if (!is_callable($callable)) {
|
||||||
$this->io->write('<warning>Method '.$callable.' is not callable, can not call '.$event->getName().' script</warning>');
|
$this->io->writeError('<warning>Method '.$callable.' is not callable, can not call '.$event->getName().' script</warning>');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,13 +166,13 @@ class EventDispatcher
|
||||||
$return = false === $this->executeEventPhpScript($className, $methodName, $event) ? 1 : 0;
|
$return = false === $this->executeEventPhpScript($className, $methodName, $event) ? 1 : 0;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$message = "Script %s handling the %s event terminated with an exception";
|
$message = "Script %s handling the %s event terminated with an exception";
|
||||||
$this->io->write('<error>'.sprintf($message, $callable, $event->getName()).'</error>');
|
$this->io->writeError('<error>'.sprintf($message, $callable, $event->getName()).'</error>');
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$args = implode(' ', array_map(array('Composer\Util\ProcessExecutor','escape'), $event->getArguments()));
|
$args = implode(' ', array_map(array('Composer\Util\ProcessExecutor','escape'), $event->getArguments()));
|
||||||
if (0 !== ($exitCode = $this->process->execute($callable . ($args === '' ? '' : ' '.$args)))) {
|
if (0 !== ($exitCode = $this->process->execute($callable . ($args === '' ? '' : ' '.$args)))) {
|
||||||
$this->io->write(sprintf('<error>Script %s handling the %s event returned with an error</error>', $callable, $event->getName()));
|
$this->io->writeError(sprintf('<error>Script %s handling the %s event returned with an error</error>', $callable, $event->getName()));
|
||||||
|
|
||||||
throw new \RuntimeException('Error Output: '.$this->process->getErrorOutput(), $exitCode);
|
throw new \RuntimeException('Error Output: '.$this->process->getErrorOutput(), $exitCode);
|
||||||
}
|
}
|
||||||
|
@ -214,10 +205,6 @@ class EventDispatcher
|
||||||
*/
|
*/
|
||||||
protected function checkListenerExpectedEvent($target, Event $event)
|
protected function checkListenerExpectedEvent($target, Event $event)
|
||||||
{
|
{
|
||||||
if (!$event instanceof Script\Event) {
|
|
||||||
return $event;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$reflected = new \ReflectionParameter($target, 0);
|
$reflected = new \ReflectionParameter($target, 0);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
@ -232,8 +219,24 @@ class EventDispatcher
|
||||||
|
|
||||||
$expected = $typehint->getName();
|
$expected = $typehint->getName();
|
||||||
|
|
||||||
|
// BC support
|
||||||
if (!$event instanceof $expected && $expected === 'Composer\Script\CommandEvent') {
|
if (!$event instanceof $expected && $expected === 'Composer\Script\CommandEvent') {
|
||||||
$event = new CommandEvent($event->getName(), $event->getComposer(), $event->getIO(), $event->isDevMode(), $event->getArguments());
|
$event = new \Composer\Script\CommandEvent(
|
||||||
|
$event->getName(), $event->getComposer(), $event->getIO(), $event->isDevMode(), $event->getArguments()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!$event instanceof $expected && $expected === 'Composer\Script\PackageEvent') {
|
||||||
|
$event = new \Composer\Script\PackageEvent(
|
||||||
|
$event->getName(), $event->getComposer(), $event->getIO(), $event->isDevMode(),
|
||||||
|
$event->getPolicy(), $event->getPool(), $event->getInstalledRepo(), $event->getRequest(),
|
||||||
|
$event->getOperations(), $event->getOperation()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!$event instanceof $expected && $expected === 'Composer\Script\Event') {
|
||||||
|
$event = new \Composer\Script\Event(
|
||||||
|
$event->getName(), $event->getComposer(), $event->getIO(), $event->isDevMode(),
|
||||||
|
$event->getArguments(), $event->getFlags()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $event;
|
return $event;
|
||||||
|
|
|
@ -113,10 +113,10 @@ class Factory
|
||||||
$config->merge(array('config' => array('home' => $home, 'cache-dir' => $cacheDir)));
|
$config->merge(array('config' => array('home' => $home, 'cache-dir' => $cacheDir)));
|
||||||
|
|
||||||
// load global config
|
// load global config
|
||||||
$file = new JsonFile($home.'/config.json');
|
$file = new JsonFile($config->get('home').'/config.json');
|
||||||
if ($file->exists()) {
|
if ($file->exists()) {
|
||||||
if ($io && $io->isDebug()) {
|
if ($io && $io->isDebug()) {
|
||||||
$io->write('Loading config file ' . $file->getPath());
|
$io->writeError('Loading config file ' . $file->getPath());
|
||||||
}
|
}
|
||||||
$config->merge($file->read());
|
$config->merge($file->read());
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ class Factory
|
||||||
$file = new JsonFile($config->get('home').'/auth.json');
|
$file = new JsonFile($config->get('home').'/auth.json');
|
||||||
if ($file->exists()) {
|
if ($file->exists()) {
|
||||||
if ($io && $io->isDebug()) {
|
if ($io && $io->isDebug()) {
|
||||||
$io->write('Loading config file ' . $file->getPath());
|
$io->writeError('Loading config file ' . $file->getPath());
|
||||||
}
|
}
|
||||||
$config->merge(array('config' => $file->read()));
|
$config->merge(array('config' => $file->read()));
|
||||||
}
|
}
|
||||||
|
@ -227,12 +227,12 @@ class Factory
|
||||||
$config->merge($localConfig);
|
$config->merge($localConfig);
|
||||||
if (isset($composerFile)) {
|
if (isset($composerFile)) {
|
||||||
if ($io && $io->isDebug()) {
|
if ($io && $io->isDebug()) {
|
||||||
$io->write('Loading config file ' . $composerFile);
|
$io->writeError('Loading config file ' . $composerFile);
|
||||||
}
|
}
|
||||||
$localAuthFile = new JsonFile(dirname(realpath($composerFile)) . '/auth.json');
|
$localAuthFile = new JsonFile(dirname(realpath($composerFile)) . '/auth.json');
|
||||||
if ($localAuthFile->exists()) {
|
if ($localAuthFile->exists()) {
|
||||||
if ($io && $io->isDebug()) {
|
if ($io && $io->isDebug()) {
|
||||||
$io->write('Loading config file ' . $localAuthFile->getPath());
|
$io->writeError('Loading config file ' . $localAuthFile->getPath());
|
||||||
}
|
}
|
||||||
$config->merge(array('config' => $localAuthFile->read()));
|
$config->merge(array('config' => $localAuthFile->read()));
|
||||||
$config->setAuthConfigSource(new JsonConfigSource($localAuthFile, true));
|
$config->setAuthConfigSource(new JsonConfigSource($localAuthFile, true));
|
||||||
|
@ -362,7 +362,7 @@ class Factory
|
||||||
$composer = self::createComposer($io, $config->get('home') . '/composer.json', $disablePlugins, $config->get('home'), false);
|
$composer = self::createComposer($io, $config->get('home') . '/composer.json', $disablePlugins, $config->get('home'), false);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
if ($io->isDebug()) {
|
if ($io->isDebug()) {
|
||||||
$io->write('Failed to initialize global composer: '.$e->getMessage());
|
$io->writeError('Failed to initialize global composer: '.$e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,16 +23,19 @@ use Symfony\Component\Console\Helper\HelperSet;
|
||||||
class BufferIO extends ConsoleIO
|
class BufferIO extends ConsoleIO
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param string $input
|
* @param string $input
|
||||||
* @param int $verbosity
|
* @param int $verbosity
|
||||||
* @param OutputFormatterInterface $formatter
|
* @param OutputFormatterInterface $formatter
|
||||||
*/
|
*/
|
||||||
public function __construct($input = '', $verbosity = null, OutputFormatterInterface $formatter = null)
|
public function __construct(
|
||||||
{
|
$input = '',
|
||||||
|
$verbosity = StreamOutput::VERBOSITY_NORMAL,
|
||||||
|
OutputFormatterInterface $formatter = null
|
||||||
|
) {
|
||||||
$input = new StringInput($input);
|
$input = new StringInput($input);
|
||||||
$input->setInteractive(false);
|
$input->setInteractive(false);
|
||||||
|
|
||||||
$output = new StreamOutput(fopen('php://memory', 'rw'), $verbosity === null ? StreamOutput::VERBOSITY_NORMAL : $verbosity, !empty($formatter), $formatter);
|
$output = new StreamOutput(fopen('php://memory', 'rw'), $verbosity, !empty($formatter), $formatter);
|
||||||
|
|
||||||
parent::__construct($input, $output, new HelperSet(array()));
|
parent::__construct($input, $output, new HelperSet(array()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
namespace Composer\IO;
|
namespace Composer\IO;
|
||||||
|
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\ConsoleOutputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
use Symfony\Component\Console\Helper\HelperSet;
|
use Symfony\Component\Console\Helper\HelperSet;
|
||||||
use Symfony\Component\Process\ExecutableFinder;
|
use Symfony\Component\Process\ExecutableFinder;
|
||||||
|
@ -29,6 +30,7 @@ class ConsoleIO extends BaseIO
|
||||||
protected $output;
|
protected $output;
|
||||||
protected $helperSet;
|
protected $helperSet;
|
||||||
protected $lastMessage;
|
protected $lastMessage;
|
||||||
|
protected $lastMessageErr;
|
||||||
private $startTime;
|
private $startTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,6 +96,24 @@ class ConsoleIO extends BaseIO
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function write($messages, $newline = true)
|
public function write($messages, $newline = true)
|
||||||
|
{
|
||||||
|
$this->doWrite($messages, $newline, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function writeError($messages, $newline = true)
|
||||||
|
{
|
||||||
|
$this->doWrite($messages, $newline, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $messages
|
||||||
|
* @param boolean $newline
|
||||||
|
* @param boolean $stderr
|
||||||
|
*/
|
||||||
|
private function doWrite($messages, $newline, $stderr)
|
||||||
{
|
{
|
||||||
if (null !== $this->startTime) {
|
if (null !== $this->startTime) {
|
||||||
$memoryUsage = memory_get_usage() / 1024 / 1024;
|
$memoryUsage = memory_get_usage() / 1024 / 1024;
|
||||||
|
@ -102,6 +122,13 @@ class ConsoleIO extends BaseIO
|
||||||
return sprintf('[%.1fMB/%.2fs] %s', $memoryUsage, $timeSpent, $message);
|
return sprintf('[%.1fMB/%.2fs] %s', $memoryUsage, $timeSpent, $message);
|
||||||
}, (array) $messages);
|
}, (array) $messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (true === $stderr && $this->output instanceof ConsoleOutputInterface) {
|
||||||
|
$this->output->getErrorOutput()->write($messages, $newline);
|
||||||
|
$this->lastMessageErr = join($newline ? "\n" : '', (array) $messages);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$this->output->write($messages, $newline);
|
$this->output->write($messages, $newline);
|
||||||
$this->lastMessage = join($newline ? "\n" : '', (array) $messages);
|
$this->lastMessage = join($newline ? "\n" : '', (array) $messages);
|
||||||
}
|
}
|
||||||
|
@ -111,12 +138,29 @@ class ConsoleIO extends BaseIO
|
||||||
*/
|
*/
|
||||||
public function overwrite($messages, $newline = true, $size = null)
|
public function overwrite($messages, $newline = true, $size = null)
|
||||||
{
|
{
|
||||||
if (!$this->output->isDecorated()) {
|
$this->doOverwrite($messages, $newline, $size, false);
|
||||||
if (!$messages) {
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->write($messages, count($messages) === 1 || $newline);
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function overwriteError($messages, $newline = true, $size = null)
|
||||||
|
{
|
||||||
|
$this->doOverwrite($messages, $newline, $size, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $messages
|
||||||
|
* @param boolean $newline
|
||||||
|
* @param integer $size
|
||||||
|
* @param boolean $stderr
|
||||||
|
*/
|
||||||
|
private function doOverwrite($messages, $newline, $size, $stderr)
|
||||||
|
{
|
||||||
|
if (true === $stderr && $this->output instanceof ConsoleOutputInterface) {
|
||||||
|
$output = $this->output->getErrorOutput();
|
||||||
|
} else {
|
||||||
|
$output = $this->output;
|
||||||
}
|
}
|
||||||
|
|
||||||
// messages can be an array, let's convert it to string anyway
|
// messages can be an array, let's convert it to string anyway
|
||||||
|
@ -125,26 +169,31 @@ class ConsoleIO extends BaseIO
|
||||||
// since overwrite is supposed to overwrite last message...
|
// since overwrite is supposed to overwrite last message...
|
||||||
if (!isset($size)) {
|
if (!isset($size)) {
|
||||||
// removing possible formatting of lastMessage with strip_tags
|
// removing possible formatting of lastMessage with strip_tags
|
||||||
$size = strlen(strip_tags($this->lastMessage));
|
$size = strlen(strip_tags($stderr ? $this->lastMessageErr : $this->lastMessage));
|
||||||
}
|
}
|
||||||
// ...let's fill its length with backspaces
|
// ...let's fill its length with backspaces
|
||||||
$this->write(str_repeat("\x08", $size), false);
|
$this->doWrite(str_repeat("\x08", $size), false, $stderr);
|
||||||
|
|
||||||
// write the new message
|
// write the new message
|
||||||
$this->write($messages, false);
|
$this->doWrite($messages, false, $stderr);
|
||||||
|
|
||||||
$fill = $size - strlen(strip_tags($messages));
|
$fill = $size - strlen(strip_tags($messages));
|
||||||
if ($fill > 0) {
|
if ($fill > 0) {
|
||||||
// whitespace whatever has left
|
// whitespace whatever has left
|
||||||
$this->write(str_repeat(' ', $fill), false);
|
$this->doWrite(str_repeat(' ', $fill), false, $stderr);
|
||||||
// move the cursor back
|
// move the cursor back
|
||||||
$this->write(str_repeat("\x08", $fill), false);
|
$this->doWrite(str_repeat("\x08", $fill), false, $stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($newline) {
|
if ($newline) {
|
||||||
$this->write('');
|
$this->doWrite('', true, $stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($stderr) {
|
||||||
|
$this->lastMessageErr = $messages;
|
||||||
|
} else {
|
||||||
|
$this->lastMessage = $messages;
|
||||||
}
|
}
|
||||||
$this->lastMessage = $messages;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -152,7 +201,16 @@ class ConsoleIO extends BaseIO
|
||||||
*/
|
*/
|
||||||
public function ask($question, $default = null)
|
public function ask($question, $default = null)
|
||||||
{
|
{
|
||||||
return $this->helperSet->get('dialog')->ask($this->output, $question, $default);
|
$output = $this->output;
|
||||||
|
|
||||||
|
if ($output instanceof ConsoleOutputInterface) {
|
||||||
|
$output = $output->getErrorOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var \Symfony\Component\Console\Helper\DialogHelper $dialog */
|
||||||
|
$dialog = $this->helperSet->get('dialog');
|
||||||
|
|
||||||
|
return $dialog->ask($output, $question, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -160,7 +218,16 @@ class ConsoleIO extends BaseIO
|
||||||
*/
|
*/
|
||||||
public function askConfirmation($question, $default = true)
|
public function askConfirmation($question, $default = true)
|
||||||
{
|
{
|
||||||
return $this->helperSet->get('dialog')->askConfirmation($this->output, $question, $default);
|
$output = $this->output;
|
||||||
|
|
||||||
|
if ($output instanceof ConsoleOutputInterface) {
|
||||||
|
$output = $output->getErrorOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var \Symfony\Component\Console\Helper\DialogHelper $dialog */
|
||||||
|
$dialog = $this->helperSet->get('dialog');
|
||||||
|
|
||||||
|
return $dialog->askConfirmation($output, $question, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -168,7 +235,16 @@ class ConsoleIO extends BaseIO
|
||||||
*/
|
*/
|
||||||
public function askAndValidate($question, $validator, $attempts = false, $default = null)
|
public function askAndValidate($question, $validator, $attempts = false, $default = null)
|
||||||
{
|
{
|
||||||
return $this->helperSet->get('dialog')->askAndValidate($this->output, $question, $validator, $attempts, $default);
|
$output = $this->output;
|
||||||
|
|
||||||
|
if ($output instanceof ConsoleOutputInterface) {
|
||||||
|
$output = $output->getErrorOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var \Symfony\Component\Console\Helper\DialogHelper $dialog */
|
||||||
|
$dialog = $this->helperSet->get('dialog');
|
||||||
|
|
||||||
|
return $dialog->askAndValidate($output, $question, $validator, $attempts, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -182,9 +258,9 @@ class ConsoleIO extends BaseIO
|
||||||
|
|
||||||
// use bash if it's present
|
// use bash if it's present
|
||||||
if ($finder->find('bash') && $finder->find('stty')) {
|
if ($finder->find('bash') && $finder->find('stty')) {
|
||||||
$this->write($question, false);
|
$this->writeError($question, false);
|
||||||
$value = rtrim(shell_exec('bash -c "stty -echo; read -n0 discard; read -r mypassword; stty echo; echo $mypassword"'));
|
$value = rtrim(shell_exec('bash -c "stty -echo; read -n0 discard; read -r mypassword; stty echo; echo $mypassword"'));
|
||||||
$this->write('');
|
$this->writeError('');
|
||||||
|
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
@ -208,9 +284,9 @@ class ConsoleIO extends BaseIO
|
||||||
$exe = $tmpExe;
|
$exe = $tmpExe;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->write($question, false);
|
$this->writeError($question, false);
|
||||||
$value = rtrim(shell_exec($exe));
|
$value = rtrim(shell_exec($exe));
|
||||||
$this->write('');
|
$this->writeError('');
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
if (isset($tmpExe)) {
|
if (isset($tmpExe)) {
|
||||||
|
@ -230,11 +306,11 @@ class ConsoleIO extends BaseIO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isset($shell)) {
|
if (isset($shell)) {
|
||||||
$this->write($question, false);
|
$this->writeError($question, false);
|
||||||
$readCmd = ($shell === 'csh') ? 'set mypassword = $<' : 'read -r mypassword';
|
$readCmd = ($shell === 'csh') ? 'set mypassword = $<' : 'read -r mypassword';
|
||||||
$command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd);
|
$command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd);
|
||||||
$value = rtrim(shell_exec($command));
|
$value = rtrim(shell_exec($command));
|
||||||
$this->write('');
|
$this->writeError('');
|
||||||
|
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,14 @@ interface IOInterface
|
||||||
*/
|
*/
|
||||||
public function write($messages, $newline = true);
|
public function write($messages, $newline = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a message to the error output.
|
||||||
|
*
|
||||||
|
* @param string|array $messages The message as an array of lines or a single string
|
||||||
|
* @param bool $newline Whether to add a newline or not
|
||||||
|
*/
|
||||||
|
public function writeError($messages, $newline = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overwrites a previous message to the output.
|
* Overwrites a previous message to the output.
|
||||||
*
|
*
|
||||||
|
@ -73,6 +81,15 @@ interface IOInterface
|
||||||
*/
|
*/
|
||||||
public function overwrite($messages, $newline = true, $size = null);
|
public function overwrite($messages, $newline = true, $size = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overwrites a previous message to the error output.
|
||||||
|
*
|
||||||
|
* @param string|array $messages The message as an array of lines or a single string
|
||||||
|
* @param bool $newline Whether to add a newline or not
|
||||||
|
* @param integer $size The size of line
|
||||||
|
*/
|
||||||
|
public function overwriteError($messages, $newline = true, $size = null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asks a question to the user.
|
* Asks a question to the user.
|
||||||
*
|
*
|
||||||
|
|
|
@ -66,6 +66,13 @@ class NullIO extends BaseIO
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function writeError($messages, $newline = true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -73,6 +80,13 @@ class NullIO extends BaseIO
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function overwriteError($messages, $newline = true, $size = 80)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -177,7 +177,7 @@ class Installer
|
||||||
// purge old require-dev packages to avoid conflicts with the new way of handling dev requirements
|
// purge old require-dev packages to avoid conflicts with the new way of handling dev requirements
|
||||||
$devRepo = new InstalledFilesystemRepository(new JsonFile($this->config->get('vendor-dir').'/composer/installed_dev.json'));
|
$devRepo = new InstalledFilesystemRepository(new JsonFile($this->config->get('vendor-dir').'/composer/installed_dev.json'));
|
||||||
if ($devRepo->getPackages()) {
|
if ($devRepo->getPackages()) {
|
||||||
$this->io->write('<warning>BC Notice: Removing old dev packages to migrate to the new require-dev handling.</warning>');
|
$this->io->writeError('<warning>BC Notice: Removing old dev packages to migrate to the new require-dev handling.</warning>');
|
||||||
foreach ($devRepo->getPackages() as $package) {
|
foreach ($devRepo->getPackages() as $package) {
|
||||||
if ($this->installationManager->isPackageInstalled($devRepo, $package)) {
|
if ($this->installationManager->isPackageInstalled($devRepo, $package)) {
|
||||||
$this->installationManager->uninstall($devRepo, new UninstallOperation($package));
|
$this->installationManager->uninstall($devRepo, new UninstallOperation($package));
|
||||||
|
@ -191,7 +191,7 @@ class Installer
|
||||||
if ($this->runScripts) {
|
if ($this->runScripts) {
|
||||||
// dispatch pre event
|
// dispatch pre event
|
||||||
$eventName = $this->update ? ScriptEvents::PRE_UPDATE_CMD : ScriptEvents::PRE_INSTALL_CMD;
|
$eventName = $this->update ? ScriptEvents::PRE_UPDATE_CMD : ScriptEvents::PRE_INSTALL_CMD;
|
||||||
$this->eventDispatcher->dispatchCommandEvent($eventName, $this->devMode);
|
$this->eventDispatcher->dispatchScript($eventName, $this->devMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->downloadManager->setPreferSource($this->preferSource);
|
$this->downloadManager->setPreferSource($this->preferSource);
|
||||||
|
@ -243,7 +243,7 @@ class Installer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->io->write($suggestion['source'].' suggests installing '.$suggestion['target'].' ('.$suggestion['reason'].')');
|
$this->io->writeError($suggestion['source'].' suggests installing '.$suggestion['target'].' ('.$suggestion['reason'].')');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,7 +257,7 @@ class Installer
|
||||||
? 'Use ' . $package->getReplacementPackage() . ' instead'
|
? 'Use ' . $package->getReplacementPackage() . ' instead'
|
||||||
: 'No replacement was suggested';
|
: 'No replacement was suggested';
|
||||||
|
|
||||||
$this->io->write(
|
$this->io->writeError(
|
||||||
sprintf(
|
sprintf(
|
||||||
"<error>Package %s is abandoned, you should avoid using it. %s.</error>",
|
"<error>Package %s is abandoned, you should avoid using it. %s.</error>",
|
||||||
$package->getPrettyName(),
|
$package->getPrettyName(),
|
||||||
|
@ -288,10 +288,10 @@ class Installer
|
||||||
$request->install($link->getTarget(), $link->getConstraint());
|
$request->install($link->getTarget(), $link->getConstraint());
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, $policy, $pool, $installedRepo, $request);
|
$this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, false, $policy, $pool, $installedRepo, $request);
|
||||||
$solver = new Solver($policy, $pool, $installedRepo);
|
$solver = new Solver($policy, $pool, $installedRepo);
|
||||||
$ops = $solver->solve($request, $this->ignorePlatformReqs);
|
$ops = $solver->solve($request, $this->ignorePlatformReqs);
|
||||||
$this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::POST_DEPENDENCIES_SOLVING, $policy, $pool, $installedRepo, $request, $ops);
|
$this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::POST_DEPENDENCIES_SOLVING, false, $policy, $pool, $installedRepo, $request, $ops);
|
||||||
foreach ($ops as $op) {
|
foreach ($ops as $op) {
|
||||||
if ($op->getJobType() === 'uninstall') {
|
if ($op->getJobType() === 'uninstall') {
|
||||||
$devPackages[] = $op->getPackage();
|
$devPackages[] = $op->getPackage();
|
||||||
|
@ -314,16 +314,16 @@ class Installer
|
||||||
$this->preferLowest
|
$this->preferLowest
|
||||||
);
|
);
|
||||||
if ($updatedLock) {
|
if ($updatedLock) {
|
||||||
$this->io->write('<info>Writing lock file</info>');
|
$this->io->writeError('<info>Writing lock file</info>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->dumpAutoloader) {
|
if ($this->dumpAutoloader) {
|
||||||
// write autoloader
|
// write autoloader
|
||||||
if ($this->optimizeAutoloader) {
|
if ($this->optimizeAutoloader) {
|
||||||
$this->io->write('<info>Generating optimized autoload files</info>');
|
$this->io->writeError('<info>Generating optimized autoload files</info>');
|
||||||
} else {
|
} else {
|
||||||
$this->io->write('<info>Generating autoload files</info>');
|
$this->io->writeError('<info>Generating autoload files</info>');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->autoloadGenerator->setDevMode($this->devMode);
|
$this->autoloadGenerator->setDevMode($this->devMode);
|
||||||
|
@ -333,7 +333,7 @@ class Installer
|
||||||
if ($this->runScripts) {
|
if ($this->runScripts) {
|
||||||
// dispatch post event
|
// dispatch post event
|
||||||
$eventName = $this->update ? ScriptEvents::POST_UPDATE_CMD : ScriptEvents::POST_INSTALL_CMD;
|
$eventName = $this->update ? ScriptEvents::POST_UPDATE_CMD : ScriptEvents::POST_INSTALL_CMD;
|
||||||
$this->eventDispatcher->dispatchCommandEvent($eventName, $this->devMode);
|
$this->eventDispatcher->dispatchScript($eventName, $this->devMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
$vendorDir = $this->config->get('vendor-dir');
|
$vendorDir = $this->config->get('vendor-dir');
|
||||||
|
@ -374,11 +374,11 @@ class Installer
|
||||||
$this->package->getDevRequires()
|
$this->package->getDevRequires()
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->io->write('<info>Loading composer repositories with package information</info>');
|
$this->io->writeError('<info>Loading composer repositories with package information</info>');
|
||||||
|
|
||||||
// creating repository pool
|
// creating repository pool
|
||||||
$policy = $this->createPolicy();
|
$policy = $this->createPolicy();
|
||||||
$pool = $this->createPool($withDevReqs);
|
$pool = $this->createPool($withDevReqs, $lockedRepository);
|
||||||
$pool->addRepository($installedRepo, $aliases);
|
$pool->addRepository($installedRepo, $aliases);
|
||||||
if ($installFromLock) {
|
if ($installFromLock) {
|
||||||
$pool->addRepository($lockedRepository, $aliases);
|
$pool->addRepository($lockedRepository, $aliases);
|
||||||
|
@ -409,7 +409,7 @@ class Installer
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->update) {
|
if ($this->update) {
|
||||||
$this->io->write('<info>Updating dependencies'.($withDevReqs ? ' (including require-dev)' : '').'</info>');
|
$this->io->writeError('<info>Updating dependencies'.($withDevReqs ? ' (including require-dev)' : '').'</info>');
|
||||||
|
|
||||||
$request->updateAll();
|
$request->updateAll();
|
||||||
|
|
||||||
|
@ -460,10 +460,10 @@ class Installer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} elseif ($installFromLock) {
|
} elseif ($installFromLock) {
|
||||||
$this->io->write('<info>Installing dependencies'.($withDevReqs ? ' (including require-dev)' : '').' from lock file</info>');
|
$this->io->writeError('<info>Installing dependencies'.($withDevReqs ? ' (including require-dev)' : '').' from lock file</info>');
|
||||||
|
|
||||||
if (!$this->locker->isFresh()) {
|
if (!$this->locker->isFresh()) {
|
||||||
$this->io->write('<warning>Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. Run update to update them.</warning>');
|
$this->io->writeError('<warning>Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. Run update to update them.</warning>');
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($lockedRepository->getPackages() as $package) {
|
foreach ($lockedRepository->getPackages() as $package) {
|
||||||
|
@ -480,7 +480,7 @@ class Installer
|
||||||
$request->install($link->getTarget(), $link->getConstraint());
|
$request->install($link->getTarget(), $link->getConstraint());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$this->io->write('<info>Installing dependencies'.($withDevReqs ? ' (including require-dev)' : '').'</info>');
|
$this->io->writeError('<info>Installing dependencies'.($withDevReqs ? ' (including require-dev)' : '').'</info>');
|
||||||
|
|
||||||
if ($withDevReqs) {
|
if ($withDevReqs) {
|
||||||
$links = array_merge($this->package->getRequires(), $this->package->getDevRequires());
|
$links = array_merge($this->package->getRequires(), $this->package->getDevRequires());
|
||||||
|
@ -497,14 +497,14 @@ class Installer
|
||||||
$this->processDevPackages($localRepo, $pool, $policy, $repositories, $lockedRepository, $installFromLock, 'force-links');
|
$this->processDevPackages($localRepo, $pool, $policy, $repositories, $lockedRepository, $installFromLock, 'force-links');
|
||||||
|
|
||||||
// solve dependencies
|
// solve dependencies
|
||||||
$this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, $policy, $pool, $installedRepo, $request);
|
$this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, $this->devMode, $policy, $pool, $installedRepo, $request);
|
||||||
$solver = new Solver($policy, $pool, $installedRepo);
|
$solver = new Solver($policy, $pool, $installedRepo);
|
||||||
try {
|
try {
|
||||||
$operations = $solver->solve($request, $this->ignorePlatformReqs);
|
$operations = $solver->solve($request, $this->ignorePlatformReqs);
|
||||||
$this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::POST_DEPENDENCIES_SOLVING, $policy, $pool, $installedRepo, $request, $operations);
|
$this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::POST_DEPENDENCIES_SOLVING, $this->devMode, $policy, $pool, $installedRepo, $request, $operations);
|
||||||
} catch (SolverProblemsException $e) {
|
} catch (SolverProblemsException $e) {
|
||||||
$this->io->write('<error>Your requirements could not be resolved to an installable set of packages.</error>');
|
$this->io->writeError('<error>Your requirements could not be resolved to an installable set of packages.</error>');
|
||||||
$this->io->write($e->getMessage());
|
$this->io->writeError($e->getMessage());
|
||||||
|
|
||||||
return max(1, $e->getCode());
|
return max(1, $e->getCode());
|
||||||
}
|
}
|
||||||
|
@ -514,7 +514,7 @@ class Installer
|
||||||
|
|
||||||
// execute operations
|
// execute operations
|
||||||
if (!$operations) {
|
if (!$operations) {
|
||||||
$this->io->write('Nothing to install or update');
|
$this->io->writeError('Nothing to install or update');
|
||||||
}
|
}
|
||||||
|
|
||||||
$operations = $this->movePluginsToFront($operations);
|
$operations = $this->movePluginsToFront($operations);
|
||||||
|
@ -553,26 +553,26 @@ class Installer
|
||||||
&& $operation->getTargetPackage()->getSourceReference() === $operation->getInitialPackage()->getSourceReference()
|
&& $operation->getTargetPackage()->getSourceReference() === $operation->getInitialPackage()->getSourceReference()
|
||||||
) {
|
) {
|
||||||
if ($this->io->isDebug()) {
|
if ($this->io->isDebug()) {
|
||||||
$this->io->write(' - Skipping update of '. $operation->getTargetPackage()->getPrettyName().' to the same reference-locked version');
|
$this->io->writeError(' - Skipping update of '. $operation->getTargetPackage()->getPrettyName().' to the same reference-locked version');
|
||||||
$this->io->write('');
|
$this->io->writeError('');
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$event = 'Composer\Script\ScriptEvents::PRE_PACKAGE_'.strtoupper($operation->getJobType());
|
$event = 'Composer\Installer\PackageEvents::PRE_PACKAGE_'.strtoupper($operation->getJobType());
|
||||||
if (defined($event) && $this->runScripts) {
|
if (defined($event) && $this->runScripts) {
|
||||||
$this->eventDispatcher->dispatchPackageEvent(constant($event), $this->devMode, $operation);
|
$this->eventDispatcher->dispatchPackageEvent(constant($event), $this->devMode, $policy, $pool, $installedRepo, $request, $operations, $operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
// output non-alias ops in dry run, output alias ops in debug verbosity
|
// output non-alias ops in dry run, output alias ops in debug verbosity
|
||||||
if ($this->dryRun && false === strpos($operation->getJobType(), 'Alias')) {
|
if ($this->dryRun && false === strpos($operation->getJobType(), 'Alias')) {
|
||||||
$this->io->write(' - ' . $operation);
|
$this->io->writeError(' - ' . $operation);
|
||||||
$this->io->write('');
|
$this->io->writeError('');
|
||||||
} elseif ($this->io->isDebug() && false !== strpos($operation->getJobType(), 'Alias')) {
|
} elseif ($this->io->isDebug() && false !== strpos($operation->getJobType(), 'Alias')) {
|
||||||
$this->io->write(' - ' . $operation);
|
$this->io->writeError(' - ' . $operation);
|
||||||
$this->io->write('');
|
$this->io->writeError('');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->installationManager->execute($localRepo, $operation);
|
$this->installationManager->execute($localRepo, $operation);
|
||||||
|
@ -583,20 +583,20 @@ class Installer
|
||||||
if ($reason instanceof Rule) {
|
if ($reason instanceof Rule) {
|
||||||
switch ($reason->getReason()) {
|
switch ($reason->getReason()) {
|
||||||
case Rule::RULE_JOB_INSTALL:
|
case Rule::RULE_JOB_INSTALL:
|
||||||
$this->io->write(' REASON: Required by root: '.$reason->getPrettyString($pool));
|
$this->io->writeError(' REASON: Required by root: '.$reason->getPrettyString($pool));
|
||||||
$this->io->write('');
|
$this->io->writeError('');
|
||||||
break;
|
break;
|
||||||
case Rule::RULE_PACKAGE_REQUIRES:
|
case Rule::RULE_PACKAGE_REQUIRES:
|
||||||
$this->io->write(' REASON: '.$reason->getPrettyString($pool));
|
$this->io->writeError(' REASON: '.$reason->getPrettyString($pool));
|
||||||
$this->io->write('');
|
$this->io->writeError('');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$event = 'Composer\Script\ScriptEvents::POST_PACKAGE_'.strtoupper($operation->getJobType());
|
$event = 'Composer\Installer\PackageEvents::POST_PACKAGE_'.strtoupper($operation->getJobType());
|
||||||
if (defined($event) && $this->runScripts) {
|
if (defined($event) && $this->runScripts) {
|
||||||
$this->eventDispatcher->dispatchPackageEvent(constant($event), $this->devMode, $operation);
|
$this->eventDispatcher->dispatchPackageEvent(constant($event), $this->devMode, $policy, $pool, $installedRepo, $request, $operations, $operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->dryRun) {
|
if (!$this->dryRun) {
|
||||||
|
@ -671,27 +671,39 @@ class Installer
|
||||||
return array_merge($uninstOps, $operations);
|
return array_merge($uninstOps, $operations);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createPool($withDevReqs)
|
private function createPool($withDevReqs, RepositoryInterface $lockedRepository = null)
|
||||||
{
|
{
|
||||||
$minimumStability = $this->package->getMinimumStability();
|
if (!$this->update && $this->locker->isLocked()) { // install from lock
|
||||||
$stabilityFlags = $this->package->getStabilityFlags();
|
|
||||||
|
|
||||||
if (!$this->update && $this->locker->isLocked()) {
|
|
||||||
$minimumStability = $this->locker->getMinimumStability();
|
$minimumStability = $this->locker->getMinimumStability();
|
||||||
$stabilityFlags = $this->locker->getStabilityFlags();
|
$stabilityFlags = $this->locker->getStabilityFlags();
|
||||||
|
|
||||||
|
$requires = array();
|
||||||
|
foreach ($lockedRepository->getPackages() as $package) {
|
||||||
|
$constraint = new VersionConstraint('=', $package->getVersion());
|
||||||
|
$constraint->setPrettyString($package->getPrettyVersion());
|
||||||
|
$requires[$package->getName()] = $constraint;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$minimumStability = $this->package->getMinimumStability();
|
||||||
|
$stabilityFlags = $this->package->getStabilityFlags();
|
||||||
|
|
||||||
|
$requires = $this->package->getRequires();
|
||||||
|
if ($withDevReqs) {
|
||||||
|
$requires = array_merge($requires, $this->package->getDevRequires());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$requires = $this->package->getRequires();
|
|
||||||
if ($withDevReqs) {
|
|
||||||
$requires = array_merge($requires, $this->package->getDevRequires());
|
|
||||||
}
|
|
||||||
$rootConstraints = array();
|
$rootConstraints = array();
|
||||||
foreach ($requires as $req => $constraint) {
|
foreach ($requires as $req => $constraint) {
|
||||||
// skip platform requirements from the root package to avoid filtering out existing platform packages
|
// skip platform requirements from the root package to avoid filtering out existing platform packages
|
||||||
if ($this->ignorePlatformReqs && preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $req)) {
|
if ($this->ignorePlatformReqs && preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $req)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$rootConstraints[$req] = $constraint->getConstraint();
|
if ($constraint instanceof Link) {
|
||||||
|
$rootConstraints[$req] = $constraint->getConstraint();
|
||||||
|
} else {
|
||||||
|
$rootConstraints[$req] = $constraint;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Pool($minimumStability, $stabilityFlags, $rootConstraints);
|
return new Pool($minimumStability, $stabilityFlags, $rootConstraints);
|
||||||
|
@ -989,7 +1001,7 @@ class Installer
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($depPackages) == 0 && !$nameMatchesRequiredPackage && !in_array($packageName, array('nothing', 'lock'))) {
|
if (count($depPackages) == 0 && !$nameMatchesRequiredPackage && !in_array($packageName, array('nothing', 'lock'))) {
|
||||||
$this->io->write('<warning>Package "' . $packageName . '" listed for update is not installed. Ignoring.</warning>');
|
$this->io->writeError('<warning>Package "' . $packageName . '" listed for update is not installed. Ignoring.</warning>');
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($depPackages as $depPackage) {
|
foreach ($depPackages as $depPackage) {
|
||||||
|
@ -1166,7 +1178,6 @@ class Installer
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set whether to run autoloader or not
|
* set whether to run autoloader or not
|
||||||
*
|
*
|
||||||
|
@ -1180,7 +1191,6 @@ class Installer
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set whether to run scripts or not
|
* set whether to run scripts or not
|
||||||
*
|
*
|
||||||
|
|
|
@ -38,6 +38,11 @@ class InstallerEvent extends Event
|
||||||
*/
|
*/
|
||||||
private $io;
|
private $io;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $devMode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var PolicyInterface
|
* @var PolicyInterface
|
||||||
*/
|
*/
|
||||||
|
@ -69,18 +74,20 @@ class InstallerEvent extends Event
|
||||||
* @param string $eventName
|
* @param string $eventName
|
||||||
* @param Composer $composer
|
* @param Composer $composer
|
||||||
* @param IOInterface $io
|
* @param IOInterface $io
|
||||||
|
* @param bool $devMode
|
||||||
* @param PolicyInterface $policy
|
* @param PolicyInterface $policy
|
||||||
* @param Pool $pool
|
* @param Pool $pool
|
||||||
* @param CompositeRepository $installedRepo
|
* @param CompositeRepository $installedRepo
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @param OperationInterface[] $operations
|
* @param OperationInterface[] $operations
|
||||||
*/
|
*/
|
||||||
public function __construct($eventName, Composer $composer, IOInterface $io, PolicyInterface $policy, Pool $pool, CompositeRepository $installedRepo, Request $request, array $operations = array())
|
public function __construct($eventName, Composer $composer, IOInterface $io, $devMode, PolicyInterface $policy, Pool $pool, CompositeRepository $installedRepo, Request $request, array $operations = array())
|
||||||
{
|
{
|
||||||
parent::__construct($eventName);
|
parent::__construct($eventName);
|
||||||
|
|
||||||
$this->composer = $composer;
|
$this->composer = $composer;
|
||||||
$this->io = $io;
|
$this->io = $io;
|
||||||
|
$this->devMode = $devMode;
|
||||||
$this->policy = $policy;
|
$this->policy = $policy;
|
||||||
$this->pool = $pool;
|
$this->pool = $pool;
|
||||||
$this->installedRepo = $installedRepo;
|
$this->installedRepo = $installedRepo;
|
||||||
|
@ -104,6 +111,14 @@ class InstallerEvent extends Event
|
||||||
return $this->io;
|
return $this->io;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isDevMode()
|
||||||
|
{
|
||||||
|
return $this->devMode;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return PolicyInterface
|
* @return PolicyInterface
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -197,7 +197,7 @@ class LibraryInstaller implements InstallerInterface
|
||||||
foreach ($binaries as $bin) {
|
foreach ($binaries as $bin) {
|
||||||
$binPath = $this->getInstallPath($package).'/'.$bin;
|
$binPath = $this->getInstallPath($package).'/'.$bin;
|
||||||
if (!file_exists($binPath)) {
|
if (!file_exists($binPath)) {
|
||||||
$this->io->write(' <warning>Skipped installation of bin '.$bin.' for package '.$package->getName().': file not found in package</warning>');
|
$this->io->writeError(' <warning>Skipped installation of bin '.$bin.' for package '.$package->getName().': file not found in package</warning>');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ class LibraryInstaller implements InstallerInterface
|
||||||
// is a fresh install of the vendor.
|
// is a fresh install of the vendor.
|
||||||
@chmod($link, 0777 & ~umask());
|
@chmod($link, 0777 & ~umask());
|
||||||
}
|
}
|
||||||
$this->io->write(' Skipped installation of bin '.$bin.' for package '.$package->getName().': name conflicts with an existing file');
|
$this->io->writeError(' Skipped installation of bin '.$bin.' for package '.$package->getName().': name conflicts with an existing file');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
|
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
|
||||||
|
@ -226,7 +226,7 @@ class LibraryInstaller implements InstallerInterface
|
||||||
@chmod($link, 0777 & ~umask());
|
@chmod($link, 0777 & ~umask());
|
||||||
$link .= '.bat';
|
$link .= '.bat';
|
||||||
if (file_exists($link)) {
|
if (file_exists($link)) {
|
||||||
$this->io->write(' Skipped installation of bin '.$bin.'.bat proxy for package '.$package->getName().': a .bat proxy was already installed');
|
$this->io->writeError(' Skipped installation of bin '.$bin.'.bat proxy for package '.$package->getName().': a .bat proxy was already installed');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!file_exists($link)) {
|
if (!file_exists($link)) {
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Installer;
|
||||||
|
|
||||||
|
use Composer\Composer;
|
||||||
|
use Composer\IO\IOInterface;
|
||||||
|
use Composer\DependencyResolver\Operation\OperationInterface;
|
||||||
|
use Composer\DependencyResolver\PolicyInterface;
|
||||||
|
use Composer\DependencyResolver\Pool;
|
||||||
|
use Composer\DependencyResolver\Request;
|
||||||
|
use Composer\EventDispatcher\Event;
|
||||||
|
use Composer\Repository\CompositeRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Package Event.
|
||||||
|
*
|
||||||
|
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*/
|
||||||
|
class PackageEvent extends InstallerEvent
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var OperationInterface The package instance
|
||||||
|
*/
|
||||||
|
private $operation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param string $eventName
|
||||||
|
* @param Composer $composer
|
||||||
|
* @param IOInterface $io
|
||||||
|
* @param bool $devMode
|
||||||
|
* @param PolicyInterface $policy
|
||||||
|
* @param Pool $pool
|
||||||
|
* @param CompositeRepository $installedRepo
|
||||||
|
* @param Request $request
|
||||||
|
* @param OperationInterface[] $operations
|
||||||
|
* @param OperationInterface $operation
|
||||||
|
*/
|
||||||
|
public function __construct($eventName, Composer $composer, IOInterface $io, $devMode, PolicyInterface $policy, Pool $pool, CompositeRepository $installedRepo, Request $request, array $operations, OperationInterface $operation)
|
||||||
|
{
|
||||||
|
parent::__construct($eventName, $composer, $io, $devMode, $policy, $pool, $installedRepo, $request, $operations);
|
||||||
|
|
||||||
|
$this->operation = $operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the package instance.
|
||||||
|
*
|
||||||
|
* @return OperationInterface
|
||||||
|
*/
|
||||||
|
public function getOperation()
|
||||||
|
{
|
||||||
|
return $this->operation;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Installer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Package Events.
|
||||||
|
*
|
||||||
|
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*/
|
||||||
|
class PackageEvents
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The PRE_PACKAGE_INSTALL event occurs before a package is installed.
|
||||||
|
*
|
||||||
|
* The event listener method receives a Composer\Script\PackageEvent instance.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const PRE_PACKAGE_INSTALL = 'pre-package-install';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The POST_PACKAGE_INSTALL event occurs after a package is installed.
|
||||||
|
*
|
||||||
|
* The event listener method receives a Composer\Script\PackageEvent instance.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const POST_PACKAGE_INSTALL = 'post-package-install';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The PRE_PACKAGE_UPDATE event occurs before a package is updated.
|
||||||
|
*
|
||||||
|
* The event listener method receives a Composer\Script\PackageEvent instance.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const PRE_PACKAGE_UPDATE = 'pre-package-update';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The POST_PACKAGE_UPDATE event occurs after a package is updated.
|
||||||
|
*
|
||||||
|
* The event listener method receives a Composer\Script\PackageEvent instance.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const POST_PACKAGE_UPDATE = 'post-package-update';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The PRE_PACKAGE_UNINSTALL event occurs before a package has been uninstalled.
|
||||||
|
*
|
||||||
|
* The event listener method receives a Composer\Script\PackageEvent instance.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const PRE_PACKAGE_UNINSTALL = 'pre-package-uninstall';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The POST_PACKAGE_UNINSTALL event occurs after a package has been uninstalled.
|
||||||
|
*
|
||||||
|
* The event listener method receives a Composer\Script\PackageEvent instance.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const POST_PACKAGE_UNINSTALL = 'post-package-uninstall';
|
||||||
|
}
|
|
@ -76,7 +76,7 @@ class PearInstaller extends LibraryInstaller
|
||||||
$pearExtractor->extractTo($this->getInstallPath($package), array('php' => '/', 'script' => '/bin', 'data' => '/data'), $vars);
|
$pearExtractor->extractTo($this->getInstallPath($package), array('php' => '/', 'script' => '/bin', 'data' => '/data'), $vars);
|
||||||
|
|
||||||
if ($this->io->isVerbose()) {
|
if ($this->io->isVerbose()) {
|
||||||
$this->io->write(' Cleaning up');
|
$this->io->writeError(' Cleaning up');
|
||||||
}
|
}
|
||||||
$this->filesystem->unlink($packageArchive);
|
$this->filesystem->unlink($packageArchive);
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,6 +184,9 @@ class JsonFile
|
||||||
{
|
{
|
||||||
if (version_compare(PHP_VERSION, '5.4', '>=')) {
|
if (version_compare(PHP_VERSION, '5.4', '>=')) {
|
||||||
$json = json_encode($data, $options);
|
$json = json_encode($data, $options);
|
||||||
|
if (false === $json) {
|
||||||
|
self::throwEncodeError(json_last_error());
|
||||||
|
}
|
||||||
|
|
||||||
// compact brackets to follow recent php versions
|
// compact brackets to follow recent php versions
|
||||||
if (PHP_VERSION_ID < 50428 || (PHP_VERSION_ID >= 50500 && PHP_VERSION_ID < 50512) || (defined('JSON_C_VERSION') && version_compare(phpversion('json'), '1.3.6', '<'))) {
|
if (PHP_VERSION_ID < 50428 || (PHP_VERSION_ID >= 50500 && PHP_VERSION_ID < 50512) || (defined('JSON_C_VERSION') && version_compare(phpversion('json'), '1.3.6', '<'))) {
|
||||||
|
@ -195,6 +198,9 @@ class JsonFile
|
||||||
}
|
}
|
||||||
|
|
||||||
$json = json_encode($data);
|
$json = json_encode($data);
|
||||||
|
if (false === $json) {
|
||||||
|
self::throwEncodeError(json_last_error());
|
||||||
|
}
|
||||||
|
|
||||||
$prettyPrint = (bool) ($options & self::JSON_PRETTY_PRINT);
|
$prettyPrint = (bool) ($options & self::JSON_PRETTY_PRINT);
|
||||||
$unescapeUnicode = (bool) ($options & self::JSON_UNESCAPED_UNICODE);
|
$unescapeUnicode = (bool) ($options & self::JSON_UNESCAPED_UNICODE);
|
||||||
|
@ -209,6 +215,34 @@ class JsonFile
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an exception according to a given code with a customized message
|
||||||
|
*
|
||||||
|
* @param int $code return code of json_last_error function
|
||||||
|
* @throws \RuntimeException
|
||||||
|
*/
|
||||||
|
private static function throwEncodeError($code)
|
||||||
|
{
|
||||||
|
switch ($code) {
|
||||||
|
case JSON_ERROR_DEPTH:
|
||||||
|
$msg = 'Maximum stack depth exceeded';
|
||||||
|
break;
|
||||||
|
case JSON_ERROR_STATE_MISMATCH:
|
||||||
|
$msg = 'Underflow or the modes mismatch';
|
||||||
|
break;
|
||||||
|
case JSON_ERROR_CTRL_CHAR:
|
||||||
|
$msg = 'Unexpected control character found';
|
||||||
|
break;
|
||||||
|
case JSON_ERROR_UTF8:
|
||||||
|
$msg = 'Malformed UTF-8 characters, possibly incorrectly encoded';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$msg = 'Unknown error';
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \RuntimeException('JSON encoding failed: '.$msg);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses json string and returns hash.
|
* Parses json string and returns hash.
|
||||||
*
|
*
|
||||||
|
@ -219,6 +253,9 @@ class JsonFile
|
||||||
*/
|
*/
|
||||||
public static function parseJson($json, $file = null)
|
public static function parseJson($json, $file = null)
|
||||||
{
|
{
|
||||||
|
if (null === $json) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
$data = json_decode($json, true);
|
$data = json_decode($json, true);
|
||||||
if (null === $data && JSON_ERROR_NONE !== json_last_error()) {
|
if (null === $data && JSON_ERROR_NONE !== json_last_error()) {
|
||||||
self::validateSyntax($json, $file);
|
self::validateSyntax($json, $file);
|
||||||
|
|
|
@ -249,7 +249,7 @@ class ArrayLoader implements LoaderInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
// If using numeric aliases ensure the alias is a valid subversion
|
// If using numeric aliases ensure the alias is a valid subversion
|
||||||
if(($sourcePrefix = $this->versionParser->parseNumericAliasPrefix($sourceBranch))
|
if (($sourcePrefix = $this->versionParser->parseNumericAliasPrefix($sourceBranch))
|
||||||
&& ($targetPrefix = $this->versionParser->parseNumericAliasPrefix($targetBranch))
|
&& ($targetPrefix = $this->versionParser->parseNumericAliasPrefix($targetBranch))
|
||||||
&& (stripos($targetPrefix, $sourcePrefix) !== 0)
|
&& (stripos($targetPrefix, $sourcePrefix) !== 0)
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -277,7 +277,18 @@ class RootPackageLoader extends ArrayLoader
|
||||||
) {
|
) {
|
||||||
$branch = preg_replace('{^dev-}', '', $version);
|
$branch = preg_replace('{^dev-}', '', $version);
|
||||||
$length = PHP_INT_MAX;
|
$length = PHP_INT_MAX;
|
||||||
|
|
||||||
|
$nonFeatureBranches = '';
|
||||||
|
if (!empty($config['non-feature-branches'])) {
|
||||||
|
$nonFeatureBranches = implode('|', $config['non-feature-branches']);
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($branches as $candidate) {
|
foreach ($branches as $candidate) {
|
||||||
|
// return directly, if branch is configured to be non-feature branch
|
||||||
|
if ($candidate === $branch && preg_match('{^(' . $nonFeatureBranches . ')$}', $candidate)) {
|
||||||
|
return $version;
|
||||||
|
}
|
||||||
|
|
||||||
// do not compare against other feature branches
|
// do not compare against other feature branches
|
||||||
if ($candidate === $branch || !preg_match('{^(master|trunk|default|develop|\d+\..+)$}', $candidate, $match)) {
|
if ($candidate === $branch || !preg_match('{^(master|trunk|default|develop|\d+\..+)$}', $candidate, $match)) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -256,7 +256,7 @@ class ValidatingArrayLoader implements LoaderInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
// If using numeric aliases ensure the alias is a valid subversion
|
// If using numeric aliases ensure the alias is a valid subversion
|
||||||
if(($sourcePrefix = $this->versionParser->parseNumericAliasPrefix($sourceBranch))
|
if (($sourcePrefix = $this->versionParser->parseNumericAliasPrefix($sourceBranch))
|
||||||
&& ($targetPrefix = $this->versionParser->parseNumericAliasPrefix($targetBranch))
|
&& ($targetPrefix = $this->versionParser->parseNumericAliasPrefix($targetBranch))
|
||||||
&& (stripos($targetPrefix, $sourcePrefix) !== 0)
|
&& (stripos($targetPrefix, $sourcePrefix) !== 0)
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -258,7 +258,10 @@ class Locker
|
||||||
$lock['packages-dev'] = $this->lockPackages($devPackages);
|
$lock['packages-dev'] = $this->lockPackages($devPackages);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($lock['packages']) && empty($lock['packages-dev'])) {
|
$lock['platform'] = $platformReqs;
|
||||||
|
$lock['platform-dev'] = $platformDevReqs;
|
||||||
|
|
||||||
|
if (empty($lock['packages']) && empty($lock['packages-dev']) && empty($lock['platform']) && empty($lock['platform-dev'])) {
|
||||||
if ($this->lockFile->exists()) {
|
if ($this->lockFile->exists()) {
|
||||||
unlink($this->lockFile->getPath());
|
unlink($this->lockFile->getPath());
|
||||||
}
|
}
|
||||||
|
@ -266,9 +269,6 @@ class Locker
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$lock['platform'] = $platformReqs;
|
|
||||||
$lock['platform-dev'] = $platformDevReqs;
|
|
||||||
|
|
||||||
if (!$this->isLocked() || $lock !== $this->getLockData()) {
|
if (!$this->isLocked() || $lock !== $this->getLockData()) {
|
||||||
$this->lockFile->write($lock);
|
$this->lockFile->write($lock);
|
||||||
$this->lockDataCache = null;
|
$this->lockDataCache = null;
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace Composer\Package;
|
||||||
interface RootPackageInterface extends CompletePackageInterface
|
interface RootPackageInterface extends CompletePackageInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Returns a set of package names and theirs aliases
|
* Returns a set of package names and their aliases
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -79,6 +79,9 @@ class PluginManager
|
||||||
*/
|
*/
|
||||||
public function addPlugin(PluginInterface $plugin)
|
public function addPlugin(PluginInterface $plugin)
|
||||||
{
|
{
|
||||||
|
if ($this->io->isDebug()) {
|
||||||
|
$this->io->writeError('Loading plugin '.get_class($plugin));
|
||||||
|
}
|
||||||
$this->plugins[] = $plugin;
|
$this->plugins[] = $plugin;
|
||||||
$plugin->activate($this->composer, $this->io);
|
$plugin->activate($this->composer, $this->io);
|
||||||
|
|
||||||
|
@ -127,7 +130,7 @@ class PluginManager
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$requiresComposer->matches(new VersionConstraint('==', $this->versionParser->normalize(PluginInterface::PLUGIN_API_VERSION)))) {
|
if (!$requiresComposer->matches(new VersionConstraint('==', $this->versionParser->normalize(PluginInterface::PLUGIN_API_VERSION)))) {
|
||||||
$this->io->write("<warning>The plugin ".$package->getName()." requires a version of composer-plugin-api that does not match your composer installation. You may need to run composer update with the '--no-plugins' option.</warning>");
|
$this->io->writeError("<warning>The plugin ".$package->getName()." requires a version of composer-plugin-api that does not match your composer installation. You may need to run composer update with the '--no-plugins' option.</warning>");
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->registerPackage($package);
|
$this->registerPackage($package);
|
||||||
|
|
|
@ -60,14 +60,14 @@ class ArtifactRepository extends ArrayRepository
|
||||||
$package = $this->getComposerInformation($file);
|
$package = $this->getComposerInformation($file);
|
||||||
if (!$package) {
|
if (!$package) {
|
||||||
if ($io->isVerbose()) {
|
if ($io->isVerbose()) {
|
||||||
$io->write("File <comment>{$file->getBasename()}</comment> doesn't seem to hold a package");
|
$io->writeError("File <comment>{$file->getBasename()}</comment> doesn't seem to hold a package");
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($io->isVerbose()) {
|
if ($io->isVerbose()) {
|
||||||
$template = 'Found package <info>%s</info> (<comment>%s</comment>) in file <info>%s</info>';
|
$template = 'Found package <info>%s</info> (<comment>%s</comment>) in file <info>%s</info>';
|
||||||
$io->write(sprintf($template, $package->getName(), $package->getPrettyVersion(), $file->getBasename()));
|
$io->writeError(sprintf($template, $package->getName(), $package->getPrettyVersion(), $file->getBasename()));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addPackage($package);
|
$this->addPackage($package);
|
||||||
|
|
|
@ -434,7 +434,7 @@ class ComposerRepository extends ArrayRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($data['warning'])) {
|
if (!empty($data['warning'])) {
|
||||||
$this->io->write('<warning>Warning from '.$this->url.': '.$data['warning'].'</warning>');
|
$this->io->writeError('<warning>Warning from '.$this->url.': '.$data['warning'].'</warning>');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($data['providers-lazy-url'])) {
|
if (!empty($data['providers-lazy-url'])) {
|
||||||
|
@ -613,8 +613,8 @@ class ComposerRepository extends ArrayRepository
|
||||||
|
|
||||||
if ($cacheKey && ($contents = $this->cache->read($cacheKey))) {
|
if ($cacheKey && ($contents = $this->cache->read($cacheKey))) {
|
||||||
if (!$this->degradedMode) {
|
if (!$this->degradedMode) {
|
||||||
$this->io->write('<warning>'.$e->getMessage().'</warning>');
|
$this->io->writeError('<warning>'.$e->getMessage().'</warning>');
|
||||||
$this->io->write('<warning>'.$this->url.' could not be fully loaded, package information was loaded from the local cache and may be out of date</warning>');
|
$this->io->writeError('<warning>'.$this->url.' could not be fully loaded, package information was loaded from the local cache and may be out of date</warning>');
|
||||||
}
|
}
|
||||||
$this->degradedMode = true;
|
$this->degradedMode = true;
|
||||||
$data = JsonFile::parseJson($contents, $this->cache->getRoot().$cacheKey);
|
$data = JsonFile::parseJson($contents, $this->cache->getRoot().$cacheKey);
|
||||||
|
|
|
@ -66,13 +66,13 @@ class PearRepository extends ArrayRepository
|
||||||
{
|
{
|
||||||
parent::initialize();
|
parent::initialize();
|
||||||
|
|
||||||
$this->io->write('Initializing PEAR repository '.$this->url);
|
$this->io->writeError('Initializing PEAR repository '.$this->url);
|
||||||
|
|
||||||
$reader = new ChannelReader($this->rfs);
|
$reader = new ChannelReader($this->rfs);
|
||||||
try {
|
try {
|
||||||
$channelInfo = $reader->read($this->url);
|
$channelInfo = $reader->read($this->url);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->io->write('<warning>PEAR repository from '.$this->url.' could not be loaded. '.$e->getMessage().'</warning>');
|
$this->io->writeError('<warning>PEAR repository from '.$this->url.' could not be loaded. '.$e->getMessage().'</warning>');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ class PearRepository extends ArrayRepository
|
||||||
$normalizedVersion = $versionParser->normalize($version);
|
$normalizedVersion = $versionParser->normalize($version);
|
||||||
} catch (\UnexpectedValueException $e) {
|
} catch (\UnexpectedValueException $e) {
|
||||||
if ($this->io->isVerbose()) {
|
if ($this->io->isVerbose()) {
|
||||||
$this->io->write('Could not load '.$packageDefinition->getPackageName().' '.$version.': '.$e->getMessage());
|
$this->io->writeError('Could not load '.$packageDefinition->getPackageName().' '.$version.': '.$e->getMessage());
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,7 +149,7 @@ class GitBitbucketDriver extends VcsDriver implements VcsDriverInterface
|
||||||
|
|
||||||
if (!extension_loaded('openssl')) {
|
if (!extension_loaded('openssl')) {
|
||||||
if ($io->isVerbose()) {
|
if ($io->isVerbose()) {
|
||||||
$io->write('Skipping Bitbucket git driver for '.$url.' because the OpenSSL PHP extension is missing.');
|
$io->writeError('Skipping Bitbucket git driver for '.$url.' because the OpenSSL PHP extension is missing.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -66,7 +66,7 @@ class GitDriver extends VcsDriver
|
||||||
};
|
};
|
||||||
$gitUtil->runCommand($commandCallable, $this->url, $this->repoDir);
|
$gitUtil->runCommand($commandCallable, $this->url, $this->repoDir);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->io->write('<error>Failed to update '.$this->url.', package information from this repository may be outdated ('.$e->getMessage().')</error>');
|
$this->io->writeError('<error>Failed to update '.$this->url.', package information from this repository may be outdated ('.$e->getMessage().')</error>');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// clean up directory and do a fresh clone into it
|
// clean up directory and do a fresh clone into it
|
||||||
|
@ -242,7 +242,7 @@ class GitDriver extends VcsDriver
|
||||||
}
|
}
|
||||||
|
|
||||||
$process = new ProcessExecutor($io);
|
$process = new ProcessExecutor($io);
|
||||||
if($process->execute('git ls-remote --heads ' . ProcessExecutor::escape($url), $output) === 0) {
|
if ($process->execute('git ls-remote --heads ' . ProcessExecutor::escape($url), $output) === 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -266,7 +266,7 @@ class GitHubDriver extends VcsDriver
|
||||||
|
|
||||||
if (!extension_loaded('openssl')) {
|
if (!extension_loaded('openssl')) {
|
||||||
if ($io->isVerbose()) {
|
if ($io->isVerbose()) {
|
||||||
$io->write('Skipping GitHub driver for '.$url.' because the OpenSSL PHP extension is missing.');
|
$io->writeError('Skipping GitHub driver for '.$url.' because the OpenSSL PHP extension is missing.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -333,7 +333,7 @@ class GitHubDriver extends VcsDriver
|
||||||
|
|
||||||
if (!$this->io->hasAuthentication($this->originUrl)) {
|
if (!$this->io->hasAuthentication($this->originUrl)) {
|
||||||
if (!$this->io->isInteractive()) {
|
if (!$this->io->isInteractive()) {
|
||||||
$this->io->write('<error>GitHub API limit exhausted. Failed to get metadata for the '.$this->url.' repository, try running in interactive mode so that you can enter your GitHub credentials to increase the API limit</error>');
|
$this->io->writeError('<error>GitHub API limit exhausted. Failed to get metadata for the '.$this->url.' repository, try running in interactive mode so that you can enter your GitHub credentials to increase the API limit</error>');
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,7 +344,7 @@ class GitHubDriver extends VcsDriver
|
||||||
|
|
||||||
if ($rateLimited) {
|
if ($rateLimited) {
|
||||||
$rateLimit = $this->getRateLimit($e->getHeaders());
|
$rateLimit = $this->getRateLimit($e->getHeaders());
|
||||||
$this->io->write(sprintf(
|
$this->io->writeError(sprintf(
|
||||||
'<error>GitHub API limit (%d calls/hr) is exhausted. You are already authorized so you have to wait until %s before doing more requests</error>',
|
'<error>GitHub API limit (%d calls/hr) is exhausted. You are already authorized so you have to wait until %s before doing more requests</error>',
|
||||||
$rateLimit['limit'],
|
$rateLimit['limit'],
|
||||||
$rateLimit['reset']
|
$rateLimit['reset']
|
||||||
|
@ -435,7 +435,7 @@ class GitHubDriver extends VcsDriver
|
||||||
} catch (\RuntimeException $e) {
|
} catch (\RuntimeException $e) {
|
||||||
$this->gitDriver = null;
|
$this->gitDriver = null;
|
||||||
|
|
||||||
$this->io->write('<error>Failed to clone the '.$this->generateSshUrl().' repository, try running in interactive mode so that you can enter your GitHub credentials</error>');
|
$this->io->writeError('<error>Failed to clone the '.$this->generateSshUrl().' repository, try running in interactive mode so that you can enter your GitHub credentials</error>');
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,7 +159,7 @@ class HgBitbucketDriver extends VcsDriver
|
||||||
|
|
||||||
if (!extension_loaded('openssl')) {
|
if (!extension_loaded('openssl')) {
|
||||||
if ($io->isVerbose()) {
|
if ($io->isVerbose()) {
|
||||||
$io->write('Skipping Bitbucket hg driver for '.$url.' because the OpenSSL PHP extension is missing.');
|
$io->writeError('Skipping Bitbucket hg driver for '.$url.' because the OpenSSL PHP extension is missing.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -50,7 +50,7 @@ class HgDriver extends VcsDriver
|
||||||
// update the repo if it is a valid hg repository
|
// update the repo if it is a valid hg repository
|
||||||
if (is_dir($this->repoDir) && 0 === $this->process->execute('hg summary', $output, $this->repoDir)) {
|
if (is_dir($this->repoDir) && 0 === $this->process->execute('hg summary', $output, $this->repoDir)) {
|
||||||
if (0 !== $this->process->execute('hg pull', $output, $this->repoDir)) {
|
if (0 !== $this->process->execute('hg pull', $output, $this->repoDir)) {
|
||||||
$this->io->write('<error>Failed to update '.$this->url.', package information from this repository may be outdated ('.$this->process->getErrorOutput().')</error>');
|
$this->io->writeError('<error>Failed to update '.$this->url.', package information from this repository may be outdated ('.$this->process->getErrorOutput().')</error>');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// clean up directory and do a fresh clone into it
|
// clean up directory and do a fresh clone into it
|
||||||
|
|
|
@ -127,16 +127,16 @@ class VcsRepository extends ArrayRepository
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
if ($verbose) {
|
if ($verbose) {
|
||||||
$this->io->write('<error>Skipped parsing '.$driver->getRootIdentifier().', '.$e->getMessage().'</error>');
|
$this->io->writeError('<error>Skipped parsing '.$driver->getRootIdentifier().', '.$e->getMessage().'</error>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($driver->getTags() as $tag => $identifier) {
|
foreach ($driver->getTags() as $tag => $identifier) {
|
||||||
$msg = 'Reading composer.json of <info>' . ($this->packageName ?: $this->url) . '</info> (<comment>' . $tag . '</comment>)';
|
$msg = 'Reading composer.json of <info>' . ($this->packageName ?: $this->url) . '</info> (<comment>' . $tag . '</comment>)';
|
||||||
if ($verbose) {
|
if ($verbose) {
|
||||||
$this->io->write($msg);
|
$this->io->writeError($msg);
|
||||||
} else {
|
} else {
|
||||||
$this->io->overwrite($msg, false);
|
$this->io->overwriteError($msg, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// strip the release- prefix from tags if present
|
// strip the release- prefix from tags if present
|
||||||
|
@ -144,7 +144,7 @@ class VcsRepository extends ArrayRepository
|
||||||
|
|
||||||
if (!$parsedTag = $this->validateTag($tag)) {
|
if (!$parsedTag = $this->validateTag($tag)) {
|
||||||
if ($verbose) {
|
if ($verbose) {
|
||||||
$this->io->write('<warning>Skipped tag '.$tag.', invalid tag name</warning>');
|
$this->io->writeError('<warning>Skipped tag '.$tag.', invalid tag name</warning>');
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ class VcsRepository extends ArrayRepository
|
||||||
try {
|
try {
|
||||||
if (!$data = $driver->getComposerInformation($identifier)) {
|
if (!$data = $driver->getComposerInformation($identifier)) {
|
||||||
if ($verbose) {
|
if ($verbose) {
|
||||||
$this->io->write('<warning>Skipped tag '.$tag.', no composer file</warning>');
|
$this->io->writeError('<warning>Skipped tag '.$tag.', no composer file</warning>');
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -173,39 +173,39 @@ class VcsRepository extends ArrayRepository
|
||||||
// broken package, version doesn't match tag
|
// broken package, version doesn't match tag
|
||||||
if ($data['version_normalized'] !== $parsedTag) {
|
if ($data['version_normalized'] !== $parsedTag) {
|
||||||
if ($verbose) {
|
if ($verbose) {
|
||||||
$this->io->write('<warning>Skipped tag '.$tag.', tag ('.$parsedTag.') does not match version ('.$data['version_normalized'].') in composer.json</warning>');
|
$this->io->writeError('<warning>Skipped tag '.$tag.', tag ('.$parsedTag.') does not match version ('.$data['version_normalized'].') in composer.json</warning>');
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($verbose) {
|
if ($verbose) {
|
||||||
$this->io->write('Importing tag '.$tag.' ('.$data['version_normalized'].')');
|
$this->io->writeError('Importing tag '.$tag.' ('.$data['version_normalized'].')');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addPackage($this->loader->load($this->preProcess($driver, $data, $identifier)));
|
$this->addPackage($this->loader->load($this->preProcess($driver, $data, $identifier)));
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
if ($verbose) {
|
if ($verbose) {
|
||||||
$this->io->write('<warning>Skipped tag '.$tag.', '.($e instanceof TransportException ? 'no composer file was found' : $e->getMessage()).'</warning>');
|
$this->io->writeError('<warning>Skipped tag '.$tag.', '.($e instanceof TransportException ? 'no composer file was found' : $e->getMessage()).'</warning>');
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$verbose) {
|
if (!$verbose) {
|
||||||
$this->io->overwrite('', false);
|
$this->io->overwriteError('', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($driver->getBranches() as $branch => $identifier) {
|
foreach ($driver->getBranches() as $branch => $identifier) {
|
||||||
$msg = 'Reading composer.json of <info>' . ($this->packageName ?: $this->url) . '</info> (<comment>' . $branch . '</comment>)';
|
$msg = 'Reading composer.json of <info>' . ($this->packageName ?: $this->url) . '</info> (<comment>' . $branch . '</comment>)';
|
||||||
if ($verbose) {
|
if ($verbose) {
|
||||||
$this->io->write($msg);
|
$this->io->writeError($msg);
|
||||||
} else {
|
} else {
|
||||||
$this->io->overwrite($msg, false);
|
$this->io->overwriteError($msg, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$parsedBranch = $this->validateBranch($branch)) {
|
if (!$parsedBranch = $this->validateBranch($branch)) {
|
||||||
if ($verbose) {
|
if ($verbose) {
|
||||||
$this->io->write('<warning>Skipped branch '.$branch.', invalid name</warning>');
|
$this->io->writeError('<warning>Skipped branch '.$branch.', invalid name</warning>');
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,7 @@ class VcsRepository extends ArrayRepository
|
||||||
try {
|
try {
|
||||||
if (!$data = $driver->getComposerInformation($identifier)) {
|
if (!$data = $driver->getComposerInformation($identifier)) {
|
||||||
if ($verbose) {
|
if ($verbose) {
|
||||||
$this->io->write('<warning>Skipped branch '.$branch.', no composer file</warning>');
|
$this->io->writeError('<warning>Skipped branch '.$branch.', no composer file</warning>');
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -230,7 +230,7 @@ class VcsRepository extends ArrayRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($verbose) {
|
if ($verbose) {
|
||||||
$this->io->write('Importing branch '.$branch.' ('.$data['version'].')');
|
$this->io->writeError('Importing branch '.$branch.' ('.$data['version'].')');
|
||||||
}
|
}
|
||||||
|
|
||||||
$packageData = $this->preProcess($driver, $data, $identifier);
|
$packageData = $this->preProcess($driver, $data, $identifier);
|
||||||
|
@ -241,23 +241,23 @@ class VcsRepository extends ArrayRepository
|
||||||
$this->addPackage($package);
|
$this->addPackage($package);
|
||||||
} catch (TransportException $e) {
|
} catch (TransportException $e) {
|
||||||
if ($verbose) {
|
if ($verbose) {
|
||||||
$this->io->write('<warning>Skipped branch '.$branch.', no composer file was found</warning>');
|
$this->io->writeError('<warning>Skipped branch '.$branch.', no composer file was found</warning>');
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
if (!$verbose) {
|
if (!$verbose) {
|
||||||
$this->io->write('');
|
$this->io->writeError('');
|
||||||
}
|
}
|
||||||
$this->branchErrorOccurred = true;
|
$this->branchErrorOccurred = true;
|
||||||
$this->io->write('<error>Skipped branch '.$branch.', '.$e->getMessage().'</error>');
|
$this->io->writeError('<error>Skipped branch '.$branch.', '.$e->getMessage().'</error>');
|
||||||
$this->io->write('');
|
$this->io->writeError('');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$driver->cleanup();
|
$driver->cleanup();
|
||||||
|
|
||||||
if (!$verbose) {
|
if (!$verbose) {
|
||||||
$this->io->overwrite('', false);
|
$this->io->overwriteError('', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->getPackages()) {
|
if (!$this->getPackages()) {
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace Composer\Script;
|
||||||
/**
|
/**
|
||||||
* The Command Event.
|
* The Command Event.
|
||||||
*
|
*
|
||||||
* @author François Pluchino <francois.pluchino@opendisplay.com>
|
* @deprecated use Composer\Script\Event instead
|
||||||
*/
|
*/
|
||||||
class CommandEvent extends Event
|
class CommandEvent extends Event
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,44 +12,13 @@
|
||||||
|
|
||||||
namespace Composer\Script;
|
namespace Composer\Script;
|
||||||
|
|
||||||
use Composer\Composer;
|
use Composer\Installer\PackageEvent as BasePackageEvent;
|
||||||
use Composer\IO\IOInterface;
|
|
||||||
use Composer\DependencyResolver\Operation\OperationInterface;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Package Event.
|
* The Package Event.
|
||||||
*
|
*
|
||||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
* @deprecated Use Composer\Installer\PackageEvent instead
|
||||||
*/
|
*/
|
||||||
class PackageEvent extends Event
|
class PackageEvent extends BasePackageEvent
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @var OperationInterface The package instance
|
|
||||||
*/
|
|
||||||
private $operation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param string $name The event name
|
|
||||||
* @param Composer $composer The composer object
|
|
||||||
* @param IOInterface $io The IOInterface object
|
|
||||||
* @param boolean $devMode Whether or not we are in dev mode
|
|
||||||
* @param OperationInterface $operation The operation object
|
|
||||||
*/
|
|
||||||
public function __construct($name, Composer $composer, IOInterface $io, $devMode, OperationInterface $operation)
|
|
||||||
{
|
|
||||||
parent::__construct($name, $composer, $io, $devMode);
|
|
||||||
$this->operation = $operation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the package instance.
|
|
||||||
*
|
|
||||||
* @return OperationInterface
|
|
||||||
*/
|
|
||||||
public function getOperation()
|
|
||||||
{
|
|
||||||
return $this->operation;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,59 +74,7 @@ class ScriptEvents
|
||||||
*/
|
*/
|
||||||
const POST_STATUS_CMD = 'post-status-cmd';
|
const POST_STATUS_CMD = 'post-status-cmd';
|
||||||
|
|
||||||
/**
|
/** Deprecated constants below */
|
||||||
* The PRE_PACKAGE_INSTALL event occurs before a package is installed.
|
|
||||||
*
|
|
||||||
* The event listener method receives a Composer\Script\PackageEvent instance.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
const PRE_PACKAGE_INSTALL = 'pre-package-install';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The POST_PACKAGE_INSTALL event occurs after a package is installed.
|
|
||||||
*
|
|
||||||
* The event listener method receives a Composer\Script\PackageEvent instance.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
const POST_PACKAGE_INSTALL = 'post-package-install';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The PRE_PACKAGE_UPDATE event occurs before a package is updated.
|
|
||||||
*
|
|
||||||
* The event listener method receives a Composer\Script\PackageEvent instance.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
const PRE_PACKAGE_UPDATE = 'pre-package-update';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The POST_PACKAGE_UPDATE event occurs after a package is updated.
|
|
||||||
*
|
|
||||||
* The event listener method receives a Composer\Script\PackageEvent instance.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
const POST_PACKAGE_UPDATE = 'post-package-update';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The PRE_PACKAGE_UNINSTALL event occurs before a package has been uninstalled.
|
|
||||||
*
|
|
||||||
* The event listener method receives a Composer\Script\PackageEvent instance.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
const PRE_PACKAGE_UNINSTALL = 'pre-package-uninstall';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The POST_PACKAGE_UNINSTALL event occurs after a package has been uninstalled.
|
|
||||||
*
|
|
||||||
* The event listener method receives a Composer\Script\PackageEvent instance.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
const POST_PACKAGE_UNINSTALL = 'post-package-uninstall';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The PRE_AUTOLOAD_DUMP event occurs before the autoload file is generated.
|
* The PRE_AUTOLOAD_DUMP event occurs before the autoload file is generated.
|
||||||
|
@ -182,4 +130,64 @@ class ScriptEvents
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
const POST_ARCHIVE_CMD = 'post-archive-cmd';
|
const POST_ARCHIVE_CMD = 'post-archive-cmd';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The PRE_PACKAGE_INSTALL event occurs before a package is installed.
|
||||||
|
*
|
||||||
|
* The event listener method receives a Composer\Script\PackageEvent instance.
|
||||||
|
*
|
||||||
|
* @deprecated Use Composer\Installer\PackageEvents::PRE_PACKAGE_INSTALL instead.
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const PRE_PACKAGE_INSTALL = 'pre-package-install';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The POST_PACKAGE_INSTALL event occurs after a package is installed.
|
||||||
|
*
|
||||||
|
* The event listener method receives a Composer\Script\PackageEvent instance.
|
||||||
|
*
|
||||||
|
* @deprecated Use Composer\Installer\PackageEvents::POST_PACKAGE_INSTALL instead.
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const POST_PACKAGE_INSTALL = 'post-package-install';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The PRE_PACKAGE_UPDATE event occurs before a package is updated.
|
||||||
|
*
|
||||||
|
* The event listener method receives a Composer\Script\PackageEvent instance.
|
||||||
|
*
|
||||||
|
* @deprecated Use Composer\Installer\PackageEvents::PRE_PACKAGE_UPDATE instead.
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const PRE_PACKAGE_UPDATE = 'pre-package-update';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The POST_PACKAGE_UPDATE event occurs after a package is updated.
|
||||||
|
*
|
||||||
|
* The event listener method receives a Composer\Script\PackageEvent instance.
|
||||||
|
*
|
||||||
|
* @deprecated Use Composer\Installer\PackageEvents::POST_PACKAGE_UPDATE instead.
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const POST_PACKAGE_UPDATE = 'post-package-update';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The PRE_PACKAGE_UNINSTALL event occurs before a package has been uninstalled.
|
||||||
|
*
|
||||||
|
* The event listener method receives a Composer\Script\PackageEvent instance.
|
||||||
|
*
|
||||||
|
* @deprecated Use Composer\Installer\PackageEvents::PRE_PACKAGE_UNINSTALL instead.
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const PRE_PACKAGE_UNINSTALL = 'pre-package-uninstall';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The POST_PACKAGE_UNINSTALL event occurs after a package has been uninstalled.
|
||||||
|
*
|
||||||
|
* The event listener method receives a Composer\Script\PackageEvent instance.
|
||||||
|
*
|
||||||
|
* @deprecated Use Composer\Installer\PackageEvents::POST_PACKAGE_UNINSTALL instead.
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
const POST_PACKAGE_UNINSTALL = 'post-package-uninstall';
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,12 +52,13 @@ class Git
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$protocols = $this->config->get('github-protocols');
|
||||||
|
if (!is_array($protocols)) {
|
||||||
|
throw new \RuntimeException('Config value "github-protocols" must be an array, got '.gettype($protocols));
|
||||||
|
}
|
||||||
|
|
||||||
// public github, autoswitch protocols
|
// public github, autoswitch protocols
|
||||||
if (preg_match('{^(?:https?|git)://'.self::getGitHubDomainsRegex($this->config).'/(.*)}', $url, $match)) {
|
if (preg_match('{^(?:https?|git)://'.self::getGitHubDomainsRegex($this->config).'/(.*)}', $url, $match)) {
|
||||||
$protocols = $this->config->get('github-protocols');
|
|
||||||
if (!is_array($protocols)) {
|
|
||||||
throw new \RuntimeException('Config value "github-protocols" must be an array, got '.gettype($protocols));
|
|
||||||
}
|
|
||||||
$messages = array();
|
$messages = array();
|
||||||
foreach ($protocols as $protocol) {
|
foreach ($protocols as $protocol) {
|
||||||
if ('ssh' === $protocol) {
|
if ('ssh' === $protocol) {
|
||||||
|
@ -79,8 +80,11 @@ class Git
|
||||||
$this->throwException('Failed to clone ' . self::sanitizeUrl($url) .' via '.implode(', ', $protocols).' protocols, aborting.' . "\n\n" . implode("\n", $messages), $url);
|
$this->throwException('Failed to clone ' . self::sanitizeUrl($url) .' via '.implode(', ', $protocols).' protocols, aborting.' . "\n\n" . implode("\n", $messages), $url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if we have a private github url and the ssh protocol is disabled then we skip it and directly fallback to https
|
||||||
|
$bypassSshForGitHub = preg_match('{^git@'.self::getGitHubDomainsRegex($this->config).':(.+?)\.git$}i', $url) && !in_array('ssh', $protocols, true);
|
||||||
|
|
||||||
$command = call_user_func($commandCallable, $url);
|
$command = call_user_func($commandCallable, $url);
|
||||||
if (0 !== $this->process->execute($command, $ignoredOutput, $cwd)) {
|
if ($bypassSshForGitHub || 0 !== $this->process->execute($command, $ignoredOutput, $cwd)) {
|
||||||
// private github repository without git access, try https with auth
|
// private github repository without git access, try https with auth
|
||||||
if (preg_match('{^git@'.self::getGitHubDomainsRegex($this->config).':(.+?)\.git$}i', $url, $match)) {
|
if (preg_match('{^git@'.self::getGitHubDomainsRegex($this->config).':(.+?)\.git$}i', $url, $match)) {
|
||||||
if (!$this->io->hasAuthentication($match[1])) {
|
if (!$this->io->hasAuthentication($match[1])) {
|
||||||
|
@ -122,7 +126,7 @@ class Git
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->io->write(' Authentication required (<info>'.parse_url($url, PHP_URL_HOST).'</info>):');
|
$this->io->writeError(' Authentication required (<info>'.parse_url($url, PHP_URL_HOST).'</info>):');
|
||||||
$auth = array(
|
$auth = array(
|
||||||
'username' => $this->io->ask(' Username: ', $defaultUsername),
|
'username' => $this->io->ask(' Username: ', $defaultUsername),
|
||||||
'password' => $this->io->askAndHideAnswer(' Password: '),
|
'password' => $this->io->askAndHideAnswer(' Password: '),
|
||||||
|
@ -160,18 +164,22 @@ class Git
|
||||||
// added in git 1.7.1, prevents prompting the user for username/password
|
// added in git 1.7.1, prevents prompting the user for username/password
|
||||||
if (getenv('GIT_ASKPASS') !== 'echo') {
|
if (getenv('GIT_ASKPASS') !== 'echo') {
|
||||||
putenv('GIT_ASKPASS=echo');
|
putenv('GIT_ASKPASS=echo');
|
||||||
|
unset($_SERVER['GIT_ASKPASS']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up rogue git env vars in case this is running in a git hook
|
// clean up rogue git env vars in case this is running in a git hook
|
||||||
if (getenv('GIT_DIR')) {
|
if (getenv('GIT_DIR')) {
|
||||||
putenv('GIT_DIR');
|
putenv('GIT_DIR');
|
||||||
|
unset($_SERVER['GIT_DIR']);
|
||||||
}
|
}
|
||||||
if (getenv('GIT_WORK_TREE')) {
|
if (getenv('GIT_WORK_TREE')) {
|
||||||
putenv('GIT_WORK_TREE');
|
putenv('GIT_WORK_TREE');
|
||||||
|
unset($_SERVER['GIT_WORK_TREE']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up env for OSX, see https://github.com/composer/composer/issues/2146#issuecomment-35478940
|
// clean up env for OSX, see https://github.com/composer/composer/issues/2146#issuecomment-35478940
|
||||||
putenv("DYLD_LIBRARY_PATH");
|
putenv("DYLD_LIBRARY_PATH");
|
||||||
|
unset($_SERVER['DYLD_LIBRARY_PATH']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getGitHubDomainsRegex(Config $config)
|
public static function getGitHubDomainsRegex(Config $config)
|
||||||
|
|
|
@ -77,11 +77,11 @@ class GitHub
|
||||||
public function authorizeOAuthInteractively($originUrl, $message = null)
|
public function authorizeOAuthInteractively($originUrl, $message = null)
|
||||||
{
|
{
|
||||||
if ($message) {
|
if ($message) {
|
||||||
$this->io->write($message);
|
$this->io->writeError($message);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->io->write(sprintf('A token will be created and stored in "%s", your password will never be stored', $this->config->getAuthConfigSource()->getName()));
|
$this->io->writeError(sprintf('A token will be created and stored in "%s", your password will never be stored', $this->config->getAuthConfigSource()->getName()));
|
||||||
$this->io->write('To revoke access to this token you can visit https://github.com/settings/applications');
|
$this->io->writeError('To revoke access to this token you can visit https://github.com/settings/applications');
|
||||||
|
|
||||||
$otp = null;
|
$otp = null;
|
||||||
$attemptCounter = 0;
|
$attemptCounter = 0;
|
||||||
|
@ -105,13 +105,13 @@ class GitHub
|
||||||
}
|
}
|
||||||
|
|
||||||
if (401 === $e->getCode()) {
|
if (401 === $e->getCode()) {
|
||||||
$this->io->write('Bad credentials.');
|
$this->io->writeError('Bad credentials.');
|
||||||
} else {
|
} else {
|
||||||
$this->io->write('Maximum number of login attempts exceeded. Please try again later.');
|
$this->io->writeError('Maximum number of login attempts exceeded. Please try again later.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->io->write('You can also manually create a personal token at https://github.com/settings/applications');
|
$this->io->writeError('You can also manually create a personal token at https://github.com/settings/applications');
|
||||||
$this->io->write('Add it using "composer config github-oauth.github.com <token>"');
|
$this->io->writeError('Add it using "composer config github-oauth.github.com <token>"');
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ class GitHub
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->io->write('Token successfully created');
|
$this->io->writeError('Token successfully created');
|
||||||
|
|
||||||
return JsonFile::parseJson($json);
|
return JsonFile::parseJson($json);
|
||||||
}
|
}
|
||||||
|
@ -184,14 +184,14 @@ class GitHub
|
||||||
list($required, $method) = array_map('trim', explode(';', substr(strstr($headers[$key], ':'), 1)));
|
list($required, $method) = array_map('trim', explode(';', substr(strstr($headers[$key], ':'), 1)));
|
||||||
|
|
||||||
if ('required' === $required) {
|
if ('required' === $required) {
|
||||||
$this->io->write('Two-factor Authentication');
|
$this->io->writeError('Two-factor Authentication');
|
||||||
|
|
||||||
if ('app' === $method) {
|
if ('app' === $method) {
|
||||||
$this->io->write('Open the two-factor authentication app on your device to view your authentication code and verify your identity.');
|
$this->io->writeError('Open the two-factor authentication app on your device to view your authentication code and verify your identity.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('sms' === $method) {
|
if ('sms' === $method) {
|
||||||
$this->io->write('You have been sent an SMS message with an authentication code to verify your identity.');
|
$this->io->writeError('You have been sent an SMS message with an authentication code to verify your identity.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->io->ask('Authentication Code: ');
|
return $this->io->ask('Authentication Code: ');
|
||||||
|
|
|
@ -45,7 +45,7 @@ class ProcessExecutor
|
||||||
{
|
{
|
||||||
if ($this->io && $this->io->isDebug()) {
|
if ($this->io && $this->io->isDebug()) {
|
||||||
$safeCommand = preg_replace('{(://[^:/\s]+:)[^@\s/]+}i', '$1****', $command);
|
$safeCommand = preg_replace('{(://[^:/\s]+:)[^@\s/]+}i', '$1****', $command);
|
||||||
$this->io->write('Executing command ('.($cwd ?: 'CWD').'): '.$safeCommand);
|
$this->io->writeError('Executing command ('.($cwd ?: 'CWD').'): '.$safeCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure that null translate to the proper directory in case the dir is a symlink
|
// make sure that null translate to the proper directory in case the dir is a symlink
|
||||||
|
@ -56,7 +56,7 @@ class ProcessExecutor
|
||||||
|
|
||||||
$this->captureOutput = count(func_get_args()) > 1;
|
$this->captureOutput = count(func_get_args()) > 1;
|
||||||
$this->errorOutput = null;
|
$this->errorOutput = null;
|
||||||
$process = new Process($command, $cwd, null, null, static::getTimeout());
|
$process = new Process($command, $cwd, array_replace($_ENV, $_SERVER, array('LANGUAGE' => 'C')), null, static::getTimeout());
|
||||||
|
|
||||||
$callback = is_callable($output) ? $output : array($this, 'outputHandler');
|
$callback = is_callable($output) ? $output : array($this, 'outputHandler');
|
||||||
$process->run($callback);
|
$process->run($callback);
|
||||||
|
|
|
@ -146,7 +146,7 @@ class RemoteFilesystem
|
||||||
$options = $this->getOptionsForUrl($originUrl, $additionalOptions);
|
$options = $this->getOptionsForUrl($originUrl, $additionalOptions);
|
||||||
|
|
||||||
if ($this->io->isDebug()) {
|
if ($this->io->isDebug()) {
|
||||||
$this->io->write((substr($fileUrl, 0, 4) === 'http' ? 'Downloading ' : 'Reading ') . $fileUrl);
|
$this->io->writeError((substr($fileUrl, 0, 4) === 'http' ? 'Downloading ' : 'Reading ') . $fileUrl);
|
||||||
}
|
}
|
||||||
if (isset($options['github-token'])) {
|
if (isset($options['github-token'])) {
|
||||||
$fileUrl .= (false === strpos($fileUrl, '?') ? '?' : '&') . 'access_token='.$options['github-token'];
|
$fileUrl .= (false === strpos($fileUrl, '?') ? '?' : '&') . 'access_token='.$options['github-token'];
|
||||||
|
@ -158,7 +158,7 @@ class RemoteFilesystem
|
||||||
$ctx = StreamContextFactory::getContext($fileUrl, $options, array('notification' => array($this, 'callbackGet')));
|
$ctx = StreamContextFactory::getContext($fileUrl, $options, array('notification' => array($this, 'callbackGet')));
|
||||||
|
|
||||||
if ($this->progress) {
|
if ($this->progress) {
|
||||||
$this->io->write(" Downloading: <comment>connection...</comment>", false);
|
$this->io->writeError(" Downloading: <comment>Connecting...</comment>", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
$errorMessage = '';
|
$errorMessage = '';
|
||||||
|
@ -228,7 +228,7 @@ class RemoteFilesystem
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->progress && !$this->retry) {
|
if ($this->progress && !$this->retry) {
|
||||||
$this->io->overwrite(" Downloading: <comment>100%</comment>");
|
$this->io->overwriteError(" Downloading: <comment>100%</comment>");
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle copy command if download was successful
|
// handle copy command if download was successful
|
||||||
|
@ -327,9 +327,9 @@ class RemoteFilesystem
|
||||||
$progression = round($bytesTransferred / $this->bytesMax * 100);
|
$progression = round($bytesTransferred / $this->bytesMax * 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((0 === $progression % 5) && $progression !== $this->lastProgress) {
|
if ((0 === $progression % 5) && 100 !== $progression && $progression !== $this->lastProgress) {
|
||||||
$this->lastProgress = $progression;
|
$this->lastProgress = $progression;
|
||||||
$this->io->overwrite(" Downloading: <comment>$progression%</comment>", false);
|
$this->io->overwriteError(" Downloading: <comment>$progression%</comment>", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -371,7 +371,7 @@ class RemoteFilesystem
|
||||||
throw new TransportException("Invalid credentials for '" . $this->fileUrl . "', aborting.", $httpStatus);
|
throw new TransportException("Invalid credentials for '" . $this->fileUrl . "', aborting.", $httpStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->io->overwrite(' Authentication required (<info>'.parse_url($this->fileUrl, PHP_URL_HOST).'</info>):');
|
$this->io->overwriteError(' Authentication required (<info>'.parse_url($this->fileUrl, PHP_URL_HOST).'</info>):');
|
||||||
$username = $this->io->ask(' Username: ');
|
$username = $this->io->ask(' Username: ');
|
||||||
$password = $this->io->askAndHideAnswer(' Password: ');
|
$password = $this->io->askAndHideAnswer(' Password: ');
|
||||||
$this->io->setAuthentication($this->originUrl, $username, $password);
|
$this->io->setAuthentication($this->originUrl, $username, $password);
|
||||||
|
|
|
@ -81,6 +81,7 @@ class Svn
|
||||||
{
|
{
|
||||||
// clean up env for OSX, see https://github.com/composer/composer/issues/2146#issuecomment-35478940
|
// clean up env for OSX, see https://github.com/composer/composer/issues/2146#issuecomment-35478940
|
||||||
putenv("DYLD_LIBRARY_PATH");
|
putenv("DYLD_LIBRARY_PATH");
|
||||||
|
unset($_SERVER['DYLD_LIBRARY_PATH']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -111,7 +112,7 @@ class Svn
|
||||||
}
|
}
|
||||||
$output .= $buffer;
|
$output .= $buffer;
|
||||||
if ($verbose) {
|
if ($verbose) {
|
||||||
$io->write($buffer, false);
|
$io->writeError($buffer, false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
$status = $this->process->execute($svnCommand, $handler, $cwd);
|
$status = $this->process->execute($svnCommand, $handler, $cwd);
|
||||||
|
@ -169,7 +170,7 @@ class Svn
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->io->write("The Subversion server ({$this->url}) requested credentials:");
|
$this->io->writeError("The Subversion server ({$this->url}) requested credentials:");
|
||||||
|
|
||||||
$this->hasAuth = true;
|
$this->hasAuth = true;
|
||||||
$this->credentials['username'] = $this->io->ask("Username: ");
|
$this->credentials['username'] = $this->io->ask("Username: ");
|
||||||
|
|
|
@ -42,7 +42,8 @@ class AllFunctionalTest extends \PHPUnit_Framework_TestCase
|
||||||
}
|
}
|
||||||
if ($this->oldenv) {
|
if ($this->oldenv) {
|
||||||
$fs->removeDirectory(getenv('COMPOSER_HOME'));
|
$fs->removeDirectory(getenv('COMPOSER_HOME'));
|
||||||
putenv('COMPOSER_HOME='.$this->oldenv);
|
$_SERVER['COMPOSER_HOME'] = $this->oldenv;
|
||||||
|
putenv('COMPOSER_HOME='.$_SERVER['COMPOSER_HOME']);
|
||||||
$this->oldenv = null;
|
$this->oldenv = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,10 +87,11 @@ class AllFunctionalTest extends \PHPUnit_Framework_TestCase
|
||||||
$testData = $this->parseTestFile($testFile);
|
$testData = $this->parseTestFile($testFile);
|
||||||
|
|
||||||
$this->oldenv = getenv('COMPOSER_HOME');
|
$this->oldenv = getenv('COMPOSER_HOME');
|
||||||
putenv('COMPOSER_HOME='.$this->testDir.'home');
|
$_SERVER['COMPOSER_HOME'] = $this->testDir.'home';
|
||||||
|
putenv('COMPOSER_HOME='.$_SERVER['COMPOSER_HOME']);
|
||||||
|
|
||||||
$cmd = 'php '.escapeshellarg(self::$pharPath).' --no-ansi '.$testData['RUN'];
|
$cmd = 'php '.escapeshellarg(self::$pharPath).' --no-ansi '.$testData['RUN'];
|
||||||
$proc = new Process($cmd, __DIR__.'/Fixtures/functional');
|
$proc = new Process($cmd, __DIR__.'/Fixtures/functional', null, null, 300);
|
||||||
$exitcode = $proc->run();
|
$exitcode = $proc->run();
|
||||||
|
|
||||||
if (isset($testData['EXPECT'])) {
|
if (isset($testData['EXPECT'])) {
|
||||||
|
|
|
@ -29,7 +29,7 @@ class ApplicationTest extends TestCase
|
||||||
->will($this->returnValue('list'));
|
->will($this->returnValue('list'));
|
||||||
|
|
||||||
$outputMock->expects($this->once())
|
$outputMock->expects($this->once())
|
||||||
->method("writeln")
|
->method("write")
|
||||||
->with($this->equalTo(sprintf('<warning>Warning: This development build of composer is over 30 days old. It is recommended to update it by running "%s self-update" to get the latest version.</warning>', $_SERVER['PHP_SELF'])));
|
->with($this->equalTo(sprintf('<warning>Warning: This development build of composer is over 30 days old. It is recommended to update it by running "%s self-update" to get the latest version.</warning>', $_SERVER['PHP_SELF'])));
|
||||||
|
|
||||||
if (!defined('COMPOSER_DEV_WARNING_TIME')) {
|
if (!defined('COMPOSER_DEV_WARNING_TIME')) {
|
||||||
|
|
|
@ -106,6 +106,7 @@ class AutoloadGeneratorTest extends TestCase
|
||||||
$ret = $ret();
|
$ret = $ret();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,13 @@ class ClassMapGeneratorTest extends \PHPUnit_Framework_TestCase
|
||||||
'Foo\\CBar' => __DIR__.'/Fixtures/php5.4/traits.php',
|
'Foo\\CBar' => __DIR__.'/Fixtures/php5.4/traits.php',
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
if (defined('HHVM_VERSION') && version_compare(HHVM_VERSION, '3.3', '>=')) {
|
||||||
|
$data[] = array(__DIR__.'/Fixtures/hhvm3.3', array(
|
||||||
|
'FooEnum' => __DIR__.'/Fixtures/hhvm3.3/HackEnum.php',
|
||||||
|
'Foo\BarEnum' => __DIR__.'/Fixtures/hhvm3.3/NamespacedHackEnum.php',
|
||||||
|
'GenericsClass' => __DIR__.'/Fixtures/hhvm3.3/Generics.php',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +135,7 @@ class ClassMapGeneratorTest extends \PHPUnit_Framework_TestCase
|
||||||
$msg = '';
|
$msg = '';
|
||||||
|
|
||||||
$io->expects($this->once())
|
$io->expects($this->once())
|
||||||
->method('write')
|
->method('writeError')
|
||||||
->will($this->returnCallback(function ($text) use (&$msg) {
|
->will($this->returnCallback(function ($text) use (&$msg) {
|
||||||
$msg = $text;
|
$msg = $text;
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?hh
|
||||||
|
|
||||||
|
class GenericsClass<Tk, Tv> {
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?hh
|
||||||
|
|
||||||
|
enum FooEnum: int {
|
||||||
|
HERP = 1;
|
||||||
|
DERP = 2;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?hh
|
||||||
|
|
||||||
|
namespace Foo;
|
||||||
|
|
||||||
|
enum BarEnum: string {
|
||||||
|
HERP = 'DERP';
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"name": "my-vend/my-app",
|
||||||
|
"license": "MIT",
|
||||||
|
"repositories": {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"name": "my-vend/my-app",
|
||||||
|
"license": "MIT",
|
||||||
|
"repositories": {
|
||||||
|
"example_tld": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "example.tld"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue