Merge remote-tracking branch 'upstream/master' into svn-auth-reloaded
commit
8f96786693
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -2,12 +2,14 @@
|
|||
|
||||
* Added `create-project` command to install a project from scratch with composer
|
||||
* Added automated `classmap` autoloading support for non-PSR-0 compliant projects
|
||||
* Git clones from GitHub automatically select between git/https/http protocols
|
||||
* Enhanced `validate` command to give more feedback
|
||||
* Improved clones from GitHub which now automatically select between git/https/http protocols
|
||||
* Added support for private GitHub repositories (use --no-interaction for CI)
|
||||
* Improved `validate` command to give more feedback
|
||||
* Added "file" downloader type to download plain files
|
||||
* Added support for authentication with svn repositories
|
||||
* Dependency on filter_var is now optional
|
||||
* Various robustness & error handling improvements
|
||||
* Removed dependency on filter_var
|
||||
* Improved the `search` & `show` commands output
|
||||
* Various robustness & error handling improvements, docs fixes and more
|
||||
|
||||
* 1.0.0-alpha1 (2012-03-01)
|
||||
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
if ((!@include __DIR__.'/../../../.composer/autoload.php') && (!@include __DIR__.'/../vendor/.composer/autoload.php')) {
|
||||
die('You must set up the project dependencies, run the following commands:'.PHP_EOL.
|
||||
'curl -s http://getcomposer.org/installer | php'.PHP_EOL.
|
||||
'php composer.phar install'.PHP_EOL);
|
||||
}
|
||||
require __DIR__.'/../src/bootstrap.php';
|
||||
|
||||
use Composer\Compiler;
|
||||
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
if ((!@include __DIR__.'/../../../.composer/autoload.php') && (!@include __DIR__.'/../vendor/.composer/autoload.php')) {
|
||||
die('You must set up the project dependencies, run the following commands:'.PHP_EOL.
|
||||
'curl -s http://getcomposer.org/installer | php'.PHP_EOL.
|
||||
'php composer.phar install'.PHP_EOL);
|
||||
}
|
||||
require __DIR__.'/../src/bootstrap.php';
|
||||
|
||||
use Composer\Console\Application;
|
||||
|
||||
|
|
|
@ -31,5 +31,10 @@
|
|||
"autoload": {
|
||||
"psr-0": { "Composer": "src/" }
|
||||
},
|
||||
"bin": ["bin/composer"]
|
||||
"bin": ["bin/composer"],
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"hash": "959be339ea6f0b140f09215c4ef451cc",
|
||||
"hash": "df0b80bd7287f1783e3bf2a2c4b9db63",
|
||||
"packages": [
|
||||
{
|
||||
"package": "justinrainbow/json-schema",
|
||||
|
@ -9,7 +9,7 @@
|
|||
{
|
||||
"package": "seld/jsonlint",
|
||||
"version": "dev-master",
|
||||
"source-reference": "12f0b1e5334a52b7035e1d15f36974db7c06b78d"
|
||||
"source-reference": "869e5d011fe1c82501ae0a3b427a686c21fd5baf"
|
||||
},
|
||||
{
|
||||
"package": "symfony/console",
|
||||
|
|
|
@ -1,23 +1,30 @@
|
|||
# Introduction
|
||||
|
||||
Composer is a tool for dependency management in PHP. It allows you to declare
|
||||
the dependencies of your project and will install them for you.
|
||||
the dependent libraries your project needs and it will install them in your
|
||||
project for you.
|
||||
|
||||
## Dependency management
|
||||
|
||||
One important distinction to make is that composer is not a package manager. It
|
||||
deals with packages, but it manages them on a per-project basis. By default it
|
||||
will never install anything globally. Thus, it is a dependency manager.
|
||||
Composer is not a package manager. Yes, it deals with "packages" or libraries, but
|
||||
it manages them on a per-project basis, installing them in a directory (e.g. `vendor`)
|
||||
inside your project. By default it will never install anything globally. Thus,
|
||||
it is a dependency manager.
|
||||
|
||||
This idea is not new by any means. Composer is strongly inspired by
|
||||
node's [npm](http://npmjs.org/) and ruby's [bundler](http://gembundler.com/).
|
||||
But there has not been such a tool for PHP so far.
|
||||
This idea is not new and Composer is strongly inspired by node's [npm](http://npmjs.org/)
|
||||
and ruby's [bundler](http://gembundler.com/). But there has not been such a tool
|
||||
for PHP.
|
||||
|
||||
The problem that composer solves is the following. You have a project that
|
||||
depends on a number of libraries. Some of those libraries have dependencies of
|
||||
their own. You declare the things you depend on. Composer will then go ahead
|
||||
and find out which versions of which packages need to be installed, and
|
||||
install them.
|
||||
The problem that Composer solves is this:
|
||||
|
||||
a) You have a project that depends on a number of libraries.
|
||||
|
||||
b) Some of those libraries depend on other libraries .
|
||||
|
||||
c) You declare the things you depend on
|
||||
|
||||
d) Composer finds out which versions of which packages need to be installed, and
|
||||
installs them (meaning it downloads them into your project).
|
||||
|
||||
## Declaring dependencies
|
||||
|
||||
|
@ -32,37 +39,50 @@ which describes the project's dependencies.
|
|||
}
|
||||
}
|
||||
|
||||
We are simply stating that our project requires the `monolog/monolog` package,
|
||||
We are simply stating that our project requires some `monolog/monolog` package,
|
||||
any version beginning with `1.0`.
|
||||
|
||||
## Installation
|
||||
|
||||
To actually get it, we need to do two things. The first one is installing
|
||||
composer:
|
||||
### 1) Downloading the Composer Executable
|
||||
|
||||
To actually get Composer, we need to do two things. The first one is installing
|
||||
Composer (again, this mean downloading it into your project):
|
||||
|
||||
$ curl -s http://getcomposer.org/installer | php
|
||||
|
||||
This will just check a few PHP settings and then download `composer.phar` to
|
||||
your working directory. This file is the composer binary.
|
||||
your working directory. This file is the Composer binary. It is a PHAR (PHP
|
||||
archive), which is an archive format for PHP which can be run on the command
|
||||
line, amongst other things.
|
||||
|
||||
You can install composer to a specific directory by using the `--install-dir`
|
||||
You can install Composer to a specific directory by using the `--install-dir`
|
||||
option and providing a target directory (it can be an absolute or relative path):
|
||||
|
||||
$ curl -s http://getcomposer.org/installer | php -- --install-dir=bin
|
||||
|
||||
After that we run the command for installing all dependencies:
|
||||
You can place this file anywhere you wish. If you put it in your `PATH`,
|
||||
you can access it globally. On unixy systems you can even make it
|
||||
executable and invoke it without `php`.
|
||||
|
||||
### 2) Using Composer
|
||||
|
||||
Next, run the command the `install` command to resolve and download dependencies:
|
||||
|
||||
$ php composer.phar install
|
||||
|
||||
This will download monolog and dump it into `vendor/monolog/monolog`.
|
||||
This will download monolog into the `vendor/monolog/monolog` directory.
|
||||
|
||||
## Autoloading
|
||||
|
||||
After this you can just add the following line to your bootstrap code to get
|
||||
autoloading:
|
||||
Besides downloading the library, Composer also prepares an autoload file that's
|
||||
capable of autoloading all of the classes in any of the libraries that it
|
||||
downloads. To use it, just add the following line to your code's bootstrap
|
||||
process:
|
||||
|
||||
require 'vendor/.composer/autoload.php';
|
||||
|
||||
That's all it takes to have a basic setup.
|
||||
Woh! Now start using monolog! To keep learning more about Composer, keep
|
||||
reading the "Basic Usage" chapter.
|
||||
|
||||
[Basic Usage](01-basic-usage.md) →
|
||||
|
|
|
@ -2,49 +2,36 @@
|
|||
|
||||
## Installation
|
||||
|
||||
To install composer, simply run this command on the command line:
|
||||
To install Composer, you just need to download the `composer.phar` executable.
|
||||
|
||||
$ curl -s http://getcomposer.org/installer | php
|
||||
|
||||
This will perform some checks on your environment to make sure you can
|
||||
actually run it.
|
||||
For the details, see the [Introduction](00-intro.md) chapter.
|
||||
|
||||
Then it will download `composer.phar` and place it in your working directory.
|
||||
`composer.phar` is the composer binary. It is a PHAR (PHP archive), which is
|
||||
an archive format for PHP which can be run on the command line, amongst other
|
||||
things.
|
||||
|
||||
You can place this file anywhere you wish. If you put it in your `PATH`,
|
||||
you can access it globally. On unixy systems you can even make it
|
||||
executable and invoke it without `php`.
|
||||
|
||||
You can install composer to a specific directory by using the `--install-dir`
|
||||
option and providing a target directory (it can be an absolute or relative path):
|
||||
|
||||
$ curl -s http://getcomposer.org/installer | php -- --install-dir=bin
|
||||
|
||||
To check if composer is working, just run the PHAR through `php`:
|
||||
To check if Composer is working, just run the PHAR through `php`:
|
||||
|
||||
$ php composer.phar
|
||||
|
||||
This should give you a list of available commands.
|
||||
|
||||
> **Note:** You can also perform the checks only without downloading composer
|
||||
> **Note:** You can also perform the checks only without downloading Composer
|
||||
> by using the `--check` option. For more information, just use `--help`.
|
||||
>
|
||||
> $ curl -s http://getcomposer.org/installer | php -- --help
|
||||
|
||||
## Project setup
|
||||
## `composer.json`: Project Setup
|
||||
|
||||
To start using composer in your project, all you need is a `composer.json`
|
||||
To start using Composer in your project, all you need is a `composer.json`
|
||||
file. This file describes the dependencies of your project and may contain
|
||||
other metadata as well.
|
||||
|
||||
The [JSON format](http://json.org/) is quite easy to write. It allows you to
|
||||
define nested structures.
|
||||
|
||||
### The `require` Key
|
||||
|
||||
The first (and often only) thing you specify in `composer.json` is the
|
||||
`require` key. You're simply telling composer which packages your project
|
||||
`require` key. You're simply telling Composer which packages your project
|
||||
depends on.
|
||||
|
||||
{
|
||||
|
@ -53,12 +40,13 @@ depends on.
|
|||
}
|
||||
}
|
||||
|
||||
As you can see, `require` takes an object that maps package names to versions.
|
||||
As you can see, `require` takes an object that maps **package names** (e.g. `monolog/monolog`)
|
||||
to **package versions** (e.g. `1.0.*`).
|
||||
|
||||
## Package names
|
||||
### Package Names
|
||||
|
||||
The package name consists of a vendor name and the project's name. Often these
|
||||
will be identical. The vendor name exists to prevent naming clashes. It allows
|
||||
will be identical - the vendor name just exists to prevent naming clashes. It allows
|
||||
two different people to create a library named `json`, which would then just be
|
||||
named `igorw/json` and `seldaek/json`.
|
||||
|
||||
|
@ -68,10 +56,10 @@ allows adding more related projects under the same namespace later on. If you
|
|||
are maintaining a library, this would make it really easy to split it up into
|
||||
smaller decoupled parts.
|
||||
|
||||
## Package versions
|
||||
### Package Versions
|
||||
|
||||
We are also requiring the version `1.0.*` of monolog. This means any version
|
||||
in the `1.0` development branch. It would match `1.0.0`, `1.0.2` and `1.0.20`.
|
||||
We are requiring version `1.0.*` of monolog. This means any version in the `1.0`
|
||||
development branch. It would match `1.0.0`, `1.0.2` or `1.0.20`.
|
||||
|
||||
Version constraints can be specified in a few different ways.
|
||||
|
||||
|
@ -80,14 +68,14 @@ Version constraints can be specified in a few different ways.
|
|||
|
||||
* **Range:** By using comparison operators you can specify ranges of valid
|
||||
versions. Valid operators are `>`, `>=`, `<`, `<=`. An example range would be
|
||||
`>=1.0`. You can define multiple of these, separated by comma: `>=1.0,<2.0`.
|
||||
`>=1.0`. You can define multiple ranges, separated by a comma: `>=1.0,<2.0`.
|
||||
|
||||
* **Wildcard:** You can specify a pattern with a `*` wildcard. `1.0.*` is the
|
||||
equivalent of `>=1.0,<1.1-dev`.
|
||||
|
||||
## Installing dependencies
|
||||
## Installing Dependencies
|
||||
|
||||
To fetch the defined dependencies into the local project, you simply run the
|
||||
To fetch the defined dependencies into your local project, just run the
|
||||
`install` command of `composer.phar`.
|
||||
|
||||
$ php composer.phar install
|
||||
|
@ -104,29 +92,33 @@ In case of monolog it will put it into `vendor/monolog/monolog`.
|
|||
Another thing that the `install` command does is it adds a `composer.lock`
|
||||
file into your project root.
|
||||
|
||||
## Lock file
|
||||
## `composer.lock` - The Lock File
|
||||
|
||||
After installing the dependencies, composer writes the list of the exact
|
||||
After installing the dependencies, Composer writes the list of the exact
|
||||
versions it installed into a `composer.lock` file. This locks the project
|
||||
to those specific versions.
|
||||
|
||||
**Commit your project's `composer.lock` into version control.**
|
||||
**Commit your project's `composer.lock` (along with `composer.json`) into version control.**
|
||||
|
||||
The reason is that anyone who sets up the project should get the same version.
|
||||
The `install` command will check if a lock file is present. If it is, it will
|
||||
use the versions specified there. If not, it will resolve the dependencies and
|
||||
create a lock file.
|
||||
This is important because the `install` command checks if a lock file is present,
|
||||
and if it is, it downloads the versions specified there (regardless of what `composer.json`
|
||||
says). This means that anyone who sets up the project will download the exact
|
||||
same version of the dependencies.
|
||||
|
||||
If any of the dependencies gets a new version, you can update to that version
|
||||
by using the `update` command. This will fetch the latest matching versions and
|
||||
also update the lock file.
|
||||
If no `composer.json` lock file exists, it will read the dependencies and
|
||||
versions from `composer.json` and create the lock file.
|
||||
|
||||
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
|
||||
the latest matching versions (according to your `composer.json` file) and also update
|
||||
the lock file with the new version.
|
||||
|
||||
$ php composer.phar update
|
||||
|
||||
## Packagist
|
||||
|
||||
[Packagist](http://packagist.org/) is the main composer repository. A composer
|
||||
repository is basically a package source. A place where you can get packages
|
||||
[Packagist](http://packagist.org/) is the main Composer repository. A Composer
|
||||
repository is basically a package source: a place where you can get packages
|
||||
from. Packagist aims to be the central repository that everybody uses. This
|
||||
means that you can automatically `require` any package that is available
|
||||
there.
|
||||
|
@ -134,20 +126,20 @@ there.
|
|||
If you go to the [packagist website](http://packagist.org/) (packagist.org),
|
||||
you can browse and search for packages.
|
||||
|
||||
Any open source project using composer should publish their packages on
|
||||
packagist.
|
||||
Any open source project using Composer should publish their packages on
|
||||
packagist. A library doesn't need to be on packagist to be used by Composer,
|
||||
but it makes life quite a bit simpler.
|
||||
|
||||
## Autoloading
|
||||
|
||||
For libraries that follow the [PSR-0](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md)
|
||||
naming standard, composer generates a
|
||||
`vendor/.composer/autoload.php` file for autoloading. You can simply include
|
||||
this file and you will get autoloading for free.
|
||||
naming standard, Composer generates a `vendor/.composer/autoload.php` file
|
||||
for autoloading. You can simply include this file and you will get autoloading
|
||||
for free.
|
||||
|
||||
require 'vendor/.composer/autoload.php';
|
||||
|
||||
This makes it really easy to use third party code, because you only
|
||||
have to add one line to `composer.json` and run `install`. For monolog, it
|
||||
This makes it really easy to use third party code: For monolog, it
|
||||
means that we can just start using classes from it, and they will be
|
||||
autoloaded.
|
||||
|
||||
|
|
|
@ -96,9 +96,9 @@ example we will publish the `acme/hello-world` library on GitHub under
|
|||
`github.com/composer/hello-world`.
|
||||
|
||||
Now, To test installing the `acme/hello-world` package, we create a new
|
||||
project locally. We will call it `acme/blog`. This blog will depend on `acme
|
||||
/hello-world`, which in turn depends on `monolog/monolog`. We can accomplish
|
||||
this by creating a new `blog` directory somewhere, containing a
|
||||
project locally. We will call it `acme/blog`. This blog will depend on
|
||||
`acme/hello-world`, which in turn depends on `monolog/monolog`. We can
|
||||
accomplish this by creating a new `blog` directory somewhere, containing a
|
||||
`composer.json`:
|
||||
|
||||
{
|
||||
|
|
|
@ -157,7 +157,7 @@ will always take precedence over the values specified in `composer.json`.
|
|||
|
||||
### COMPOSER
|
||||
|
||||
By setting the `COMPOSER` env variable is is possible to set the filename of
|
||||
By setting the `COMPOSER` env variable it is possible to set the filename of
|
||||
`composer.json` to something else.
|
||||
|
||||
For example:
|
||||
|
|
|
@ -13,7 +13,9 @@ can also be used to validate your `composer.json`. In fact, it is used by the
|
|||
|
||||
The root of the package definition is a JSON object.
|
||||
|
||||
## name
|
||||
## Properties
|
||||
|
||||
### name
|
||||
|
||||
The name of the package. It consists of vendor name and project name,
|
||||
separated by `/`.
|
||||
|
@ -25,13 +27,13 @@ Examples:
|
|||
|
||||
Required for published packages (libraries).
|
||||
|
||||
## description
|
||||
### description
|
||||
|
||||
A short description of the package. Usually this is just one line long.
|
||||
|
||||
Optional but recommended.
|
||||
|
||||
## version
|
||||
### version
|
||||
|
||||
The version of the package.
|
||||
|
||||
|
@ -52,7 +54,7 @@ Optional if the package repository can infer the version from somewhere, such
|
|||
as the VCS tag name in the VCS repository. In that case it is also recommended
|
||||
to omit it.
|
||||
|
||||
## type
|
||||
### type
|
||||
|
||||
The type of the package. It defaults to `library`.
|
||||
|
||||
|
@ -74,7 +76,7 @@ order to be able to install the bundle.
|
|||
Only use a custom type if you need custom logic during installation. It is
|
||||
recommended to omit this field and have it just default to `library`.
|
||||
|
||||
## keywords
|
||||
### keywords
|
||||
|
||||
An array of keywords that the package is related to. These can be used for
|
||||
searching and filtering.
|
||||
|
@ -89,13 +91,13 @@ Examples:
|
|||
|
||||
Optional.
|
||||
|
||||
## homepage
|
||||
### homepage
|
||||
|
||||
An URL to the website of the project.
|
||||
|
||||
Optional.
|
||||
|
||||
## time
|
||||
### time
|
||||
|
||||
Release date of the version.
|
||||
|
||||
|
@ -103,7 +105,7 @@ Must be in `YYYY-MM-DD` or `YYYY-MM-DD HH:MM:SS` format.
|
|||
|
||||
Optional.
|
||||
|
||||
## license
|
||||
### license
|
||||
|
||||
The license of the package. This can be either a string or an array of strings.
|
||||
|
||||
|
@ -122,7 +124,7 @@ The recommended notation for the most common licenses is:
|
|||
|
||||
Optional, but it is highly recommended to supply this.
|
||||
|
||||
## authors
|
||||
### authors
|
||||
|
||||
The authors of the package. This is an array of objects.
|
||||
|
||||
|
@ -151,7 +153,7 @@ An example:
|
|||
|
||||
Optional, but highly recommended.
|
||||
|
||||
## Link types
|
||||
### Link types
|
||||
|
||||
Each of these takes an object which maps package names to version constraints.
|
||||
|
||||
|
@ -179,7 +181,7 @@ Example:
|
|||
|
||||
Optional.
|
||||
|
||||
## autoload
|
||||
### autoload
|
||||
|
||||
Autoload mapping for a PHP autoloader.
|
||||
|
||||
|
@ -211,7 +213,7 @@ Example:
|
|||
}
|
||||
}
|
||||
|
||||
## target-dir
|
||||
### target-dir
|
||||
|
||||
Defines the installation target.
|
||||
|
||||
|
@ -236,7 +238,7 @@ To do that, `autoload` and `target-dir` are defined as follows:
|
|||
|
||||
Optional.
|
||||
|
||||
## repositories
|
||||
### repositories
|
||||
|
||||
Custom package repositories to use.
|
||||
|
||||
|
@ -297,11 +299,12 @@ Example:
|
|||
]
|
||||
}
|
||||
|
||||
> **Note:** Order is significant here. Repositories added later will take
|
||||
precedence. This also means that custom repositories can override packages
|
||||
that exist on packagist.
|
||||
> **Note:** Order is significant here. When looking for a package, Composer
|
||||
will look from the first to the last repository, and pick the first match.
|
||||
By default Packagist is added last which means that custom repositories can
|
||||
override packages from it.
|
||||
|
||||
## config
|
||||
### config
|
||||
|
||||
A set of configuration options. It is only used for projects.
|
||||
|
||||
|
@ -323,7 +326,7 @@ Example:
|
|||
}
|
||||
}
|
||||
|
||||
## scripts
|
||||
### scripts
|
||||
|
||||
Composer allows you to hook into various parts of the installation process
|
||||
through the use of scripts.
|
||||
|
@ -382,7 +385,7 @@ which gives you access to the `Composer\Composer` instance through the
|
|||
}
|
||||
}
|
||||
|
||||
## extra
|
||||
### extra
|
||||
|
||||
Arbitrary extra data for consumption by `scripts`.
|
||||
|
||||
|
@ -393,12 +396,12 @@ handler, you can do:
|
|||
|
||||
Optional.
|
||||
|
||||
## bin
|
||||
### bin
|
||||
|
||||
A set of files that should be treated as binaries and symlinked into the `bin-
|
||||
dir` (from config).
|
||||
|
||||
See (Vendor Bins)[articles/vendor-bins.md] for more details.
|
||||
See [Vendor Bins](articles/vendor-bins.md) for more details.
|
||||
|
||||
Optional.
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ use Symfony\Component\Console\Input\InputArgument;
|
|||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Composer\Json\JsonFile;
|
||||
|
||||
/**
|
||||
* Install a package as new project into new directory.
|
||||
|
@ -85,7 +86,7 @@ EOT
|
|||
if (null === $repositoryUrl) {
|
||||
$sourceRepo = new ComposerRepository(array('url' => 'http://packagist.org'));
|
||||
} elseif (".json" === substr($repositoryUrl, -5)) {
|
||||
$sourceRepo = new FilesystemRepository($repositoryUrl);
|
||||
$sourceRepo = new FilesystemRepository(new JsonFile($repositoryUrl));
|
||||
} elseif (0 === strpos($repositoryUrl, 'http')) {
|
||||
$sourceRepo = new ComposerRepository(array('url' => $repositoryUrl));
|
||||
} else {
|
||||
|
|
|
@ -33,7 +33,7 @@ class InitCommand extends Command
|
|||
|
||||
public function parseAuthorString($author)
|
||||
{
|
||||
if (preg_match('/^(?P<name>[- \.,a-z0-9]+) <(?P<email>.+?)>$/i', $author, $match)) {
|
||||
if (preg_match('/^(?P<name>[- \.,\w]+) <(?P<email>.+?)>$/u', $author, $match)) {
|
||||
if (!function_exists('filter_var') || $match['email'] === filter_var($match['email'], FILTER_VALIDATE_EMAIL)) {
|
||||
return array(
|
||||
'name' => trim($match['name']),
|
||||
|
|
|
@ -102,12 +102,11 @@ class Compiler
|
|||
{
|
||||
$path = str_replace(dirname(dirname(__DIR__)).DIRECTORY_SEPARATOR, '', $file->getRealPath());
|
||||
|
||||
if ($strip) {
|
||||
$content = php_strip_whitespace($file);
|
||||
} elseif ('LICENSE' === basename($file)) {
|
||||
$content = "\n".file_get_contents($file)."\n";
|
||||
} else {
|
||||
$content = file_get_contents($file);
|
||||
if ($strip) {
|
||||
$content = $this->stripWhitespace($content);
|
||||
} elseif ('LICENSE' === basename($file)) {
|
||||
$content = "\n".$content."\n";
|
||||
}
|
||||
|
||||
$content = str_replace('@package_version@', $this->version, $content);
|
||||
|
@ -122,6 +121,40 @@ class Compiler
|
|||
$phar->addFromString('bin/composer', $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes whitespace from a PHP source string while preserving line numbers.
|
||||
*
|
||||
* @param string $source A PHP string
|
||||
* @return string The PHP string with the whitespace removed
|
||||
*/
|
||||
private function stripWhitespace($source)
|
||||
{
|
||||
if (!function_exists('token_get_all')) {
|
||||
return $source;
|
||||
}
|
||||
|
||||
$output = '';
|
||||
foreach (token_get_all($source) as $token) {
|
||||
if (is_string($token)) {
|
||||
$output .= $token;
|
||||
} elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) {
|
||||
$output .= str_repeat("\n", substr_count($token[1], "\n"));
|
||||
} elseif (T_WHITESPACE === $token[0]) {
|
||||
// reduce wide spaces
|
||||
$whitespace = preg_replace('{[ \t]+}', ' ', $token[1]);
|
||||
// normalize newlines to \n
|
||||
$whitespace = preg_replace('{(?:\r\n|\r|\n)}', "\n", $whitespace);
|
||||
// trim leading spaces
|
||||
$whitespace = preg_replace('{\n +}', "\n", $whitespace);
|
||||
$output .= $whitespace;
|
||||
} else {
|
||||
$output .= $token[1];
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
private function getStub()
|
||||
{
|
||||
return <<<'EOF'
|
||||
|
|
|
@ -53,7 +53,7 @@ class Pool
|
|||
throw new \RuntimeException("Could not determine repository priority. The repository was not registered in the pool.");
|
||||
}
|
||||
|
||||
return $priority;
|
||||
return -$priority;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -911,7 +911,7 @@ class Solver
|
|||
$this->installedMap[$package->getId()] = $package;
|
||||
}
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.3.3', '>')) {
|
||||
if (version_compare(PHP_VERSION, '5.3.4', '>=')) {
|
||||
$this->decisionMap = new \SplFixedArray($this->pool->getMaxId() + 1);
|
||||
} else {
|
||||
$this->decisionMap = array_fill(0, $this->pool->getMaxId() + 1, 0);
|
||||
|
|
|
@ -15,7 +15,6 @@ namespace Composer\Downloader;
|
|||
use Composer\IO\IOInterface;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Util\Filesystem;
|
||||
use Composer\Util\RemoteFilesystem;
|
||||
|
||||
/**
|
||||
* Base downloader for archives
|
||||
|
|
|
@ -27,15 +27,17 @@ use Composer\Util\RemoteFilesystem;
|
|||
class FileDownloader implements DownloaderInterface
|
||||
{
|
||||
protected $io;
|
||||
protected $rfs;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param IOInterface $io The IO instance
|
||||
*/
|
||||
public function __construct(IOInterface $io)
|
||||
public function __construct(IOInterface $io, RemoteFilesystem $rfs = null)
|
||||
{
|
||||
$this->io = $io;
|
||||
$this->rfs = $rfs ?: new RemoteFilesystem($io);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,8 +73,7 @@ class FileDownloader implements DownloaderInterface
|
|||
|
||||
$url = $this->processUrl($url);
|
||||
|
||||
$rfs = new RemoteFilesystem($this->io);
|
||||
$rfs->copy($package->getSourceUrl(), $url, $fileName);
|
||||
$this->rfs->copy($package->getSourceUrl(), $url, $fileName);
|
||||
$this->io->write('');
|
||||
|
||||
if (!file_exists($fileName)) {
|
||||
|
|
|
@ -34,6 +34,13 @@ class GitDownloader extends VcsDownloader
|
|||
};
|
||||
|
||||
$this->runCommand($commandCallable, $package->getSourceUrl(), $path);
|
||||
|
||||
// set push url for github projects
|
||||
if (preg_match('{^(?:https?|git)://github.com/([^/]+)/([^/]+?)(?:\.git)?$}', $package->getSourceUrl(), $match)) {
|
||||
$pushUrl = 'git@github.com:'.$match[1].'/'.$match[2].'.git';
|
||||
$cmd = sprintf('cd %s && git remote set-url --push origin %s', escapeshellarg($path), escapeshellarg($pushUrl));
|
||||
$this->process->execute($cmd, $ignoredOutput);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -78,17 +78,7 @@ class Factory
|
|||
$rm = $this->createRepositoryManager($io);
|
||||
|
||||
// load default repository unless it's explicitly disabled
|
||||
$loadPackagist = true;
|
||||
if (isset($packageConfig['repositories'])) {
|
||||
foreach ($packageConfig['repositories'] as $repo) {
|
||||
if (isset($repo['packagist']) && $repo['packagist'] === false) {
|
||||
$loadPackagist = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($loadPackagist) {
|
||||
$this->addPackagistRepository($rm);
|
||||
}
|
||||
$packageConfig = $this->addPackagistRepository($packageConfig);
|
||||
|
||||
// load local repository
|
||||
$this->addLocalRepository($rm, $vendorDir);
|
||||
|
@ -103,6 +93,9 @@ class Factory
|
|||
// initialize installation manager
|
||||
$im = $this->createInstallationManager($rm, $dm, $vendorDir, $binDir, $io);
|
||||
|
||||
// purge packages if they have been deleted on the filesystem
|
||||
$this->purgePackages($rm, $im);
|
||||
|
||||
// init locker
|
||||
$lockFile = substr($composerFile, -5) === '.json' ? substr($composerFile, 0, -4).'lock' : $composerFile . '.lock';
|
||||
$locker = new Package\Locker(new JsonFile($lockFile), $rm, md5_file($composerFile));
|
||||
|
@ -137,9 +130,33 @@ class Factory
|
|||
$rm->setLocalRepository(new Repository\InstalledFilesystemRepository(new JsonFile($vendorDir.'/.composer/installed.json')));
|
||||
}
|
||||
|
||||
protected function addPackagistRepository(RepositoryManager $rm)
|
||||
protected function addPackagistRepository(array $packageConfig)
|
||||
{
|
||||
$rm->addRepository(new Repository\ComposerRepository(array('url' => 'http://packagist.org')));
|
||||
$loadPackagist = true;
|
||||
$packagistConfig = array(
|
||||
'type' => 'composer',
|
||||
'url' => 'http://packagist.org'
|
||||
);
|
||||
if (isset($packageConfig['repositories'])) {
|
||||
foreach ($packageConfig['repositories'] as $key => $repo) {
|
||||
if (isset($repo['packagist'])) {
|
||||
if (true === $repo['packagist']) {
|
||||
$packageConfig['repositories'][$key] = $packagistConfig;
|
||||
}
|
||||
|
||||
$loadPackagist = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$packageConfig['repositories'] = array();
|
||||
}
|
||||
|
||||
if ($loadPackagist) {
|
||||
$packageConfig['repositories'][] = $packagistConfig;
|
||||
}
|
||||
|
||||
return $packageConfig;
|
||||
}
|
||||
|
||||
public function createDownloadManager(IOInterface $io)
|
||||
|
@ -166,6 +183,15 @@ class Factory
|
|||
return $im;
|
||||
}
|
||||
|
||||
protected function purgePackages(Repository\RepositoryManager $rm, Installer\InstallationManager $im)
|
||||
{
|
||||
foreach ($rm->getLocalRepository()->getPackages() as $package) {
|
||||
if (!$im->isPackageInstalled($package)) {
|
||||
$rm->getLocalRepository()->removePackage($package);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static public function create(IOInterface $io, $composerFile = null)
|
||||
{
|
||||
$factory = new static();
|
||||
|
|
|
@ -68,7 +68,7 @@ class RootPackageLoader extends ArrayLoader
|
|||
throw new \UnexpectedValueException('Repository '.$index.' should be an array, '.gettype($repo).' given');
|
||||
}
|
||||
if (!isset($repo['type'])) {
|
||||
throw new \UnexpectedValueException('Repository '.$index.' must have a type defined');
|
||||
throw new \UnexpectedValueException('Repository '.$index.' ('.json_encode($repo).') must have a type defined');
|
||||
}
|
||||
$repository = $this->manager->createRepository($repo['type'], $repo);
|
||||
$this->manager->addRepository($repository);
|
||||
|
|
|
@ -2,8 +2,11 @@
|
|||
|
||||
namespace Composer\Repository\Vcs;
|
||||
|
||||
use Composer\Downloader\TransportException;
|
||||
use Composer\Json\JsonFile;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Util\ProcessExecutor;
|
||||
use Composer\Util\RemoteFilesystem;
|
||||
|
||||
/**
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
|
@ -16,14 +19,30 @@ class GitHubDriver extends VcsDriver
|
|||
protected $branches;
|
||||
protected $rootIdentifier;
|
||||
protected $infoCache = array();
|
||||
protected $isPrivate = false;
|
||||
|
||||
public function __construct($url, IOInterface $io)
|
||||
/**
|
||||
* Git Driver
|
||||
*
|
||||
* @var GitDriver
|
||||
*/
|
||||
protected $gitDriver;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $url
|
||||
* @param IOInterface $io
|
||||
* @param ProcessExecutor $process
|
||||
* @param RemoteFilesystem $remoteFilesystem
|
||||
*/
|
||||
public function __construct($url, IOInterface $io, ProcessExecutor $process = null, RemoteFilesystem $remoteFilesystem = null)
|
||||
{
|
||||
preg_match('#^(?:https?|git)://github\.com/([^/]+)/(.+?)(?:\.git)?$#', $url, $match);
|
||||
$this->owner = $match[1];
|
||||
$this->repository = $match[2];
|
||||
|
||||
parent::__construct($url, $io);
|
||||
parent::__construct($url, $io, $process, $remoteFilesystem);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -31,6 +50,7 @@ class GitHubDriver extends VcsDriver
|
|||
*/
|
||||
public function initialize()
|
||||
{
|
||||
$this->fetchRootIdentifier();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,11 +58,9 @@ class GitHubDriver extends VcsDriver
|
|||
*/
|
||||
public function getRootIdentifier()
|
||||
{
|
||||
if (null === $this->rootIdentifier) {
|
||||
$repoData = JsonFile::parseJson($this->getContents($this->getScheme() . '://api.github.com/repos/'.$this->owner.'/'.$this->repository));
|
||||
$this->rootIdentifier = $repoData['master_branch'] ?: 'master';
|
||||
if ($this->gitDriver) {
|
||||
return $this->gitDriver->getRootIdentifier();
|
||||
}
|
||||
|
||||
return $this->rootIdentifier;
|
||||
}
|
||||
|
||||
|
@ -51,6 +69,9 @@ class GitHubDriver extends VcsDriver
|
|||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
if ($this->gitDriver) {
|
||||
return $this->gitDriver->getUrl();
|
||||
}
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
|
@ -59,9 +80,19 @@ class GitHubDriver extends VcsDriver
|
|||
*/
|
||||
public function getSource($identifier)
|
||||
{
|
||||
if ($this->gitDriver) {
|
||||
return $this->gitDriver->getSource($identifier);
|
||||
}
|
||||
$label = array_search($identifier, $this->getTags()) ?: $identifier;
|
||||
if ($this->isPrivate) {
|
||||
// Private GitHub repositories should be accessed using the
|
||||
// SSH version of the URL.
|
||||
$url = $this->generateSshUrl();
|
||||
} else {
|
||||
$url = $this->getUrl();
|
||||
}
|
||||
|
||||
return array('type' => 'git', 'url' => $this->getUrl(), 'reference' => $label);
|
||||
return array('type' => 'git', 'url' => $url, 'reference' => $label);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,6 +100,9 @@ class GitHubDriver extends VcsDriver
|
|||
*/
|
||||
public function getDist($identifier)
|
||||
{
|
||||
if ($this->gitDriver) {
|
||||
return $this->gitDriver->getDist($identifier);
|
||||
}
|
||||
$label = array_search($identifier, $this->getTags()) ?: $identifier;
|
||||
$url = $this->getScheme() . '://github.com/'.$this->owner.'/'.$this->repository.'/zipball/'.$label;
|
||||
|
||||
|
@ -80,6 +114,9 @@ class GitHubDriver extends VcsDriver
|
|||
*/
|
||||
public function getComposerInformation($identifier)
|
||||
{
|
||||
if ($this->gitDriver) {
|
||||
return $this->gitDriver->getComposerInformation($identifier);
|
||||
}
|
||||
if (!isset($this->infoCache[$identifier])) {
|
||||
$composer = $this->getContents($this->getScheme() . '://raw.github.com/'.$this->owner.'/'.$this->repository.'/'.$identifier.'/composer.json');
|
||||
if (!$composer) {
|
||||
|
@ -103,6 +140,9 @@ class GitHubDriver extends VcsDriver
|
|||
*/
|
||||
public function getTags()
|
||||
{
|
||||
if ($this->gitDriver) {
|
||||
return $this->gitDriver->getTags();
|
||||
}
|
||||
if (null === $this->tags) {
|
||||
$tagsData = JsonFile::parseJson($this->getContents($this->getScheme() . '://api.github.com/repos/'.$this->owner.'/'.$this->repository.'/tags'));
|
||||
$this->tags = array();
|
||||
|
@ -119,6 +159,9 @@ class GitHubDriver extends VcsDriver
|
|||
*/
|
||||
public function getBranches()
|
||||
{
|
||||
if ($this->gitDriver) {
|
||||
return $this->gitDriver->getBranches();
|
||||
}
|
||||
if (null === $this->branches) {
|
||||
$branchData = JsonFile::parseJson($this->getContents($this->getScheme() . '://api.github.com/repos/'.$this->owner.'/'.$this->repository.'/branches'));
|
||||
$this->branches = array();
|
||||
|
@ -137,4 +180,63 @@ class GitHubDriver extends VcsDriver
|
|||
{
|
||||
return extension_loaded('openssl') && preg_match('#^(?:https?|git)://github\.com/([^/]+)/(.+?)(?:\.git)?$#', $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an SSH URL
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function generateSshUrl()
|
||||
{
|
||||
return 'git@github.com:'.$this->owner.'/'.$this->repository.'.git';
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch root identifier from GitHub
|
||||
*
|
||||
* @throws TransportException
|
||||
*/
|
||||
protected function fetchRootIdentifier()
|
||||
{
|
||||
$repoDataUrl = $this->getScheme() . '://api.github.com/repos/'.$this->owner.'/'.$this->repository;
|
||||
$attemptCounter = 0;
|
||||
while (null === $this->rootIdentifier) {
|
||||
if (5 == $attemptCounter++) {
|
||||
throw new \RuntimeException("Either you have entered invalid credentials or this GitHub repository does not exists (404)");
|
||||
}
|
||||
try {
|
||||
$repoData = JsonFile::parseJson($this->getContents($repoDataUrl));
|
||||
$this->rootIdentifier = $repoData['master_branch'] ?: 'master';
|
||||
} catch (TransportException $e) {
|
||||
switch($e->getCode()) {
|
||||
case 401:
|
||||
case 404:
|
||||
$this->isPrivate = true;
|
||||
if (!$this->io->isInteractive()) {
|
||||
// If this repository may be private (hard to say for sure,
|
||||
// GitHub returns 404 for private repositories) and we
|
||||
// cannot ask for authentication credentials (because we
|
||||
// are not interactive) then we fallback to GitDriver.
|
||||
$this->gitDriver = new GitDriver(
|
||||
$this->generateSshUrl(),
|
||||
$this->io,
|
||||
$this->process,
|
||||
$this->remoteFilesystem
|
||||
);
|
||||
$this->gitDriver->initialize();
|
||||
return;
|
||||
}
|
||||
$this->io->write('Authentication required (<info>'.$this->url.'</info>):');
|
||||
$username = $this->io->ask('Username: ');
|
||||
$password = $this->io->askAndHideAnswer('Password: ');
|
||||
$this->io->setAuthorization($this->url, $username, $password);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw $e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ abstract class VcsDriver implements VcsDriverInterface
|
|||
protected $url;
|
||||
protected $io;
|
||||
protected $process;
|
||||
protected $remoteFilesystem;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
@ -34,12 +35,14 @@ abstract class VcsDriver implements VcsDriverInterface
|
|||
* @param string $url The URL
|
||||
* @param IOInterface $io The IO instance
|
||||
* @param ProcessExecutor $process Process instance, injectable for mocking
|
||||
* @param callable $remoteFilesystem Remote Filesystem, injectable for mocking
|
||||
*/
|
||||
public function __construct($url, IOInterface $io, ProcessExecutor $process = null)
|
||||
public function __construct($url, IOInterface $io, ProcessExecutor $process = null, $remoteFilesystem = null)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->io = $io;
|
||||
$this->process = $process ?: new ProcessExecutor;
|
||||
$this->remoteFilesystem = $remoteFilesystem ?: new RemoteFilesystem($io);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -80,8 +83,7 @@ abstract class VcsDriver implements VcsDriverInterface
|
|||
*/
|
||||
protected function getContents($url)
|
||||
{
|
||||
$rfs = new RemoteFilesystem($this->io);
|
||||
return $rfs->getContents($this->url, $url, false);
|
||||
return $this->remoteFilesystem->getContents($this->url, $url, false);
|
||||
}
|
||||
|
||||
protected static function isLocalUrl($url)
|
||||
|
|
|
@ -80,13 +80,11 @@ class RemoteFilesystem
|
|||
* @param string $fileUrl The file URL
|
||||
* @param string $fileName the local filename
|
||||
* @param boolean $progress Display the progression
|
||||
* @param boolean $firstCall Whether this is the first attempt at fetching this resource
|
||||
*
|
||||
* @throws TransportException When the file could not be downloaded
|
||||
*/
|
||||
protected function get($originUrl, $fileUrl, $fileName = null, $progress = true, $firstCall = true)
|
||||
protected function get($originUrl, $fileUrl, $fileName = null, $progress = true)
|
||||
{
|
||||
$this->firstCall = $firstCall;
|
||||
$this->bytesMax = 0;
|
||||
$this->result = null;
|
||||
$this->originUrl = $originUrl;
|
||||
|
@ -102,10 +100,9 @@ class RemoteFilesystem
|
|||
$this->io->write(" Downloading: <comment>connection...</comment>", false);
|
||||
}
|
||||
|
||||
if (null !== $fileName) {
|
||||
$result = @copy($fileUrl, $fileName, $ctx);
|
||||
} else {
|
||||
$result = @file_get_contents($fileUrl, false, $ctx);
|
||||
if (null !== $fileName) {
|
||||
$result = @file_put_contents($fileName, $result) ? true : false;
|
||||
}
|
||||
|
||||
// fix for 5.4.0 https://bugs.php.net/bug.php?id=61336
|
||||
|
@ -140,20 +137,12 @@ class RemoteFilesystem
|
|||
protected function callbackGet($notificationCode, $severity, $message, $messageCode, $bytesTransferred, $bytesMax)
|
||||
{
|
||||
switch ($notificationCode) {
|
||||
case STREAM_NOTIFY_AUTH_REQUIRED:
|
||||
case STREAM_NOTIFY_FAILURE:
|
||||
if (404 === $messageCode && !$this->firstCall) {
|
||||
throw new TransportException("The '" . $this->fileUrl . "' URL not found", 404);
|
||||
}
|
||||
throw new TransportException(trim($message), $messageCode);
|
||||
break;
|
||||
|
||||
// for private repository returning 404 error when the authorization is incorrect
|
||||
$auth = $this->io->getAuthorization($this->originUrl);
|
||||
$attemptAuthentication = $this->firstCall && 404 === $messageCode && null === $auth['username'];
|
||||
|
||||
$this->firstCall = false;
|
||||
|
||||
// get authorization informations
|
||||
if (401 === $messageCode || $attemptAuthentication) {
|
||||
case STREAM_NOTIFY_AUTH_REQUIRED:
|
||||
if (401 === $messageCode) {
|
||||
if (!$this->io->isInteractive()) {
|
||||
$message = "The '" . $this->fileUrl . "' URL required authentication.\nYou must be using the interactive console";
|
||||
|
||||
|
@ -165,7 +154,7 @@ class RemoteFilesystem
|
|||
$password = $this->io->askAndHideAnswer(' Password: ');
|
||||
$this->io->setAuthorization($this->originUrl, $username, $password);
|
||||
|
||||
$this->get($this->originUrl, $this->fileUrl, $this->fileName, $this->progress, false);
|
||||
$this->get($this->originUrl, $this->fileUrl, $this->fileName, $this->progress);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
function includeIfExists($file) {
|
||||
if (file_exists($file)) {
|
||||
return include $file;
|
||||
}
|
||||
}
|
||||
|
||||
if ((!$loader = includeIfExists(__DIR__.'/../../../.composer/autoload.php')) && (!$loader = includeIfExists(__DIR__.'/../vendor/.composer/autoload.php'))) {
|
||||
die('You must set up the project dependencies, run the following commands:'.PHP_EOL.
|
||||
'curl -s http://getcomposer.org/installer | php'.PHP_EOL.
|
||||
'php composer.phar install'.PHP_EOL);
|
||||
}
|
||||
|
||||
return $loader;
|
|
@ -80,7 +80,7 @@ class DefaultPolicyTest extends TestCase
|
|||
$this->assertEquals($expected, $selected);
|
||||
}
|
||||
|
||||
public function testSelectLastRepo()
|
||||
public function testSelectFirstRepo()
|
||||
{
|
||||
$this->repoImportant = new ArrayRepository;
|
||||
|
||||
|
@ -88,8 +88,8 @@ class DefaultPolicyTest extends TestCase
|
|||
$this->repoImportant->addPackage($packageAImportant = $this->getPackage('A', '1.0'));
|
||||
|
||||
$this->pool->addRepository($this->repoInstalled);
|
||||
$this->pool->addRepository($this->repo);
|
||||
$this->pool->addRepository($this->repoImportant);
|
||||
$this->pool->addRepository($this->repo);
|
||||
|
||||
$literals = array(new Literal($packageA, true), new Literal($packageAImportant, true));
|
||||
$expected = array(new Literal($packageAImportant, true));
|
||||
|
|
|
@ -54,7 +54,44 @@ class PoolTest extends TestCase
|
|||
$secondPriority = $pool->getPriority($secondRepository);
|
||||
|
||||
$this->assertEquals(0, $firstPriority);
|
||||
$this->assertEquals(1, $secondPriority);
|
||||
$this->assertEquals(-1, $secondPriority);
|
||||
}
|
||||
|
||||
public function testWhatProvidesSamePackageForDifferentRepositories()
|
||||
{
|
||||
$pool = new Pool;
|
||||
$firstRepository = new ArrayRepository;
|
||||
$secondRepository = new ArrayRepository;
|
||||
|
||||
$firstPackage = $this->getPackage('foo', '1');
|
||||
$secondPackage = $this->getPackage('foo', '1');
|
||||
$thirdPackage = $this->getPackage('foo', '2');
|
||||
|
||||
$firstRepository->addPackage($firstPackage);
|
||||
$secondRepository->addPackage($secondPackage);
|
||||
$secondRepository->addPackage($thirdPackage);
|
||||
|
||||
$pool->addRepository($firstRepository);
|
||||
$pool->addRepository($secondRepository);
|
||||
|
||||
$this->assertEquals(array($firstPackage, $secondPackage, $thirdPackage), $pool->whatProvides('foo'));
|
||||
}
|
||||
|
||||
public function testWhatProvidesPackageWithConstraint()
|
||||
{
|
||||
$pool = new Pool;
|
||||
$repository = new ArrayRepository;
|
||||
|
||||
$firstPackage = $this->getPackage('foo', '1');
|
||||
$secondPackage = $this->getPackage('foo', '2');
|
||||
|
||||
$repository->addPackage($firstPackage);
|
||||
$repository->addPackage($secondPackage);
|
||||
|
||||
$pool->addRepository($repository);
|
||||
|
||||
$this->assertEquals(array($firstPackage, $secondPackage), $pool->whatProvides('foo'));
|
||||
$this->assertEquals(array($secondPackage), $pool->whatProvides('foo', $this->getVersionConstraint('==', '2')));
|
||||
}
|
||||
|
||||
public function testPackageById()
|
||||
|
|
|
@ -47,6 +47,32 @@ class RequestTest extends TestCase
|
|||
$request->getJobs());
|
||||
}
|
||||
|
||||
public function testRequestInstallSamePackageFromDifferentRepositories()
|
||||
{
|
||||
$pool = new Pool;
|
||||
$repo1 = new ArrayRepository;
|
||||
$repo2 = new ArrayRepository;
|
||||
|
||||
$foo1 = $this->getPackage('foo', '1');
|
||||
$foo2 = $this->getPackage('foo', '1');
|
||||
|
||||
$repo1->addPackage($foo1);
|
||||
$repo2->addPackage($foo2);
|
||||
|
||||
$pool->addRepository($repo1);
|
||||
$pool->addRepository($repo2);
|
||||
|
||||
$request = new Request($pool);
|
||||
$request->install('foo', $this->getVersionConstraint('=', '1'));
|
||||
|
||||
$this->assertEquals(
|
||||
array(
|
||||
array('packages' => array($foo1, $foo2), 'cmd' => 'install', 'packageName' => 'foo'),
|
||||
),
|
||||
$request->getJobs()
|
||||
);
|
||||
}
|
||||
|
||||
public function testUpdateAll()
|
||||
{
|
||||
$pool = new Pool;
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Test\DependencyResolver;
|
||||
|
||||
use Composer\Repository\ArrayRepository;
|
||||
|
@ -70,6 +69,25 @@ class SolverTest extends TestCase
|
|||
}
|
||||
}
|
||||
|
||||
public function testSolverInstallSamePackageFromDifferentRepositories()
|
||||
{
|
||||
$repo1 = new ArrayRepository;
|
||||
$repo2 = new ArrayRepository;
|
||||
|
||||
$repo1->addPackage($foo1 = $this->getPackage('foo', '1'));
|
||||
$repo2->addPackage($foo2 = $this->getPackage('foo', '1'));
|
||||
|
||||
$this->pool->addRepository($this->repoInstalled);
|
||||
$this->pool->addRepository($repo1);
|
||||
$this->pool->addRepository($repo2);
|
||||
|
||||
$this->request->install('foo');
|
||||
|
||||
$this->checkSolverResult(array(
|
||||
array('job' => 'install', 'package' => $foo1),
|
||||
));
|
||||
}
|
||||
|
||||
public function testSolverInstallWithDeps()
|
||||
{
|
||||
$this->repo->addPackage($packageA = $this->getPackage('A', '1.0'));
|
||||
|
|
|
@ -17,6 +17,13 @@ use Composer\Util\Filesystem;
|
|||
|
||||
class FileDownloaderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected function getDownloader($io = null, $rfs = null)
|
||||
{
|
||||
$io = $io ?: $this->getMock('Composer\IO\IOInterface');
|
||||
$rfs = $rfs ?: $this->getMockBuilder('Composer\Util\RemoteFilesystem')->disableOriginalConstructor()->getMock();
|
||||
return new FileDownloader($io, $rfs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
|
@ -28,7 +35,7 @@ class FileDownloaderTest extends \PHPUnit_Framework_TestCase
|
|||
->will($this->returnValue(null))
|
||||
;
|
||||
|
||||
$downloader = new FileDownloader($this->getMock('Composer\IO\IOInterface'));
|
||||
$downloader = $this->getDownloader();
|
||||
$downloader->download($packageMock, '/path');
|
||||
}
|
||||
|
||||
|
@ -42,7 +49,7 @@ class FileDownloaderTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
$path = tempnam(sys_get_temp_dir(), 'c');
|
||||
|
||||
$downloader = new FileDownloader($this->getMock('Composer\IO\IOInterface'));
|
||||
$downloader = $this->getDownloader();
|
||||
try {
|
||||
$downloader->download($packageMock, $path);
|
||||
$this->fail();
|
||||
|
@ -63,7 +70,7 @@ class FileDownloaderTest extends \PHPUnit_Framework_TestCase
|
|||
->will($this->returnValue('http://example.com/script.js'))
|
||||
;
|
||||
|
||||
$downloader = new FileDownloader($this->getMock('Composer\IO\IOInterface'));
|
||||
$downloader = $this->getDownloader();
|
||||
$method = new \ReflectionMethod($downloader, 'getFileName');
|
||||
$method->setAccessible(true);
|
||||
|
||||
|
@ -93,7 +100,7 @@ class FileDownloaderTest extends \PHPUnit_Framework_TestCase
|
|||
}))
|
||||
;
|
||||
|
||||
$downloader = new FileDownloader($ioMock);
|
||||
$downloader = $this->getDownloader($ioMock);
|
||||
try {
|
||||
$downloader->download($packageMock, $path);
|
||||
$this->fail();
|
||||
|
@ -126,7 +133,12 @@ class FileDownloaderTest extends \PHPUnit_Framework_TestCase
|
|||
$path = sys_get_temp_dir().'/'.md5(time().rand());
|
||||
} while (file_exists($path));
|
||||
|
||||
$downloader = new FileDownloader($this->getMock('Composer\IO\IOInterface'));
|
||||
$downloader = $this->getDownloader();
|
||||
|
||||
// make sure the file expected to be downloaded is on disk already
|
||||
mkdir($path, 0777, true);
|
||||
touch($path.'/script.js');
|
||||
|
||||
try {
|
||||
$downloader->download($packageMock, $path);
|
||||
$this->fail();
|
||||
|
|
|
@ -41,7 +41,6 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
public function testDownload()
|
||||
{
|
||||
$expectedGitCommand = $this->getCmd("git clone 'https://example.com/composer/composer' 'composerPath' && cd 'composerPath' && git checkout 'ref' && git reset --hard 'ref'");
|
||||
$packageMock = $this->getMock('Composer\Package\PackageInterface');
|
||||
$packageMock->expects($this->any())
|
||||
->method('getSourceReference')
|
||||
|
@ -50,6 +49,8 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase
|
|||
->method('getSourceUrl')
|
||||
->will($this->returnValue('https://example.com/composer/composer'));
|
||||
$processExecutor = $this->getMock('Composer\Util\ProcessExecutor');
|
||||
|
||||
$expectedGitCommand = $this->getCmd("git clone 'https://example.com/composer/composer' 'composerPath' && cd 'composerPath' && git checkout 'ref' && git reset --hard 'ref'");
|
||||
$processExecutor->expects($this->once())
|
||||
->method('execute')
|
||||
->with($this->equalTo($expectedGitCommand))
|
||||
|
@ -59,13 +60,13 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase
|
|||
$downloader->download($packageMock, 'composerPath');
|
||||
}
|
||||
|
||||
public function testDownloadUsesVariousProtocolsForGithub()
|
||||
public function testDownloadUsesVariousProtocolsAndSetsPushUrlForGithub()
|
||||
{
|
||||
$packageMock = $this->getMock('Composer\Package\PackageInterface');
|
||||
$packageMock->expects($this->any())
|
||||
->method('getSourceReference')
|
||||
->will($this->returnValue('ref'));
|
||||
$packageMock->expects($this->once())
|
||||
$packageMock->expects($this->any())
|
||||
->method('getSourceUrl')
|
||||
->will($this->returnValue('https://github.com/composer/composer'));
|
||||
$processExecutor = $this->getMock('Composer\Util\ProcessExecutor');
|
||||
|
@ -88,6 +89,12 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase
|
|||
->with($this->equalTo($expectedGitCommand))
|
||||
->will($this->returnValue(0));
|
||||
|
||||
$expectedGitCommand = $this->getCmd("cd 'composerPath' && git remote set-url --push origin 'git@github.com:composer/composer.git'");
|
||||
$processExecutor->expects($this->at(3))
|
||||
->method('execute')
|
||||
->with($this->equalTo($expectedGitCommand))
|
||||
->will($this->returnValue(0));
|
||||
|
||||
$downloader = $this->getDownloaderMock(null, $processExecutor);
|
||||
$downloader->download($packageMock, 'composerPath');
|
||||
}
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
<?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;
|
||||
|
||||
use Composer\Factory;
|
||||
|
||||
class FactoryTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider dataAddPackagistRepository
|
||||
*/
|
||||
public function testAddPackagistRepository($expected, $config)
|
||||
{
|
||||
$factory = new Factory();
|
||||
|
||||
$ref = new \ReflectionMethod($factory, 'addPackagistRepository');
|
||||
$ref->setAccessible(true);
|
||||
|
||||
$this->assertEquals($expected, $ref->invoke($factory, $config));
|
||||
}
|
||||
|
||||
public function dataAddPackagistRepository()
|
||||
{
|
||||
$f = function() {
|
||||
$repositories = func_get_args();
|
||||
return array('repositories' => $repositories);
|
||||
};
|
||||
|
||||
$data = array();
|
||||
$data[] = array(
|
||||
$f(array('type' => 'composer', 'url' => 'http://packagist.org')),
|
||||
$f()
|
||||
);
|
||||
|
||||
$data[] = array(
|
||||
$f(array('packagist' => false)),
|
||||
$f(array('packagist' => false))
|
||||
);
|
||||
|
||||
$data[] = array(
|
||||
$f(
|
||||
array('type' => 'vcs', 'url' => 'git://github.com/composer/composer.git'),
|
||||
array('type' => 'composer', 'url' => 'http://packagist.org'),
|
||||
array('type' => 'pear', 'url' => 'http://pear.composer.org')
|
||||
),
|
||||
$f(
|
||||
array('type' => 'vcs', 'url' => 'git://github.com/composer/composer.git'),
|
||||
array('packagist' => true),
|
||||
array('type' => 'pear', 'url' => 'http://pear.composer.org')
|
||||
)
|
||||
);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,234 @@
|
|||
<?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\Repository\Vcs;
|
||||
|
||||
use Composer\Downloader\TransportException;
|
||||
use Composer\Repository\Vcs\GitHubDriver;
|
||||
use Composer\Util\Filesystem;
|
||||
|
||||
/**
|
||||
* @author Beau Simensen <beau@dflydev.com>
|
||||
*/
|
||||
class GitHubDriverTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testPrivateRepository()
|
||||
{
|
||||
$scheme = extension_loaded('openssl') ? 'https' : 'http';
|
||||
|
||||
$repoUrl = 'http://github.com/composer/packagist';
|
||||
$repoApiUrl = $scheme.'://api.github.com/repos/composer/packagist';
|
||||
$repoSshUrl = 'git@github.com:composer/packagist.git';
|
||||
$identifier = 'v0.0.0';
|
||||
$sha = 'SOMESHA';
|
||||
|
||||
$io = $this->getMock('Composer\IO\IOInterface');
|
||||
$io->expects($this->any())
|
||||
->method('isInteractive')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem')
|
||||
->setConstructorArgs(array($io))
|
||||
->getMock();
|
||||
|
||||
$remoteFilesystem->expects($this->at(0))
|
||||
->method('getContents')
|
||||
->with($this->equalTo($repoUrl), $this->equalTo($repoApiUrl), $this->equalTo(false))
|
||||
->will($this->throwException(new TransportException('HTTP/1.1 404 Not Found', 404)));
|
||||
|
||||
$io->expects($this->once())
|
||||
->method('ask')
|
||||
->with($this->equalTo('Username: '))
|
||||
->will($this->returnValue('someuser'));
|
||||
|
||||
$io->expects($this->once())
|
||||
->method('askAndHideAnswer')
|
||||
->with($this->equalTo('Password: '))
|
||||
->will($this->returnValue('somepassword'));
|
||||
|
||||
$io->expects($this->once())
|
||||
->method('setAuthorization')
|
||||
->with($this->equalTo($repoUrl), 'someuser', 'somepassword');
|
||||
|
||||
$remoteFilesystem->expects($this->at(1))
|
||||
->method('getContents')
|
||||
->with($this->equalTo($repoUrl), $this->equalTo($repoApiUrl), $this->equalTo(false))
|
||||
->will($this->returnValue('{"master_branch": "test_master"}'));
|
||||
|
||||
$gitHubDriver = new GitHubDriver($repoUrl, $io, null, $remoteFilesystem);
|
||||
$gitHubDriver->initialize();
|
||||
$this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha));
|
||||
|
||||
$this->assertEquals('test_master', $gitHubDriver->getRootIdentifier());
|
||||
|
||||
$dist = $gitHubDriver->getDist($identifier);
|
||||
$this->assertEquals('zip', $dist['type']);
|
||||
$this->assertEquals($scheme.'://github.com/composer/packagist/zipball/v0.0.0', $dist['url']);
|
||||
$this->assertEquals('v0.0.0', $dist['reference']);
|
||||
|
||||
$source = $gitHubDriver->getSource($identifier);
|
||||
$this->assertEquals('git', $source['type']);
|
||||
$this->assertEquals($repoSshUrl, $source['url']);
|
||||
$this->assertEquals('v0.0.0', $source['reference']);
|
||||
|
||||
$dist = $gitHubDriver->getDist($sha);
|
||||
$this->assertEquals('zip', $dist['type']);
|
||||
$this->assertEquals($scheme.'://github.com/composer/packagist/zipball/v0.0.0', $dist['url']);
|
||||
$this->assertEquals('v0.0.0', $dist['reference']);
|
||||
|
||||
$source = $gitHubDriver->getSource($sha);
|
||||
$this->assertEquals('git', $source['type']);
|
||||
$this->assertEquals($repoSshUrl, $source['url']);
|
||||
$this->assertEquals('v0.0.0', $source['reference']);
|
||||
}
|
||||
|
||||
public function testPublicRepository()
|
||||
{
|
||||
$scheme = extension_loaded('openssl') ? 'https' : 'http';
|
||||
|
||||
$repoUrl = 'http://github.com/composer/packagist';
|
||||
$repoApiUrl = $scheme.'://api.github.com/repos/composer/packagist';
|
||||
$identifier = 'v0.0.0';
|
||||
$sha = 'SOMESHA';
|
||||
|
||||
$io = $this->getMock('Composer\IO\IOInterface');
|
||||
$io->expects($this->any())
|
||||
->method('isInteractive')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem')
|
||||
->setConstructorArgs(array($io))
|
||||
->getMock();
|
||||
|
||||
$remoteFilesystem->expects($this->at(0))
|
||||
->method('getContents')
|
||||
->with($this->equalTo($repoUrl), $this->equalTo($repoApiUrl), $this->equalTo(false))
|
||||
->will($this->returnValue('{"master_branch": "test_master"}'));
|
||||
|
||||
$gitHubDriver = new GitHubDriver($repoUrl, $io, null, $remoteFilesystem);
|
||||
$gitHubDriver->initialize();
|
||||
$this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha));
|
||||
|
||||
$this->assertEquals('test_master', $gitHubDriver->getRootIdentifier());
|
||||
|
||||
$dist = $gitHubDriver->getDist($identifier);
|
||||
$this->assertEquals('zip', $dist['type']);
|
||||
$this->assertEquals($scheme.'://github.com/composer/packagist/zipball/v0.0.0', $dist['url']);
|
||||
$this->assertEquals($identifier, $dist['reference']);
|
||||
|
||||
$source = $gitHubDriver->getSource($identifier);
|
||||
$this->assertEquals('git', $source['type']);
|
||||
$this->assertEquals($repoUrl, $source['url']);
|
||||
$this->assertEquals($identifier, $source['reference']);
|
||||
|
||||
$dist = $gitHubDriver->getDist($sha);
|
||||
$this->assertEquals('zip', $dist['type']);
|
||||
$this->assertEquals($scheme.'://github.com/composer/packagist/zipball/v0.0.0', $dist['url']);
|
||||
$this->assertEquals($identifier, $dist['reference']);
|
||||
|
||||
$source = $gitHubDriver->getSource($sha);
|
||||
$this->assertEquals('git', $source['type']);
|
||||
$this->assertEquals($repoUrl, $source['url']);
|
||||
$this->assertEquals($identifier, $source['reference']);
|
||||
}
|
||||
|
||||
public function testPrivateRepositoryNoInteraction()
|
||||
{
|
||||
$scheme = extension_loaded('openssl') ? 'https' : 'http';
|
||||
|
||||
$repoUrl = 'http://github.com/composer/packagist';
|
||||
$repoApiUrl = $scheme.'://api.github.com/repos/composer/packagist';
|
||||
$repoSshUrl = 'git@github.com:composer/packagist.git';
|
||||
$identifier = 'v0.0.0';
|
||||
$sha = 'SOMESHA';
|
||||
|
||||
$process = $this->getMockBuilder('Composer\Util\ProcessExecutor')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$io = $this->getMock('Composer\IO\IOInterface');
|
||||
$io->expects($this->any())
|
||||
->method('isInteractive')
|
||||
->will($this->returnValue(false));
|
||||
|
||||
$remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem')
|
||||
->setConstructorArgs(array($io))
|
||||
->getMock();
|
||||
|
||||
$remoteFilesystem->expects($this->at(0))
|
||||
->method('getContents')
|
||||
->with($this->equalTo($repoUrl), $this->equalTo($repoApiUrl), $this->equalTo(false))
|
||||
->will($this->throwException(new TransportException('HTTP/1.1 404 Not Found', 404)));
|
||||
|
||||
// clean local clone if present
|
||||
$fs = new Filesystem();
|
||||
$fs->removeDirectory(sys_get_temp_dir() . '/composer-' . preg_replace('{[^a-z0-9]}i', '-', $repoSshUrl) . '/');
|
||||
|
||||
$process->expects($this->at(0))
|
||||
->method('execute')
|
||||
->with($this->stringContains($repoSshUrl));
|
||||
|
||||
$process->expects($this->at(1))
|
||||
->method('execute')
|
||||
->with($this->stringContains('git tag'));
|
||||
|
||||
$process->expects($this->at(2))
|
||||
->method('splitLines')
|
||||
->will($this->returnValue(array($identifier)));
|
||||
|
||||
$process->expects($this->at(3))
|
||||
->method('execute')
|
||||
->with($this->stringContains('git branch'));
|
||||
|
||||
$process->expects($this->at(4))
|
||||
->method('splitLines')
|
||||
->will($this->returnValue(array(' test_master edf93f1fccaebd8764383dc12016d0a1a9672d89 Fix test & behavior')));
|
||||
|
||||
$process->expects($this->at(5))
|
||||
->method('execute')
|
||||
->with($this->stringContains('git branch'));
|
||||
|
||||
$process->expects($this->at(6))
|
||||
->method('splitLines')
|
||||
->will($this->returnValue(array(' upstream/HEAD -> upstream/test_master')));
|
||||
|
||||
$gitHubDriver = new GitHubDriver($repoUrl, $io, $process, $remoteFilesystem);
|
||||
$gitHubDriver->initialize();
|
||||
|
||||
$this->assertEquals('test_master', $gitHubDriver->getRootIdentifier());
|
||||
|
||||
// Dist is not available for GitDriver
|
||||
$dist = $gitHubDriver->getDist($identifier);
|
||||
$this->assertNull($dist);
|
||||
|
||||
$source = $gitHubDriver->getSource($identifier);
|
||||
$this->assertEquals('git', $source['type']);
|
||||
$this->assertEquals($repoSshUrl, $source['url']);
|
||||
$this->assertEquals($identifier, $source['reference']);
|
||||
|
||||
// Dist is not available for GitDriver
|
||||
$dist = $gitHubDriver->getDist($sha);
|
||||
$this->assertNull($dist);
|
||||
|
||||
$source = $gitHubDriver->getSource($sha);
|
||||
$this->assertEquals('git', $source['type']);
|
||||
$this->assertEquals($repoSshUrl, $source['url']);
|
||||
$this->assertEquals($sha, $source['reference']);
|
||||
}
|
||||
|
||||
protected function setAttribute($object, $attribute, $value)
|
||||
{
|
||||
$attr = new \ReflectionProperty($object, $attribute);
|
||||
$attr->setAccessible(true);
|
||||
$attr->setValue($object, $value);
|
||||
}
|
||||
}
|
|
@ -105,41 +105,14 @@ class RemoteFilesystemTest extends \PHPUnit_Framework_TestCase
|
|||
public function testCallbackGetNotifyFailure404()
|
||||
{
|
||||
$fs = new RemoteFilesystem($this->getMock('Composer\IO\IOInterface'));
|
||||
$this->setAttribute($fs, 'firstCall', false);
|
||||
|
||||
try {
|
||||
$this->callCallbackGet($fs, STREAM_NOTIFY_FAILURE, 0, '', 404, 0, 0);
|
||||
$this->callCallbackGet($fs, STREAM_NOTIFY_FAILURE, 0, 'HTTP/1.1 404 Not Found', 404, 0, 0);
|
||||
$this->fail();
|
||||
} catch (\Exception $e) {
|
||||
$this->assertInstanceOf('Composer\Downloader\TransportException', $e);
|
||||
$this->assertContains('URL not found', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function testCallbackGetNotifyFailure404FirstCall()
|
||||
{
|
||||
$io = $this->getMock('Composer\IO\IOInterface');
|
||||
$io
|
||||
->expects($this->once())
|
||||
->method('getAuthorization')
|
||||
->will($this->returnValue(array('username' => null)))
|
||||
;
|
||||
$io
|
||||
->expects($this->once())
|
||||
->method('isInteractive')
|
||||
->will($this->returnValue(false))
|
||||
;
|
||||
|
||||
$fs = new RemoteFilesystem($io);
|
||||
$this->setAttribute($fs, 'firstCall', true);
|
||||
|
||||
try {
|
||||
$this->callCallbackGet($fs, STREAM_NOTIFY_FAILURE, 0, '', 404, 0, 0);
|
||||
$this->fail();
|
||||
} catch (\Exception $e) {
|
||||
$this->assertInstanceOf('Composer\Downloader\TransportException', $e);
|
||||
$this->assertContains('URL required authentication', $e->getMessage());
|
||||
$this->assertAttributeEquals(false, 'firstCall', $fs);
|
||||
$this->assertEquals(404, $e->getCode());
|
||||
$this->assertContains('HTTP/1.1 404 Not Found', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,10 +10,5 @@
|
|||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
if ((!$loader = @include __DIR__.'/../../../.composer/autoload.php') && (!$loader = @include __DIR__.'/../vendor/.composer/autoload.php')) {
|
||||
die('You must set up the project dependencies, run the following commands:'.PHP_EOL.
|
||||
'curl -s http://getcomposer.org/installer | php'.PHP_EOL.
|
||||
'php composer.phar install'.PHP_EOL);
|
||||
}
|
||||
|
||||
$loader = require __DIR__.'/../src/bootstrap.php';
|
||||
$loader->add('Composer\Test', __DIR__);
|
||||
|
|
Loading…
Reference in New Issue