* Added config.platform to let you specify what your target environment looks like and make sure you do not inadvertently install dependencies that would break it
* Added `exclude-from-classmap` in the autoload config that lets you ignore sub-paths of classmapped directories, or psr-0/4 directories when building optimized autoloaders
* Added `path` repository type to install/symlink packages from local paths
* Added possibility to reference script handlers from within other handlers using @script-name to reduce duplication
* Added `suggests` command to show what packages are suggested, use -v to see more details
* Added `content-hash` inside the composer.lock to restrict the warnings about outdated lock file to some specific changes in the composer.json file
* Added `archive-format` and `archive-dir` config options to specify default values for the archive command
* Added --classmap-authoritative to `install`, `update`, `require`, `remove` and `dump-autoload` commands, forcing the optimized classmap to be authoritative
* Added -A / --with-dependencies to the `validate` command to allow validating all your dependencies recursively
* Added --strict to the `validate` command to treat any warning as an error that then returns a non-zero exit code
* Added a dependency on composer/semver, which is the externalized lib for all the version constraints parsing and handling
* Added support for classmap autoloading to load plugin classes and script handlers
* Added `bin-compat` config option that if set to `full` will create .bat proxy for binaries even if Compoesr runs in a linux VM
* Added SPDX 2.0 support, and externalized that in a composer/spdx-licenses lib
* Added warnings when the classmap autoloader finds duplicate classes
* Added --file to the `archive` command to choose the filename
* Added Ctrl+C handling in create-project to cancel the operation cleanly
* Fixed version guessing to use ^ always, default to stable versions, and avoid versions that require a higher php version than you have
* Fixed the lock file switching back and forth between old and new URL when a package URL is changed and many people run updates
* Fixed partial updates updating things they shouldn't when the current vendor dir was out of date with the lock file
* Fixed PHAR file creation to be more reproducible and always generate the exact same phar file from a given source
* Fixed issue when checking out git branches or tags that are also the name of a file in the repo
* Many minor fixes and documentation additions and UX improvements
### [1.0.0-alpha10] - 2015-04-14
* Break: The following event classes are deprecated and you should update your script handlers to use the new ones in type hints:
- `Composer\Script\CommandEvent` is deprecated, use `Composer\Script\Event`
- `Composer\Script\PackageEvent` is deprecated, use `Composer\Installer\PackageEvent`
* Break: Output is now split between stdout and stderr. Any irrelevant output to each command is on stderr as per unix best practices.
* Added support for npm-style semver operators (`^` and `-` ranges, ` ` = AND, `||` = OR)
* Added --prefer-lowest to `update` command to allow testing a package with the lowest declared dependencies
* Added support for parsing semver build metadata `+anything` at the end of versions
* Added --sort-packages option to `require` command for sorting dependencies
* Added --no-autoloader to `install` and `update` commands to skip autoload generation
* Added --list to `run-script` command to see available scripts
* Added --absolute to `config` command to get back absolute paths
* Added `classmap-authoritative` config option, if enabled only the classmap info will be used by the composer autoloader
* Added support for branch-alias on numeric branches
* Added support for the `https_proxy`/`HTTPS_PROXY` env vars used only for https URLs
* Added support for using real composer repos as local paths in `create-project` command
* Added --no-dev to `licenses` command
* Added support for PHP 7.0 nightly builds
* Fixed detection of stability when parsing multiple constraints
* Fixed installs from lock file containing updated composer.json requirement
* Fixed the autoloader suffix in vendor/autoload.php changing in every build
* Many minor fixes, documentation additions and UX improvements
### [1.0.0-alpha9] - 2014-12-07
* Added `remove` command to do the reverse of `require`
* Added `remove` command to do the reverse of `require`
* Added --ignore-platform-reqs to `install`/`update` commands to install even if you are missing a php extension or have an invalid php version
* Added --ignore-platform-reqs to `install`/`update` commands to install even if you are missing a php extension or have an invalid php version
@ -28,7 +78,7 @@
* Improved SVN and Perforce support
* Improved SVN and Perforce support
* A boatload of minor fixes, documentation additions and UX improvements
* A boatload of minor fixes, documentation additions and UX improvements
### 1.0.0-alpha8 (2014-01-06)
### [1.0.0-alpha8] - 2014-01-06
* Break: The `install` command now has --dev enabled by default. --no-dev can be used to install without dev requirements
* Break: The `install` command now has --dev enabled by default. --no-dev can be used to install without dev requirements
* Added `composer-plugin` package type to allow extensibility, and deprecated `composer-installer`
* Added `composer-plugin` package type to allow extensibility, and deprecated `composer-installer`
@ -59,7 +109,7 @@
* Improved memory usage and performance of solving dependencies
* Improved memory usage and performance of solving dependencies
* Tons of minor bug fixes and improvements
* Tons of minor bug fixes and improvements
### 1.0.0-alpha7 (2013-05-04)
### [1.0.0-alpha7] - 2013-05-04
* Break: For forward compatibility, you should change your deployment scripts to run `composer install --no-dev`. The install command will install dev dependencies by default starting in the next release
* Break: For forward compatibility, you should change your deployment scripts to run `composer install --no-dev`. The install command will install dev dependencies by default starting in the next release
* Break: The `update` command now has --dev enabled by default. --no-dev can be used to update without dev requirements, but it will create an incomplete lock file and is discouraged
* Break: The `update` command now has --dev enabled by default. --no-dev can be used to update without dev requirements, but it will create an incomplete lock file and is discouraged
@ -110,10 +160,10 @@
* Improved the coverage of the `validate` command
* Improved the coverage of the `validate` command
* Tons of minor bug fixes and improvements
* Tons of minor bug fixes and improvements
### 1.0.0-alpha6 (2012-10-23)
### [1.0.0-alpha6] - 2012-10-23
* Schema: Added ability to pass additional options to repositories (i.e. ssh keys/client certificates to secure private repos)
* Schema: Added ability to pass additional options to repositories (i.e. ssh keys/client certificates to secure private repos)
* Schema: Added a new `~` operator that should be prefered over `>=`, see http://getcomposer.org/doc/01-basic-usage.md#package-versions
* Schema: Added a new `~` operator that should be preferred over `>=`, see http://getcomposer.org/doc/01-basic-usage.md#package-versions
* Schema: Version constraints `<x.y` are assumed to be `<x.y-dev` unless specified as `<x.y-stable` to reduce confusion
* Schema: Version constraints `<x.y` are assumed to be `<x.y-dev` unless specified as `<x.y-stable` to reduce confusion
* Added `config` command to edit/list config values, including --global switch for system config
* Added `config` command to edit/list config values, including --global switch for system config
* Added OAuth token support for the GitHub API
* Added OAuth token support for the GitHub API
@ -121,7 +171,7 @@
* Added --prefer-dist flag to force installs of dev packages from zip archives instead of clones
* Added --prefer-dist flag to force installs of dev packages from zip archives instead of clones
* Added --working-dir (-d) flag to change the working directory
* Added --working-dir (-d) flag to change the working directory
* Added --profile flag to all commands to display execution time and memory usage
* Added --profile flag to all commands to display execution time and memory usage
* Added `github-protocols` config key to define the order of prefered protocols for github.com clones
* Added `github-protocols` config key to define the order of preferred protocols for github.com clones
* Added ability to interactively reset changes to vendor dirs while updating
* Added ability to interactively reset changes to vendor dirs while updating
* Added support for hg bookmarks in the hg driver
* Added support for hg bookmarks in the hg driver
* Added support for svn repositories not following the standard trunk/branch/tags scheme
* Added support for svn repositories not following the standard trunk/branch/tags scheme
@ -135,7 +185,7 @@
* Improved performance of a few essential code paths
* Improved performance of a few essential code paths
* Many bug small fixes and docs improvements
* Many bug small fixes and docs improvements
### 1.0.0-alpha5 (2012-08-18)
### [1.0.0-alpha5] - 2012-08-18
* Added `dump-autoload` command to only regenerate the autoloader
* Added `dump-autoload` command to only regenerate the autoloader
* Added --optimize to `dump-autoload` to generate a more performant classmap-based autoloader for production
* Added --optimize to `dump-autoload` to generate a more performant classmap-based autoloader for production
@ -153,7 +203,7 @@
* Improved error reporting on network failures and some other edge cases
* Improved error reporting on network failures and some other edge cases
* Various minor bug fixes and docs improvements
* Various minor bug fixes and docs improvements
### 1.0.0-alpha4 (2012-07-04)
### [1.0.0-alpha4] - 2012-07-04
* Break: The default `minimum-stability` is now `stable`, [read more](https://groups.google.com/d/topic/composer-dev/_g3ASeIFlrc/discussion)
* Break: The default `minimum-stability` is now `stable`, [read more](https://groups.google.com/d/topic/composer-dev/_g3ASeIFlrc/discussion)
* Break: Custom installers now receive the IO instance and a Composer instance in their constructor
* Break: Custom installers now receive the IO instance and a Composer instance in their constructor
@ -181,7 +231,7 @@
* Cleaned up / refactored the dependency solver code as well as the output for unsolvable requirements
* Cleaned up / refactored the dependency solver code as well as the output for unsolvable requirements
* Various bug fixes and docs improvements
* Various bug fixes and docs improvements
### 1.0.0-alpha3 (2012-05-13)
### [1.0.0-alpha3] - 2012-05-13
* Schema: Added `require-dev` for development-time requirements (tests, etc), install with --dev
* Schema: Added `require-dev` for development-time requirements (tests, etc), install with --dev
* Schema: Added author.role to list the author's role in the project
* Schema: Added author.role to list the author's role in the project
@ -203,7 +253,7 @@
* Fixed various bugs relating to package aliasing, proxy configuration, binaries
* Fixed various bugs relating to package aliasing, proxy configuration, binaries
* Various bug fixes and docs improvements
* Various bug fixes and docs improvements
### 1.0.0-alpha2 (2012-04-03)
### [1.0.0-alpha2] - 2012-04-03
* Added `create-project` command to install a project from scratch with composer
* Added `create-project` command to install a project from scratch with composer
* Added automated `classmap` autoloading support for non-PSR-0 compliant projects
* Added automated `classmap` autoloading support for non-PSR-0 compliant projects
@ -218,6 +268,17 @@
* Removed dependency on filter_var
* Removed dependency on filter_var
* Various robustness & error handling improvements, docs fixes and more bug fixes
* Various robustness & error handling improvements, docs fixes and more bug fixes
"_":"phpunit/phpunit-mock-objects required in 2.3.0 due to https://github.com/sebastianbergmann/phpunit-mock-objects/issues/223 - needs hhvm 3.8+ on travis",
"config":{
"platform":{
"php":"5.3.9"
}
},
},
"suggest":{
"suggest":{
"ext-zip":"Enabling the zip extension allows you to unzip archives, and allows gzip compression of all internet traffic",
"ext-zip":"Enabling the zip extension allows you to unzip archives, and allows gzip compression of all internet traffic",
"ext-openssl":"Enabling the openssl extension allows you to access https URLs for repositories and packages"
"ext-openssl":"Enabling the openssl extension allows you to access https URLs for repositories and packages"
Now just run `php bin/composer` in order to run Composer.
#### Globally
#### Globally
You can place this file anywhere you wish. If you put it in your `PATH`,
You can place the Composer PHAR anywhere you wish. If you put it in a directory
you can access it globally. On unixy systems you can even make it
that is part of your `PATH`, you can access it globally. On unixy systems you
executable and invoke it without `php`.
can even make it executable and invoke it without directly using the `php`
interpreter.
You can run these commands to easily access `composer` from anywhere on your system:
Run these commands to globally install `composer` on your system:
```sh
```sh
curl -sS https://getcomposer.org/installer | php
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
mv composer.phar /usr/local/bin/composer
```
```
> **Note:** If the above fails due to permissions, run the `mv` line
> **Note:** If the above fails due to permissions, run the `mv` line again
> again with sudo.
> with sudo.
> **Note:** In OSX Yosemite the `/usr` directory does not exist by default. If you receive the error "/usr/local/bin/composer: No such file or directory" then you must create `/usr/local/bin/` manually before proceeding.
A quick copy-paste version including sudo:
Then, just run `composer` in order to run Composer instead of `php composer.phar`.
Exact version | `1.0.2` | You can specify the exact version of a package.
Range | `>=1.0``>=1.0 <2.0`<code>>=1.0 <1.1 ||>=1.2</code> | By using comparison operators you can specify ranges of valid versions. Valid operators are `>`, `>=`, `<`, `<=`, `!=`. <br/>You can define multiple ranges. Ranges separated by a space (<code></code>) or comma (`,`) will be treated as a **logical AND**. A double pipe (<code>||</code>) will be treated as a **logical OR**. AND has higher precedence than OR.
Hyphen Range | `1.0 - 2.0` | Inclusive set of versions. Partial versions on the right include are completed with a wildcard. For example `1.0 - 2.0` is equivalent to `>=1.0.0 <2.1` as the `2.0` becomes `2.0.*`. On the other hand `1.0.0 - 2.1.0` is equivalent to `>=1.0.0 <=2.1.0`.
Wildcard | `1.0.*` | You can specify a pattern with a `*` wildcard. `1.0.*` is the equivalent of `>=1.0 <1.1`.
Tilde Operator | `~1.2` | Very useful for projects that follow semantic versioning. `~1.2` is equivalent to `>=1.2 <2.0`. For more details, read the next section below.
Caret Operator | `^1.2.3` | Very useful for projects that follow semantic versioning. `^1.2.3` is equivalent to `>=1.2.3 <2.0`. For more details, read the next section below.
### Next Significant Release (Tilde and Caret Operators)
The `~` operator is best explained by example: `~1.2` is equivalent to
`>=1.2 <2.0.0`, while `~1.2.3` is equivalent to `>=1.2.3 <1.3.0`. As you can see
it is mostly useful for projects respecting [semantic
versioning](http://semver.org/). A common usage would be to mark the minimum
minor version you depend on, like `~1.2` (which allows anything up to, but not
including, 2.0). Since in theory there should be no backwards compatibility
breaks until 2.0, that works well. Another way of looking at it is that using
`~` specifies a minimum version, but allows the last digit specified to go up.
The `^` operator behaves very similarly but it sticks closer to semantic
versioning, and will always allow non-breaking updates. For example `^1.2.3`
is equivalent to `>=1.2.3 <2.0.0` as none of the releases until 2.0 should
break backwards compatibility. For pre-1.0 versions it also acts with safety
in mind and treats `^0.3` as `>=0.3.0 <0.4.0`
> **Note:** Though `2.0-beta.1` is strictly before `2.0`, a version constraint
> like `~1.2` would not install it. As said above `~1.2` only means the `.2`
> can change but the `1.` part is fixed.
> **Note:** The `~` operator has an exception on its behavior for the major
> release number. This means for example that `~1` is the same as `~1.0` as
> it will not allow the major number to increase trying to keep backwards
> compatibility.
### Stability
### Stability
By default only stable releases are taken into consideration. If you would like
By default only stable releases are taken into consideration. If you would
to also get RC, beta, alpha or dev versions of your dependencies you can do
like to also get RC, beta, alpha or dev versions of your dependencies you can
so using [stability flags](04-schema.md#package-links). To change that for all
do so using [stability flags](04-schema.md#package-links). To change that for
packages instead of doing per dependency you can also use the
all packages instead of doing per dependency you can also use the
[Toran Proxy](https://toranproxy.com/) is a commercial alternative to Satis offering professional support as well as a web UI to manage everything and a better integration with Composer.
[Toran Proxy](https://toranproxy.com/) is a commercial alternative to Satis
offering professional support as well as a web UI to manage everything and a
better integration with Composer. It also provides proxying/mirroring for git
repos and package zip files which makes installs faster and independent from
third party systems.
Toran's revenue is also used to pay for Composer and Packagist development and hosting so using it is a good way to support open source financially. You can find more information about how to set it up and use it on the [Toran Proxy](https://toranproxy.com/) website.
Toran's revenue is also used to pay for Composer and Packagist development and
hosting so using it is a good way to support open source financially. You can
find more information about how to set it up and use it on the [Toran Proxy](https://toranproxy.com/) website.
# Satis
# Satis
Satis on the other hand is open source but only a static `composer`
Satis on the other hand is open source but only a static `composer`
repository generator. It is a bit like an ultra-lightweight, static file-based
repository generator. It is a bit like an ultra-lightweight, static file-based
version of packagist and can be used to host the metadata of your company's
version of packagist and can be used to host the metadata of your company's
private packages, or your own. You can get it from [GitHub](http://github.com/composer/satis)
private packages, or your own. You can get it from [GitHub](https://github.com/composer/satis)
That will store it in the current directory's auth.json, but if you want it available globally you can use the
`--global` (`-g`) flag.
### Downloads
### Downloads
@ -176,10 +243,14 @@ following to your `satis.json`:
#### Options explained
#### Options explained
* `directory`: the location of the dist files (inside the `output-dir`)
* `directory`: required, the location of the dist files (inside the `output-dir`)
* `format`: optional, `zip` (default) or `tar`
* `format`: optional, `zip` (default) or `tar`
* `prefix-url`: optional, location of the downloads, homepage (from `satis.json`) followed by `directory` by default
* `prefix-url`: optional, location of the downloads, homepage (from `satis.json`) followed by `directory` by default
* `skip-dev`: optional, `false` by default, when enabled (`true`) satis will not create downloads for branches
* `skip-dev`: optional, `false` by default, when enabled (`true`) satis will not create downloads for branches
* `absolute-directory`: optional, a _local_ directory where the dist files are dumped instead of `output-dir`/`directory`
* `whitelist`: optional, if set as a list of package names, satis will only dump the dist files of these packages
* `blacklist`: optional, if set as a list of package names, satis will not dump the dist files of these packages
* `checksum`: optional, `true` by default, when disabled (`false`) satis will not provide the sha1 checksum for the dist files
Once enabled, all downloads (include those from GitHub and BitBucket) will be replaced with a _local_ version.
Once enabled, all downloads (include those from GitHub and BitBucket) will be replaced with a _local_ version.
@ -188,9 +259,31 @@ Once enabled, all downloads (include those from GitHub and BitBucket) will be re
Prefixing the URL with another host is especially helpful if the downloads end up in a private Amazon S3
Prefixing the URL with another host is especially helpful if the downloads end up in a private Amazon S3
bucket or on a CDN host. A CDN would drastically improve download times and therefore package installation.
bucket or on a CDN host. A CDN would drastically improve download times and therefore package installation.
Example: A `prefix-url` of `http://my-bucket.s3.amazonaws.com` (and `directory` set to `dist`) creates download URLs
Example: A `prefix-url` of `https://my-bucket.s3.amazonaws.com` (and `directory` set to `dist`) creates download URLs
which look like the following: `http://my-bucket.s3.amazonaws.com/dist/vendor-package-version-ref.zip`.
which look like the following: `https://my-bucket.s3.amazonaws.com/dist/vendor-package-version-ref.zip`.
### Web outputs
* `output-html`: optional, `true` by default, when disabled (`false`) satis will not generate the `output-dir`/index.html page.
* `twig-template`: optional, a path to a personalized [Twig](http://twig.sensiolabs.org/) template for the `output-dir`/index.html page.
### Abandoned packages
To enable your satis installation to indicate that some packages are abandoned, add the following to your `satis.json`:
```json
{
"abandoned": {
"company/package": true,
"company/package2": "company/newpackage"
}
}
```
The `true` value indicates that the package is truly abandoned while the `"company/newpackage"` value specifies that the package is replaced by
the `company/newpackage` package.
Note that all packages set as abandoned in their own `composer.json` file will be marked abandoned as well.
### Resolving dependencies
### Resolving dependencies
@ -209,3 +302,11 @@ When searching for packages, satis will attempt to resolve all the required pack
Therefore, if you are requiring a package from Packagist, you will need to define it in your `satis.json`.
Therefore, if you are requiring a package from Packagist, you will need to define it in your `satis.json`.
Dev dependencies are packaged only if the `require-dev-dependencies` parameter is set to true.
Dev dependencies are packaged only if the `require-dev-dependencies` parameter is set to true.
### Other options
* `output-dir`: optional, defines where to output the repository files
if not provided as an argument when calling the `build` command.
* `config`: optional, lets you define all config options from composer, except `archive-format` and `archive-dir` as the configuration is done through [archive](#downloads) instead. See
(http://getcomposer.org/doc/04-schema.md#config)
* `notify-batch`: optional, specify a URL that will be called every time a user installs a package. See (https://getcomposer.org/doc/05-repositories.md#notify-batch)
"description":"Package version, see http://getcomposer.org/doc/04-schema.md#version for more info on valid schemes."
"description":"Package version, see https://getcomposer.org/doc/04-schema.md#version for more info on valid schemes."
},
},
"time":{
"time":{
"type":"string",
"type":"string",
@ -136,6 +136,11 @@
"description":"A hash of domain name => github API oauth tokens, typically {\"github.com\":\"<token>\"}.",
"description":"A hash of domain name => github API oauth tokens, typically {\"github.com\":\"<token>\"}.",
"additionalProperties":true
"additionalProperties":true
},
},
"gitlab-oauth":{
"type":"object",
"description":"A hash of domain name => gitlab API oauth tokens, typically {\"gitlab.com\":\"<token>\"}.",
"additionalProperties":true
},
"http-basic":{
"http-basic":{
"type":"object",
"type":"object",
"description":"A hash of domain name => {\"username\": \"...\", \"password\": \"...\"}.",
"description":"A hash of domain name => {\"username\": \"...\", \"password\": \"...\"}.",
@ -145,6 +150,11 @@
"type":["string","boolean"],
"type":["string","boolean"],
"description":"What to do after prompting for authentication, one of: true (store), false (do not store) or \"prompt\" (ask every time), defaults to prompt."
"description":"What to do after prompting for authentication, one of: true (store), false (do not store) or \"prompt\" (ask every time), defaults to prompt."
},
},
"platform":{
"type":"object",
"description":"This is a hash of package name (keys) and version (values) that will be used to mock the platform packages on this machine.",
"additionalProperties":true
},
"vendor-dir":{
"vendor-dir":{
"type":"string",
"type":"string",
"description":"The location where all packages are installed, defaults to \"vendor\"."
"description":"The location where all packages are installed, defaults to \"vendor\"."
@ -181,6 +191,10 @@
"type":["string","integer"],
"type":["string","integer"],
"description":"The cache max size for the files cache, defaults to \"300MiB\"."
"description":"The cache max size for the files cache, defaults to \"300MiB\"."
},
},
"bin-compat":{
"enum":["auto","full"],
"description":"The compatibility of the binaries, defaults to \"auto\" (automatically guessed) and can be \"full\" (compatible with both Windows and Unix-based systems)."
},
"discard-changes":{
"discard-changes":{
"type":["string","boolean"],
"type":["string","boolean"],
"description":"The default style of handling dirty updates, defaults to false and can be any of true, false or \"stash\"."
"description":"The default style of handling dirty updates, defaults to false and can be any of true, false or \"stash\"."
@ -211,6 +225,21 @@
"github-expose-hostname":{
"github-expose-hostname":{
"type":"boolean",
"type":"boolean",
"description":"Defaults to true. If set to false, the OAuth tokens created to access the github API will have a date instead of the machine hostname."
"description":"Defaults to true. If set to false, the OAuth tokens created to access the github API will have a date instead of the machine hostname."
},
"gitlab-domains":{
"type":"array",
"description":"A list of domains to use in gitlab mode. This is used for custom GitLab setups, defaults to [\"gitlab.com\"].",
"items":{
"type":"string"
}
},
"archive-format":{
"type":"string",
"description":"The default archiving format when not provided on cli, defaults to \"tar\"."
},
"archive-dir":{
"type":"string",
"description":"The default archive path when not provided on cli, defaults to \".\"."
}
}
}
}
},
},
@ -240,6 +269,10 @@
"files":{
"files":{
"type":"array",
"type":"array",
"description":"This is an array of files that are always required on every request."
"description":"This is an array of files that are always required on every request."
},
"exclude-from-classmap":{
"type":"array",
"description":"This is an array of patterns to exclude from autoload classmap generation. (e.g. \"exclude-from-classmap\": [\"/test/\", \"/tests/\", \"/Tests/\"]"
}
}
}
}
},
},
@ -284,11 +317,12 @@
},
},
"minimum-stability":{
"minimum-stability":{
"type":["string"],
"type":["string"],
"description":"The minimum stability the packages must have to be install-able. Possible values are: dev, alpha, beta, RC, stable."
"description":"The minimum stability the packages must have to be install-able. Possible values are: dev, alpha, beta, RC, stable.",
"pattern":"^dev|alpha|beta|rc|RC|stable$"
},
},
"prefer-stable":{
"prefer-stable":{
"type":["boolean"],
"type":["boolean"],
"description":"If set to true, stable packages will be prefered to dev packages when possible, even if the minimum-stability allows unstable packages."
"description":"If set to true, stable packages will be preferred to dev packages when possible, even if the minimum-stability allows unstable packages."
},
},
"bin":{
"bin":{
"type":["array"],
"type":["array"],
@ -384,17 +418,17 @@
},
},
"issues":{
"issues":{
"type":"string",
"type":"string",
"description":"URL to the Issue Tracker.",
"description":"URL to the issue tracker.",
"format":"uri"
"format":"uri"
},
},
"forum":{
"forum":{
"type":"string",
"type":"string",
"description":"URL to the Forum.",
"description":"URL to the forum.",
"format":"uri"
"format":"uri"
},
},
"wiki":{
"wiki":{
"type":"string",
"type":"string",
"description":"URL to the Wiki.",
"description":"URL to the wiki.",
"format":"uri"
"format":"uri"
},
},
"irc":{
"irc":{
@ -406,8 +440,24 @@
"type":"string",
"type":"string",
"description":"URL to browse or download the sources.",
"description":"URL to browse or download the sources.",
"format":"uri"
"format":"uri"
},
"docs":{
"type":"string",
"description":"URL to the documentation.",
"format":"uri"
}
}
}
}
},
"non-feature-branches":{
"type":["array"],
"description":"A set of string or regex patterns for non-numeric branch names that will not be handled as feature branches.",
"items":{
"type":"string"
}
},
"abandoned":{
"type":["boolean","string"],
"description":"Indicates whether this package has been abandoned, it can be boolean or a package name/URL pointing to a recommended alternative. Defaults to false."
'<warning>Warning: Ambiguous class resolution, "'.$class.'"'.
' was found in both "'.str_replace(array('$vendorDir . \'', "',\n"), array($vendorPath, ''), $classMap[$class]).'" and "'.$path.'", the first will be used.</warning>'
);
}
}
return $classMap;
}
private function generateClassMap($dir, $blacklist = null, $namespaceFilter = null)
throw new \InvalidArgumentException("Could not find package $name" . ($packageVersion ? " with version $packageVersion." : " with stability $stability."));
throw new \InvalidArgumentException("Could not find package $name" . ($packageVersion ? " with version $packageVersion." : " with stability $stability."));
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputOption;
@ -39,6 +45,9 @@ class DependsCommand extends Command
->setDefinition(array(
->setDefinition(array(
new InputArgument('package', InputArgument::REQUIRED, 'Package to inspect'),
new InputArgument('package', InputArgument::REQUIRED, 'Package to inspect'),
new InputOption('link-type', '', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Link types to show (require, require-dev)', array_keys($this->linkTypes)),
new InputOption('link-type', '', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Link types to show (require, require-dev)', array_keys($this->linkTypes)),
new InputOption('match-constraint', 'm', InputOption::VALUE_REQUIRED, 'Filters the dependencies shown using this constraint', '*'),
new InputOption('invert-match-constraint', 'i', InputOption::VALUE_NONE, 'Turns --match-constraint around into a blacklist insteead of whitelist'),
new InputOption('with-replaces', '', InputOption::VALUE_NONE, 'Search for replaced packages as well'),
))
))
->setHelp(<<<EOT
->setHelp(<<<EOT
Displays detailed information about where a package is referenced.
Displays detailed information about where a package is referenced.
@ -57,7 +66,12 @@ EOT
$commandEvent = new CommandEvent(PluginEvents::COMMAND, 'depends', $input, $output);
$commandEvent = new CommandEvent(PluginEvents::COMMAND, 'depends', $input, $output);
return '<warning>Your git color.ui setting is set to always, this is known to create issues. Use "git config --global color.ui true" to set it correctly.</warning>';
return '<comment>Your git color.ui setting is set to always, this is known to create issues. Use "git config --global color.ui true" to set it correctly.</comment>';
}
}
return true;
return true;
}
}
private function checkHttp(Config $config)
private function checkHttp($proto, Config $config)
{
{
$disableTls = false;
$disableTls = false;
$result = array();
$result = array();
if($config->get('disable-tls') === true) {
if ($proto === 'https' && $config->get('disable-tls') === true) {
$protocol = 'http';
$disableTls = true;
$disableTls = true;
$result[] = '<warning>Composer is configured to disable SSL/TLS protection. This will leave remote HTTPS requests vulnerable to Man-In-The-Middle attacks.</warning>';
$result[] = '<warning>Composer is configured to disable SSL/TLS protection. This will leave remote HTTPS requests vulnerable to Man-In-The-Middle attacks.</warning>';
} else {
$protocol = 'https';
}
}
if (!extension_loaded('openssl') && !$disableTls) {
if ($proto === 'https' && !extension_loaded('openssl') && !$disableTls) {
$result[] = '<error>Composer is configured to use SSL/TLS protection but the openssl extension is not available.</error>';
$result[] = '<error>Composer is configured to use SSL/TLS protection but the openssl extension is not available.</error>';
// code below taken from getcomposer.org/installer, any changes should be made there and replicated here
// code below taken from getcomposer.org/installer, any changes should be made there and replicated here
@ -335,32 +388,46 @@ EOT
}
}
$iniMessage .= PHP_EOL.'If you can not modify the ini file, you can also run `php -d option=value` to modify ini values on the fly. You can use -d multiple times.';
$iniMessage .= PHP_EOL.'If you can not modify the ini file, you can also run `php -d option=value` to modify ini values on the fly. You can use -d multiple times.';
if (!function_exists('json_decode')) {
$errors['json'] = true;
}
if (!extension_loaded('Phar')) {
$errors['phar'] = true;
}
if (!extension_loaded('filter')) {
$errors['filter'] = true;
}
if (!extension_loaded('hash')) {
$errors['hash'] = true;
}
if (!ini_get('allow_url_fopen')) {
if (!ini_get('allow_url_fopen')) {
$errors['allow_url_fopen'] = true;
$errors['allow_url_fopen'] = true;
}
}
if (version_compare(PHP_VERSION, '5.3.2', '<')) {
if (extension_loaded('ionCube Loader') && ioncube_loader_iversion() <40009){
$errors['ioncube'] = ioncube_loader_version();
}
if (PHP_VERSION_ID <50302){
$errors['php'] = PHP_VERSION;
$errors['php'] = PHP_VERSION;
}
}
if (!isset($errors['php']) && version_compare(PHP_VERSION, '5.3.4', '<')) {
if (!isset($errors['php']) &&PHP_VERSION_ID <50304){
$warnings['php'] = PHP_VERSION;
$warnings['php'] = PHP_VERSION;
}
}
if (!extension_loaded('openssl')) {
if (!extension_loaded('openssl')) {
$warnings['openssl'] = true;
$errors['openssl'] = true;
}
}
if (!defined('HHVM_VERSION') && !extension_loaded('apcu') && ini_get('apc.enable_cli')) {
if (!defined('HHVM_VERSION') && !extension_loaded('apcu') && ini_get('apc.enable_cli')) {
$warnings['apc_cli'] = true;
$warnings['apc_cli'] = true;
}
}
if (ini_get('xdebug.profiler_enabled')) {
$warnings['xdebug_profile'] = true;
} elseif (extension_loaded('xdebug')) {
$warnings['xdebug_loaded'] = true;
}
ob_start();
ob_start();
phpinfo(INFO_GENERAL);
phpinfo(INFO_GENERAL);
$phpinfo = ob_get_clean();
$phpinfo = ob_get_clean();
@ -376,9 +443,49 @@ EOT
}
}
}
}
if (ini_get('xdebug.profiler_enabled')) {
$warnings['xdebug_profile'] = true;
} elseif (extension_loaded('xdebug')) {
$warnings['xdebug_loaded'] = true;
}
if (!empty($errors)) {
if (!empty($errors)) {
foreach ($errors as $error => $current) {
foreach ($errors as $error => $current) {
switch ($error) {
switch ($error) {
case 'json':
$text = PHP_EOL."The json extension is missing.".PHP_EOL;
$text .= "Install it or recompile php without --disable-json";
break;
case 'phar':
$text = PHP_EOL."The phar extension is missing.".PHP_EOL;
$text .= "Install it or recompile php without --disable-phar";
break;
case 'filter':
$text = PHP_EOL."The filter extension is missing.".PHP_EOL;
$text .= "Install it or recompile php without --disable-filter";
break;
case 'hash':
$text = PHP_EOL."The hash extension is missing.".PHP_EOL;
$text .= "Install it or recompile php without --disable-hash";
break;
case 'unicode':
$text = PHP_EOL."The detect_unicode setting must be disabled.".PHP_EOL;
$text .= "Add the following to the end of your `php.ini`:".PHP_EOL;
$text .= " detect_unicode = Off";
$displayIniMessage = true;
break;
case 'suhosin':
$text = PHP_EOL."The suhosin.executor.include.whitelist setting is incorrect.".PHP_EOL;
$text .= "Add the following to the end of your `php.ini` or suhosin.ini (Example path [for Debian]: /etc/php5/cli/conf.d/suhosin.ini):".PHP_EOL;
$output->writeln('<warning>'.($input->getOption('homepage') ? 'Invalid or missing homepage' : 'Invalid or missing repository URL').' for '.$packageName.'</warning>');
$io->writeError('<warning>Package '.$packageName.' not found</warning>');
$io->writeError('<warning>'.($input->getOption('homepage') ? 'Invalid or missing homepage' : 'Invalid or missing repository URL').' for '.$packageName.'</warning>');
$this->openBrowser($url);
}
}
}
}
return $return;
return $return;
}
}
/**
private function handlePackage(CompletePackageInterface $package, $showHomepage, $showOnly)
* finds a package by name
*
* @param RepositoryInterface $repos
* @param string $name
* @return CompletePackageInterface
*/
protected function getPackage(RepositoryInterface $repos, $name)
@ -16,10 +16,10 @@ use Composer\DependencyResolver\Pool;
use Composer\Json\JsonFile;
use Composer\Json\JsonFile;
use Composer\Factory;
use Composer\Factory;
use Composer\Package\BasePackage;
use Composer\Package\BasePackage;
use Composer\Package\Version\VersionParser;
use Composer\Package\Version\VersionSelector;
use Composer\Package\Version\VersionSelector;
use Composer\Repository\CompositeRepository;
use Composer\Repository\CompositeRepository;
use Composer\Repository\PlatformRepository;
use Composer\Repository\PlatformRepository;
use Composer\Package\Version\VersionParser;
use Composer\Util\ProcessExecutor;
use Composer\Util\ProcessExecutor;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputOption;
@ -33,28 +33,18 @@ use Symfony\Component\Process\ExecutableFinder;
*/
*/
class InitCommand extends Command
class InitCommand extends Command
{
{
/** @var CompositeRepository */
protected $repos;
protected $repos;
/** @var array */
private $gitConfig;
private $gitConfig;
private $pool;
public function parseAuthorString($author)
/** @var Pool */
{
private $pool;
if (preg_match('/^(?P<name>[- \.,\p{L}\'’]+) <(?P<email>.+?)>$/u', $author, $match)) {
if ($this->isValidEmail($match['email'])) {
return array(
'name' => trim($match['name']),
'email' => $match['email']
);
}
}
throw new \InvalidArgumentException(
'Invalid author string. Must be in the format: '.
'John Smith <john@example.com>'
);
}
/**
* {@inheritdoc}
*/
protected function configure()
protected function configure()
{
{
$this
$this
@ -65,6 +55,7 @@ class InitCommand extends Command
new InputOption('description', null, InputOption::VALUE_REQUIRED, 'Description of package'),
new InputOption('description', null, InputOption::VALUE_REQUIRED, 'Description of package'),
new InputOption('author', null, InputOption::VALUE_REQUIRED, 'Author name of package'),
new InputOption('author', null, InputOption::VALUE_REQUIRED, 'Author name of package'),
// new InputOption('version', null, InputOption::VALUE_NONE, 'Version of package'),
// new InputOption('version', null, InputOption::VALUE_NONE, 'Version of package'),
new InputOption('type', null, InputOption::VALUE_OPTIONAL, 'Type of package'),
new InputOption('homepage', null, InputOption::VALUE_REQUIRED, 'Homepage of package'),
new InputOption('homepage', null, InputOption::VALUE_REQUIRED, 'Homepage of package'),
new InputOption('require', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Package to require with a version constraint, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"'),
new InputOption('require', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Package to require with a version constraint, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"'),
new InputOption('require-dev', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Package to require for development with a version constraint, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"'),
new InputOption('require-dev', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Package to require for development with a version constraint, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"'),
@ -82,11 +73,12 @@ EOT
;
;
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output)
$question = 'Would you like to define your dev dependencies (require-dev) interactively [<comment>yes</comment>]? ';
$devRequirements = array();
$devRequirements = array();
if ($dialog->askConfirmation($output, $dialog->getQuestion('Would you like to define your dev dependencies (require-dev) interactively', 'yes', '?'), true)) {
$package = $dialog->askAndValidate($output, $dialog->getQuestion('Enter package # to add, or the complete package name if it is not listed', false, ':'), $validator, 3);
$package = $io->askAndValidate(
'Enter package # to add, or the complete package name if it is not listed: ',
$validator,
3,
false
);
}
}
// no constraint yet, determine the best version automatically
// no constraint yet, determine the best version automatically
@ -383,16 +418,17 @@ EOT
return $input ?: false;
return $input ?: false;
};
};
$constraint = $dialog->askAndValidate(
$constraint = $io->askAndValidate(
$output,
'Enter the version constraint to require (or leave blank to use the latest version): ',
$dialog->getQuestion('Enter the version constraint to require (or leave blank to use the latest version)', false, ':'),
@ -48,6 +48,7 @@ class InstallCommand extends Command
new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump'),
new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump'),
new InputOption('disable-tls', null, InputOption::VALUE_NONE, 'Disable SSL/TLS protection for HTTPS requests'),
new InputOption('disable-tls', null, InputOption::VALUE_NONE, 'Disable SSL/TLS protection for HTTPS requests'),
new InputOption('cafile', null, InputOption::VALUE_REQUIRED, 'The path to a valid CA certificate file for SSL/TLS certificate verification'),
new InputOption('cafile', null, InputOption::VALUE_REQUIRED, 'The path to a valid CA certificate file for SSL/TLS certificate verification'),
new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'),
new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Should not be provided, use composer require instead to add a given package to composer.json.'),
new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Should not be provided, use composer require instead to add a given package to composer.json.'),
))
))
@ -66,20 +67,24 @@ EOT
protected function execute(InputInterface $input, OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output)
{
{
$io = $this->getIO();
if ($args = $input->getArgument('packages')) {
if ($args = $input->getArgument('packages')) {
$output->writeln('<error>Invalid argument '.implode(' ', $args).'. Use "composer require '.implode(' ', $args).'" instead to add packages to your composer.json.</error>');
$io->writeError('<error>Invalid argument '.implode(' ', $args).'. Use "composer require '.implode(' ', $args).'" instead to add packages to your composer.json.</error>');
return 1;
return 1;
}
}
if ($input->getOption('no-custom-installers')) {
if ($input->getOption('no-custom-installers')) {
$output->writeln('<warning>You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.</warning>');
$io->writeError('<warning>You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.</warning>');
$input->setOption('no-plugins', true);
$input->setOption('no-plugins', true);
}
}
if ($input->getOption('dev')) {
$io->writeError('<warning>You are using the deprecated option "dev". Dev packages are installed by default now.</warning>');
new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump'),
new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'),
))
))
->setHelp(<<<EOT
->setHelp(<<<EOT
The <info>remove</info> command removes a package from the current
The <info>remove</info> command removes a package from the current
new InputOption('sort-packages', null, InputOption::VALUE_NONE, 'Sorts packages when adding/updating a new dependency'),
new InputOption('sort-packages', null, InputOption::VALUE_NONE, 'Sorts packages when adding/updating a new dependency'),
new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump'),
new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'),
))
))
->setHelp(<<<EOT
->setHelp(<<<EOT
The require command adds required packages to your composer.json and installs them.
The require command adds required packages to your composer.json and installs them.
@ -66,24 +68,29 @@ EOT
protected function execute(InputInterface $input, OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output)
{
{
$file = Factory::getComposerFile();
$file = Factory::getComposerFile();
$io = $this->getIO();
$newlyCreated = !file_exists($file);
$newlyCreated = !file_exists($file);
if (!file_exists($file) && !file_put_contents($file, "{\n}\n")) {
if (!file_exists($file) && !file_put_contents($file, "{\n}\n")) {
$output->writeln('<error>'.$file.' could not be created.</error>');
$io->writeError('<error>'.$file.' could not be created.</error>');
return 1;
return 1;
}
}
if (!is_readable($file)) {
if (!is_readable($file)) {
$output->writeln('<error>'.$file.' is not readable.</error>');
$io->writeError('<error>'.$file.' is not readable.</error>');
return 1;
return 1;
}
}
if (!is_writable($file)) {
if (!is_writable($file)) {
$output->writeln('<error>'.$file.' is not writable.</error>');
$io->writeError('<error>'.$file.' is not writable.</error>');
@ -16,9 +16,11 @@ use Composer\DependencyResolver\Pool;
use Composer\DependencyResolver\DefaultPolicy;
use Composer\DependencyResolver\DefaultPolicy;
use Composer\Factory;
use Composer\Factory;
use Composer\Package\CompletePackageInterface;
use Composer\Package\CompletePackageInterface;
use Composer\Package\Version\VersionParser;
use Composer\Semver\VersionParser;
use Composer\Plugin\CommandEvent;
use Composer\Plugin\CommandEvent;
use Composer\Plugin\PluginEvents;
use Composer\Plugin\PluginEvents;
use Composer\Package\PackageInterface;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputOption;
@ -28,14 +30,17 @@ use Composer\Repository\CompositeRepository;
use Composer\Repository\ComposerRepository;
use Composer\Repository\ComposerRepository;
use Composer\Repository\PlatformRepository;
use Composer\Repository\PlatformRepository;
use Composer\Repository\RepositoryInterface;
use Composer\Repository\RepositoryInterface;
use Composer\Spdx\SpdxLicenses;
/**
/**
* @author Robert Schönthal <seroscho@googlemail.com>
* @author Robert Schönthal <seroscho@googlemail.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @author Jérémy Romey <jeremyFreeAgent>
*/
*/
class ShowCommand extends Command
class ShowCommand extends Command
{
{
protected $versionParser;
protected $versionParser;
protected $colors;
protected function configure()
protected function configure()
{
{
@ -54,6 +59,7 @@ class ShowCommand extends Command
new InputOption('disable-tls', null, InputOption::VALUE_NONE, 'Disable SSL/TLS protection for HTTPS requests'),
new InputOption('disable-tls', null, InputOption::VALUE_NONE, 'Disable SSL/TLS protection for HTTPS requests'),
new InputOption('cafile', null, InputOption::VALUE_REQUIRED, 'The path to a valid CA certificate file for SSL/TLS certificate verification'),
new InputOption('cafile', null, InputOption::VALUE_REQUIRED, 'The path to a valid CA certificate file for SSL/TLS certificate verification'),
new InputOption('path', 'P', InputOption::VALUE_NONE, 'Show package paths'),
new InputOption('path', 'P', InputOption::VALUE_NONE, 'Show package paths'),
new InputOption('tree', 't', InputOption::VALUE_NONE, 'List the dependencies as a tree'),
))
))
->setHelp(<<<EOT
->setHelp(<<<EOT
The show command displays detailed information about a package, or
The show command displays detailed information about a package, or
@ -67,11 +73,25 @@ EOT
protected function execute(InputInterface $input, OutputInterface $output)
protected function execute(InputInterface $input, OutputInterface $output)
{
{
$this->versionParser = new VersionParser;
$this->versionParser = new VersionParser;
if ($input->getOption('tree')) {
$this->initStyles($output);
}
$composer = $this->getComposer(false);
$io = $this->getIO();
if ($input->getOption('tree') && !$input->getOption('installed')) {
$io->writeError('The --tree (-t) option is only usable in combination with --installed (-i) or by passing a single package name to show, assuming -i');
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\Question;
/**
/**
* @author Jordi Boggiano <j.boggiano@seld.be>
* @author Jordi Boggiano <j.boggiano@seld.be>
@ -49,9 +54,11 @@ class UpdateCommand extends Command
new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump.'),
new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump.'),
new InputOption('disable-tls', null, InputOption::VALUE_NONE, 'Disable SSL/TLS protection for HTTPS requests'),
new InputOption('disable-tls', null, InputOption::VALUE_NONE, 'Disable SSL/TLS protection for HTTPS requests'),
new InputOption('cafile', null, InputOption::VALUE_REQUIRED, 'The path to a valid CA certificate file for SSL/TLS certificate verification'),
new InputOption('cafile', null, InputOption::VALUE_REQUIRED, 'The path to a valid CA certificate file for SSL/TLS certificate verification'),
new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'),
* The Compiler class compiles composer into a phar
* The Compiler class compiles composer into a phar
@ -31,8 +33,8 @@ class Compiler
/**
/**
* Compiles composer into a single phar file
* Compiles composer into a single phar file
*
*
* @throws \RuntimeException
* @param string $pharFile The full path to the file to create
* @param string $pharFile The full path to the file to create
* @throws \RuntimeException
*/
*/
public function compile($pharFile = 'composer.phar')
public function compile($pharFile = 'composer.phar')
{
{
@ -51,9 +53,8 @@ class Compiler
throw new \RuntimeException('Can\'t run git log. You must ensure to run compile from composer git repository clone and that git binary is available.');
throw new \RuntimeException('Can\'t run git log. You must ensure to run compile from composer git repository clone and that git binary is available.');
}
}
$date = new \DateTime(trim($process->getOutput()));
$this->versionDate = new \DateTime(trim($process->getOutput()));
@ -89,23 +104,29 @@ class Application extends BaseApplication
public function doRun(InputInterface $input, OutputInterface $output)
public function doRun(InputInterface $input, OutputInterface $output)
{
{
$this->io = new ConsoleIO($input, $output, $this->getHelperSet());
$this->io = new ConsoleIO($input, $output, $this->getHelperSet());
ErrorHandler::register($this->io);
$io = $this->getIO();
if (version_compare(PHP_VERSION, '5.3.2', '<')) {
// determine command name to be executed
$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>');
$commandName = '';
if ($name = $this->getCommandName($input)) {
try {
$commandName = $this->find($name)->getName();
} catch (\InvalidArgumentException $e) {
}
}
}
if (defined('COMPOSER_DEV_WARNING_TIME')) {
if ($commandName !== 'global') {
$commandName = '';
if (PHP_VERSION_ID <50302){
if ($name = $this->getCommandName($input)) {
$io->writeError('<warning>Composer only officially supports PHP 5.3.2 and above, you will most likely encounter problems with your PHP '.PHP_VERSION.', upgrading is strongly recommended.</warning>');
try {
$commandName = $this->find($name)->getName();
} catch (\InvalidArgumentException $e) {
}
}
}
if ($commandName !== 'self-update' && $commandName !== 'selfupdate') {
if (time() > COMPOSER_DEV_WARNING_TIME) {
if (extension_loaded('xdebug') && !getenv('COMPOSER_DISABLE_XDEBUG_WARN')) {
$output->writeln(sprintf('<warning>Warning: This development build of composer is over 30 days old. It is recommended to update it by running "%s self-update" to get the latest version.</warning>', $_SERVER['PHP_SELF']));
$io->writeError('<warning>You are running composer with xdebug enabled. This has a major impact on runtime performance. See https://getcomposer.org/xdebug</warning>');
$io->writeError(sprintf('<warning>Warning: This development build of composer is over 60 days old. It is recommended to update it by running "%s self-update" to get the latest version.</warning>', $_SERVER['PHP_SELF']));
}
}
}
}
@ -117,8 +138,8 @@ class Application extends BaseApplication
if ($newWorkDir = $this->getNewWorkingDir($input)) {
if ($newWorkDir = $this->getNewWorkingDir($input)) {
$oldWorkingDir = getcwd();
$oldWorkingDir = getcwd();
chdir($newWorkDir);
chdir($newWorkDir);
if ($output->getVerbosity() >= 4) {
if ($io->isDebug() >= 4) {
$output->writeln('Changed CWD to ' . getcwd());
$io->writeError('Changed CWD to ' . getcwd());
}
}
}
}
@ -129,7 +150,7 @@ class Application extends BaseApplication
foreach ($composer['scripts'] as $script => $dummy) {
foreach ($composer['scripts'] as $script => $dummy) {
if (!defined('Composer\Script\ScriptEvents::'.str_replace('-', '_', strtoupper($script)))) {
if (!defined('Composer\Script\ScriptEvents::'.str_replace('-', '_', strtoupper($script)))) {
if ($this->has($script)) {
if ($this->has($script)) {
$output->writeln('<warning>A script named '.$script.' would override a native Composer function and has been skipped</warning>');
$io->writeError('<warning>A script named '.$script.' would override a native Composer function and has been skipped</warning>');
$output->writeln('<error>The disk hosting '.$dir.' is full, this may be the cause of the following exception</error>');
$io->writeError('<error>The disk hosting '.$dir.' is full, this may be the cause of the following exception</error>');
}
}
}
}
} catch (\Exception $e) {
} catch (\Exception $e) {
}
}
if (defined('PHP_WINDOWS_VERSION_BUILD') && false !== strpos($exception->getMessage(), 'The system cannot find the path specified')) {
if (defined('PHP_WINDOWS_VERSION_BUILD') && false !== strpos($exception->getMessage(), 'The system cannot find the path specified')) {
$output->writeln('<error>The following exception may be caused by a stale entry in your cmd.exe AutoRun</error>');
$io->writeError('<error>The following exception may be caused by a stale entry in your cmd.exe AutoRun</error>');
$output->writeln('<error>Check https://getcomposer.org/doc/articles/troubleshooting.md#-the-system-cannot-find-the-path-specified-windows- for details</error>');
$io->writeError('<error>Check https://getcomposer.org/doc/articles/troubleshooting.md#-the-system-cannot-find-the-path-specified-windows- for details</error>');
@ -32,11 +32,11 @@ class SolverProblemsException extends \RuntimeException
{
{
$text = "\n";
$text = "\n";
foreach ($this->problems as $i => $problem) {
foreach ($this->problems as $i => $problem) {
$text .= " Problem ".($i+1).$problem->getPrettyString($this->installedMap)."\n";
$text .= " Problem ".($i+1).$problem->getPrettyString($this->installedMap)."\n";
}
}
if (strpos($text, 'could not be found') || strpos($text, 'no matching package found')) {
if (strpos($text, 'could not be found') || strpos($text, 'no matching package found')) {
$text .= "\nPotential causes:\n - A typo in the package name\n - The package is not available in a stable-enough version according to your minimum-stability setting\n see <https://groups.google.com/d/topic/composer-dev/_g3ASeIFlrc/discussion> for more details.\n\nRead <http://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.";
$text .= "\nPotential causes:\n - A typo in the package name\n - The package is not available in a stable-enough version according to your minimum-stability setting\n see <https://groups.google.com/d/topic/composer-dev/_g3ASeIFlrc/discussion> for more details.\n\nRead <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.";
* @param string $eventName The constant in InstallerEvents
* @param string $eventName The constant in InstallerEvents
* @param bool $devMode Whether or not we are in dev mode
* @param PolicyInterface $policy The policy
* @param PolicyInterface $policy The policy
* @param Pool $pool The pool
* @param Pool $pool The pool
* @param CompositeRepository $installedRepo The installed repository
* @param CompositeRepository $installedRepo The installed repository
@ -134,9 +128,9 @@ class EventDispatcher
* @return int return code of the executed script if any, for php scripts a false return
* @return int return code of the executed script if any, for php scripts a false return
* value is changed to 1, anything else to 0
* value is changed to 1, anything else to 0
*/
*/
public function dispatchInstallerEvent($eventName, PolicyInterface $policy, Pool $pool, CompositeRepository $installedRepo, Request $request, array $operations = array())
public function dispatchInstallerEvent($eventName, $devMode, PolicyInterface $policy, Pool $pool, CompositeRepository $installedRepo, Request $request, array $operations = array())