Merge branch 'master' of git://github.com/composer/composer
Conflicts: src/Composer/Repository/PearRepository.phppull/658/head
commit
4b3fc2b5fa
63
CHANGELOG.md
63
CHANGELOG.md
|
@ -1,28 +1,35 @@
|
|||
* 1.0.0-alpha3
|
||||
|
||||
* Schema: Added 'require-dev' for development-time requirements (tests, etc), install with --dev
|
||||
* Schema: Removed 'recommend'
|
||||
* Schema: 'suggest' is now informational and can use any description for a package, not only a constraint
|
||||
* Added caching of repository metadata (faster startup times & failover if packagist is down)
|
||||
* Added include_path support for legacy projects that are full of require_once statements
|
||||
* Added installation notifications API to allow better statistics on Composer repositories
|
||||
* Improved repository protocol to have large cacheable parts
|
||||
|
||||
* 1.0.0-alpha2 (2012-04-03)
|
||||
|
||||
* Added `create-project` command to install a project from scratch with composer
|
||||
* Added automated `classmap` autoloading support for non-PSR-0 compliant projects
|
||||
* Added human readable error reporting when deps can not be solved
|
||||
* Added support for private GitHub and SVN repositories (use --no-interaction for CI)
|
||||
* Added "file" downloader type to download plain files
|
||||
* Added support for authentication with svn repositories
|
||||
* Added autoload support for PEAR repositories
|
||||
* Improved clones from GitHub which now automatically select between git/https/http protocols
|
||||
* Improved `validate` command to give more feedback
|
||||
* Improved the `search` & `show` commands output
|
||||
* Removed dependency on filter_var
|
||||
* Various robustness & error handling improvements, docs fixes and more bug fixes
|
||||
|
||||
* 1.0.0-alpha1 (2012-03-01)
|
||||
|
||||
* Initial release
|
||||
* 1.0.0-alpha3
|
||||
|
||||
* Schema: Added 'require-dev' for development-time requirements (tests, etc), install with --dev
|
||||
* Schema: Removed 'recommend'
|
||||
* Schema: 'suggest' is now informational and can use any description for a package, not only a constraint
|
||||
* Break: vendor/.composer/autoload.php has been moved to vendor/autoload.php, other files are now in vendor/composer/
|
||||
* Added caching of repository metadata (faster startup times & failover if packagist is down)
|
||||
* Added removal of packages that are not needed anymore
|
||||
* Added include_path support for legacy projects that are full of require_once statements
|
||||
* Added installation notifications API to allow better statistics on Composer repositories
|
||||
* Added autoloading support for root packages that use target-dir
|
||||
* Added awareness of the root package presence and support for it's provide/replace/conflict keys
|
||||
* Added IOInterface::isDecorated to test for colored output support
|
||||
* Improved repository protocol to have large cacheable parts
|
||||
* Fixed various bugs relating to package aliasing, proxy configuration, binaries
|
||||
* Various bug fixes and docs improvements
|
||||
|
||||
* 1.0.0-alpha2 (2012-04-03)
|
||||
|
||||
* Added `create-project` command to install a project from scratch with composer
|
||||
* Added automated `classmap` autoloading support for non-PSR-0 compliant projects
|
||||
* Added human readable error reporting when deps can not be solved
|
||||
* Added support for private GitHub and SVN repositories (use --no-interaction for CI)
|
||||
* Added "file" downloader type to download plain files
|
||||
* Added support for authentication with svn repositories
|
||||
* Added autoload support for PEAR repositories
|
||||
* Improved clones from GitHub which now automatically select between git/https/http protocols
|
||||
* Improved `validate` command to give more feedback
|
||||
* Improved the `search` & `show` commands output
|
||||
* Removed dependency on filter_var
|
||||
* Various robustness & error handling improvements, docs fixes and more bug fixes
|
||||
|
||||
* 1.0.0-alpha1 (2012-03-01)
|
||||
|
||||
* Initial release
|
||||
|
|
|
@ -12,19 +12,19 @@
|
|||
{
|
||||
"package": "symfony/console",
|
||||
"version": "dev-master",
|
||||
"source-reference": "8e3c42aa976f18a9bfcb0694553e5f99def3309c",
|
||||
"source-reference": "eaad4427b10ff39402bce0ae4f8cd1faf2b6532a",
|
||||
"alias": "2.1.9999999.9999999-dev"
|
||||
},
|
||||
{
|
||||
"package": "symfony/finder",
|
||||
"version": "dev-master",
|
||||
"source-reference": "57ec7198a70e6c40e450ba66cc2f8ecab98746c8",
|
||||
"source-reference": "78b2e33951821b6d423718f57788f1894dcb935a",
|
||||
"alias": "2.1.9999999.9999999-dev"
|
||||
},
|
||||
{
|
||||
"package": "symfony/process",
|
||||
"version": "dev-master",
|
||||
"source-reference": "2e4da8c8076744bafed97451bb1574c96cda0e68",
|
||||
"source-reference": "718655f4bc664d693b33f3e6e8a895e454208021",
|
||||
"alias": "2.1.9999999.9999999-dev"
|
||||
}
|
||||
],
|
||||
|
|
|
@ -67,7 +67,7 @@ executable and invoke it without `php`.
|
|||
|
||||
### Using Composer
|
||||
|
||||
Next, run the command the `install` command to resolve and download dependencies:
|
||||
Next, run the `install` command to resolve and download dependencies:
|
||||
|
||||
$ php composer.phar install
|
||||
|
||||
|
@ -80,7 +80,7 @@ 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';
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
Woh! Now start using monolog! To keep learning more about Composer, keep
|
||||
reading the "Basic Usage" chapter.
|
||||
|
|
|
@ -108,7 +108,7 @@ same version of the dependencies.
|
|||
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.
|
||||
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.
|
||||
|
@ -136,10 +136,10 @@ but it makes life quite a bit simpler.
|
|||
## Autoloading
|
||||
|
||||
For libraries that specify autoload information, Composer generates a
|
||||
`vendor/.composer/autoload.php` file. You can simply include this file and you
|
||||
`vendor/autoload.php` file. You can simply include this file and you
|
||||
will get autoloading for free.
|
||||
|
||||
require 'vendor/.composer/autoload.php';
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
This makes it really easy to use third party code. For example: If your
|
||||
project depends on monolog, you can just start using classes from it, and they
|
||||
|
@ -168,13 +168,13 @@ be in your project root. An example filename would be `src/Acme/Foo.php`
|
|||
containing an `Acme\Foo` class.
|
||||
|
||||
After adding the `autoload` field, you have to re-run `install` to re-generate
|
||||
the `vendor/.composer/autoload.php` file.
|
||||
the `vendor/autoload.php` file.
|
||||
|
||||
Including that file will also return the autoloader instance, so you can store
|
||||
the return value of the include call in a variable and add more namespaces.
|
||||
This can be useful for autoloading classes in a test suite, for example.
|
||||
|
||||
$loader = require 'vendor/.composer/autoload.php';
|
||||
$loader = require 'vendor/autoload.php';
|
||||
$loader->add('Acme\Test', __DIR__);
|
||||
|
||||
In addition to PSR-0 autoloading, classmap is also supported. This allows
|
||||
|
@ -182,7 +182,7 @@ classes to be autoloaded even if they do not conform to PSR-0. See the
|
|||
[autoload reference](04-schema.md#autoload) for more details.
|
||||
|
||||
> **Note:** Composer provides its own autoloader. If you don't want to use
|
||||
that one, you can just include `vendor/.composer/autoload_namespaces.php`,
|
||||
that one, you can just include `vendor/autoload_namespaces.php`,
|
||||
which returns an associative array mapping namespaces to directories.
|
||||
|
||||
← [Intro](00-intro.md) | [Libraries](02-libraries.md) →
|
||||
|
|
|
@ -62,20 +62,29 @@ Here are a few examples of valid tag names:
|
|||
|
||||
For every branch, a package development version will be created. If the branch
|
||||
name looks like a version, the version will be `{branchname}-dev`. For example
|
||||
a branch `2.0` will get a version `2.0-dev`. If the branch does not look like
|
||||
a version, it will be `dev-{branchname}`. `master` results in a `dev-master`
|
||||
version.
|
||||
a branch `2.0` will get a version `2.0.x-dev` (the `.x` is added for technical
|
||||
reasons, to make sure it is recognized as a branch, a `2.0.x` branch would also
|
||||
be valid and be turned into `2.0.x-dev` as well. If the branch does not look
|
||||
like a version, it will be `dev-{branchname}`. `master` results in a
|
||||
`dev-master` version.
|
||||
|
||||
Here are some examples of version branch names:
|
||||
|
||||
1.0
|
||||
1.*
|
||||
1.x
|
||||
1.0 (equals 1.0.x)
|
||||
1.1.x
|
||||
1.1.*
|
||||
|
||||
> **Note:** When you install a dev version, it will install it from source.
|
||||
See [Repositories](05-repositories.md) for more information.
|
||||
|
||||
### Aliases
|
||||
|
||||
It is possible alias branch names to versions. For example, you could alias
|
||||
`dev-master` to `1.0.x-dev`, which would allow you to require `1.0.x-dev` in all
|
||||
the packages.
|
||||
|
||||
See [Aliases](articles/aliases.md) for more information.
|
||||
|
||||
## Lock file
|
||||
|
||||
For your library you may commit the `composer.lock` file if you want to. This
|
||||
|
|
|
@ -199,11 +199,6 @@ directory other than `vendor`.
|
|||
By setting this option you can change the `bin` ([Vendor Bins](articles/vendor-bins.md))
|
||||
directory to something other than `vendor/bin`.
|
||||
|
||||
### COMPOSER_PROCESS_TIMEOUT
|
||||
|
||||
This env var controls the time composer waits for commands (such as git
|
||||
commands) to finish executing. The default value is 60 seconds.
|
||||
|
||||
### http_proxy or HTTP_PROXY
|
||||
|
||||
If you are using composer from behind an HTTP proxy, you can use the standard
|
||||
|
@ -215,4 +210,19 @@ 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_HOME
|
||||
|
||||
The `COMPOSER_HOME` var allows you to change the composer home directory. This
|
||||
is a hidden, global (per-user on the machine) directory that is shared between
|
||||
all projects.
|
||||
|
||||
By default it points to `/home/<user>/.composer` on *nix,
|
||||
`/Users/<user>/.composer` on OSX and
|
||||
`C:\Users\<user>\AppData\Roaming\Composer` on Windows.
|
||||
|
||||
### 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).
|
||||
|
||||
← [Libraries](02-libraries.md) | [Schema](04-schema.md) →
|
||||
|
|
|
@ -145,6 +145,7 @@ Each author object can have following properties:
|
|||
* **name:** The author's name. Usually his real name.
|
||||
* **email:** The author's email address.
|
||||
* **homepage:** An URL to the author's website.
|
||||
* **role:** The authors' role in the project (e.g. developer or translator)
|
||||
|
||||
An example:
|
||||
|
||||
|
@ -153,12 +154,14 @@ An example:
|
|||
{
|
||||
"name": "Nils Adermann",
|
||||
"email": "naderman@naderman.de",
|
||||
"homepage": "http://www.naderman.de"
|
||||
"homepage": "http://www.naderman.de",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
"homepage": "http://seld.be",
|
||||
"role": "Developer"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -215,21 +218,26 @@ Example:
|
|||
Autoload mapping for a PHP autoloader.
|
||||
|
||||
Currently [PSR-0](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md)
|
||||
autoloading and classmap generation are supported.
|
||||
autoloading and classmap generation are supported. PSR-0 is the recommended way though
|
||||
since it offers greater flexibility (no need to regenerate the autoloader when you add
|
||||
classes).
|
||||
|
||||
Under the `psr-0` key you define a mapping from namespaces to paths, relative to the
|
||||
package root.
|
||||
package root. Note that this also supports the PEAR-style convention.
|
||||
|
||||
Example:
|
||||
|
||||
{
|
||||
"autoload": {
|
||||
"psr-0": { "Monolog": "src/" }
|
||||
"psr-0": {
|
||||
"Monolog": "src/",
|
||||
"Vendor\\Namespace": "src/",
|
||||
"Pear_Style": "src/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Optional, but it is highly recommended that you follow PSR-0 and use this.
|
||||
If you need to search for a same namespace prefix in multiple directories,
|
||||
If you need to search for a same prefix in multiple directories,
|
||||
you can specify them as an array as such:
|
||||
|
||||
{
|
||||
|
@ -238,15 +246,24 @@ you can specify them as an array as such:
|
|||
}
|
||||
}
|
||||
|
||||
If you want to have a fallback directory where any namespace can be, you can
|
||||
use an empty prefix like:
|
||||
|
||||
{
|
||||
"autoload": {
|
||||
"psr-0": { "": "src/" }
|
||||
}
|
||||
}
|
||||
|
||||
You can use the classmap generation support to define autoloading for all libraries
|
||||
that do not follow PSR-0. To configure this you specify all directories
|
||||
that do not follow PSR-0. To configure this you specify all directories or files
|
||||
to search for classes.
|
||||
|
||||
Example:
|
||||
|
||||
{
|
||||
"autoload: {
|
||||
"classmap": ["src/", "lib/"]
|
||||
"classmap": ["src/", "lib/", "Something.php"]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -368,6 +385,9 @@ The following options are supported:
|
|||
* **process-timeout:** Defaults to `300`. The duration processes like git clones
|
||||
can run before Composer assumes they died out. You may need to make this
|
||||
higher if you have a slow connection or huge vendors.
|
||||
* **notify-on-install:** Defaults to `true`. Composer allows repositories to
|
||||
define a notification URL, so that they get notified whenever a package from
|
||||
that repository is installed. This option allows you to disable that behaviour.
|
||||
|
||||
Example:
|
||||
|
||||
|
|
|
@ -54,15 +54,24 @@ want to learn why.
|
|||
### Composer
|
||||
|
||||
The main repository type is the `composer` repository. It uses a single
|
||||
`packages.json` file that contains all of the package metadata. The JSON
|
||||
format is as follows:
|
||||
`packages.json` file that contains all of the package metadata.
|
||||
|
||||
This is also the repository type that packagist uses. To reference a
|
||||
`composer` repository, just supply the path before the `packages.json` file.
|
||||
In case of packagist, that file is located at `/packages.json`, so the URL of
|
||||
the repository would be `packagist.org`. For `example.org/packages.json` the
|
||||
repository URL would be `example.org`.
|
||||
|
||||
#### packages
|
||||
|
||||
The only required field is `packages`. The JSON structure is as follows:
|
||||
|
||||
{
|
||||
"vendor/packageName": {
|
||||
"name": "vendor/packageName",
|
||||
"description": "Package description",
|
||||
"versions": {
|
||||
"packages": {
|
||||
"vendor/packageName": {
|
||||
"master-dev": { @composer.json },
|
||||
"1.0.x-dev": { @composer.json },
|
||||
"0.0.1": { @composer.json },
|
||||
"1.0.0": { @composer.json }
|
||||
}
|
||||
}
|
||||
|
@ -88,12 +97,54 @@ Here is a minimal package definition:
|
|||
|
||||
It may include any of the other fields specified in the [schema](04-schema.md).
|
||||
|
||||
The `composer` repository is also what packagist uses. To reference a
|
||||
`composer` repository, just supply the path before the `packages.json` file.
|
||||
In case of packagist, that file is located at `/packages.json`, so the URL of
|
||||
the repository would be `http://packagist.org`. For
|
||||
`http://example.org/packages.json` the repository URL would be
|
||||
`http://example.org`.
|
||||
#### notify
|
||||
|
||||
The `notify` field allows you to specify an URL template for a URL that will
|
||||
be called every time a user installs a package.
|
||||
|
||||
An example value:
|
||||
|
||||
{
|
||||
"notify": "/downloads/%package%"
|
||||
}
|
||||
|
||||
For `example.org/packages.json` containing a `monolog/monolog` package, this
|
||||
would send a `POST` request to `example.org/downloads/monolog/monolog` with
|
||||
following parameters:
|
||||
|
||||
* **version:** The version of the package.
|
||||
* **version_normalized:** The normalized internal representation of the
|
||||
version.
|
||||
|
||||
This field is optional.
|
||||
|
||||
#### includes
|
||||
|
||||
For large repositories it is possible to split the `packages.json` into
|
||||
multiple files. The `includes` field allows you to reference these additional
|
||||
files.
|
||||
|
||||
An example:
|
||||
|
||||
{
|
||||
"includes": {
|
||||
"packages-2011.json": {
|
||||
"sha1": "525a85fb37edd1ad71040d429928c2c0edec9d17"
|
||||
},
|
||||
"packages-2012-01.json": {
|
||||
"sha1": "897cde726f8a3918faf27c803b336da223d400dd"
|
||||
},
|
||||
"packages-2012-02.json": {
|
||||
"sha1": "26f911ad717da26bbcac3f8f435280d13917efa5"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
The SHA-1 sum of the file allows it to be cached and only re-requested if the
|
||||
hash changed.
|
||||
|
||||
This field is optional. You probably don't need it for your own custom
|
||||
repository.
|
||||
|
||||
### VCS
|
||||
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
<!--
|
||||
tagline: Alias branch names to versions
|
||||
-->
|
||||
# Aliases
|
||||
|
||||
## Why aliases?
|
||||
|
||||
When you are using a VCS repository, you will only get comparable versions for
|
||||
branches that look like versions, such as `2.0`. For your `master` branch, you
|
||||
will get a `dev-master` version. For your `bugfix` branch, you will get a
|
||||
`dev-bugfix` version.
|
||||
|
||||
If your `master` branch is used to tag releases of the `1.0` development line,
|
||||
i.e. `1.0.1`, `1.0.2`, `1.0.3`, etc., any package depending on it will
|
||||
probably require version `1.0.*`.
|
||||
|
||||
If anyone wants to require the latest `dev-master`, they have a problem: Other
|
||||
packages may require `1.0.*`, so requiring that dev version will lead to
|
||||
conflicts, since `dev-master` does not match the `1.0.*` constraint.
|
||||
|
||||
Enter aliases.
|
||||
|
||||
## Branch alias
|
||||
|
||||
The `dev-master` branch is one in your main VCS repo. It is rather common that
|
||||
someone will want the latest master dev version. Thus, Composer allows you to
|
||||
alias your `dev-master` branch to a `1.0.x-dev` version. It is done by
|
||||
specifying a `branch-alias` field under `extra` in `composer.json`:
|
||||
|
||||
{
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
The branch version must begin with `dev-` (non-comparable version), the alias
|
||||
must be a comparable dev version. The `branch-alias` must be present on the
|
||||
branch that it references. For `dev-master`, you need to commit it on the
|
||||
`master` branch.
|
||||
|
||||
As a result, you can now require `1.0.*` and it will happily install
|
||||
`dev-master` for you.
|
||||
|
||||
## Require inline alias
|
||||
|
||||
Branch aliases are great for aliasing main development lines. But in order to
|
||||
use them you need to have control over the source repository, and you need to
|
||||
commit changes to version control.
|
||||
|
||||
This is not really fun when you just want to try a bugfix of some library that
|
||||
is a dependency of your local project.
|
||||
|
||||
For this reason, you can alias packages in your `require` and `require-dev`
|
||||
fields. Let's say you found a bug in the `monolog/monolog` package. You cloned
|
||||
Monolog on GitHub and fixed the issue in a branch named `bugfix`. Now you want
|
||||
to install that version of monolog in your local project.
|
||||
|
||||
You are using `symfony/monolog-bundle` which requires `monolog/monolog` version
|
||||
`1.*`. So you need your `dev-bugfix` to match that constraint.
|
||||
|
||||
Just add this to your project's root `composer.json`:
|
||||
|
||||
{
|
||||
"repositories": [
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/you/monolog"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"symfony/monolog-bundle": "2.0",
|
||||
"monolog/monolog": "dev-bugfix as 1.0.x-dev"
|
||||
}
|
||||
}
|
||||
|
||||
That will fetch the `dev-bugfix` version of `monolog/monolog` from your GitHub
|
||||
and alias it to `1.0.x-dev`.
|
||||
|
||||
> **Note:** If a package with inline aliases is required, the alias (right of
|
||||
> the `as`) is used as the version constraint. The part left of the `as` is
|
||||
> discarded. As a consequence, if A requires B and B requires `monolog/monolog`
|
||||
> version `dev-bugfix as 1.0.x-dev`, installing A will make B require
|
||||
> `1.0.x-dev`, which may exist as a branch alias or an actual `1.0` branch. If
|
||||
> it does not, it must be re-inline-aliased in A's `composer.json`.
|
||||
|
||||
> **Note:** Inline aliasing should be avoided, especially for published
|
||||
> packages. If you found a bug, try and get your fix merged upstream. This
|
||||
> helps to avoid issues for users of your package.
|
|
@ -5,7 +5,8 @@
|
|||
|
||||
Satis can be used to host the metadata of your company's private packages, or
|
||||
your own. It basically acts as a micro-packagist. You can get it from
|
||||
[GitHub](http://github.com/composer/satis).
|
||||
[GitHub](http://github.com/composer/satis) or install via CLI:
|
||||
`composer.phar create-project composer/satis`.
|
||||
|
||||
## Setup
|
||||
|
||||
|
@ -13,12 +14,29 @@ For example let's assume you have a few packages you want to reuse across your
|
|||
company but don't really want to open-source. You would first define a Satis
|
||||
configuration file, which is basically a stripped-down version of a
|
||||
`composer.json` file. It contains a few repositories, and then you use the require
|
||||
key to say which packages it should dump in the static repository it creates.
|
||||
key to say which packages it should dump in the static repository it creates, or
|
||||
use require-all to select all of them.
|
||||
|
||||
Here is an example configuration, you see that it holds a few VCS repositories,
|
||||
but those could be any types of [repositories](../05-repositories.md). Then
|
||||
the require just lists all the packages we need, using a `"*"` constraint to
|
||||
make sure all versions are selected.
|
||||
but those could be any types of [repositories](../05-repositories.md). Then it
|
||||
uses `"require-all": true` which selects all versions of all packages in the
|
||||
repositories you defined.
|
||||
|
||||
{
|
||||
"name": "My Repository",
|
||||
"homepage": "http://packages.example.org",
|
||||
"repositories": [
|
||||
{ "type": "vcs", "url": "http://github.com/mycompany/privaterepo" },
|
||||
{ "type": "vcs", "url": "http://svn.example.org/private/repo" },
|
||||
{ "type": "vcs", "url": "http://github.com/mycompany/privaterepo2" }
|
||||
],
|
||||
"require-all": true
|
||||
}
|
||||
|
||||
If you want to cherry pick which packages you want, you can list all the packages
|
||||
you want to have in your satis repository inside the classic composer `require` key,
|
||||
using a `"*"` constraint to make sure all versions are selected, or another
|
||||
constraint if you want really specific versions.
|
||||
|
||||
{
|
||||
"repositories": [
|
||||
|
@ -29,7 +47,7 @@ make sure all versions are selected.
|
|||
"require": {
|
||||
"company/package": "*",
|
||||
"company/package2": "*",
|
||||
"company/package3": "*"
|
||||
"company/package3": "2.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,10 @@
|
|||
"type": "string",
|
||||
"description": "Homepage URL for the author.",
|
||||
"format": "uri"
|
||||
},
|
||||
"role": {
|
||||
"type": "string",
|
||||
"description": "Author's role in the project."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,25 +25,26 @@ use Composer\Util\Filesystem;
|
|||
*/
|
||||
class AutoloadGenerator
|
||||
{
|
||||
public function dump(RepositoryInterface $localRepo, PackageInterface $mainPackage, InstallationManager $installationManager, $targetDir)
|
||||
public function dump(RepositoryInterface $localRepo, PackageInterface $mainPackage, InstallationManager $installationManager, $targetDir, $bcLinks = false)
|
||||
{
|
||||
$filesystem = new Filesystem();
|
||||
$filesystem->ensureDirectoryExists($installationManager->getVendorPath());
|
||||
$filesystem->ensureDirectoryExists($targetDir);
|
||||
$vendorPath = strtr(realpath($installationManager->getVendorPath()), '\\', '/');
|
||||
$relVendorPath = $filesystem->findShortestPath(getcwd(), $vendorPath, true);
|
||||
$vendorDirCode = $filesystem->findShortestPathCode(realpath($targetDir), $vendorPath, true);
|
||||
$vendorPathCode = $filesystem->findShortestPathCode(realpath($targetDir), $vendorPath, true);
|
||||
$vendorPathToTargetDirCode = $filesystem->findShortestPathCode($vendorPath, realpath($targetDir), true);
|
||||
|
||||
$appBaseDir = $filesystem->findShortestPathCode($vendorPath, getcwd(), true);
|
||||
$appBaseDir = str_replace('__DIR__', '$vendorDir', $appBaseDir);
|
||||
$appBaseDirCode = $filesystem->findShortestPathCode($vendorPath, getcwd(), true);
|
||||
$appBaseDirCode = str_replace('__DIR__', '$vendorDir', $appBaseDirCode);
|
||||
|
||||
$namespacesFile = <<<EOF
|
||||
<?php
|
||||
|
||||
// autoload_namespace.php generated by Composer
|
||||
|
||||
\$vendorDir = $vendorDirCode;
|
||||
\$baseDir = $appBaseDir;
|
||||
\$vendorDir = $vendorPathCode;
|
||||
\$baseDir = $appBaseDirCode;
|
||||
|
||||
return array(
|
||||
|
||||
|
@ -55,22 +56,7 @@ EOF;
|
|||
foreach ($autoloads['psr-0'] as $namespace => $paths) {
|
||||
$exportedPaths = array();
|
||||
foreach ($paths as $path) {
|
||||
$path = strtr($path, '\\', '/');
|
||||
$baseDir = '';
|
||||
if (!$filesystem->isAbsolutePath($path)) {
|
||||
if (strpos($path, $relVendorPath) === 0) {
|
||||
// path starts with vendor dir
|
||||
$path = substr($path, strlen($relVendorPath));
|
||||
$baseDir = '$vendorDir . ';
|
||||
} else {
|
||||
$path = '/'.$path;
|
||||
$baseDir = '$baseDir . ';
|
||||
}
|
||||
} elseif (strpos($path, $vendorPath) === 0) {
|
||||
$path = substr($path, strlen($vendorPath));
|
||||
$baseDir = '$vendorDir . ';
|
||||
}
|
||||
$exportedPaths[] = $baseDir.var_export($path, true);
|
||||
$exportedPaths[] = $this->getPathCode($filesystem, $relVendorPath, $vendorPath, $path);
|
||||
}
|
||||
$exportedPrefix = var_export($namespace, true);
|
||||
$namespacesFile .= " $exportedPrefix => ";
|
||||
|
@ -87,13 +73,44 @@ EOF;
|
|||
|
||||
// autoload_classmap.php generated by Composer
|
||||
|
||||
\$vendorDir = $vendorDirCode;
|
||||
\$baseDir = $appBaseDir;
|
||||
\$vendorDir = $vendorPathCode;
|
||||
\$baseDir = $appBaseDirCode;
|
||||
|
||||
return array(
|
||||
|
||||
EOF;
|
||||
|
||||
// add custom psr-0 autoloading if the root package has a target dir
|
||||
$targetDirLoader = null;
|
||||
$mainAutoload = $mainPackage->getAutoload();
|
||||
if ($mainPackage->getTargetDir() && $mainAutoload['psr-0']) {
|
||||
$levels = count(explode('/', trim(strtr($mainPackage->getTargetDir(), '\\', '/'), '/')));
|
||||
$prefixes = implode(', ', array_map(function ($prefix) {
|
||||
return var_export($prefix, true);
|
||||
}, array_keys($mainAutoload['psr-0'])));
|
||||
$baseDirFromVendorDirCode = $filesystem->findShortestPathCode($vendorPath, getcwd(), true);
|
||||
|
||||
$targetDirLoader = <<<EOF
|
||||
spl_autoload_register(function(\$class) {
|
||||
\$dir = $baseDirFromVendorDirCode . '/';
|
||||
\$prefixes = array($prefixes);
|
||||
foreach (\$prefixes as \$prefix) {
|
||||
if (0 !== strpos(\$class, \$prefix)) {
|
||||
continue;
|
||||
}
|
||||
\$path = \$dir . implode('/', array_slice(explode('\\\\', \$class), $levels)).'.php';
|
||||
if (!stream_resolve_include_path(\$path)) {
|
||||
return false;
|
||||
}
|
||||
require_once \$path;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
EOF;
|
||||
}
|
||||
|
||||
// flatten array
|
||||
$autoloads['classmap'] = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($autoloads['classmap']));
|
||||
foreach ($autoloads['classmap'] as $dir) {
|
||||
|
@ -106,11 +123,23 @@ EOF;
|
|||
|
||||
file_put_contents($targetDir.'/autoload_namespaces.php', $namespacesFile);
|
||||
file_put_contents($targetDir.'/autoload_classmap.php', $classmapFile);
|
||||
if ($includePathFile = $this->getIncludePathsFile($packageMap)) {
|
||||
if ($includePathFile = $this->getIncludePathsFile($packageMap, $filesystem, $relVendorPath, $vendorPath, $vendorPathCode, $appBaseDirCode)) {
|
||||
file_put_contents($targetDir.'/include_paths.php', $includePathFile);
|
||||
}
|
||||
file_put_contents($targetDir.'/autoload.php', $this->getAutoloadFile(true, true, (Boolean) $includePathFile));
|
||||
file_put_contents($vendorPath.'/autoload.php', $this->getAutoloadFile($vendorPathToTargetDirCode, true, true, (Boolean) $includePathFile, $targetDirLoader));
|
||||
copy(__DIR__.'/ClassLoader.php', $targetDir.'/ClassLoader.php');
|
||||
|
||||
// TODO BC feature, add E_DEPRECATED in autoload.php on April 30th, remove after May 30th
|
||||
if ($bcLinks) {
|
||||
$filesystem->ensureDirectoryExists($vendorPath.'/.composer');
|
||||
file_put_contents($vendorPath.'/.composer/autoload_namespaces.php', "<?php\n// Deprecated file, use the one in root of vendor dir\nreturn include dirname(__DIR__).'/composer/autoload_namespaces.php';\n");
|
||||
file_put_contents($vendorPath.'/.composer/autoload_classmap.php', "<?php\n// Deprecated file, use the one in root of vendor dir\nreturn include dirname(__DIR__).'/composer/autoload_classmap.php';\n");
|
||||
file_put_contents($vendorPath.'/.composer/autoload.php', "<?php\n// Deprecated file, use the one in root of vendor dir\nreturn include dirname(__DIR__).'/autoload.php';\n");
|
||||
file_put_contents($vendorPath.'/.composer/ClassLoader.php', "<?php\n// Deprecated file, use the one in root of vendor dir\nreturn include dirname(__DIR__).'/composer/ClassLoader.php';\n");
|
||||
if ($includePathFile) {
|
||||
file_put_contents($vendorPath.'/.composer/include_paths.php', "<?php\n// Deprecated file, use the one in root of vendor dir\nreturn include dirname(__DIR__).'/composer/include_paths.php';\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function buildPackageMap(InstallationManager $installationManager, PackageInterface $mainPackage, array $packages)
|
||||
|
@ -186,7 +215,7 @@ EOF;
|
|||
return $loader;
|
||||
}
|
||||
|
||||
protected function getIncludePathsFile(array $packageMap)
|
||||
protected function getIncludePathsFile(array $packageMap, Filesystem $filesystem, $relVendorPath, $vendorPath, $vendorPathCode, $appBaseDirCode)
|
||||
{
|
||||
$includePaths = array();
|
||||
|
||||
|
@ -198,6 +227,7 @@ EOF;
|
|||
}
|
||||
|
||||
foreach ($package->getIncludePaths() as $includePath) {
|
||||
$includePath = trim($includePath, '/');
|
||||
$includePaths[] = empty($installPath) ? $includePath : $installPath.'/'.$includePath;
|
||||
}
|
||||
}
|
||||
|
@ -206,30 +236,65 @@ EOF;
|
|||
return;
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
"<?php\nreturn %s;\n", var_export($includePaths, true)
|
||||
);
|
||||
$includePathsFile = <<<EOF
|
||||
<?php
|
||||
|
||||
// include_paths.php generated by Composer
|
||||
|
||||
\$vendorDir = $vendorPathCode;
|
||||
\$baseDir = $appBaseDirCode;
|
||||
|
||||
return array(
|
||||
|
||||
EOF;
|
||||
|
||||
foreach ($includePaths as $path) {
|
||||
$includePathsFile .= " " . $this->getPathCode($filesystem, $relVendorPath, $vendorPath, $path) . ",\n";
|
||||
}
|
||||
|
||||
return $includePathsFile . ");\n";
|
||||
}
|
||||
|
||||
protected function getAutoloadFile($usePSR0, $useClassMap, $useIncludePath)
|
||||
protected function getPathCode(Filesystem $filesystem, $relVendorPath, $vendorPath, $path)
|
||||
{
|
||||
$file = <<<'HEADER'
|
||||
$path = strtr($path, '\\', '/');
|
||||
$baseDir = '';
|
||||
if (!$filesystem->isAbsolutePath($path)) {
|
||||
if (strpos($path, $relVendorPath) === 0) {
|
||||
// path starts with vendor dir
|
||||
$path = substr($path, strlen($relVendorPath));
|
||||
$baseDir = '$vendorDir . ';
|
||||
} else {
|
||||
$path = '/'.$path;
|
||||
$baseDir = '$baseDir . ';
|
||||
}
|
||||
} elseif (strpos($path, $vendorPath) === 0) {
|
||||
$path = substr($path, strlen($vendorPath));
|
||||
$baseDir = '$vendorDir . ';
|
||||
}
|
||||
return $baseDir.var_export($path, true);
|
||||
}
|
||||
|
||||
protected function getAutoloadFile($vendorPathToTargetDirCode, $usePSR0, $useClassMap, $useIncludePath, $targetDirLoader)
|
||||
{
|
||||
$file = <<<HEADER
|
||||
<?php
|
||||
|
||||
// autoload.php generated by Composer
|
||||
if (!class_exists('Composer\\Autoload\\ClassLoader', false)) {
|
||||
require __DIR__.'/ClassLoader.php';
|
||||
if (!class_exists('Composer\\\\Autoload\\\\ClassLoader', false)) {
|
||||
require $vendorPathToTargetDirCode . '/ClassLoader.php';
|
||||
}
|
||||
|
||||
return call_user_func(function() {
|
||||
$loader = new \Composer\Autoload\ClassLoader();
|
||||
\$loader = new \\Composer\\Autoload\\ClassLoader();
|
||||
\$composerDir = $vendorPathToTargetDirCode;
|
||||
|
||||
|
||||
HEADER;
|
||||
|
||||
if ($useIncludePath) {
|
||||
$file .= <<<'INCLUDE_PATH'
|
||||
$includePaths = require __DIR__.'/include_paths.php';
|
||||
$includePaths = require $composerDir . '/include_paths.php';
|
||||
array_unshift($includePaths, get_include_path());
|
||||
set_include_path(join(PATH_SEPARATOR, $includePaths));
|
||||
|
||||
|
@ -239,7 +304,7 @@ INCLUDE_PATH;
|
|||
|
||||
if ($usePSR0) {
|
||||
$file .= <<<'PSR0'
|
||||
$map = require __DIR__.'/autoload_namespaces.php';
|
||||
$map = require $composerDir . '/autoload_namespaces.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->add($namespace, $path);
|
||||
}
|
||||
|
@ -250,7 +315,7 @@ PSR0;
|
|||
|
||||
if ($useClassMap) {
|
||||
$file .= <<<'CLASSMAP'
|
||||
$classMap = require __DIR__.'/autoload_classmap.php';
|
||||
$classMap = require $composerDir . '/autoload_classmap.php';
|
||||
if ($classMap) {
|
||||
$loader->addClassMap($classMap);
|
||||
}
|
||||
|
@ -259,6 +324,8 @@ PSR0;
|
|||
CLASSMAP;
|
||||
}
|
||||
|
||||
$file .= $targetDirLoader;
|
||||
|
||||
return $file . <<<'FOOTER'
|
||||
$loader->register();
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ use Composer\Installer\ProjectInstaller;
|
|||
use Composer\IO\IOInterface;
|
||||
use Composer\Repository\ComposerRepository;
|
||||
use Composer\Repository\FilesystemRepository;
|
||||
use Composer\Repository\InstalledFilesystemRepository;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
@ -113,7 +114,7 @@ EOT
|
|||
|
||||
$io->write('<info>Installing ' . $package->getName() . ' as new project.</info>', true);
|
||||
$projectInstaller = new ProjectInstaller($directory, $dm);
|
||||
$projectInstaller->install(new FilesystemRepository(new JsonFile('php://memory')), $package);
|
||||
$projectInstaller->install(new InstalledFilesystemRepository(new JsonFile('php://memory')), $package);
|
||||
|
||||
$io->write('<info>Created project into directory ' . $directory . '</info>', true);
|
||||
chdir($directory);
|
||||
|
|
|
@ -35,7 +35,7 @@ class InitCommand extends Command
|
|||
public function parseAuthorString($author)
|
||||
{
|
||||
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)) {
|
||||
if (!function_exists('filter_var') || version_compare(PHP_VERSION, '5.3.3', '<') || $match['email'] === filter_var($match['email'], FILTER_VALIDATE_EMAIL)) {
|
||||
return array(
|
||||
'name' => trim($match['name']),
|
||||
'email' => $match['email']
|
||||
|
|
|
@ -53,7 +53,7 @@ EOT
|
|||
$rfs->copy('getcomposer.org', $remoteFilename, $tempFilename);
|
||||
|
||||
try {
|
||||
chmod($tempFilename, 0755);
|
||||
chmod($tempFilename, 0777 & ~umask());
|
||||
// test the phar validity
|
||||
$phar = new \Phar($tempFilename);
|
||||
// free the variable to unlock the file
|
||||
|
|
|
@ -81,10 +81,10 @@ class Compiler
|
|||
$this->addFile($phar, $file);
|
||||
}
|
||||
|
||||
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/.composer/ClassLoader.php'));
|
||||
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/.composer/autoload.php'));
|
||||
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/.composer/autoload_namespaces.php'));
|
||||
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/.composer/autoload_classmap.php'));
|
||||
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/autoload.php'));
|
||||
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/autoload_namespaces.php'));
|
||||
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/autoload_classmap.php'));
|
||||
$this->addFile($phar, new \SplFileInfo(__DIR__.'/../../vendor/composer/ClassLoader.php'));
|
||||
$this->addComposerBin($phar);
|
||||
|
||||
// Stubs
|
||||
|
|
|
@ -67,6 +67,10 @@ class Application extends BaseApplication
|
|||
$this->registerCommands();
|
||||
$this->io = new ConsoleIO($input, $output, $this->getHelperSet());
|
||||
|
||||
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>');
|
||||
}
|
||||
|
||||
return parent::doRun($input, $output);
|
||||
}
|
||||
|
||||
|
|
|
@ -69,6 +69,8 @@ class DefaultPolicy implements PolicyInterface
|
|||
$literals = $this->pruneToBestVersion($literals);
|
||||
|
||||
$literals = $this->pruneToHighestPriorityOrInstalled($pool, $installedMap, $literals);
|
||||
|
||||
$literals = $this->pruneRemoteAliases($literals);
|
||||
}
|
||||
|
||||
$selected = call_user_func_array('array_merge', $packages);
|
||||
|
@ -210,8 +212,8 @@ class DefaultPolicy implements PolicyInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* Assumes that installed packages come first and then all highest priority packages
|
||||
*/
|
||||
* Assumes that installed packages come first and then all highest priority packages
|
||||
*/
|
||||
protected function pruneToHighestPriorityOrInstalled(Pool $pool, array $installedMap, array $literals)
|
||||
{
|
||||
$selected = array();
|
||||
|
@ -239,4 +241,38 @@ class DefaultPolicy implements PolicyInterface
|
|||
|
||||
return $selected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assumes that locally aliased (in root package requires) packages take priority over branch-alias ones
|
||||
*
|
||||
* If no package is a local alias, nothing happens
|
||||
*/
|
||||
protected function pruneRemoteAliases(array $literals)
|
||||
{
|
||||
$hasLocalAlias = false;
|
||||
|
||||
foreach ($literals as $literal) {
|
||||
$package = $literal->getPackage();
|
||||
|
||||
if ($package instanceof AliasPackage && $package->isRootPackageAlias()) {
|
||||
$hasLocalAlias = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$hasLocalAlias) {
|
||||
return $literals;
|
||||
}
|
||||
|
||||
$selected = array();
|
||||
foreach ($literals as $literal) {
|
||||
$package = $literal->getPackage();
|
||||
|
||||
if ($package instanceof AliasPackage && $package->isRootPackageAlias()) {
|
||||
$selected[] = $literal;
|
||||
}
|
||||
}
|
||||
|
||||
return $selected;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ use Composer\Util\Filesystem;
|
|||
class DownloadManager
|
||||
{
|
||||
private $preferSource = false;
|
||||
private $filesystem;
|
||||
private $downloaders = array();
|
||||
|
||||
/**
|
||||
|
@ -31,9 +32,10 @@ class DownloadManager
|
|||
*
|
||||
* @param Boolean $preferSource prefer downloading from source
|
||||
*/
|
||||
public function __construct($preferSource = false)
|
||||
public function __construct($preferSource = false, Filesystem $filesystem = null)
|
||||
{
|
||||
$this->preferSource = $preferSource;
|
||||
$this->filesystem = $filesystem ?: new Filesystem();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -135,8 +137,7 @@ class DownloadManager
|
|||
throw new \InvalidArgumentException('Package '.$package.' must have a source or dist specified');
|
||||
}
|
||||
|
||||
$fs = new Filesystem();
|
||||
$fs->ensureDirectoryExists($targetDir);
|
||||
$this->filesystem->ensureDirectoryExists($targetDir);
|
||||
|
||||
$downloader = $this->getDownloaderForInstalledPackage($package);
|
||||
$downloader->download($package, $targetDir);
|
||||
|
|
|
@ -61,7 +61,7 @@ class GitDownloader extends VcsDownloader
|
|||
*/
|
||||
protected function enforceCleanDirectory($path)
|
||||
{
|
||||
$command = sprintf('cd %s && git status --porcelain', escapeshellarg($path));
|
||||
$command = sprintf('cd %s && git status --porcelain --untracked-files=no', escapeshellarg($path));
|
||||
if (0 !== $this->process->execute($command, $output)) {
|
||||
throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
|
||||
}
|
||||
|
|
|
@ -38,6 +38,14 @@ class Factory
|
|||
}
|
||||
}
|
||||
|
||||
// Protect directory against web access
|
||||
if (!file_exists($home . '/.htaccess')) {
|
||||
if (!is_dir($home)) {
|
||||
@mkdir($home, 0777, true);
|
||||
}
|
||||
@file_put_contents($home . '/.htaccess', 'Deny from all');
|
||||
}
|
||||
|
||||
$config = new Config();
|
||||
|
||||
$file = new JsonFile($home.'/config.json');
|
||||
|
@ -151,8 +159,25 @@ class Factory
|
|||
|
||||
protected function addLocalRepository(RepositoryManager $rm, $vendorDir)
|
||||
{
|
||||
$rm->setLocalRepository(new Repository\InstalledFilesystemRepository(new JsonFile($vendorDir.'/.composer/installed.json')));
|
||||
$rm->setLocalDevRepository(new Repository\InstalledFilesystemRepository(new JsonFile($vendorDir.'/.composer/installed_dev.json')));
|
||||
// TODO BC feature, remove after May 30th
|
||||
if (file_exists($vendorDir.'/.composer/installed.json')) {
|
||||
if (!is_dir($vendorDir.'/composer')) { mkdir($vendorDir.'/composer/', 0777, true); }
|
||||
rename($vendorDir.'/.composer/installed.json', $vendorDir.'/composer/installed.json');
|
||||
}
|
||||
if (file_exists($vendorDir.'/.composer/installed_dev.json')) {
|
||||
if (!is_dir($vendorDir.'/composer')) { mkdir($vendorDir.'/composer/', 0777, true); }
|
||||
rename($vendorDir.'/.composer/installed_dev.json', $vendorDir.'/composer/installed_dev.json');
|
||||
}
|
||||
if (file_exists($vendorDir.'/installed.json')) {
|
||||
if (!is_dir($vendorDir.'/composer')) { mkdir($vendorDir.'/composer/', 0777, true); }
|
||||
rename($vendorDir.'/installed.json', $vendorDir.'/composer/installed.json');
|
||||
}
|
||||
if (file_exists($vendorDir.'/installed_dev.json')) {
|
||||
if (!is_dir($vendorDir.'/composer')) { mkdir($vendorDir.'/composer/', 0777, true); }
|
||||
rename($vendorDir.'/installed_dev.json', $vendorDir.'/composer/installed_dev.json');
|
||||
}
|
||||
$rm->setLocalRepository(new Repository\InstalledFilesystemRepository(new JsonFile($vendorDir.'/composer/installed.json')));
|
||||
$rm->setLocalDevRepository(new Repository\InstalledFilesystemRepository(new JsonFile($vendorDir.'/composer/installed_dev.json')));
|
||||
}
|
||||
|
||||
protected function addPackagistRepository(array $localConfig)
|
||||
|
|
|
@ -55,6 +55,14 @@ class ConsoleIO implements IOInterface
|
|||
return $this->input->isInteractive();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function isDecorated()
|
||||
{
|
||||
return $this->output->isDecorated();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
|
|
@ -33,6 +33,13 @@ interface IOInterface
|
|||
*/
|
||||
function isVerbose();
|
||||
|
||||
/**
|
||||
* Is this output decorated?
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
function isDecorated();
|
||||
|
||||
/**
|
||||
* Writes a message to the output.
|
||||
*
|
||||
|
|
|
@ -35,6 +35,14 @@ class NullIO implements IOInterface
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function isDecorated()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
|
|
@ -27,6 +27,7 @@ use Composer\Package\Link;
|
|||
use Composer\Package\LinkConstraint\VersionConstraint;
|
||||
use Composer\Package\Locker;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Repository\ArrayRepository;
|
||||
use Composer\Repository\CompositeRepository;
|
||||
use Composer\Repository\PlatformRepository;
|
||||
use Composer\Repository\RepositoryInterface;
|
||||
|
@ -76,6 +77,11 @@ class Installer
|
|||
*/
|
||||
protected $eventDispatcher;
|
||||
|
||||
/**
|
||||
* @var AutoloadGenerator
|
||||
*/
|
||||
protected $autoloadGenerator;
|
||||
|
||||
protected $preferSource = false;
|
||||
protected $devMode = false;
|
||||
protected $dryRun = false;
|
||||
|
@ -102,8 +108,9 @@ class Installer
|
|||
* @param Locker $locker
|
||||
* @param InstallationManager $installationManager
|
||||
* @param EventDispatcher $eventDispatcher
|
||||
* @param AutoloadGenerator $autoloadGenerator
|
||||
*/
|
||||
public function __construct(IOInterface $io, PackageInterface $package, DownloadManager $downloadManager, RepositoryManager $repositoryManager, Locker $locker, InstallationManager $installationManager, EventDispatcher $eventDispatcher)
|
||||
public function __construct(IOInterface $io, PackageInterface $package, DownloadManager $downloadManager, RepositoryManager $repositoryManager, Locker $locker, InstallationManager $installationManager, EventDispatcher $eventDispatcher, AutoloadGenerator $autoloadGenerator)
|
||||
{
|
||||
$this->io = $io;
|
||||
$this->package = $package;
|
||||
|
@ -112,6 +119,7 @@ class Installer
|
|||
$this->locker = $locker;
|
||||
$this->installationManager = $installationManager;
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
$this->autoloadGenerator = $autoloadGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -128,7 +136,13 @@ class Installer
|
|||
}
|
||||
|
||||
// create installed repo, this contains all local packages + platform packages (php & extensions)
|
||||
$repos = array_merge($this->repositoryManager->getLocalRepositories(), array(new PlatformRepository()));
|
||||
$repos = array_merge(
|
||||
$this->repositoryManager->getLocalRepositories(),
|
||||
array(
|
||||
new ArrayRepository(array($this->package)),
|
||||
new PlatformRepository(),
|
||||
)
|
||||
);
|
||||
$installedRepo = new CompositeRepository($repos);
|
||||
if ($this->additionalInstalledRepository) {
|
||||
$installedRepo->addRepository($this->additionalInstalledRepository);
|
||||
|
@ -152,9 +166,11 @@ class Installer
|
|||
}
|
||||
}
|
||||
|
||||
// dump suggestions
|
||||
// output suggestions
|
||||
foreach ($this->suggestedPackages as $suggestion) {
|
||||
$this->io->write($suggestion['source'].' suggests installing '.$suggestion['target'].' ('.$suggestion['reason'].')');
|
||||
if (!$installedRepo->findPackages($suggestion['target'])) {
|
||||
$this->io->write($suggestion['source'].' suggests installing '.$suggestion['target'].' ('.$suggestion['reason'].')');
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->dryRun) {
|
||||
|
@ -172,9 +188,8 @@ class Installer
|
|||
|
||||
// write autoloader
|
||||
$this->io->write('<info>Generating autoload files</info>');
|
||||
$generator = new AutoloadGenerator;
|
||||
$localRepos = new CompositeRepository($this->repositoryManager->getLocalRepositories());
|
||||
$generator->dump($localRepos, $this->package, $this->installationManager, $this->installationManager->getVendorPath().'/.composer');
|
||||
$this->autoloadGenerator->dump($localRepos, $this->package, $this->installationManager, $this->installationManager->getVendorPath() . '/composer', true);
|
||||
|
||||
// dispatch post event
|
||||
$eventName = $this->update ? ScriptEvents::POST_UPDATE_CMD : ScriptEvents::POST_INSTALL_CMD;
|
||||
|
@ -186,6 +201,11 @@ class Installer
|
|||
|
||||
protected function doInstall($localRepo, $installedRepo, $aliases, $devMode = false)
|
||||
{
|
||||
// initialize locker to create aliased packages
|
||||
if (!$this->update && $this->locker->isLocked($devMode)) {
|
||||
$lockedPackages = $this->locker->getLockedPackages($devMode);
|
||||
}
|
||||
|
||||
// creating repository pool
|
||||
$pool = new Pool;
|
||||
$pool->addRepository($installedRepo);
|
||||
|
@ -196,6 +216,10 @@ class Installer
|
|||
// creating requirements request
|
||||
$installFromLock = false;
|
||||
$request = new Request($pool);
|
||||
|
||||
$constraint = new VersionConstraint('=', $this->package->getVersion());
|
||||
$request->install($this->package->getName(), $constraint);
|
||||
|
||||
if ($this->update) {
|
||||
$this->io->write('<info>Updating '.($devMode ? 'dev ': '').'dependencies</info>');
|
||||
|
||||
|
@ -214,7 +238,7 @@ class Installer
|
|||
$this->io->write('<warning>Your lock file is out of sync with your composer.json, run "composer.phar update" to update dependencies</warning>');
|
||||
}
|
||||
|
||||
foreach ($this->locker->getLockedPackages($devMode) as $package) {
|
||||
foreach ($lockedPackages as $package) {
|
||||
$version = $package->getVersion();
|
||||
foreach ($aliases as $alias) {
|
||||
if ($alias['package'] === $package->getName() && $alias['version'] === $package->getVersion()) {
|
||||
|
@ -378,14 +402,16 @@ class Installer
|
|||
foreach ($this->repositoryManager->findPackages($alias['package'], $alias['version']) as $package) {
|
||||
$package->setAlias($alias['alias_normalized']);
|
||||
$package->setPrettyAlias($alias['alias']);
|
||||
$package->getRepository()->addPackage(new AliasPackage($package, $alias['alias_normalized'], $alias['alias']));
|
||||
$package->getRepository()->addPackage($aliasPackage = new AliasPackage($package, $alias['alias_normalized'], $alias['alias']));
|
||||
$aliasPackage->setRootPackageAlias(true);
|
||||
}
|
||||
foreach ($this->repositoryManager->getLocalRepositories() as $repo) {
|
||||
foreach ($repo->findPackages($alias['package'], $alias['version']) as $package) {
|
||||
$package->setAlias($alias['alias_normalized']);
|
||||
$package->setPrettyAlias($alias['alias']);
|
||||
$package->getRepository()->addPackage(new AliasPackage($package, $alias['alias_normalized'], $alias['alias']));
|
||||
$package->getRepository()->addPackage($aliasPackage = new AliasPackage($package, $alias['alias_normalized'], $alias['alias']));
|
||||
$package->getRepository()->removePackage($package);
|
||||
$aliasPackage->setRootPackageAlias(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -399,11 +425,13 @@ class Installer
|
|||
* @param IOInterface $io
|
||||
* @param Composer $composer
|
||||
* @param EventDispatcher $eventDispatcher
|
||||
* @param AutoloadGenerator $autoloadGenerator
|
||||
* @return Installer
|
||||
*/
|
||||
static public function create(IOInterface $io, Composer $composer, EventDispatcher $eventDispatcher = null)
|
||||
static public function create(IOInterface $io, Composer $composer, EventDispatcher $eventDispatcher = null, AutoloadGenerator $autoloadGenerator = null)
|
||||
{
|
||||
$eventDispatcher = $eventDispatcher ?: new EventDispatcher($composer, $io);
|
||||
$autoloadGenerator = $autoloadGenerator ?: new AutoloadGenerator;
|
||||
|
||||
return new static(
|
||||
$io,
|
||||
|
@ -412,7 +440,8 @@ class Installer
|
|||
$composer->getRepositoryManager(),
|
||||
$composer->getLocker(),
|
||||
$composer->getInstallationManager(),
|
||||
$eventDispatcher
|
||||
$eventDispatcher,
|
||||
$autoloadGenerator
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -127,11 +127,7 @@ class InstallationManager
|
|||
*/
|
||||
public function install(RepositoryInterface $repo, InstallOperation $operation)
|
||||
{
|
||||
$package = $operation->getPackage();
|
||||
if ($package instanceof AliasPackage) {
|
||||
$package = $package->getAliasOf();
|
||||
$package->setInstalledAsAlias(true);
|
||||
}
|
||||
$package = $this->antiAlias($operation->getPackage());
|
||||
$installer = $this->getInstaller($package->getType());
|
||||
$installer->install($repo, $package);
|
||||
$this->notifyInstall($package);
|
||||
|
@ -145,15 +141,8 @@ class InstallationManager
|
|||
*/
|
||||
public function update(RepositoryInterface $repo, UpdateOperation $operation)
|
||||
{
|
||||
$initial = $operation->getInitialPackage();
|
||||
if ($initial instanceof AliasPackage) {
|
||||
$initial = $initial->getAliasOf();
|
||||
}
|
||||
$target = $operation->getTargetPackage();
|
||||
if ($target instanceof AliasPackage) {
|
||||
$target = $target->getAliasOf();
|
||||
$target->setInstalledAsAlias(true);
|
||||
}
|
||||
$initial = $this->antiAlias($operation->getInitialPackage());
|
||||
$target = $this->antiAlias($operation->getTargetPackage());
|
||||
|
||||
$initialType = $initial->getType();
|
||||
$targetType = $target->getType();
|
||||
|
@ -176,10 +165,7 @@ class InstallationManager
|
|||
*/
|
||||
public function uninstall(RepositoryInterface $repo, UninstallOperation $operation)
|
||||
{
|
||||
$package = $operation->getPackage();
|
||||
if ($package instanceof AliasPackage) {
|
||||
$package = $package->getAliasOf();
|
||||
}
|
||||
$package = $this->antiAlias($operation->getPackage());
|
||||
$installer = $this->getInstaller($package->getType());
|
||||
$installer->uninstall($repo, $package);
|
||||
}
|
||||
|
@ -211,10 +197,23 @@ class InstallationManager
|
|||
return getcwd().DIRECTORY_SEPARATOR.$this->vendorPath;
|
||||
}
|
||||
|
||||
protected function notifyInstall(PackageInterface $package)
|
||||
private function notifyInstall(PackageInterface $package)
|
||||
{
|
||||
if ($package->getRepository() instanceof NotifiableRepositoryInterface) {
|
||||
$package->getRepository()->notifyInstall($package);
|
||||
}
|
||||
}
|
||||
|
||||
private function antiAlias(PackageInterface $package)
|
||||
{
|
||||
if ($package instanceof AliasPackage) {
|
||||
$alias = $package;
|
||||
$package = $package->getAliasOf();
|
||||
$package->setInstalledAsAlias(true);
|
||||
$package->setAlias($alias->getVersion());
|
||||
$package->setPrettyAlias($alias->getPrettyVersion());
|
||||
}
|
||||
|
||||
return $package;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,7 +152,7 @@ class LibraryInstaller implements InstallerInterface
|
|||
// likely leftover from a previous install, make sure
|
||||
// that the target is still executable in case this
|
||||
// is a fresh install of the vendor.
|
||||
chmod($link, 0755);
|
||||
chmod($link, 0777 & ~umask());
|
||||
}
|
||||
$this->io->write('Skipped installation of '.$bin.' for package '.$package->getName().', name conflicts with an existing file');
|
||||
continue;
|
||||
|
@ -163,21 +163,24 @@ class LibraryInstaller implements InstallerInterface
|
|||
// add unixy support for cygwin and similar environments
|
||||
if ('.bat' !== substr($bin, -4)) {
|
||||
file_put_contents($link, $this->generateUnixyProxyCode($bin, $link));
|
||||
chmod($link, 0755);
|
||||
chmod($link, 0777 & ~umask());
|
||||
$link .= '.bat';
|
||||
}
|
||||
file_put_contents($link, $this->generateWindowsProxyCode($bin, $link));
|
||||
} else {
|
||||
$cwd = getcwd();
|
||||
try {
|
||||
// under linux symlinks are not always supported for example
|
||||
// when using it in smbfs mounted folder
|
||||
symlink($bin, $link);
|
||||
$relativeBin = $this->filesystem->findShortestPath($link, $bin);
|
||||
chdir(dirname($link));
|
||||
symlink($relativeBin, $link);
|
||||
} catch (\ErrorException $e) {
|
||||
file_put_contents($link, $this->generateUnixyProxyCode($bin, $link));
|
||||
}
|
||||
|
||||
chdir($cwd);
|
||||
}
|
||||
chmod($link, 0755);
|
||||
chmod($link, 0777 & ~umask());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,7 +189,7 @@ class LibraryInstaller implements InstallerInterface
|
|||
if (!$package->getBinaries()) {
|
||||
return;
|
||||
}
|
||||
foreach ($package->getBinaries() as $bin => $os) {
|
||||
foreach ($package->getBinaries() as $bin) {
|
||||
$link = $this->binDir.'/'.basename($bin);
|
||||
if (!file_exists($link)) {
|
||||
continue;
|
||||
|
|
|
@ -237,7 +237,7 @@ class JsonFile
|
|||
}
|
||||
} else {
|
||||
// Collapse empty {} and []
|
||||
$result = rtrim($result);
|
||||
$result = rtrim($result)."\n\n".$indentStr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ class AliasPackage extends BasePackage
|
|||
protected $prettyVersion;
|
||||
protected $dev;
|
||||
protected $aliasOf;
|
||||
protected $rootPackageAlias = false;
|
||||
|
||||
protected $requires;
|
||||
protected $conflicts;
|
||||
|
@ -146,6 +147,27 @@ class AliasPackage extends BasePackage
|
|||
return $this->devRequires;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores whether this is an alias created by an aliasing in the requirements of the root package or not
|
||||
*
|
||||
* Use by the policy for sorting manually aliased packages first, see #576
|
||||
*
|
||||
* @param Boolean $value
|
||||
*/
|
||||
public function setRootPackageAlias($value)
|
||||
{
|
||||
return $this->rootPackageAlias = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see setRootPackageAlias
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isRootPackageAlias()
|
||||
{
|
||||
return $this->rootPackageAlias;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -222,6 +244,14 @@ class AliasPackage extends BasePackage
|
|||
{
|
||||
return $this->aliasOf->getScripts();
|
||||
}
|
||||
public function setAliases(array $aliases)
|
||||
{
|
||||
return $this->aliasOf->setAliases($aliases);
|
||||
}
|
||||
public function getAliases()
|
||||
{
|
||||
return $this->aliasOf->getAliases();
|
||||
}
|
||||
public function getLicense()
|
||||
{
|
||||
return $this->aliasOf->getLicense();
|
||||
|
|
|
@ -58,7 +58,10 @@ class ArrayLoader
|
|||
$package->setExtra($config['extra']);
|
||||
}
|
||||
|
||||
if (isset($config['bin']) && is_array($config['bin'])) {
|
||||
if (isset($config['bin'])) {
|
||||
if (!is_array($config['bin'])) {
|
||||
throw new \UnexpectedValueException('Package '.$config['name'].'\'s bin key should be an array, '.gettype($config['bin']).' given.');
|
||||
}
|
||||
foreach ($config['bin'] as $key => $bin) {
|
||||
$config['bin'][$key]= ltrim($bin, '/');
|
||||
}
|
||||
|
@ -166,6 +169,11 @@ class ArrayLoader
|
|||
}
|
||||
|
||||
if (isset($config['suggest']) && is_array($config['suggest'])) {
|
||||
foreach ($config['suggest'] as $target => $reason) {
|
||||
if ('self.version' === trim($reason)) {
|
||||
$config['suggest'][$target] = $package->getPrettyVersion();
|
||||
}
|
||||
}
|
||||
$package->setSuggests($config['suggest']);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@ namespace Composer\Package\Loader;
|
|||
|
||||
use Composer\Package\Version\VersionParser;
|
||||
use Composer\Repository\RepositoryManager;
|
||||
use Composer\Util\ProcessExecutor;
|
||||
use Composer\Package\AliasPackage;
|
||||
|
||||
/**
|
||||
* ArrayLoader built for the sole purpose of loading the root package
|
||||
|
@ -25,10 +27,12 @@ use Composer\Repository\RepositoryManager;
|
|||
class RootPackageLoader extends ArrayLoader
|
||||
{
|
||||
private $manager;
|
||||
private $process;
|
||||
|
||||
public function __construct(RepositoryManager $manager, VersionParser $parser = null)
|
||||
public function __construct(RepositoryManager $manager, VersionParser $parser = null, ProcessExecutor $process = null)
|
||||
{
|
||||
$this->manager = $manager;
|
||||
$this->process = $process ?: new ProcessExecutor();
|
||||
parent::__construct($parser);
|
||||
}
|
||||
|
||||
|
@ -38,7 +42,20 @@ class RootPackageLoader extends ArrayLoader
|
|||
$config['name'] = '__root__';
|
||||
}
|
||||
if (!isset($config['version'])) {
|
||||
$config['version'] = '1.0.0';
|
||||
$version = '1.0.0';
|
||||
|
||||
// try to fetch current version from git branch
|
||||
if (0 === $this->process->execute('git branch --no-color --no-abbrev -v', $output)) {
|
||||
foreach ($this->process->splitLines($output) as $branch) {
|
||||
if ($branch && preg_match('{^(?:\* ) *(?:[^/ ]+?/)?(\S+) *[a-f0-9]+ .*$}', $branch, $match)) {
|
||||
$version = 'dev-'.$match[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$config['version'] = $version;
|
||||
} else {
|
||||
$version = $config['version'];
|
||||
}
|
||||
|
||||
$package = parent::load($config);
|
||||
|
@ -76,6 +93,16 @@ class RootPackageLoader extends ArrayLoader
|
|||
$package->setRepositories($config['repositories']);
|
||||
}
|
||||
|
||||
if (isset($config['extra']['branch-alias'][$version])
|
||||
&& substr($config['extra']['branch-alias'][$version], -4) === '-dev'
|
||||
) {
|
||||
$targetBranch = $config['extra']['branch-alias'][$version];
|
||||
$normalized = $this->versionParser->normalizeBranch(substr($targetBranch, 0, -4));
|
||||
$version = preg_replace('{(\.9{7})+}', '.x', $normalized);
|
||||
|
||||
return new AliasPackage($package, $normalized, $version);
|
||||
}
|
||||
|
||||
return $package;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,12 +90,22 @@ class Locker
|
|||
|
||||
foreach ($lockedPackages as $info) {
|
||||
$resolvedVersion = !empty($info['alias']) ? $info['alias'] : $info['version'];
|
||||
|
||||
// try to find the package in the local repo (best match)
|
||||
$package = $repo->findPackage($info['package'], $resolvedVersion);
|
||||
|
||||
// try to find the package in any repo
|
||||
if (!$package) {
|
||||
$package = $this->repositoryManager->findPackage($info['package'], $resolvedVersion);
|
||||
}
|
||||
|
||||
// try to find the package in any repo (second pass without alias + rebuild alias since it disappeared)
|
||||
if (!$package && !empty($info['alias'])) {
|
||||
$package = $this->repositoryManager->findPackage($info['package'], $info['version']);
|
||||
if ($package && !empty($info['alias'])) {
|
||||
$package = new AliasPackage($package, $info['alias'], $info['alias']);
|
||||
if ($package) {
|
||||
$alias = new AliasPackage($package, $info['alias'], $info['alias']);
|
||||
$package->getRepository()->addPackage($alias);
|
||||
$package = $alias;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,13 @@ class ArrayRepository implements RepositoryInterface
|
|||
{
|
||||
protected $packages;
|
||||
|
||||
public function __construct(array $packages = array())
|
||||
{
|
||||
foreach ($packages as $package) {
|
||||
$this->addPackage($package);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
|
|
@ -40,7 +40,7 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
|
|||
$repoConfig['url'] = 'http://'.$repoConfig['url'];
|
||||
}
|
||||
$repoConfig['url'] = rtrim($repoConfig['url'], '/');
|
||||
if (function_exists('filter_var') && !filter_var($repoConfig['url'], FILTER_VALIDATE_URL)) {
|
||||
if (function_exists('filter_var') && version_compare(PHP_VERSION, '5.3.3', '>=') && !filter_var($repoConfig['url'], FILTER_VALIDATE_URL)) {
|
||||
throw new \UnexpectedValueException('Invalid url given for Composer repository: '.$repoConfig['url']);
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ class ComposerRepository extends ArrayRepository implements NotifiableRepository
|
|||
array(
|
||||
'method' => 'POST',
|
||||
'header' => 'Content-type: application/x-www-form-urlencoded',
|
||||
'content' => http_build_query($params),
|
||||
'content' => http_build_query($params, '', '&'),
|
||||
'timeout' => 3,
|
||||
)
|
||||
);
|
||||
|
|
|
@ -39,7 +39,7 @@ class PearRepository extends ArrayRepository
|
|||
$repoConfig['url'] = 'http://'.$repoConfig['url'];
|
||||
}
|
||||
|
||||
if (function_exists('filter_var') && !filter_var($repoConfig['url'], FILTER_VALIDATE_URL)) {
|
||||
if (function_exists('filter_var') && version_compare(PHP_VERSION, '5.3.3', '>=') && !filter_var($repoConfig['url'], FILTER_VALIDATE_URL)) {
|
||||
throw new \UnexpectedValueException('Invalid url given for PEAR repository: '.$repoConfig['url']);
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ class PearRepository extends ArrayRepository
|
|||
}
|
||||
$this->addPackage($loader->load($rev));
|
||||
if ($this->io->isVerbose()) {
|
||||
$this->io->write('Loaded '. $data['name'].' '. $data['version']);
|
||||
$this->io->write('Loaded '.$rev['name'].' '.$rev['version']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,20 +27,14 @@ class GitBitbucketDriver extends VcsDriver implements VcsDriverInterface
|
|||
protected $rootIdentifier;
|
||||
protected $infoCache = array();
|
||||
|
||||
public function __construct($url, IOInterface $io)
|
||||
{
|
||||
preg_match('#^https://bitbucket\.org/([^/]+)/(.+?)\.git$#', $url, $match);
|
||||
$this->owner = $match[1];
|
||||
$this->repository = $match[2];
|
||||
|
||||
parent::__construct($url, $io);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
preg_match('#^https://bitbucket\.org/([^/]+)/(.+?)\.git$#', $this->url, $match);
|
||||
$this->owner = $match[1];
|
||||
$this->repository = $match[2];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,11 +28,6 @@ class GitDriver extends VcsDriver
|
|||
protected $repoDir;
|
||||
protected $infoCache = array();
|
||||
|
||||
public function __construct($url, IOInterface $io, ProcessExecutor $process = null)
|
||||
{
|
||||
parent::__construct($url, $io, $process);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -41,11 +36,13 @@ class GitDriver extends VcsDriver
|
|||
if (static::isLocalUrl($this->url)) {
|
||||
$this->repoDir = str_replace('file://', '', $this->url);
|
||||
} else {
|
||||
$this->repoDir = sys_get_temp_dir() . '/composer-' . preg_replace('{[^a-z0-9.]}i', '-', $this->url) . '/';
|
||||
$this->repoDir = $this->config->get('home') . '/cache.git/' . preg_replace('{[^a-z0-9.]}i', '-', $this->url) . '/';
|
||||
|
||||
// update the repo if it is a valid git repository
|
||||
if (is_dir($this->repoDir) && 0 === $this->process->execute('git remote', $output, $this->repoDir)) {
|
||||
$this->process->execute('git remote update --prune origin', $output, $this->repoDir);
|
||||
if (0 !== $this->process->execute('git remote update --prune origin', $output, $this->repoDir)) {
|
||||
$this->io->write('<error>Failed to update '.$this->url.', package information from this repository may be outdated ('.$this->process->getErrorOutput().')</error>');
|
||||
}
|
||||
} else {
|
||||
// clean up directory and do a fresh clone into it
|
||||
$fs = new Filesystem();
|
||||
|
|
|
@ -38,28 +38,15 @@ class GitHubDriver extends VcsDriver
|
|||
*/
|
||||
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, $process, $remoteFilesystem);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
preg_match('#^(?:https?|git)://github\.com/([^/]+)/(.+?)(?:\.git)?$#', $this->url, $match);
|
||||
$this->owner = $match[1];
|
||||
$this->repository = $match[2];
|
||||
|
||||
$this->fetchRootIdentifier();
|
||||
}
|
||||
|
||||
|
@ -248,6 +235,7 @@ class GitHubDriver extends VcsDriver
|
|||
$this->gitDriver = new GitDriver(
|
||||
$this->generateSshUrl(),
|
||||
$this->io,
|
||||
$this->config,
|
||||
$this->process,
|
||||
$this->remoteFilesystem
|
||||
);
|
||||
|
|
|
@ -27,20 +27,14 @@ class HgBitbucketDriver extends VcsDriver
|
|||
protected $rootIdentifier;
|
||||
protected $infoCache = array();
|
||||
|
||||
public function __construct($url, IOInterface $io)
|
||||
{
|
||||
preg_match('#^https://bitbucket\.org/([^/]+)/([^/]+)/?$#', $url, $match);
|
||||
$this->owner = $match[1];
|
||||
$this->repository = $match[2];
|
||||
|
||||
parent::__construct($url, $io);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
preg_match('#^https://bitbucket\.org/([^/]+)/([^/]+)/?$#', $this->url, $match);
|
||||
$this->owner = $match[1];
|
||||
$this->repository = $match[2];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,24 +26,21 @@ class HgDriver extends VcsDriver
|
|||
protected $rootIdentifier;
|
||||
protected $infoCache = array();
|
||||
|
||||
public function __construct($url, IOInterface $io, ProcessExecutor $process = null)
|
||||
{
|
||||
$this->tmpDir = sys_get_temp_dir() . '/composer-' . preg_replace('{[^a-z0-9]}i', '-', $url) . '/';
|
||||
|
||||
parent::__construct($url, $io, $process);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
$url = escapeshellarg($this->url);
|
||||
$tmpDir = escapeshellarg($this->tmpDir);
|
||||
$this->tmpDir = $this->config->get('home') . '/cache.hg/' . preg_replace('{[^a-z0-9]}i', '-', $this->url) . '/';
|
||||
|
||||
if (is_dir($this->tmpDir)) {
|
||||
$this->process->execute(sprintf('cd %s && hg pull -u', $tmpDir), $output);
|
||||
$this->process->execute(sprintf('cd %s && hg pull -u', escapeshellarg($this->tmpDir)), $output);
|
||||
} else {
|
||||
$this->process->execute(sprintf('cd %s && hg clone %s %s', escapeshellarg(sys_get_temp_dir()), $url, $tmpDir), $output);
|
||||
$dir = dirname($this->tmpDir);
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0777, true);
|
||||
}
|
||||
$this->process->execute(sprintf('cd %s && hg clone %s %s', escapeshellarg($dir), escapeshellarg($this->url), escapeshellarg($this->tmpDir)), $output);
|
||||
}
|
||||
|
||||
$this->getTags();
|
||||
|
|
|
@ -33,25 +33,7 @@ class SvnDriver extends VcsDriver
|
|||
/**
|
||||
* @var \Composer\Util\Svn
|
||||
*/
|
||||
protected $util;
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param IOInterface $io
|
||||
* @param ProcessExecutor $process
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function __construct($url, IOInterface $io, ProcessExecutor $process = null)
|
||||
{
|
||||
$url = self::normalizeUrl($url);
|
||||
parent::__construct($this->baseUrl = rtrim($url, '/'), $io, $process);
|
||||
|
||||
if (false !== ($pos = strrpos($url, '/trunk'))) {
|
||||
$this->baseUrl = substr($url, 0, $pos);
|
||||
}
|
||||
$this->util = new SvnUtil($this->baseUrl, $io, $this->process);
|
||||
}
|
||||
private $util;
|
||||
|
||||
/**
|
||||
* Execute an SVN command and try to fix up the process with credentials
|
||||
|
@ -64,6 +46,10 @@ class SvnDriver extends VcsDriver
|
|||
*/
|
||||
protected function execute($command, $url)
|
||||
{
|
||||
if (null === $this->util) {
|
||||
$this->util = new SvnUtil($this->baseUrl, $this->io, $this->process);
|
||||
}
|
||||
|
||||
try {
|
||||
return $this->util->execute($command, $url);
|
||||
} catch (\RuntimeException $e) {
|
||||
|
@ -78,6 +64,12 @@ class SvnDriver extends VcsDriver
|
|||
*/
|
||||
public function initialize()
|
||||
{
|
||||
$this->url = $this->baseUrl = rtrim(self::normalizeUrl($this->url), '/');
|
||||
|
||||
if (false !== ($pos = strrpos($this->url, '/trunk'))) {
|
||||
$this->baseUrl = substr($this->url, 0, $pos);
|
||||
}
|
||||
|
||||
$this->getBranches();
|
||||
$this->getTags();
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
namespace Composer\Repository\Vcs;
|
||||
|
||||
use Composer\Downloader\TransportException;
|
||||
use Composer\Config;
|
||||
use Composer\IO\IOInterface;
|
||||
use Composer\Util\ProcessExecutor;
|
||||
use Composer\Util\RemoteFilesystem;
|
||||
|
@ -26,6 +27,7 @@ abstract class VcsDriver implements VcsDriverInterface
|
|||
{
|
||||
protected $url;
|
||||
protected $io;
|
||||
protected $config;
|
||||
protected $process;
|
||||
protected $remoteFilesystem;
|
||||
|
||||
|
@ -34,13 +36,15 @@ abstract class VcsDriver implements VcsDriverInterface
|
|||
*
|
||||
* @param string $url The URL
|
||||
* @param IOInterface $io The IO instance
|
||||
* @param Config $config The composer configuration
|
||||
* @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, $remoteFilesystem = null)
|
||||
final public function __construct($url, IOInterface $io, Config $config, ProcessExecutor $process = null, $remoteFilesystem = null)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->io = $io;
|
||||
$this->config = $config;
|
||||
$this->process = $process ?: new ProcessExecutor;
|
||||
$this->remoteFilesystem = $remoteFilesystem ?: new RemoteFilesystem($io);
|
||||
}
|
||||
|
@ -58,7 +62,6 @@ abstract class VcsDriver implements VcsDriverInterface
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the https or http protocol depending on SSL support.
|
||||
*
|
||||
|
|
|
@ -30,10 +30,11 @@ class VcsRepository extends ArrayRepository
|
|||
protected $packageName;
|
||||
protected $verbose;
|
||||
protected $io;
|
||||
protected $config;
|
||||
protected $versionParser;
|
||||
protected $type;
|
||||
|
||||
public function __construct(array $repoConfig, IOInterface $io, Config $config = null, array $drivers = null)
|
||||
public function __construct(array $repoConfig, IOInterface $io, Config $config, array $drivers = null)
|
||||
{
|
||||
$this->drivers = $drivers ?: array(
|
||||
'github' => 'Composer\Repository\Vcs\GitHubDriver',
|
||||
|
@ -48,20 +49,21 @@ class VcsRepository extends ArrayRepository
|
|||
$this->io = $io;
|
||||
$this->type = isset($repoConfig['type']) ? $repoConfig['type'] : 'vcs';
|
||||
$this->verbose = $io->isVerbose();
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
public function getDriver()
|
||||
{
|
||||
if (isset($this->drivers[$this->type])) {
|
||||
$class = $this->drivers[$this->type];
|
||||
$driver = new $class($this->url, $this->io);
|
||||
$driver = new $class($this->url, $this->io, $this->config);
|
||||
$driver->initialize();
|
||||
return $driver;
|
||||
}
|
||||
|
||||
foreach ($this->drivers as $driver) {
|
||||
if ($driver::supports($this->io, $this->url)) {
|
||||
$driver = new $driver($this->url, $this->io);
|
||||
$driver = new $driver($this->url, $this->io, $this->config);
|
||||
$driver->initialize();
|
||||
return $driver;
|
||||
}
|
||||
|
@ -69,7 +71,7 @@ class VcsRepository extends ArrayRepository
|
|||
|
||||
foreach ($this->drivers as $driver) {
|
||||
if ($driver::supports($this->io, $this->url, true)) {
|
||||
$driver = new $driver($this->url, $this->io);
|
||||
$driver = new $driver($this->url, $this->io, $this->config);
|
||||
$driver->initialize();
|
||||
return $driver;
|
||||
}
|
||||
|
@ -102,7 +104,7 @@ class VcsRepository extends ArrayRepository
|
|||
}
|
||||
|
||||
foreach ($driver->getTags() as $tag => $identifier) {
|
||||
$msg = 'Get composer info for <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) {
|
||||
$this->io->write($msg);
|
||||
} else {
|
||||
|
@ -123,45 +125,45 @@ class VcsRepository extends ArrayRepository
|
|||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// manually versioned package
|
||||
if (isset($data['version'])) {
|
||||
$data['version_normalized'] = $this->versionParser->normalize($data['version']);
|
||||
} else {
|
||||
// auto-versionned package, read value from tag
|
||||
$data['version'] = $tag;
|
||||
$data['version_normalized'] = $parsedTag;
|
||||
}
|
||||
|
||||
// make sure tag packages have no -dev flag
|
||||
$data['version'] = preg_replace('{[.-]?dev$}i', '', $data['version']);
|
||||
$data['version_normalized'] = preg_replace('{(^dev-|[.-]?dev$)}i', '', $data['version_normalized']);
|
||||
|
||||
// broken package, version doesn't match tag
|
||||
if ($data['version_normalized'] !== $parsedTag) {
|
||||
if ($verbose) {
|
||||
$this->io->write('Skipped tag '.$tag.', tag ('.$parsedTag.') does not match version ('.$data['version_normalized'].') in composer.json');
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($verbose) {
|
||||
$this->io->write('Importing tag '.$tag.' ('.$data['version_normalized'].')');
|
||||
}
|
||||
|
||||
$this->addPackage($loader->load($this->preProcess($driver, $data, $identifier)));
|
||||
} catch (\Exception $e) {
|
||||
if ($verbose) {
|
||||
$this->io->write('Skipped tag '.$tag.', '.($e instanceof TransportException ? 'no composer file was found' : $e->getMessage()));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// manually versioned package
|
||||
if (isset($data['version'])) {
|
||||
$data['version_normalized'] = $this->versionParser->normalize($data['version']);
|
||||
} else {
|
||||
// auto-versionned package, read value from tag
|
||||
$data['version'] = $tag;
|
||||
$data['version_normalized'] = $parsedTag;
|
||||
}
|
||||
|
||||
// make sure tag packages have no -dev flag
|
||||
$data['version'] = preg_replace('{[.-]?dev$}i', '', $data['version']);
|
||||
$data['version_normalized'] = preg_replace('{(^dev-|[.-]?dev$)}i', '', $data['version_normalized']);
|
||||
|
||||
// broken package, version doesn't match tag
|
||||
if ($data['version_normalized'] !== $parsedTag) {
|
||||
if ($verbose) {
|
||||
$this->io->write('Skipped tag '.$tag.', tag ('.$parsedTag.') does not match version ('.$data['version_normalized'].') in composer.json');
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($verbose) {
|
||||
$this->io->write('Importing tag '.$tag.' ('.$data['version_normalized'].')');
|
||||
}
|
||||
|
||||
$this->addPackage($loader->load($this->preProcess($driver, $data, $identifier)));
|
||||
}
|
||||
|
||||
$this->io->overwrite('', false);
|
||||
|
||||
foreach ($driver->getBranches() as $branch => $identifier) {
|
||||
$msg = 'Get composer info for <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) {
|
||||
$this->io->write($msg);
|
||||
} else {
|
||||
|
@ -182,6 +184,23 @@ class VcsRepository extends ArrayRepository
|
|||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// branches are always auto-versionned, read value from branch name
|
||||
$data['version'] = $branch;
|
||||
$data['version_normalized'] = $parsedBranch;
|
||||
|
||||
// make sure branch packages have a dev flag
|
||||
if ('dev-' === substr($parsedBranch, 0, 4) || '9999999-dev' === $parsedBranch) {
|
||||
$data['version'] = 'dev-' . $data['version'];
|
||||
} else {
|
||||
$data['version'] = preg_replace('{(\.9{7})+}', '.x', $parsedBranch);
|
||||
}
|
||||
|
||||
if ($verbose) {
|
||||
$this->io->write('Importing branch '.$branch.' ('.$data['version'].')');
|
||||
}
|
||||
|
||||
$this->addPackage($loader->load($this->preProcess($driver, $data, $identifier)));
|
||||
} catch (TransportException $e) {
|
||||
if ($verbose) {
|
||||
$this->io->write('Skipped branch '.$branch.', no composer file was found');
|
||||
|
@ -191,23 +210,6 @@ class VcsRepository extends ArrayRepository
|
|||
$this->io->write('Skipped branch '.$branch.', '.$e->getMessage());
|
||||
continue;
|
||||
}
|
||||
|
||||
// branches are always auto-versionned, read value from branch name
|
||||
$data['version'] = $branch;
|
||||
$data['version_normalized'] = $parsedBranch;
|
||||
|
||||
// make sure branch packages have a dev flag
|
||||
if ('dev-' === substr($parsedBranch, 0, 4) || '9999999-dev' === $parsedBranch) {
|
||||
$data['version'] = 'dev-' . $data['version'];
|
||||
} else {
|
||||
$data['version'] = preg_replace('{(\.9{7})+}', '.x', $parsedBranch);
|
||||
}
|
||||
|
||||
if ($verbose) {
|
||||
$this->io->write('Importing branch '.$branch.' ('.$data['version'].')');
|
||||
}
|
||||
|
||||
$this->addPackage($loader->load($this->preProcess($driver, $data, $identifier)));
|
||||
}
|
||||
|
||||
$this->io->overwrite('', false);
|
||||
|
|
|
@ -34,23 +34,51 @@ final class StreamContextFactory
|
|||
// Handle system proxy
|
||||
if (isset($_SERVER['HTTP_PROXY']) || isset($_SERVER['http_proxy'])) {
|
||||
// Some systems seem to rely on a lowercased version instead...
|
||||
$proxy = isset($_SERVER['http_proxy']) ? $_SERVER['http_proxy'] : $_SERVER['HTTP_PROXY'];
|
||||
$proxy = parse_url(isset($_SERVER['http_proxy']) ? $_SERVER['http_proxy'] : $_SERVER['HTTP_PROXY']);
|
||||
}
|
||||
|
||||
if (!empty($proxy)) {
|
||||
$proxyURL = (isset($proxy['scheme']) ? $proxy['scheme'] : '') . '://';
|
||||
$proxyURL .= isset($proxy['host']) ? $proxy['host'] : '';
|
||||
|
||||
if (isset($proxy['port'])) {
|
||||
$proxyURL .= ":" . $proxy['port'];
|
||||
} elseif ('http://' == substr($proxyURL, 0, 7)) {
|
||||
$proxyURL .= ":80";
|
||||
} elseif ('https://' == substr($proxyURL, 0, 8)) {
|
||||
$proxyURL .= ":443";
|
||||
}
|
||||
|
||||
// http(s):// is not supported in proxy
|
||||
$proxy = str_replace(array('http://', 'https://'), array('tcp://', 'ssl://'), $proxy);
|
||||
$proxyURL = str_replace(array('http://', 'https://'), array('tcp://', 'ssl://'), $proxyURL);
|
||||
|
||||
if (0 === strpos($proxy, 'ssl:') && !extension_loaded('openssl')) {
|
||||
if (0 === strpos($proxyURL, 'ssl:') && !extension_loaded('openssl')) {
|
||||
throw new \RuntimeException('You must enable the openssl extension to use a proxy over https');
|
||||
}
|
||||
|
||||
$options['http'] = array(
|
||||
'proxy' => $proxy,
|
||||
'proxy' => $proxyURL,
|
||||
'request_fulluri' => true,
|
||||
);
|
||||
|
||||
if (isset($proxy['user'])) {
|
||||
$auth = $proxy['user'];
|
||||
if (isset($proxy['pass'])) {
|
||||
$auth .= ':' . $proxy['pass'];
|
||||
}
|
||||
$auth = base64_encode($auth);
|
||||
|
||||
// Preserve headers if already set in default options
|
||||
if (isset($defaultOptions['http']['header'])) {
|
||||
$defaultOptions['http']['header'] .= "Proxy-Authorization: Basic {$auth}\r\n";
|
||||
} else {
|
||||
$options['http']['header'] = "Proxy-Authorization: Basic {$auth}\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$options = array_merge_recursive($options, $defaultOptions);
|
||||
|
||||
$options = array_replace_recursive($options, $defaultOptions);
|
||||
|
||||
return stream_context_create($options, $defaultParams);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +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__.'/../vendor/.composer/autoload.php')) && (!$loader = includeIfExists(__DIR__.'/../../../.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;
|
||||
<?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__.'/../vendor/autoload.php')) && (!$loader = includeIfExists(__DIR__.'/../../../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;
|
||||
|
|
|
@ -60,14 +60,14 @@ class AutoloadGeneratorTest extends TestCase
|
|||
protected function tearDown()
|
||||
{
|
||||
if ($this->vendorDir === $this->workingDir) {
|
||||
if (is_dir($this->workingDir.'/.composer')) {
|
||||
$this->fs->removeDirectory($this->workingDir.'/.composer');
|
||||
if (is_dir($this->workingDir.'/composer')) {
|
||||
$this->fs->removeDirectory($this->workingDir.'/composer');
|
||||
}
|
||||
} elseif (is_dir($this->vendorDir)) {
|
||||
$this->fs->removeDirectory($this->vendorDir);
|
||||
}
|
||||
if (is_dir($this->workingDir.'/.composersrc')) {
|
||||
$this->fs->removeDirectory($this->workingDir.'/.composersrc');
|
||||
if (is_dir($this->workingDir.'/composersrc')) {
|
||||
$this->fs->removeDirectory($this->workingDir.'/composersrc');
|
||||
}
|
||||
|
||||
chdir($this->dir);
|
||||
|
@ -78,22 +78,22 @@ class AutoloadGeneratorTest extends TestCase
|
|||
$package = new MemoryPackage('a', '1.0', '1.0');
|
||||
$package->setAutoload(array(
|
||||
'psr-0' => array('Main' => 'src/', 'Lala' => array('src/', 'lib/')),
|
||||
'classmap' => array('.composersrc/'),
|
||||
'classmap' => array('composersrc/'),
|
||||
));
|
||||
|
||||
$this->repository->expects($this->once())
|
||||
->method('getPackages')
|
||||
->will($this->returnValue(array()));
|
||||
|
||||
if (!is_dir($this->vendorDir.'/.composer')) {
|
||||
mkdir($this->vendorDir.'/.composer');
|
||||
if (!is_dir($this->vendorDir.'/composer')) {
|
||||
mkdir($this->vendorDir.'/composer');
|
||||
}
|
||||
|
||||
$this->createClassFile($this->workingDir);
|
||||
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir.'/.composer');
|
||||
$this->assertAutoloadFiles('main', $this->vendorDir.'/.composer');
|
||||
$this->assertAutoloadFiles('classmap', $this->vendorDir.'/.composer', 'classmap');
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir.'/composer');
|
||||
$this->assertAutoloadFiles('main', $this->vendorDir.'/composer');
|
||||
$this->assertAutoloadFiles('classmap', $this->vendorDir.'/composer', 'classmap');
|
||||
}
|
||||
|
||||
public function testVendorDirSameAsWorkingDir()
|
||||
|
@ -103,22 +103,22 @@ class AutoloadGeneratorTest extends TestCase
|
|||
$package = new MemoryPackage('a', '1.0', '1.0');
|
||||
$package->setAutoload(array(
|
||||
'psr-0' => array('Main' => 'src/', 'Lala' => 'src/'),
|
||||
'classmap' => array('.composersrc/'),
|
||||
'classmap' => array('composersrc/'),
|
||||
));
|
||||
|
||||
$this->repository->expects($this->once())
|
||||
->method('getPackages')
|
||||
->will($this->returnValue(array()));
|
||||
|
||||
if (!is_dir($this->vendorDir.'/.composer')) {
|
||||
mkdir($this->vendorDir.'/.composer', 0777, true);
|
||||
if (!is_dir($this->vendorDir.'/composer')) {
|
||||
mkdir($this->vendorDir.'/composer', 0777, true);
|
||||
}
|
||||
|
||||
$this->createClassFile($this->vendorDir);
|
||||
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir.'/.composer');
|
||||
$this->assertAutoloadFiles('main3', $this->vendorDir.'/.composer');
|
||||
$this->assertAutoloadFiles('classmap3', $this->vendorDir.'/.composer', 'classmap');
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir.'/composer');
|
||||
$this->assertAutoloadFiles('main3', $this->vendorDir.'/composer');
|
||||
$this->assertAutoloadFiles('classmap3', $this->vendorDir.'/composer', 'classmap');
|
||||
}
|
||||
|
||||
public function testMainPackageAutoloadingAlternativeVendorDir()
|
||||
|
@ -126,7 +126,7 @@ class AutoloadGeneratorTest extends TestCase
|
|||
$package = new MemoryPackage('a', '1.0', '1.0');
|
||||
$package->setAutoload(array(
|
||||
'psr-0' => array('Main' => 'src/', 'Lala' => 'src/'),
|
||||
'classmap' => array('.composersrc/'),
|
||||
'classmap' => array('composersrc/'),
|
||||
));
|
||||
|
||||
$this->repository->expects($this->once())
|
||||
|
@ -134,11 +134,27 @@ class AutoloadGeneratorTest extends TestCase
|
|||
->will($this->returnValue(array()));
|
||||
|
||||
$this->vendorDir .= '/subdir';
|
||||
mkdir($this->vendorDir.'/.composer', 0777, true);
|
||||
mkdir($this->vendorDir.'/composer', 0777, true);
|
||||
$this->createClassFile($this->workingDir);
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir.'/.composer');
|
||||
$this->assertAutoloadFiles('main2', $this->vendorDir.'/.composer');
|
||||
$this->assertAutoloadFiles('classmap2', $this->vendorDir.'/.composer', 'classmap');
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir.'/composer');
|
||||
$this->assertAutoloadFiles('main2', $this->vendorDir.'/composer');
|
||||
$this->assertAutoloadFiles('classmap2', $this->vendorDir.'/composer', 'classmap');
|
||||
}
|
||||
|
||||
public function testMainPackageAutoloadingWithTargetDir()
|
||||
{
|
||||
$package = new MemoryPackage('a', '1.0', '1.0');
|
||||
$package->setAutoload(array(
|
||||
'psr-0' => array('Main\\Foo' => '', 'Main\\Bar' => ''),
|
||||
));
|
||||
$package->setTargetDir('Main/Foo/');
|
||||
|
||||
$this->repository->expects($this->once())
|
||||
->method('getPackages')
|
||||
->will($this->returnValue(array()));
|
||||
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir.'/composer');
|
||||
$this->assertFileEquals(__DIR__.'/Fixtures/autoload_target_dir.php', $this->vendorDir.'/autoload.php');
|
||||
}
|
||||
|
||||
public function testVendorsAutoloading()
|
||||
|
@ -155,10 +171,10 @@ class AutoloadGeneratorTest extends TestCase
|
|||
->method('getPackages')
|
||||
->will($this->returnValue($packages));
|
||||
|
||||
mkdir($this->vendorDir.'/.composer', 0777, true);
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir.'/.composer');
|
||||
$this->assertAutoloadFiles('vendors', $this->vendorDir.'/.composer');
|
||||
$this->assertTrue(file_exists($this->vendorDir.'/.composer/autoload_classmap.php'), "ClassMap file needs to be generated, even if empty.");
|
||||
mkdir($this->vendorDir.'/composer', 0777, true);
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir.'/composer');
|
||||
$this->assertAutoloadFiles('vendors', $this->vendorDir.'/composer');
|
||||
$this->assertTrue(file_exists($this->vendorDir.'/composer/autoload_classmap.php'), "ClassMap file needs to be generated, even if empty.");
|
||||
}
|
||||
|
||||
public function testVendorsClassMapAutoloading()
|
||||
|
@ -175,7 +191,7 @@ class AutoloadGeneratorTest extends TestCase
|
|||
->method('getPackages')
|
||||
->will($this->returnValue($packages));
|
||||
|
||||
@mkdir($this->vendorDir.'/.composer', 0777, true);
|
||||
@mkdir($this->vendorDir.'/composer', 0777, true);
|
||||
mkdir($this->vendorDir.'/a/a/src', 0777, true);
|
||||
mkdir($this->vendorDir.'/b/b/src', 0777, true);
|
||||
mkdir($this->vendorDir.'/b/b/lib', 0777, true);
|
||||
|
@ -183,17 +199,17 @@ class AutoloadGeneratorTest extends TestCase
|
|||
file_put_contents($this->vendorDir.'/b/b/src/b.php', '<?php class ClassMapBar {}');
|
||||
file_put_contents($this->vendorDir.'/b/b/lib/c.php', '<?php class ClassMapBaz {}');
|
||||
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir.'/.composer');
|
||||
$this->assertTrue(file_exists($this->vendorDir.'/.composer/autoload_classmap.php'), "ClassMap file needs to be generated.");
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir.'/composer');
|
||||
$this->assertTrue(file_exists($this->vendorDir.'/composer/autoload_classmap.php'), "ClassMap file needs to be generated.");
|
||||
$this->assertEquals(
|
||||
array(
|
||||
'ClassMapFoo' => $this->workingDir.'/composer-test-autoload/a/a/src/a.php',
|
||||
'ClassMapBar' => $this->workingDir.'/composer-test-autoload/b/b/src/b.php',
|
||||
'ClassMapBaz' => $this->workingDir.'/composer-test-autoload/b/b/lib/c.php',
|
||||
),
|
||||
include ($this->vendorDir.'/.composer/autoload_classmap.php')
|
||||
include ($this->vendorDir.'/composer/autoload_classmap.php')
|
||||
);
|
||||
$this->assertAutoloadFiles('classmap4', $this->vendorDir.'/.composer', 'classmap');
|
||||
$this->assertAutoloadFiles('classmap4', $this->vendorDir.'/composer', 'classmap');
|
||||
}
|
||||
|
||||
public function testClassMapAutoloadingEmptyDirAndExactFile()
|
||||
|
@ -212,7 +228,7 @@ class AutoloadGeneratorTest extends TestCase
|
|||
->method('getPackages')
|
||||
->will($this->returnValue($packages));
|
||||
|
||||
@mkdir($this->vendorDir.'/.composer', 0777, true);
|
||||
@mkdir($this->vendorDir.'/composer', 0777, true);
|
||||
mkdir($this->vendorDir.'/a/a/src', 0777, true);
|
||||
mkdir($this->vendorDir.'/b/b', 0777, true);
|
||||
mkdir($this->vendorDir.'/c/c/foo', 0777, true);
|
||||
|
@ -220,17 +236,17 @@ class AutoloadGeneratorTest extends TestCase
|
|||
file_put_contents($this->vendorDir.'/b/b/test.php', '<?php class ClassMapBar {}');
|
||||
file_put_contents($this->vendorDir.'/c/c/foo/test.php', '<?php class ClassMapBaz {}');
|
||||
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir.'/.composer');
|
||||
$this->assertTrue(file_exists($this->vendorDir.'/.composer/autoload_classmap.php'), "ClassMap file needs to be generated.");
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir.'/composer');
|
||||
$this->assertTrue(file_exists($this->vendorDir.'/composer/autoload_classmap.php'), "ClassMap file needs to be generated.");
|
||||
$this->assertEquals(
|
||||
array(
|
||||
'ClassMapFoo' => $this->workingDir.'/composer-test-autoload/a/a/src/a.php',
|
||||
'ClassMapBar' => $this->workingDir.'/composer-test-autoload/b/b/test.php',
|
||||
'ClassMapBaz' => $this->workingDir.'/composer-test-autoload/c/c/foo/test.php',
|
||||
),
|
||||
include ($this->vendorDir.'/.composer/autoload_classmap.php')
|
||||
include ($this->vendorDir.'/composer/autoload_classmap.php')
|
||||
);
|
||||
$this->assertAutoloadFiles('classmap5', $this->vendorDir.'/.composer', 'classmap');
|
||||
$this->assertAutoloadFiles('classmap5', $this->vendorDir.'/composer', 'classmap');
|
||||
}
|
||||
|
||||
public function testOverrideVendorsAutoloading()
|
||||
|
@ -248,9 +264,9 @@ class AutoloadGeneratorTest extends TestCase
|
|||
->method('getPackages')
|
||||
->will($this->returnValue($packages));
|
||||
|
||||
mkdir($this->vendorDir.'/.composer', 0777, true);
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir.'/.composer');
|
||||
$this->assertAutoloadFiles('override_vendors', $this->vendorDir.'/.composer');
|
||||
mkdir($this->vendorDir.'/composer', 0777, true);
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir.'/composer');
|
||||
$this->assertAutoloadFiles('override_vendors', $this->vendorDir.'/composer');
|
||||
}
|
||||
|
||||
public function testIncludePathFileGeneration()
|
||||
|
@ -264,23 +280,29 @@ class AutoloadGeneratorTest extends TestCase
|
|||
$b = new MemoryPackage("b/b", "1.0", "1.0");
|
||||
$b->setIncludePaths(array("library"));
|
||||
|
||||
$c = new MemoryPackage("c", "1.0", "1.0");
|
||||
$c->setIncludePaths(array("library"));
|
||||
|
||||
$packages[] = $a;
|
||||
$packages[] = $b;
|
||||
$packages[] = $c;
|
||||
|
||||
$this->repository->expects($this->once())
|
||||
->method("getPackages")
|
||||
->will($this->returnValue($packages));
|
||||
|
||||
mkdir($this->vendorDir."/.composer", 0777, true);
|
||||
mkdir($this->vendorDir."/composer", 0777, true);
|
||||
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir."/.composer");
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir."/composer");
|
||||
|
||||
$this->assertFileEquals(__DIR__.'/Fixtures/include_paths.php', $this->vendorDir.'/composer/include_paths.php');
|
||||
$this->assertEquals(
|
||||
array(
|
||||
$this->vendorDir."/a/a/lib/",
|
||||
$this->vendorDir."/b/b/library"
|
||||
$this->vendorDir."/a/a/lib",
|
||||
$this->vendorDir."/b/b/library",
|
||||
$this->vendorDir."/c/library",
|
||||
),
|
||||
require($this->vendorDir."/.composer/include_paths.php")
|
||||
require($this->vendorDir."/composer/include_paths.php")
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -298,16 +320,16 @@ class AutoloadGeneratorTest extends TestCase
|
|||
->method("getPackages")
|
||||
->will($this->returnValue($packages));
|
||||
|
||||
mkdir($this->vendorDir."/.composer", 0777, true);
|
||||
mkdir($this->vendorDir."/composer", 0777, true);
|
||||
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir."/.composer");
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir."/composer");
|
||||
|
||||
$oldIncludePath = get_include_path();
|
||||
|
||||
require($this->vendorDir."/.composer/autoload.php");
|
||||
require($this->vendorDir."/autoload.php");
|
||||
|
||||
$this->assertEquals(
|
||||
$oldIncludePath.PATH_SEPARATOR.$this->vendorDir."/a/a/lib/",
|
||||
$oldIncludePath.PATH_SEPARATOR.$this->vendorDir."/a/a/lib",
|
||||
get_include_path()
|
||||
);
|
||||
|
||||
|
@ -326,20 +348,20 @@ class AutoloadGeneratorTest extends TestCase
|
|||
->method("getPackages")
|
||||
->will($this->returnValue($packages));
|
||||
|
||||
mkdir($this->vendorDir."/.composer", 0777, true);
|
||||
mkdir($this->vendorDir."/composer", 0777, true);
|
||||
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir."/.composer");
|
||||
$this->generator->dump($this->repository, $package, $this->im, $this->vendorDir."/composer");
|
||||
|
||||
$this->assertFalse(file_exists($this->vendorDir."/.composer/include_paths.php"));
|
||||
$this->assertFalse(file_exists($this->vendorDir."/composer/include_paths.php"));
|
||||
}
|
||||
|
||||
private function createClassFile($basedir)
|
||||
{
|
||||
if (!is_dir($basedir.'/.composersrc')) {
|
||||
mkdir($basedir.'/.composersrc', 0777, true);
|
||||
if (!is_dir($basedir.'/composersrc')) {
|
||||
mkdir($basedir.'/composersrc', 0777, true);
|
||||
}
|
||||
|
||||
file_put_contents($basedir.'/.composersrc/foo.php', '<?php class ClassMapFoo {}');
|
||||
file_put_contents($basedir.'/composersrc/foo.php', '<?php class ClassMapFoo {}');
|
||||
}
|
||||
|
||||
private function assertAutoloadFiles($name, $dir, $type = 'namespaces')
|
||||
|
|
|
@ -6,5 +6,5 @@ $vendorDir = dirname(__DIR__);
|
|||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'ClassMapFoo' => $baseDir . '/.composersrc/foo.php',
|
||||
'ClassMapFoo' => $baseDir . '/composersrc/foo.php',
|
||||
);
|
||||
|
|
|
@ -6,5 +6,5 @@ $vendorDir = dirname(__DIR__);
|
|||
$baseDir = dirname(dirname($vendorDir));
|
||||
|
||||
return array(
|
||||
'ClassMapFoo' => $baseDir . '/.composersrc/foo.php',
|
||||
'ClassMapFoo' => $baseDir . '/composersrc/foo.php',
|
||||
);
|
||||
|
|
|
@ -6,5 +6,5 @@ $vendorDir = dirname(__DIR__);
|
|||
$baseDir = $vendorDir;
|
||||
|
||||
return array(
|
||||
'ClassMapFoo' => $baseDir . '/.composersrc/foo.php',
|
||||
'ClassMapFoo' => $baseDir . '/composersrc/foo.php',
|
||||
);
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
// autoload.php generated by Composer
|
||||
if (!class_exists('Composer\\Autoload\\ClassLoader', false)) {
|
||||
require __DIR__ . '/composer' . '/ClassLoader.php';
|
||||
}
|
||||
|
||||
return call_user_func(function() {
|
||||
$loader = new \Composer\Autoload\ClassLoader();
|
||||
$composerDir = __DIR__ . '/composer';
|
||||
|
||||
$map = require $composerDir . '/autoload_namespaces.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->add($namespace, $path);
|
||||
}
|
||||
|
||||
$classMap = require $composerDir . '/autoload_classmap.php';
|
||||
if ($classMap) {
|
||||
$loader->addClassMap($classMap);
|
||||
}
|
||||
|
||||
spl_autoload_register(function($class) {
|
||||
$dir = dirname(__DIR__) . '/';
|
||||
$prefixes = array('Main\\Foo', 'Main\\Bar');
|
||||
foreach ($prefixes as $prefix) {
|
||||
if (0 !== strpos($class, $prefix)) {
|
||||
continue;
|
||||
}
|
||||
$path = $dir . implode('/', array_slice(explode('\\', $class), 2)).'.php';
|
||||
if (!stream_resolve_include_path($path)) {
|
||||
return false;
|
||||
}
|
||||
require_once $path;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
$loader->register();
|
||||
|
||||
return $loader;
|
||||
});
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
// include_paths.php generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
$vendorDir . '/a/a/lib',
|
||||
$vendorDir . '/b/b/library',
|
||||
$vendorDir . '/c/library',
|
||||
);
|
|
@ -18,6 +18,7 @@ use Composer\DependencyResolver\DefaultPolicy;
|
|||
use Composer\DependencyResolver\Pool;
|
||||
use Composer\DependencyResolver\Literal;
|
||||
use Composer\Package\Link;
|
||||
use Composer\Package\AliasPackage;
|
||||
use Composer\Package\LinkConstraint\VersionConstraint;
|
||||
use Composer\Test\TestCase;
|
||||
|
||||
|
@ -99,6 +100,35 @@ class DefaultPolicyTest extends TestCase
|
|||
$this->assertEquals($expected, $selected);
|
||||
}
|
||||
|
||||
public function testSelectLocalReposFirst()
|
||||
{
|
||||
$this->repoImportant = new ArrayRepository;
|
||||
|
||||
$this->repo->addPackage($packageA = $this->getPackage('A', 'dev-master'));
|
||||
$this->repo->addPackage($packageAAlias = new AliasPackage($packageA, '2.1.9999999.9999999-dev', '2.1.x-dev'));
|
||||
$this->repoImportant->addPackage($packageAImportant = $this->getPackage('A', 'dev-feature-a'));
|
||||
$this->repoImportant->addPackage($packageAAliasImportant = new AliasPackage($packageAImportant, '2.1.9999999.9999999-dev', '2.1.x-dev'));
|
||||
$this->repoImportant->addPackage($packageA2Important = $this->getPackage('A', 'dev-master'));
|
||||
$this->repoImportant->addPackage($packageA2AliasImportant = new AliasPackage($packageA2Important, '2.1.9999999.9999999-dev', '2.1.x-dev'));
|
||||
$packageAAliasImportant->setRootPackageAlias(true);
|
||||
|
||||
$this->pool->addRepository($this->repoInstalled);
|
||||
$this->pool->addRepository($this->repoImportant);
|
||||
$this->pool->addRepository($this->repo);
|
||||
|
||||
$packages = $this->pool->whatProvides('a', new VersionConstraint('=', '2.1.9999999.9999999-dev'));
|
||||
$literals = array();
|
||||
foreach ($packages as $package) {
|
||||
$literals[] = new Literal($package, true);
|
||||
}
|
||||
|
||||
$expected = array(new Literal($packageAAliasImportant, true));
|
||||
|
||||
$selected = $this->policy->selectPreferedPackages($this->pool, array(), $literals);
|
||||
|
||||
$this->assertEquals($expected, $selected);
|
||||
}
|
||||
|
||||
public function testSelectAllProviders()
|
||||
{
|
||||
$this->repo->addPackage($packageA = $this->getPackage('A', '1.0'));
|
||||
|
|
|
@ -16,10 +16,17 @@ use Composer\Downloader\DownloadManager;
|
|||
|
||||
class DownloadManagerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $filesystem;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->filesystem = $this->getMock('Composer\Util\Filesystem');
|
||||
}
|
||||
|
||||
public function testSetGetDownloader()
|
||||
{
|
||||
$downloader = $this->createDownloaderMock();
|
||||
$manager = new DownloadManager();
|
||||
$manager = new DownloadManager(false, $this->filesystem);
|
||||
|
||||
$manager->setDownloader('test', $downloader);
|
||||
$this->assertSame($downloader, $manager->getDownloader('test'));
|
||||
|
@ -36,7 +43,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
|
|||
->method('getInstallationSource')
|
||||
->will($this->returnValue(null));
|
||||
|
||||
$manager = new DownloadManager();
|
||||
$manager = new DownloadManager(false, $this->filesystem);
|
||||
|
||||
$this->setExpectedException('InvalidArgumentException');
|
||||
|
||||
|
@ -62,6 +69,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
|
|||
->will($this->returnValue('dist'));
|
||||
|
||||
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
|
||||
->setConstructorArgs(array(false, $this->filesystem))
|
||||
->setMethods(array('getDownloader'))
|
||||
->getMock();
|
||||
|
||||
|
@ -93,6 +101,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
|
|||
->will($this->returnValue('source'));
|
||||
|
||||
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
|
||||
->setConstructorArgs(array(false, $this->filesystem))
|
||||
->setMethods(array('getDownloader'))
|
||||
->getMock();
|
||||
|
||||
|
@ -126,6 +135,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
|
|||
->will($this->returnValue('source'));
|
||||
|
||||
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
|
||||
->setConstructorArgs(array(false, $this->filesystem))
|
||||
->setMethods(array('getDownloader'))
|
||||
->getMock();
|
||||
|
||||
|
@ -157,6 +167,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
|
|||
->will($this->returnValue('dist'));
|
||||
|
||||
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
|
||||
->setConstructorArgs(array(false, $this->filesystem))
|
||||
->setMethods(array('getDownloader'))
|
||||
->getMock();
|
||||
|
||||
|
@ -195,6 +206,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
|
|||
->with($package, 'target_dir');
|
||||
|
||||
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
|
||||
->setConstructorArgs(array(false, $this->filesystem))
|
||||
->setMethods(array('getDownloaderForInstalledPackage'))
|
||||
->getMock();
|
||||
$manager
|
||||
|
@ -218,7 +230,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
|
|||
->method('getDistType')
|
||||
->will($this->returnValue(null));
|
||||
|
||||
$manager = new DownloadManager();
|
||||
$manager = new DownloadManager(false, $this->filesystem);
|
||||
|
||||
$this->setExpectedException('InvalidArgumentException');
|
||||
$manager->download($package, 'target_dir');
|
||||
|
@ -248,6 +260,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
|
|||
->with($package, 'target_dir');
|
||||
|
||||
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
|
||||
->setConstructorArgs(array(false, $this->filesystem))
|
||||
->setMethods(array('getDownloaderForInstalledPackage'))
|
||||
->getMock();
|
||||
$manager
|
||||
|
@ -283,6 +296,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
|
|||
->with($package, 'target_dir');
|
||||
|
||||
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
|
||||
->setConstructorArgs(array(false, $this->filesystem))
|
||||
->setMethods(array('getDownloaderForInstalledPackage'))
|
||||
->getMock();
|
||||
$manager
|
||||
|
@ -318,6 +332,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
|
|||
->with($package, 'target_dir');
|
||||
|
||||
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
|
||||
->setConstructorArgs(array(false, $this->filesystem))
|
||||
->setMethods(array('getDownloaderForInstalledPackage'))
|
||||
->getMock();
|
||||
$manager
|
||||
|
@ -354,6 +369,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
|
|||
->with($package, 'target_dir');
|
||||
|
||||
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
|
||||
->setConstructorArgs(array(false, $this->filesystem))
|
||||
->setMethods(array('getDownloaderForInstalledPackage'))
|
||||
->getMock();
|
||||
$manager
|
||||
|
@ -390,6 +406,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
|
|||
->with($package, 'target_dir');
|
||||
|
||||
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
|
||||
->setConstructorArgs(array(false, $this->filesystem))
|
||||
->setMethods(array('getDownloaderForInstalledPackage'))
|
||||
->getMock();
|
||||
$manager
|
||||
|
@ -414,7 +431,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
|
|||
->method('getDistType')
|
||||
->will($this->returnValue(null));
|
||||
|
||||
$manager = new DownloadManager();
|
||||
$manager = new DownloadManager(false, $this->filesystem);
|
||||
$manager->setPreferSource(true);
|
||||
|
||||
$this->setExpectedException('InvalidArgumentException');
|
||||
|
@ -450,6 +467,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
|
|||
->with($initial, $target, 'vendor/bundles/FOS/UserBundle');
|
||||
|
||||
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
|
||||
->setConstructorArgs(array(false, $this->filesystem))
|
||||
->setMethods(array('getDownloaderForInstalledPackage'))
|
||||
->getMock();
|
||||
$manager
|
||||
|
@ -486,6 +504,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
|
|||
->with($initial, 'vendor/bundles/FOS/UserBundle');
|
||||
|
||||
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
|
||||
->setConstructorArgs(array(false, $this->filesystem))
|
||||
->setMethods(array('getDownloaderForInstalledPackage', 'download'))
|
||||
->getMock();
|
||||
$manager
|
||||
|
@ -526,6 +545,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
|
|||
->with($initial, $target, 'vendor/pkg');
|
||||
|
||||
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
|
||||
->setConstructorArgs(array(false, $this->filesystem))
|
||||
->setMethods(array('getDownloaderForInstalledPackage', 'download'))
|
||||
->getMock();
|
||||
$manager
|
||||
|
@ -562,6 +582,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
|
|||
->with($initial, 'vendor/pkg');
|
||||
|
||||
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
|
||||
->setConstructorArgs(array(false, $this->filesystem))
|
||||
->setMethods(array('getDownloaderForInstalledPackage', 'download'))
|
||||
->getMock();
|
||||
$manager
|
||||
|
@ -588,6 +609,7 @@ class DownloadManagerTest extends \PHPUnit_Framework_TestCase
|
|||
->with($package, 'vendor/bundles/FOS/UserBundle');
|
||||
|
||||
$manager = $this->getMockBuilder('Composer\Downloader\DownloadManager')
|
||||
->setConstructorArgs(array(false, $this->filesystem))
|
||||
->setMethods(array('getDownloaderForInstalledPackage'))
|
||||
->getMock();
|
||||
$manager
|
||||
|
|
|
@ -140,7 +140,7 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase
|
|||
public function testUpdate()
|
||||
{
|
||||
$expectedGitUpdateCommand = $this->getCmd("cd 'composerPath' && git remote set-url composer 'git://github.com/composer/composer' && git fetch composer && git fetch --tags composer && git checkout 'ref' && git reset --hard 'ref'");
|
||||
$expectedGitResetCommand = $this->getCmd("cd 'composerPath' && git status --porcelain");
|
||||
$expectedGitResetCommand = $this->getCmd("cd 'composerPath' && git status --porcelain --untracked-files=no");
|
||||
|
||||
$packageMock = $this->getMock('Composer\Package\PackageInterface');
|
||||
$packageMock->expects($this->any())
|
||||
|
@ -173,7 +173,7 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase
|
|||
public function testUpdateThrowsRuntimeExceptionIfGitCommandFails()
|
||||
{
|
||||
$expectedGitUpdateCommand = $this->getCmd("cd 'composerPath' && git remote set-url composer 'git://github.com/composer/composer' && git fetch composer && git fetch --tags composer && git checkout 'ref' && git reset --hard 'ref'");
|
||||
$expectedGitResetCommand = $this->getCmd("cd 'composerPath' && git status --porcelain");
|
||||
$expectedGitResetCommand = $this->getCmd("cd 'composerPath' && git status --porcelain --untracked-files=no");
|
||||
|
||||
$packageMock = $this->getMock('Composer\Package\PackageInterface');
|
||||
$packageMock->expects($this->any())
|
||||
|
@ -202,7 +202,7 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
public function testRemove()
|
||||
{
|
||||
$expectedGitResetCommand = $this->getCmd("cd 'composerPath' && git status --porcelain");
|
||||
$expectedGitResetCommand = $this->getCmd("cd 'composerPath' && git status --porcelain --untracked-files=no");
|
||||
|
||||
$packageMock = $this->getMock('Composer\Package\PackageInterface');
|
||||
$processExecutor = $this->getMock('Composer\Util\ProcessExecutor');
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
<?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\Installer;
|
||||
use Composer\Repository\ArrayRepository;
|
||||
use Composer\Repository\RepositoryManager;
|
||||
use Composer\Repository\RepositoryInterface;
|
||||
use Composer\Package\PackageInterface;
|
||||
use Composer\Package\Link;
|
||||
use Composer\Test\Mock\WritableRepositoryMock;
|
||||
use Composer\Test\Mock\InstallationManagerMock;
|
||||
|
||||
class InstallerTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideInstaller
|
||||
*/
|
||||
public function testInstaller(PackageInterface $rootPackage, $repositories, array $options)
|
||||
{
|
||||
$io = $this->getMock('Composer\IO\IOInterface');
|
||||
|
||||
$downloadManager = $this->getMock('Composer\Downloader\DownloadManager');
|
||||
$config = $this->getMock('Composer\Config');
|
||||
|
||||
$repositoryManager = new RepositoryManager($io, $config);
|
||||
$repositoryManager->setLocalRepository(new WritableRepositoryMock());
|
||||
$repositoryManager->setLocalDevRepository(new WritableRepositoryMock());
|
||||
|
||||
if (!is_array($repositories)) {
|
||||
$repositories = array($repositories);
|
||||
}
|
||||
foreach ($repositories as $repository) {
|
||||
$repositoryManager->addRepository($repository);
|
||||
}
|
||||
|
||||
$locker = $this->getMockBuilder('Composer\Package\Locker')->disableOriginalConstructor()->getMock();
|
||||
$installationManager = new InstallationManagerMock();
|
||||
$eventDispatcher = $this->getMockBuilder('Composer\Script\EventDispatcher')->disableOriginalConstructor()->getMock();
|
||||
$autoloadGenerator = $this->getMock('Composer\Autoload\AutoloadGenerator');
|
||||
|
||||
$installer = new Installer($io, clone $rootPackage, $downloadManager, $repositoryManager, $locker, $installationManager, $eventDispatcher, $autoloadGenerator);
|
||||
$result = $installer->run();
|
||||
$this->assertTrue($result);
|
||||
|
||||
$expectedInstalled = isset($options['install']) ? $options['install'] : array();
|
||||
$expectedUpdated = isset($options['update']) ? $options['update'] : array();
|
||||
$expectedUninstalled = isset($options['uninstall']) ? $options['uninstall'] : array();
|
||||
|
||||
$installed = $installationManager->getInstalledPackages();
|
||||
$this->assertSame($expectedInstalled, $installed);
|
||||
|
||||
$updated = $installationManager->getUpdatedPackages();
|
||||
$this->assertSame($expectedUpdated, $updated);
|
||||
|
||||
$uninstalled = $installationManager->getUninstalledPackages();
|
||||
$this->assertSame($expectedUninstalled, $uninstalled);
|
||||
}
|
||||
|
||||
public function provideInstaller()
|
||||
{
|
||||
$cases = array();
|
||||
|
||||
// when A requires B and B requires A, and A is a non-published root package
|
||||
// the install of B should succeed
|
||||
|
||||
$a = $this->getPackage('A', '1.0.0');
|
||||
$a->setRequires(array(
|
||||
new Link('A', 'B', $this->getVersionConstraint('=', '1.0.0')),
|
||||
));
|
||||
$b = $this->getPackage('B', '1.0.0');
|
||||
$b->setRequires(array(
|
||||
new Link('B', 'A', $this->getVersionConstraint('=', '1.0.0')),
|
||||
));
|
||||
|
||||
$cases[] = array(
|
||||
$a,
|
||||
new ArrayRepository(array($b)),
|
||||
array(
|
||||
'install' => array($b)
|
||||
),
|
||||
);
|
||||
|
||||
// #480: when A requires B and B requires A, and A is a published root package
|
||||
// only B should be installed, as A is the root
|
||||
|
||||
$a = $this->getPackage('A', '1.0.0');
|
||||
$a->setRequires(array(
|
||||
new Link('A', 'B', $this->getVersionConstraint('=', '1.0.0')),
|
||||
));
|
||||
$b = $this->getPackage('B', '1.0.0');
|
||||
$b->setRequires(array(
|
||||
new Link('B', 'A', $this->getVersionConstraint('=', '1.0.0')),
|
||||
));
|
||||
|
||||
$cases[] = array(
|
||||
$a,
|
||||
new ArrayRepository(array($a, $b)),
|
||||
array(
|
||||
'install' => array($b)
|
||||
),
|
||||
);
|
||||
|
||||
return $cases;
|
||||
}
|
||||
}
|
|
@ -128,6 +128,20 @@ class JsonFileTest extends \PHPUnit_Framework_TestCase
|
|||
$this->assertJsonFormat($json, $data);
|
||||
}
|
||||
|
||||
public function testFormatEmptyArray()
|
||||
{
|
||||
$data = array('test' => array(), 'test2' => new \stdClass);
|
||||
$json = '{
|
||||
"test": [
|
||||
|
||||
],
|
||||
"test2": {
|
||||
|
||||
}
|
||||
}';
|
||||
$this->assertJsonFormat($json, $data);
|
||||
}
|
||||
|
||||
public function testEscape()
|
||||
{
|
||||
$data = array("Metadata\\\"" => 'src/');
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
<?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\Mock;
|
||||
|
||||
use Composer\Installer\InstallationManager;
|
||||
use Composer\Repository\RepositoryInterface;
|
||||
use Composer\DependencyResolver\Operation\OperationInterface;
|
||||
use Composer\DependencyResolver\Operation\InstallOperation;
|
||||
use Composer\DependencyResolver\Operation\UpdateOperation;
|
||||
use Composer\DependencyResolver\Operation\UninstallOperation;
|
||||
|
||||
class InstallationManagerMock extends InstallationManager
|
||||
{
|
||||
private $installed = array();
|
||||
private $updated = array();
|
||||
private $uninstalled = array();
|
||||
|
||||
public function install(RepositoryInterface $repo, InstallOperation $operation)
|
||||
{
|
||||
$this->installed[] = $operation->getPackage();
|
||||
}
|
||||
|
||||
public function update(RepositoryInterface $repo, UpdateOperation $operation)
|
||||
{
|
||||
$this->updated[] = array($operation->getInitialPackage(), $operation->getTargetPackage());
|
||||
}
|
||||
|
||||
public function uninstall(RepositoryInterface $repo, UninstallOperation $operation)
|
||||
{
|
||||
$this->uninstalled[] = $operation->getPackage();
|
||||
}
|
||||
|
||||
public function getInstalledPackages()
|
||||
{
|
||||
return $this->installed;
|
||||
}
|
||||
|
||||
public function getUpdatedPackages()
|
||||
{
|
||||
return $this->updated;
|
||||
}
|
||||
|
||||
public function getUninstalledPackages()
|
||||
{
|
||||
return $this->uninstalled;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?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\Mock;
|
||||
|
||||
use Composer\Repository\ArrayRepository;
|
||||
use Composer\Repository\WritableRepositoryInterface;
|
||||
|
||||
class WritableRepositoryMock extends ArrayRepository implements WritableRepositoryInterface
|
||||
{
|
||||
public function reload()
|
||||
{
|
||||
}
|
||||
|
||||
public function write()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -89,7 +89,7 @@ class ArrayLoaderTest extends \PHPUnit_Framework_TestCase
|
|||
'homepage' => 'http://example.com',
|
||||
'license' => array('MIT', 'GPLv3'),
|
||||
'authors' => array(
|
||||
array('name' => 'Bob', 'email' => 'bob@example.org', 'homepage' => 'example.org'),
|
||||
array('name' => 'Bob', 'email' => 'bob@example.org', 'homepage' => 'example.org', 'role' => 'Developer'),
|
||||
),
|
||||
'require' => array(
|
||||
'foo/bar' => '1.0',
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace Composer\Test\Repository\Vcs;
|
|||
use Composer\Downloader\TransportException;
|
||||
use Composer\Repository\Vcs\GitHubDriver;
|
||||
use Composer\Util\Filesystem;
|
||||
use Composer\Config;
|
||||
|
||||
/**
|
||||
* @author Beau Simensen <beau@dflydev.com>
|
||||
|
@ -64,7 +65,7 @@ class GitHubDriverTest extends \PHPUnit_Framework_TestCase
|
|||
->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 = new GitHubDriver($repoUrl, $io, new Config(), null, $remoteFilesystem);
|
||||
$gitHubDriver->initialize();
|
||||
$this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha));
|
||||
|
||||
|
@ -114,7 +115,7 @@ class GitHubDriverTest extends \PHPUnit_Framework_TestCase
|
|||
->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 = new GitHubDriver($repoUrl, $io, new Config(), null, $remoteFilesystem);
|
||||
$gitHubDriver->initialize();
|
||||
$this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha));
|
||||
|
||||
|
@ -171,7 +172,14 @@ class GitHubDriverTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
// clean local clone if present
|
||||
$fs = new Filesystem();
|
||||
$fs->removeDirectory(sys_get_temp_dir() . '/composer-' . preg_replace('{[^a-z0-9.]}i', '-', $repoSshUrl) . '/');
|
||||
$fs->removeDirectory(sys_get_temp_dir() . '/composer-test');
|
||||
|
||||
$config = new Config();
|
||||
$config->merge(array(
|
||||
'config' => array(
|
||||
'home' => sys_get_temp_dir() . '/composer-test',
|
||||
),
|
||||
));
|
||||
|
||||
$process->expects($this->at(0))
|
||||
->method('execute')
|
||||
|
@ -202,7 +210,7 @@ class GitHubDriverTest extends \PHPUnit_Framework_TestCase
|
|||
->method('splitLines')
|
||||
->will($this->returnValue(array('* test_master')));
|
||||
|
||||
$gitHubDriver = new GitHubDriver($repoUrl, $io, $process, $remoteFilesystem);
|
||||
$gitHubDriver = new GitHubDriver($repoUrl, $io, $config, $process, $remoteFilesystem);
|
||||
$gitHubDriver->initialize();
|
||||
|
||||
$this->assertEquals('test_master', $gitHubDriver->getRootIdentifier());
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace Composer\Test\Repository\Vcs;
|
|||
|
||||
use Composer\Repository\Vcs\SvnDriver;
|
||||
use Composer\IO\NullIO;
|
||||
use Composer\Config;
|
||||
|
||||
class SvnDriverTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
@ -39,8 +40,8 @@ class SvnDriverTest extends \PHPUnit_Framework_TestCase
|
|||
->method('getErrorOutput')
|
||||
->will($this->returnValue($output));
|
||||
|
||||
$svn = new SvnDriver('http://till:secret@corp.svn.local/repo', $console, $process);
|
||||
$svn->getTags();
|
||||
$svn = new SvnDriver('http://till:secret@corp.svn.local/repo', $console, new Config(), $process);
|
||||
$svn->initialize();
|
||||
}
|
||||
|
||||
private function getCmd($cmd)
|
||||
|
|
|
@ -19,6 +19,7 @@ use Composer\Repository\Vcs\GitDriver;
|
|||
use Composer\Util\Filesystem;
|
||||
use Composer\Util\ProcessExecutor;
|
||||
use Composer\IO\NullIO;
|
||||
use Composer\Config;
|
||||
|
||||
class VcsRepositoryTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
@ -123,7 +124,7 @@ class VcsRepositoryTest extends \PHPUnit_Framework_TestCase
|
|||
'dev-master' => true,
|
||||
);
|
||||
|
||||
$repo = new VcsRepository(array('url' => self::$gitRepo, 'type' => 'vcs'), new NullIO);
|
||||
$repo = new VcsRepository(array('url' => self::$gitRepo, 'type' => 'vcs'), new NullIO, new Config());
|
||||
$packages = $repo->getPackages();
|
||||
$dumper = new ArrayDumper();
|
||||
|
||||
|
|
|
@ -19,26 +19,29 @@ use Composer\Util\Filesystem;
|
|||
|
||||
abstract class TestCase extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
private static $versionParser;
|
||||
private static $parser;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
protected static function getVersionParser()
|
||||
{
|
||||
if (!self::$versionParser) {
|
||||
self::$versionParser = new VersionParser();
|
||||
if (!self::$parser) {
|
||||
self::$parser = new VersionParser();
|
||||
}
|
||||
|
||||
return self::$parser;
|
||||
}
|
||||
|
||||
protected function getVersionConstraint($operator, $version)
|
||||
{
|
||||
return new VersionConstraint(
|
||||
$operator,
|
||||
self::$versionParser->normalize($version)
|
||||
self::getVersionParser()->normalize($version)
|
||||
);
|
||||
}
|
||||
|
||||
protected function getPackage($name, $version)
|
||||
{
|
||||
$normVersion = self::$versionParser->normalize($version);
|
||||
$normVersion = self::getVersionParser()->normalize($version);
|
||||
|
||||
return new MemoryPackage($name, $normVersion, $version);
|
||||
}
|
||||
|
||||
|
|
|
@ -57,31 +57,63 @@ class StreamContextFactoryTest extends \PHPUnit_Framework_TestCase
|
|||
|
||||
public function testHttpProxy()
|
||||
{
|
||||
$_SERVER['http_proxy'] = 'http://username:password@proxyserver.net:port/';
|
||||
$_SERVER['http_proxy'] = 'http://username:password@proxyserver.net:3128/';
|
||||
$_SERVER['HTTP_PROXY'] = 'http://proxyserver/';
|
||||
|
||||
$context = StreamContextFactory::getContext(array('http' => array('method' => 'GET')));
|
||||
$options = stream_context_get_options($context);
|
||||
|
||||
$this->assertSame('http://proxyserver/', $_SERVER['HTTP_PROXY']);
|
||||
|
||||
$this->assertEquals(array('http' => array(
|
||||
'proxy' => 'tcp://username:password@proxyserver.net:port/',
|
||||
'proxy' => 'tcp://proxyserver.net:3128',
|
||||
'request_fulluri' => true,
|
||||
'method' => 'GET',
|
||||
'header' => "Proxy-Authorization: Basic " . base64_encode('username:password') . "\r\n"
|
||||
)), $options);
|
||||
}
|
||||
|
||||
public function testSSLProxy()
|
||||
public function testOptionsArePreserved()
|
||||
{
|
||||
$_SERVER['http_proxy'] = 'https://proxyserver/';
|
||||
$_SERVER['http_proxy'] = 'http://username:password@proxyserver.net:3128/';
|
||||
|
||||
$context = StreamContextFactory::getContext(array('http' => array('method' => 'GET', 'header' => "X-Foo: bar\r\n", 'request_fulluri' => false)));
|
||||
$options = stream_context_get_options($context);
|
||||
|
||||
$this->assertEquals(array('http' => array(
|
||||
'proxy' => 'tcp://proxyserver.net:3128',
|
||||
'request_fulluri' => false,
|
||||
'method' => 'GET',
|
||||
'header' => "X-Foo: bar\r\nProxy-Authorization: Basic " . base64_encode('username:password') . "\r\n"
|
||||
)), $options);
|
||||
}
|
||||
|
||||
public function testHttpProxyWithoutPort()
|
||||
{
|
||||
$_SERVER['http_proxy'] = 'http://username:password@proxyserver.net';
|
||||
|
||||
$context = StreamContextFactory::getContext(array('http' => array('method' => 'GET')));
|
||||
$options = stream_context_get_options($context);
|
||||
|
||||
$this->assertEquals(array('http' => array(
|
||||
'proxy' => 'tcp://proxyserver.net:80',
|
||||
'request_fulluri' => true,
|
||||
'method' => 'GET',
|
||||
'header' => "Proxy-Authorization: Basic " . base64_encode('username:password') . "\r\n"
|
||||
)), $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataSSLProxy
|
||||
*/
|
||||
public function testSSLProxy($expected, $proxy)
|
||||
{
|
||||
$_SERVER['http_proxy'] = $proxy;
|
||||
|
||||
if (extension_loaded('openssl')) {
|
||||
$context = StreamContextFactory::getContext();
|
||||
$options = stream_context_get_options($context);
|
||||
|
||||
$this->assertSame(array('http' => array(
|
||||
'proxy' => 'ssl://proxyserver/',
|
||||
$this->assertEquals(array('http' => array(
|
||||
'proxy' => $expected,
|
||||
'request_fulluri' => true,
|
||||
)), $options);
|
||||
} else {
|
||||
|
@ -93,4 +125,12 @@ class StreamContextFactoryTest extends \PHPUnit_Framework_TestCase
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function dataSSLProxy()
|
||||
{
|
||||
return array(
|
||||
array('ssl://proxyserver:443', 'https://proxyserver/'),
|
||||
array('ssl://proxyserver:8443', 'https://proxyserver:8443'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue