Merge branch 'master' into 2.0

main
Jordi Boggiano 5 years ago
commit 0b928b2a42

@ -0,0 +1,11 @@
root = true
[*]
charset = utf-8
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.yml]
indent_size = 2

@ -1,7 +1,5 @@
language: php
sudo: false
dist: trusty
git:
@ -16,54 +14,53 @@ addons:
packages:
- parallel
php:
- 5.4
- 5.5
- 5.6
- 7.0
- 7.1
- 7.2
- 7.3
- nightly
matrix:
include:
- php: 5.3
dist: precise
- php: 5.4
- php: 5.5
- php: 5.6
- php: 7.0
- php: 7.1
- php: 7.2
- php: 7.3
- php: 7.3
env: deps=high
- php: nightly
fast_finish: true
allow_failures:
- php: nightly
before_install:
# disable xdebug if available
- phpenv config-rm xdebug.ini || echo "xdebug not available"
# disable default memory limit
- export INI=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
- echo memory_limit = -1 >> $INI
# disable xdebug if available
- phpenv config-rm xdebug.ini || echo "xdebug not available"
# disable default memory limit
- export INI=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
- echo memory_limit = -1 >> $INI
- composer validate
install:
# flags to pass to install
- flags="--ansi --prefer-dist --no-interaction --optimize-autoloader --no-suggest --no-progress"
# update deps to latest in case of high deps build
- if [ "$deps" == "high" ]; then composer config platform.php 7.2.4; composer update $flags; fi
# install dependencies using system provided composer binary
- composer install $flags
# install dependencies using composer from source
- bin/composer install $flags
# flags to pass to install
- flags="--ansi --prefer-dist --no-interaction --optimize-autoloader --no-suggest --no-progress"
# update deps to latest in case of high deps build
- if [ "$deps" == "high" ]; then composer config platform.php 7.2.4; composer update $flags; fi
# install dependencies using system provided composer binary
- composer install $flags
# install dependencies using composer from source
- bin/composer install $flags
before_script:
# make sure git tests do not complain about user/email not being set
- git config --global user.name travis-ci
- git config --global user.email travis@example.com
# make sure git tests do not complain about user/email not being set
- git config --global user.name travis-ci
- git config --global user.email travis@example.com
script:
# run test suite directories in parallel using GNU parallel
- ls -d tests/Composer/Test/* | grep -v TestCase.php | parallel --gnu --keep-order 'echo "Running {} tests"; ./vendor/bin/phpunit -c tests/complete.phpunit.xml --colors=always {} || (echo -e "\e[41mFAILED\e[0m {}" && exit 1);'
# run test suite directories in parallel using GNU parallel
- ls -d tests/Composer/Test/* | grep -v TestCase.php | parallel --gnu --keep-order 'echo "Running {} tests"; ./vendor/bin/phpunit -c tests/complete.phpunit.xml --colors=always {} || (echo -e "\e[41mFAILED\e[0m {}" && exit 1);'
before_deploy:
- php -d phar.readonly=0 bin/compile
- php -d phar.readonly=0 bin/compile
deploy:
provider: releases

@ -73,8 +73,13 @@
"bin/composer"
],
"scripts": {
"compile": "@php -dphar.readonly=0 bin/compile",
"test": "phpunit"
},
"scripts-descriptions": {
"compile": "Compile composer.phar",
"test": "Run all tests"
},
"support": {
"issues": "https://github.com/composer/composer/issues",
"irc": "irc://irc.freenode.org/composer"

10
composer.lock generated

@ -8,16 +8,16 @@
"packages": [
{
"name": "composer/ca-bundle",
"version": "1.1.3",
"version": "1.1.4",
"source": {
"type": "git",
"url": "https://github.com/composer/ca-bundle.git",
"reference": "8afa52cd417f4ec417b4bfe86b68106538a87660"
"reference": "558f321c52faeb4828c03e7dc0cfe39a09e09a2d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/8afa52cd417f4ec417b4bfe86b68106538a87660",
"reference": "8afa52cd417f4ec417b4bfe86b68106538a87660",
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/558f321c52faeb4828c03e7dc0cfe39a09e09a2d",
"reference": "558f321c52faeb4828c03e7dc0cfe39a09e09a2d",
"shasum": ""
},
"require": {
@ -60,7 +60,7 @@
"ssl",
"tls"
],
"time": "2018-10-18T06:09:13+00:00"
"time": "2019-01-28T09:30:10+00:00"
},
{
"name": "composer/semver",

@ -796,58 +796,40 @@ COMPOSER=composer-other.json php composer.phar install
The generated lock file will use the same name: `composer-other.lock` in this example.
### COMPOSER_ROOT_VERSION
### COMPOSER_ALLOW_SUPERUSER
By setting this var you can specify the version of the root package, if it can
not be guessed from VCS info and is not present in `composer.json`.
If set to 1, this env disables the warning about running commands as root/super user.
It also disables automatic clearing of sudo sessions, so you should really only set this
if you use Composer as super user at all times like in docker containers.
### COMPOSER_VENDOR_DIR
### COMPOSER_AUTH
By setting this var you can make Composer install the dependencies into a
directory other than `vendor`.
The `COMPOSER_AUTH` var allows you to set up authentication as an environment variable.
The contents of the variable should be a JSON formatted object containing http-basic,
github-oauth, bitbucket-oauth, ... objects as needed, and following the
[spec from the config](06-config.md#gitlab-oauth).
### COMPOSER_BIN_DIR
By setting this option you can change the `bin` ([Vendor Binaries](articles/vendor-binaries.md))
directory to something other than `vendor/bin`.
### http_proxy or HTTP_PROXY
If you are using Composer from behind an HTTP proxy, you can use the standard
`http_proxy` or `HTTP_PROXY` env vars. Simply set it to the URL of your proxy.
Many operating systems already set this variable for you.
Using `http_proxy` (lowercased) or even defining both might be preferable since
some tools like git or curl will only use the lower-cased `http_proxy` version.
Alternatively you can also define the git proxy using
`git config --global http.proxy <proxy url>`.
If you are using Composer in a non-CLI context (i.e. integration into a CMS or
similar use case), and need to support proxies, please provide the `CGI_HTTP_PROXY`
environment variable instead. See [httpoxy.org](https://httpoxy.org/) for further
details.
### no_proxy or NO_PROXY
### COMPOSER_CACHE_DIR
If you are behind a proxy and would like to disable it for certain domains, you
can use the `no_proxy` or `NO_PROXY` env var. Simply set it to a comma separated list of
domains the proxy should *not* be used for.
The `COMPOSER_CACHE_DIR` var allows you to change the Composer cache directory,
which is also configurable via the [`cache-dir`](06-config.md#cache-dir) option.
The env var accepts domains, IP addresses, and IP address blocks in CIDR
notation. You can restrict the filter to a particular port (e.g. `:80`). You
can also set it to `*` to ignore the proxy for all HTTP requests.
By default it points to `$COMPOSER_HOME/cache` on \*nix and macOS, and
`C:\Users\<user>\AppData\Local\Composer` (or `%LOCALAPPDATA%/Composer`) on Windows.
### HTTP_PROXY_REQUEST_FULLURI
### COMPOSER_CAFILE
If you use a proxy but it does not support the request_fulluri flag, then you
should set this env var to `false` or `0` to prevent Composer from setting the
request_fulluri option.
By setting this environmental value, you can set a path to a certificate bundle
file to be used during SSL/TLS peer verification.
### HTTPS_PROXY_REQUEST_FULLURI
### COMPOSER_DISCARD_CHANGES
If you use a proxy but it does not support the request_fulluri flag for HTTPS
requests, then you should set this env var to `false` or `0` to prevent Composer
from setting the request_fulluri option.
This env var controls the [`discard-changes`](06-config.md#discard-changes) config option.
### COMPOSER_HOME
@ -873,60 +855,78 @@ This file allows you to set [repositories](05-repositories.md) and
In case global configuration matches _local_ configuration, the _local_
configuration in the project's `composer.json` always wins.
### COMPOSER_CACHE_DIR
### COMPOSER_HTACCESS_PROTECT
The `COMPOSER_CACHE_DIR` var allows you to change the Composer cache directory,
which is also configurable via the [`cache-dir`](06-config.md#cache-dir) option.
Defaults to `1`. If set to `0`, Composer will not create `.htaccess` files in the
composer home, cache, and data directories.
By default it points to `$COMPOSER_HOME/cache` on \*nix and macOS, and
`C:\Users\<user>\AppData\Local\Composer` (or `%LOCALAPPDATA%/Composer`) on Windows.
### COMPOSER_MEMORY_LIMIT
If set, the value is used as php's memory_limit.
### COMPOSER_MIRROR_PATH_REPOS
If set to 1, this env changes the default path repository strategy to `mirror` instead
of `symlink`. As it is the default strategy being set it can still be overwritten by
repository options.
### COMPOSER_NO_INTERACTION
If set to 1, this env var will make Composer behave as if you passed the
`--no-interaction` flag to every command. This can be set on build boxes/CI.
### COMPOSER_PROCESS_TIMEOUT
This env var controls the time Composer waits for commands (such as git
commands) to finish executing. The default value is 300 seconds (5 minutes).
### COMPOSER_CAFILE
By setting this environmental value, you can set a path to a certificate bundle
file to be used during SSL/TLS peer verification.
### COMPOSER_ROOT_VERSION
### COMPOSER_AUTH
By setting this var you can specify the version of the root package, if it can
not be guessed from VCS info and is not present in `composer.json`.
The `COMPOSER_AUTH` var allows you to set up authentication as an environment variable.
The contents of the variable should be a JSON formatted object containing http-basic,
github-oauth, bitbucket-oauth, ... objects as needed, and following the
[spec from the config](06-config.md#gitlab-oauth).
### COMPOSER_VENDOR_DIR
### COMPOSER_DISCARD_CHANGES
By setting this var you can make Composer install the dependencies into a
directory other than `vendor`.
This env var controls the [`discard-changes`](06-config.md#discard-changes) config option.
### http_proxy or HTTP_PROXY
### COMPOSER_NO_INTERACTION
If you are using Composer from behind an HTTP proxy, you can use the standard
`http_proxy` or `HTTP_PROXY` env vars. Simply set it to the URL of your proxy.
Many operating systems already set this variable for you.
If set to 1, this env var will make Composer behave as if you passed the
`--no-interaction` flag to every command. This can be set on build boxes/CI.
Using `http_proxy` (lowercased) or even defining both might be preferable since
some tools like git or curl will only use the lower-cased `http_proxy` version.
Alternatively you can also define the git proxy using
`git config --global http.proxy <proxy url>`.
### COMPOSER_ALLOW_SUPERUSER
If you are using Composer in a non-CLI context (i.e. integration into a CMS or
similar use case), and need to support proxies, please provide the `CGI_HTTP_PROXY`
environment variable instead. See [httpoxy.org](https://httpoxy.org/) for further
details.
If set to 1, this env disables the warning about running commands as root/super user.
It also disables automatic clearing of sudo sessions, so you should really only set this
if you use Composer as super user at all times like in docker containers.
### HTTP_PROXY_REQUEST_FULLURI
### COMPOSER_MEMORY_LIMIT
If you use a proxy but it does not support the request_fulluri flag, then you
should set this env var to `false` or `0` to prevent Composer from setting the
request_fulluri option.
If set, the value is used as php's memory_limit.
### HTTPS_PROXY_REQUEST_FULLURI
### COMPOSER_MIRROR_PATH_REPOS
If you use a proxy but it does not support the request_fulluri flag for HTTPS
requests, then you should set this env var to `false` or `0` to prevent Composer
from setting the request_fulluri option.
If set to 1, this env changes the default path repository strategy to `mirror` instead
of `symlink`. As it is the default strategy being set it can still be overwritten by
repository options.
### no_proxy or NO_PROXY
### COMPOSER_HTACCESS_PROTECT
If you are behind a proxy and would like to disable it for certain domains, you
can use the `no_proxy` or `NO_PROXY` env var. Simply set it to a comma separated list of
domains the proxy should *not* be used for.
Defaults to `1`. If set to `0`, Composer will not create `.htaccess` files in the
composer home, cache, and data directories.
The env var accepts domains, IP addresses, and IP address blocks in CIDR
notation. You can restrict the filter to a particular port (e.g. `:80`). You
can also set it to `*` to ignore the proxy for all HTTP requests.
### COMPOSER_DISABLE_NETWORK

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
@ -8,7 +10,6 @@
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="tests/bootstrap.php"
>
<testsuites>

@ -48,6 +48,7 @@ class RunScriptCommand extends BaseCommand
{
$this
->setName('run-script')
->setAliases(array('run'))
->setDescription('Runs the scripts defined in composer.json.')
->setDefinition(array(
new InputArgument('script', InputArgument::OPTIONAL, 'Script name to run.'),

@ -216,7 +216,6 @@ class Config
case 'cache-vcs-dir':
case 'cafile':
case 'capath':
case 'htaccess-protect':
// convert foo-bar to COMPOSER_FOO_BAR and check if it exists since it overrides the local config
$env = 'COMPOSER_' . strtoupper(strtr($key, '-', '_'));
@ -230,6 +229,13 @@ class Config
return (($flags & self::RELATIVE_PATHS) == self::RELATIVE_PATHS) ? $val : $this->realpath($val);
case 'htaccess-protect':
$value = $this->getComposerEnv('COMPOSER_HTACCESS_PROTECT');
if (false === $value) {
$value = $this->config[$key];
}
return $value !== 'false' && (bool) $value;
case 'cache-ttl':
return (int) $this->config[$key];

@ -17,6 +17,8 @@ use Composer\Util\Platform;
use Composer\Util\Silencer;
use Symfony\Component\Console\Application as BaseApplication;
use Symfony\Component\Console\Exception\CommandNotFoundException;
use Symfony\Component\Console\Helper\HelperSet;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
@ -111,7 +113,9 @@ class Application extends BaseApplication
{
$this->disablePluginsByDefault = $input->hasParameterOption('--no-plugins');
$io = $this->io = new ConsoleIO($input, $output, $this->getHelperSet());
$io = $this->io = new ConsoleIO($input, $output, new HelperSet(array(
new QuestionHelper(),
)));
ErrorHandler::register($io);
// switch working dir

@ -244,6 +244,12 @@ class EventDispatcher
if (substr($exec, 0, 5) === '@php ') {
$exec = $this->getPhpExecCommand() . ' ' . substr($exec, 5);
} else {
$finder = new PhpExecutableFinder();
$phpPath = $finder->find(false);
if ($phpPath) {
putenv('PHP_BINARY=' . $phpPath);
}
}
if (0 !== ($exitCode = $this->process->execute($exec))) {

@ -165,6 +165,16 @@ class Factory
'data-dir' => self::getDataDir($home),
)));
// load global config
$file = new JsonFile($config->get('home').'/config.json');
if ($file->exists()) {
if ($io && $io->isDebug()) {
$io->writeError('Loading config file ' . $file->getPath());
}
$config->merge($file->read());
}
$config->setConfigSource(new JsonConfigSource($file));
$htaccessProtect = (bool) $config->get('htaccess-protect');
if ($htaccessProtect) {
// Protect directory against web access. Since HOME could be
@ -181,16 +191,6 @@ class Factory
}
}
// load global config
$file = new JsonFile($config->get('home').'/config.json');
if ($file->exists()) {
if ($io && $io->isDebug()) {
$io->writeError('Loading config file ' . $file->getPath());
}
$config->merge($file->read());
}
$config->setConfigSource(new JsonConfigSource($file));
// load global auth file
$file = new JsonFile($config->get('home').'/auth.json');
if ($file->exists()) {

@ -12,8 +12,10 @@
namespace Composer\IO;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Output\StreamOutput;
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
use Symfony\Component\Console\Input\StreamableInputInterface;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Helper\HelperSet;
@ -34,7 +36,9 @@ class BufferIO extends ConsoleIO
$output = new StreamOutput(fopen('php://memory', 'rw'), $verbosity, $formatter ? $formatter->isDecorated() : false, $formatter);
parent::__construct($input, $output, new HelperSet(array()));
parent::__construct($input, $output, new HelperSet(array(
new QuestionHelper(),
)));
}
public function getOutput()
@ -56,4 +60,27 @@ class BufferIO extends ConsoleIO
return $output;
}
public function setUserInputs(array $inputs)
{
if (!$this->input instanceof StreamableInputInterface) {
throw new \RuntimeException('Setting the user inputs requires at least the version 3.2 of the symfony/console component.');
}
$this->input->setStream($this->createStream($inputs));
$this->input->setInteractive(true);
}
private function createStream(array $inputs)
{
$stream = fopen('php://memory', 'r+', false);
foreach ($inputs as $input) {
fwrite($stream, $input.PHP_EOL);
}
rewind($stream);
return $stream;
}
}

@ -197,7 +197,7 @@ class BinaryInstaller
dir=\$(cd "\${0%[/\\\\]*}" > /dev/null; cd $binDir && pwd)
if [ -d /proc/cygdrive ] && [[ \$(which php) == \$(readlink -n /proc/cygdrive)/* ]]; then
# We are in Cgywin using Windows php, so the path must be translated
# We are in Cygwin using Windows php, so the path must be translated
dir=\$(cygpath -m "\$dir");
fi

@ -34,6 +34,8 @@ class JsonFile
const JSON_PRETTY_PRINT = 128;
const JSON_UNESCAPED_UNICODE = 256;
const COMPOSER_SCHEMA_PATH = '/../../../res/composer-schema.json';
private $path;
private $httpDownloader;
private $io;
@ -144,10 +146,11 @@ class JsonFile
* Validates the schema of the current json file according to composer-schema.json rules
*
* @param int $schema a JsonFile::*_SCHEMA constant
* @param string|null $schemaFile a path to the schema file
* @throws JsonValidationException
* @return bool true on success
*/
public function validateSchema($schema = self::STRICT_SCHEMA)
public function validateSchema($schema = self::STRICT_SCHEMA, $schemaFile = null)
{
$content = file_get_contents($this->path);
$data = json_decode($content);
@ -156,7 +159,9 @@ class JsonFile
self::validateSyntax($content, $this->path);
}
$schemaFile = __DIR__ . '/../../../res/composer-schema.json';
if (null === $schemaFile) {
$schemaFile = __DIR__ . self::COMPOSER_SCHEMA_PATH;
}
// Prepend with file:// only when not using a special schema already (e.g. in the phar)
if (false === strpos($schemaFile, '://')) {

@ -150,10 +150,15 @@ class ArchiveManager
$sourcePath = sys_get_temp_dir().'/composer_archive'.uniqid();
$filesystem->ensureDirectoryExists($sourcePath);
// Download sources
$promise = $this->downloadManager->download($package, $sourcePath);
$this->loop->wait(array($promise));
$this->downloadManager->install($package, $sourcePath);
try {
// Download sources
$promise = $this->downloadManager->download($package, $sourcePath);
$this->loop->wait(array($promise));
$this->downloadManager->install($package, $sourcePath);
} catch (\Exception $e) {
$filesystem->removeDirectory($sourcePath);
throw $e;
}
// Check exclude from downloaded composer.json
if (file_exists($composerJsonPath = $sourcePath.'/composer.json')) {

@ -0,0 +1,43 @@
<?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\Test\IO;
use Composer\IO\BufferIO;
use Composer\Test\TestCase;
use Symfony\Component\Console\Input\StreamableInputInterface;
class BufferIOTest extends TestCase
{
public function testSetUserInputs()
{
$bufferIO = new BufferIO();
$refl = new \ReflectionProperty($bufferIO, 'input');
$refl->setAccessible(true);
$input = $refl->getValue($bufferIO);
if (!$input instanceof StreamableInputInterface) {
$this->setExpectedException('\RuntimeException', 'Setting the user inputs requires at least the version 3.2 of the symfony/console component.');
}
$bufferIO->setUserInputs(array(
'yes',
'no',
'',
));
$this->assertTrue($bufferIO->askConfirmation('Please say yes!', 'no'));
$this->assertFalse($bufferIO->askConfirmation('Now please say no!', 'yes'));
$this->assertSame('default', $bufferIO->ask('Empty string last', 'default'));
}
}
Loading…
Cancel
Save