从官方网站上拉取最新的英文文档到本地。

This commit is contained in:
YuCheng Hu 2024-04-08 22:22:54 -04:00
parent 6384707a14
commit e712385ede
53 changed files with 6692 additions and 2514 deletions

10
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Zeppelin ignored files
/ZeppelinRemoteNotebooks/

19
.idea/php.xml Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PhpIncludePathManager">
<include_path>
<path value="$PROJECT_DIR$/tests/Composer/Test/Fixtures/functional/plugin-autoloading-only-loads-dependencies/vendor/composer" />
<path value="$PROJECT_DIR$/tests/Composer/Test/Fixtures/functional/plugin-autoloading-only-loads-dependencies/vendor/evil/pkg" />
<path value="$PROJECT_DIR$/tests/Composer/Test/Fixtures/functional/installed-versions2/vendor/plugin/a" />
<path value="$PROJECT_DIR$/tests/Composer/Test/Fixtures/functional/installed-versions2/vendor/symfony/polyfill-ctype" />
<path value="$PROJECT_DIR$/tests/Composer/Test/Fixtures/functional/installed-versions2/vendor/composer" />
<path value="$PROJECT_DIR$/tests/Composer/Test/Fixtures/functional/installed-versions2/vendor/symfony/filesystem" />
<path value="$PROJECT_DIR$/tests/Composer/Test/Fixtures/functional/installed-versions2/vendor/symfony/console" />
<path value="$PROJECT_DIR$/tests/Composer/Test/Fixtures/functional/installed-versions2/vendor/plugin/b" />
<path value="$PROJECT_DIR$/tests/Composer/Test/Fixtures/functional/installed-versions2/vendor/symfony/process" />
</include_path>
</component>
<component name="PhpProjectSharedConfiguration" php_language_level="8.0">
<option name="suggestChangeDefaultLanguageLevel" value="false" />
</component>
</project>

10
.idea/phpunit.xml Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PHPUnit">
<option name="directories">
<list>
<option value="$PROJECT_DIR$/tests/Composer/Test/Json/Fixtures/tests" />
</list>
</option>
</component>
</project>

View File

@ -2,7 +2,31 @@
<module type="WEB_MODULE" version="4"> <module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true"> <component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$" /> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/Composer" isTestSource="false" packagePrefix="Composer\" />
<sourceFolder url="file://$MODULE_DIR$/tests/Composer/Test" isTestSource="true" packagePrefix="Composer\Test\" />
<sourceFolder url="file://$MODULE_DIR$/tests/Composer/Test/Autoload/MinimumVersionSupport/." isTestSource="false" packagePrefix="Test\" />
<sourceFolder url="file://$MODULE_DIR$/tests/Composer/Test/Json/Fixtures/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tests/Composer/Test/Json/Fixtures/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/tests/Composer/Test/Plugin/Fixtures/plugin-v1/" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tests/Composer/Test/Plugin/Fixtures/plugin-v2/" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tests/Composer/Test/Plugin/Fixtures/plugin-v3/" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tests/Composer/Test/Plugin/Fixtures/plugin-v4/" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tests/Composer/Test/Plugin/Fixtures/plugin-v5/" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tests/Composer/Test/Plugin/Fixtures/plugin-v6/" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tests/Composer/Test/Plugin/Fixtures/plugin-v7/" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tests/Composer/Test/Plugin/Fixtures/plugin-v8/" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tests/Composer/Test/Plugin/Fixtures/plugin-v9/" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/tests/Composer/Test/Fixtures/functional/installed-versions2/vendor/composer" />
<excludeFolder url="file://$MODULE_DIR$/tests/Composer/Test/Fixtures/functional/installed-versions2/vendor/plugin/a" />
<excludeFolder url="file://$MODULE_DIR$/tests/Composer/Test/Fixtures/functional/installed-versions2/vendor/plugin/b" />
<excludeFolder url="file://$MODULE_DIR$/tests/Composer/Test/Fixtures/functional/installed-versions2/vendor/symfony/console" />
<excludeFolder url="file://$MODULE_DIR$/tests/Composer/Test/Fixtures/functional/installed-versions2/vendor/symfony/filesystem" />
<excludeFolder url="file://$MODULE_DIR$/tests/Composer/Test/Fixtures/functional/installed-versions2/vendor/symfony/polyfill-ctype" />
<excludeFolder url="file://$MODULE_DIR$/tests/Composer/Test/Fixtures/functional/installed-versions2/vendor/symfony/process" />
<excludeFolder url="file://$MODULE_DIR$/tests/Composer/Test/Fixtures/functional/plugin-autoloading-only-loads-dependencies/vendor/composer" />
<excludeFolder url="file://$MODULE_DIR$/tests/Composer/Test/Fixtures/functional/plugin-autoloading-only-loads-dependencies/vendor/evil/pkg" />
</content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>

203
doc/00-intro.md Normal file
View File

@ -0,0 +1,203 @@
# Introduction
Composer is a tool for dependency management in PHP. It allows you to declare
the libraries your project depends on and it will manage (install/update) them
for you.
## Dependency management
Composer is **not** a package manager in the same sense as Yum or Apt are. Yes,
it deals with "packages" or libraries, but it manages them on a per-project
basis, installing them in a directory (e.g. `vendor`) inside your project. By
default, it does not install anything globally. Thus, it is a dependency
manager. It does however support a "global" project for convenience via the
[global](03-cli.md#global) command.
This idea is not new and Composer is strongly inspired by node's
[npm](https://www.npmjs.com/) and ruby's [bundler](https://bundler.io/).
Suppose:
1. You have a project that depends on a number of libraries.
2. Some of those libraries depend on other libraries.
Composer:
1. Enables you to declare the libraries you depend on.
2. Finds out which versions of which packages can and need to be installed, and
installs them (meaning it downloads them into your project).
3. You can update all your dependencies in one command.
See the [Basic usage](01-basic-usage.md) chapter for more details on declaring
dependencies.
## System Requirements
Composer in its latest version requires PHP 7.2.5 to run. A long-term-support
version (2.2.x) still offers support for PHP 5.3.2+ in case you are stuck with
a legacy PHP version. A few sensitive php settings and compile flags are also
required, but when using the installer you will be warned about any
incompatibilities.
Composer needs several supporting applications to work effectively, making the
process of handling package dependencies more efficient. For decompressing
files, Composer relies on tools like `7z` (or `7zz`), `gzip`, `tar`, `unrar`,
`unzip` and `xz`. As for version control systems, Composer integrates seamlessly
with Fossil, Git, Mercurial, Perforce and Subversion, thereby ensuring the
application's smooth operation and management of library repositories. Before
using Composer, ensure that these dependencies are correctly installed on your
system.
Composer is multi-platform and we strive to make it run equally well on Windows,
Linux and macOS.
## Installation - Linux / Unix / macOS
### Downloading the Composer Executable
Composer offers a convenient installer that you can execute directly from the
command line. Feel free to [download this file](https://getcomposer.org/installer)
or review it on [GitHub](https://github.com/composer/getcomposer.org/blob/main/web/installer)
if you wish to know more about the inner workings of the installer. The source
is plain PHP.
There are, in short, two ways to install Composer. Locally as part of your
project, or globally as a system wide executable.
#### Locally
To install Composer locally, run the installer in your project directory. See
[the Download page](https://getcomposer.org/download/) for instructions.
The installer will check a few PHP settings and then download `composer.phar`
to your working directory. This file is the Composer binary. It is a PHAR
(PHP archive), which is an archive format for PHP which can be run on
the command line, amongst other things.
Now run `php composer.phar` in order to run Composer.
You can install Composer to a specific directory by using the `--install-dir`
option and additionally (re)name it as well using the `--filename` option. When
running the installer when following
[the Download page instructions](https://getcomposer.org/download/) add the
following parameters:
```shell
php composer-setup.php --install-dir=bin --filename=composer
```
Now run `php bin/composer` in order to run Composer.
#### Globally
You can place the Composer PHAR anywhere you wish. If you put it in a directory
that is part of your `PATH`, you can access it globally. On Unix systems you
can even make it executable and invoke it without directly using the `php`
interpreter.
After running the installer following [the Download page instructions](https://getcomposer.org/download/)
you can run this to move composer.phar to a directory that is in your path:
```shell
mv composer.phar /usr/local/bin/composer
```
If you like to install it only for your user and avoid requiring root permissions,
you can use `~/.local/bin` instead which is available by default on some
Linux distributions.
> **Note:** If the above fails due to permissions, you may need to run it again
> with `sudo`.
> **Note:** On some versions of macOS 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 the directory manually before proceeding:
> `mkdir -p /usr/local/bin`.
> **Note:** For information on changing your PATH, please read the
> [Wikipedia article](https://en.wikipedia.org/wiki/PATH_(variable)) and/or use
> your search engine of choice.
Now run `composer` in order to run Composer instead of `php composer.phar`.
## Installation - Windows
### Using the Installer
This is the easiest way to get Composer set up on your machine.
Download and run
[Composer-Setup.exe](https://getcomposer.org/Composer-Setup.exe). It will
install the latest Composer version and set up your PATH so that you can
call `composer` from any directory in your command line.
> **Note:** Close your current terminal. Test usage with a new terminal: This is
> important since the PATH only gets loaded when the terminal starts.
### Manual Installation
Change to a directory on your `PATH` and run the installer following
[the Download page instructions](https://getcomposer.org/download/)
to download `composer.phar`.
Create a new `composer.bat` file alongside `composer.phar`:
Using cmd.exe:
```shell
C:\bin> echo @php "%~dp0composer.phar" %*>composer.bat
```
Using PowerShell:
```shell
PS C:\bin> Set-Content composer.bat '@php "%~dp0composer.phar" %*'
```
Add the directory to your PATH environment variable if it isn't already.
For information on changing your PATH variable, please see
[this article](https://www.computerhope.com/issues/ch000549.htm) and/or
use your search engine of choice.
Close your current terminal. Test usage with a new terminal:
```shell
C:\Users\username>composer -V
```
```text
Composer version 2.4.0 2022-08-16 16:10:48
```
## Docker Image
Composer is published as Docker container in a few places, see the list in the [composer/docker README](https://github.com/composer/docker).
Example usage:
```shell
docker pull composer/composer
docker run --rm -it -v "$(pwd):/app" composer/composer install
```
To add Composer to an existing **Dockerfile** you can simply copy binary file from pre-built, low-size images:
```Dockerfile
# Latest release
COPY --from=composer/composer:latest-bin /composer /usr/bin/composer
# Specific release
COPY --from=composer/composer:2-bin /composer /usr/bin/composer
```
Read the [image description](https://hub.docker.com/r/composer/composer) for further usage information.
**Note:** Docker specific issues should be filed [on the composer/docker repository](https://github.com/composer/docker/issues).
**Note:** You may also use `composer` instead of `composer/composer` as image name above. It is shorter and is a Docker official image but is not published directly by us and thus usually receives new releases with a delay of a few days. **Important**: short-aliased images don't have binary-only equivalents, so for `COPY --from` approach it's better to use `composer/composer` ones.
## Using Composer
Now that you've installed Composer, you are ready to use it! Head on over to the
next chapter for a short demonstration.
[Basic usage](01-basic-usage.md) &rarr;

286
doc/01-basic-usage.md Normal file
View File

@ -0,0 +1,286 @@
# Basic usage
## Introduction
For our basic usage introduction, we will be installing `monolog/monolog`,
a logging library. If you have not yet installed Composer, refer to the
[Intro](00-intro.md) chapter.
> **Note:** for the sake of simplicity, this introduction will assume you
> have performed a [local](00-intro.md#locally) install of Composer.
## `composer.json`: Project setup
To start using Composer in your project, all you need is a `composer.json`
file. This file describes the dependencies of your project and may contain
other metadata as well. It typically should go in the top-most directory of
your project/VCS repository. You can technically run Composer anywhere but
if you want to publish a package to Packagist.org, it will have to be able
to find the file at the top of your VCS repository.
### The `require` key
The first thing you specify in `composer.json` is the
[`require`](04-schema.md#require) key. You are telling Composer which
packages your project depends on.
```json
{
"require": {
"monolog/monolog": "2.0.*"
}
}
```
As you can see, [`require`](04-schema.md#require) takes an object that maps
**package names** (e.g. `monolog/monolog`) to **version constraints** (e.g.
`1.0.*`).
Composer uses this information to search for the right set of files in package
"repositories" that you register using the [`repositories`](04-schema.md#repositories)
key, or in [Packagist.org](https://packagist.org), the default package repository.
In the above example, since no other repository has been registered in the
`composer.json` file, it is assumed that the `monolog/monolog` package is registered
on Packagist.org. (Read more [about Packagist](#packagist), and
[about repositories](05-repositories.md)).
### Package names
The package name consists of a vendor name and the project's name. Often these
will be identical - the vendor name only exists to prevent naming clashes. For
example, it would allow two different people to create a library named `json`.
One might be named `igorw/json` while the other might be `seldaek/json`.
Read more about [publishing packages and package naming](02-libraries.md).
(Note that you can also specify "platform packages" as dependencies, allowing
you to require certain versions of server software. See
[platform packages](#platform-packages) below.)
### Package version constraints
In our example, we are requesting the Monolog package with the version constraint
[`2.0.*`](https://semver.madewithlove.com/?package=monolog%2Fmonolog&constraint=2.0.*).
This means any version in the `2.0` development branch, or any version that is
greater than or equal to 2.0 and less than 2.1 (`>=2.0 <2.1`).
Please read [versions](articles/versions.md) for more in-depth information on
versions, how versions relate to each other, and on version constraints.
> **How does Composer download the right files?** When you specify a dependency in
> `composer.json`, Composer first takes the name of the package that you have requested
> and searches for it in any repositories that you have registered using the
> [`repositories`](04-schema.md#repositories) key. If you have not registered
> any extra repositories, or it does not find a package with that name in the
> repositories you have specified, it falls back to Packagist.org (more [below](#packagist)).
>
> When Composer finds the right package, either in Packagist.org or in a repo you have specified,
> it then uses the versioning features of the package's VCS (i.e., branches and tags)
> to attempt to find the best match for the version constraint you have specified. Be sure to read
> about versions and package resolution in the [versions article](articles/versions.md).
> **Note:** If you are trying to require a package but Composer throws an error
> regarding package stability, the version you have specified may not meet your
> default minimum stability requirements. By default, only stable releases are taken
> into consideration when searching for valid package versions in your VCS.
>
> You might run into this if you are trying to require dev, alpha, beta, or RC
> versions of a package. Read more about stability flags and the `minimum-stability`
> key on the [schema page](04-schema.md).
## Installing dependencies
To initially install the defined dependencies for your project, you should run the
[`update`](03-cli.md#update-u) command.
```shell
php composer.phar update
```
This will make Composer do two things:
- It resolves all dependencies listed in your `composer.json` file and writes all of the
packages and their exact versions to the `composer.lock` file, locking the project to
those specific versions. You should commit the `composer.lock` file to your project repo
so that all people working on the project are locked to the same versions of dependencies
(more below). This is the main role of the `update` command.
- It then implicitly runs the [`install`](03-cli.md#install-i) command. This will download
the dependencies' files into the `vendor` directory in your project. (The `vendor`
directory is the conventional location for all third-party code in a project). In our
example from above, you would end up with the Monolog source files in
`vendor/monolog/monolog/`. As Monolog has a dependency on `psr/log`, that package's files
can also be found inside `vendor/`.
> **Tip:** If you are using git for your project, you probably want to add
> `vendor` in your `.gitignore`. You really don't want to add all of that
> third-party code to your versioned repository.
### Commit your `composer.lock` file to version control
Committing this file to version control is important because it will cause anyone
who sets up the project to use the exact same
versions of the dependencies that you are using. Your CI server, production
machines, other developers in your team, everything and everyone runs on the
same dependencies, which mitigates the potential for bugs affecting only some
parts of the deployments. Even if you develop alone, in six months when
reinstalling the project you can feel confident that the dependencies installed are
still working, even if the dependencies have released many new versions since then.
(See note below about using the `update` command.)
> **Note:** For libraries it is not necessary to commit the lock
> file, see also: [Libraries - Lock file](02-libraries.md#lock-file).
### Installing from `composer.lock`
If there is already a `composer.lock` file in the project folder, it means either
you ran the `update` command before, or someone else on the project ran the `update`
command and committed the `composer.lock` file to the project (which is good).
Either way, running `install` when a `composer.lock` file is present resolves and installs
all dependencies that you listed in `composer.json`, but Composer uses the exact versions listed
in `composer.lock` to ensure that the package versions are consistent for everyone
working on your project. As a result you will have all dependencies requested by your
`composer.json` file, but they may not all be at the very latest available versions
(some of the dependencies listed in the `composer.lock` file may have released newer versions since
the file was created). This is by design, ensuring that your project does not break because of
unexpected changes in dependencies.
So after fetching new changes from your VCS repository it is recommended to run
a Composer `install` to make sure the vendor directory is up in sync with your
`composer.lock` file.
```shell
php composer.phar install
```
Composer enables reproducible builds by default. This means that running the
same command multiple times will produce a `vendor/` directory containing files
that are identical (*except their timestamps*), including the autoloader files.
It is especially beneficial for environments that require strict
verification processes, as well as for Linux distributions aiming to package PHP
applications in a secure and predictable manner.
## Updating dependencies to their latest versions
As mentioned above, the `composer.lock` file prevents you from automatically getting
the latest versions of your dependencies. To update to the latest versions, use the
[`update`](03-cli.md#update-u) command. This will fetch the latest matching
versions (according to your `composer.json` file) and update the lock file
with the new versions.
```shell
php composer.phar update
```
> **Note:** Composer will display a Warning when executing an `install` command
> if the `composer.lock` has not been updated since changes were made to the
> `composer.json` that might affect dependency resolution.
If you only want to install, upgrade or remove one dependency, you can explicitly list it as an argument:
```shell
php composer.phar update monolog/monolog [...]
```
## Packagist
[Packagist.org](https://packagist.org/) is the main Composer repository. A Composer
repository is basically a package source: a place where you can get packages
from. Packagist aims to be the central repository that everybody uses. This
means that you can automatically `require` any package that is available there,
without further specifying where Composer should look for the package.
If you go to the [Packagist.org website](https://packagist.org/),
you can browse and search for packages.
Any open source project using Composer is recommended to publish their packages
on Packagist. A library does not need to be on Packagist to be used by Composer,
but it enables discovery and adoption by other developers more quickly.
## Platform packages
Composer has platform packages, which are virtual packages for things that are
installed on the system but are not actually installable by Composer. This
includes PHP itself, PHP extensions and some system libraries.
* `php` represents the PHP version of the user, allowing you to apply
constraints, e.g. `^7.1`. To require a 64bit version of php, you can
require the `php-64bit` package.
* `hhvm` represents the version of the HHVM runtime and allows you to apply
a constraint, e.g., `^2.3`.
* `ext-<name>` allows you to require PHP extensions (includes core
extensions). Versioning can be quite inconsistent here, so it's often
a good idea to set the constraint to `*`. An example of an extension
package name is `ext-gd`.
* `lib-<name>` allows constraints to be made on versions of libraries used by
PHP. The following are available: `curl`, `iconv`, `icu`, `libxml`,
`openssl`, `pcre`, `uuid`, `xsl`.
You can use [`show --platform`](03-cli.md#show) to get a list of your locally
available platform packages.
## Autoloading
For libraries that specify autoload information, Composer generates a
`vendor/autoload.php` file. You can include this file and start
using the classes that those libraries provide without any extra work:
```php
require __DIR__ . '/vendor/autoload.php';
$log = new Monolog\Logger('name');
$log->pushHandler(new Monolog\Handler\StreamHandler('app.log', Monolog\Logger::WARNING));
$log->warning('Foo');
```
You can even add your own code to the autoloader by adding an
[`autoload`](04-schema.md#autoload) field to `composer.json`.
```json
{
"autoload": {
"psr-4": {"Acme\\": "src/"}
}
}
```
Composer will register a [PSR-4](https://www.php-fig.org/psr/psr-4/) autoloader
for the `Acme` namespace.
You define a mapping from namespaces to directories. The `src` directory would
be in your project root, on the same level as the `vendor` directory. An example
filename would be `src/Foo.php` containing an `Acme\Foo` class.
After adding the [`autoload`](04-schema.md#autoload) field, you have to re-run
this command:
```shell
php composer.phar dump-autoload
```
This command will re-generate the `vendor/autoload.php` file.
See the [`dump-autoload`](03-cli.md#dump-autoload-dumpautoload-) section for
more information.
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.
```php
$loader = require __DIR__ . '/vendor/autoload.php';
$loader->addPsr4('Acme\\Test\\', __DIR__);
```
In addition to PSR-4 autoloading, Composer also supports PSR-0, classmap and
files autoloading. See the [`autoload`](04-schema.md#autoload) reference for
more information.
See also the docs on [optimizing the autoloader](articles/autoloader-optimization.md).
> **Note:** Composer provides its own autoloader. If you don't want to use that
> one, you can include `vendor/composer/autoload_*.php` files, which return
> associative arrays allowing you to configure your own autoloader.
&larr; [Intro](00-intro.md) | [Libraries](02-libraries.md) &rarr;

183
doc/02-libraries.md Normal file
View File

@ -0,0 +1,183 @@
# Libraries
This chapter will tell you how to make your library installable through
Composer.
## Every project is a package
As soon as you have a `composer.json` in a directory, that directory is a
package. When you add a [`require`](04-schema.md#require) to a project, you are
making a package that depends on other packages. The only difference between
your project and a library is that your project is a package without a name.
In order to make that package installable you need to give it a name. You do
this by adding the [`name`](04-schema.md#name) property in `composer.json`:
```json
{
"name": "acme/hello-world",
"require": {
"monolog/monolog": "1.0.*"
}
}
```
In this case the project name is `acme/hello-world`, where `acme` is the vendor
name. Supplying a vendor name is mandatory.
> **Note:** If you don't know what to use as a vendor name, your GitHub
> username is usually a good bet. Package names must be lowercase, and the
> convention is to use dashes for word separation.
## Library Versioning
In the vast majority of cases, you will be maintaining your library using some
sort of version control system like git, svn, hg or fossil. In these cases,
Composer infers versions from your VCS, and you **should not** specify a version
in your `composer.json` file. (See the [Versions article](articles/versions.md)
to learn about how Composer uses VCS branches and tags to resolve version
constraints.)
If you are maintaining packages by hand (i.e., without a VCS), you'll need to
specify the version explicitly by adding a `version` value in your `composer.json`
file:
```json
{
"version": "1.0.0"
}
```
> **Note:** When you add a hardcoded version to a VCS, the version will conflict
> with tag names. Composer will not be able to determine the version number.
### VCS Versioning
Composer uses your VCS's branch and tag features to resolve the version
constraints you specify in your [`require`](04-schema.md#require) field to specific sets of files.
When determining valid available versions, Composer looks at all of your tags
and branches and translates their names into an internal list of options that
it then matches against the version constraint you provided.
For more on how Composer treats tags and branches and how it resolves package
version constraints, read the [versions](articles/versions.md) article.
## Lock file
For your library you may commit the `composer.lock` file if you want to. This
can help your team to always test against the same dependency versions.
However, this lock file will not have any effect on other projects that depend
on it. It only has an effect on the main project.
If you do not want to commit the lock file, and you are using git, add it to
the `.gitignore`.
## Publishing to a VCS
Once you have a VCS repository (version control system, e.g. git) containing a
`composer.json` file, your library is already composer-installable. In this
example we will publish the `acme/hello-world` library on GitHub under
`github.com/username/hello-world`.
Now, to test installing the `acme/hello-world` package, we create a new
project locally. We will call it `acme/blog`. This blog will depend on
`acme/hello-world`, which in turn depends on `monolog/monolog`. We can
accomplish this by creating a new `blog` directory somewhere, containing a
`composer.json`:
```json
{
"name": "acme/blog",
"require": {
"acme/hello-world": "dev-master"
}
}
```
The name is not needed in this case, since we don't want to publish the blog
as a library. It is added here to clarify which `composer.json` is being
described.
Now we need to tell the blog app where to find the `hello-world` dependency.
We do this by adding a package repository specification to the blog's
`composer.json`:
```json
{
"name": "acme/blog",
"repositories": [
{
"type": "vcs",
"url": "https://github.com/username/hello-world"
}
],
"require": {
"acme/hello-world": "dev-master"
}
}
```
For more details on how package repositories work and what other types are
available, see [Repositories](05-repositories.md).
That's all. You can now install the dependencies by running Composer's
[`install`](03-cli.md#install) command!
**Recap:** Any git/svn/hg/fossil repository containing a `composer.json` can be
added to your project by specifying the package repository and declaring the
dependency in the [`require`](04-schema.md#require) field.
## Publishing to packagist
Alright, so now you can publish packages. But specifying the VCS repository
every time is cumbersome. You don't want to force all your users to do that.
The other thing that you may have noticed is that we did not specify a package
repository for `monolog/monolog`. How did that work? The answer is Packagist.
[Packagist](https://packagist.org/) is the main package repository for
Composer, and it is enabled by default. Anything that is published on
Packagist is available automatically through Composer. Since
[Monolog is on Packagist](https://packagist.org/packages/monolog/monolog), we
can depend on it without having to specify any additional repositories.
If we wanted to share `hello-world` with the world, we would publish it on
Packagist as well.
You visit [Packagist](https://packagist.org) and hit the "Submit"
button. This will prompt you to sign up if you haven't already, and then
allows you to submit the URL to your VCS repository, at which point Packagist
will start crawling it. Once it is done, your package will be available to
anyone!
## Light-weight distribution packages
Some useless information like the `.github` directory, or large examples, test
data, etc. should typically not be included in distributed packages.
The `.gitattributes` file is a git specific file like `.gitignore` also living
at the root directory of your library. It overrides local and global
configuration (`.git/config` and `~/.gitconfig` respectively) when present and
tracked by git.
Use `.gitattributes` to prevent unwanted files from bloating the zip
distribution packages.
```text
// .gitattributes
/demo export-ignore
phpunit.xml.dist export-ignore
/.github/ export-ignore
```
Test it by inspecting the zip file generated manually:
```shell
git archive branchName --format zip -o file.zip
```
> **Note:** Files would be still tracked by git just not included in the
> zip distribution. This only works for packages installed from
> dist (i.e. tagged releases) coming from GitHub, GitLab or Bitbucket.
&larr; [Basic usage](01-basic-usage.md) | [Command-line interface](03-cli.md) &rarr;

1338
doc/03-cli.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,12 @@
# The composer.json Schema # The composer.json schema
This chapter will explain all of the fields available in `composer.json`. This chapter will explain all of the fields available in `composer.json`.
## JSON schema ## JSON schema
We have a [JSON schema](http://json-schema.org) that documents the format and We have a [JSON schema](https://json-schema.org) that documents the format and
can also be used to validate your `composer.json`. In fact, it is used by the can also be used to validate your `composer.json`. In fact, it is used by the
`validate` command. You can find it at: `validate` command. You can find it at: https://getcomposer.org/schema.json
[`res/composer-schema.json`](https://github.com/composer/composer/blob/master/res/composer-schema.json).
## Root Package ## Root Package
@ -30,18 +29,21 @@ The config of dependencies is ignored. This makes the `config` field
### name ### name
The name of the package. It consists of vendor name and project name, The name of the package. It consists of vendor name and project name,
separated by `/`. separated by `/`. Examples:
Examples:
* monolog/monolog * monolog/monolog
* igorw/event-source * igorw/event-source
Required for published packages (libraries). The name must be lowercase and consist of words separated by `-`, `.` or `_`.
The complete name should match `^[a-z0-9]([_.-]?[a-z0-9]+)*/[a-z0-9](([_.]|-{1,2})?[a-z0-9]+)*$`.
The `name` property is required for published packages (libraries).
> **Note:** Before Composer version 2.0, a name could contain any character, including white spaces.
### description ### description
A short description of the package. Usually this is just one line long. A short description of the package. Usually this is one line long.
Required for published packages (libraries). Required for published packages (libraries).
@ -80,16 +82,16 @@ The type of the package. It defaults to `library`.
Package types are used for custom installation logic. If you have a package Package types are used for custom installation logic. If you have a package
that needs some special logic, you can define a custom type. This could be a that needs some special logic, you can define a custom type. This could be a
`symfony-bundle`, a `wordpress-plugin` or a `typo3-module`. These types will `symfony-bundle`, a `wordpress-plugin` or a `typo3-cms-extension`. These types
all be specific to certain projects, and they will need to provide an will all be specific to certain projects, and they will need to provide an
installer capable of installing packages of that type. installer capable of installing packages of that type.
Out of the box, Composer supports four types: Out of the box, Composer supports four types:
- **library:** This is the default. It will simply copy the files to `vendor`. - **library:** This is the default. It will copy the files to `vendor`.
- **project:** This denotes a project rather than a library. For example - **project:** This denotes a project rather than a library. For example
application shells like the [Symfony standard edition](https://github.com/symfony/symfony-standard), application shells like the [Symfony standard edition](https://github.com/symfony/symfony-standard),
CMSs like the [SilverStripe installer](https://github.com/silverstripe/silverstripe-installer) CMSs like the [Silverstripe installer](https://github.com/silverstripe/silverstripe-installer)
or full fledged applications distributed as packages. This can for example or full fledged applications distributed as packages. This can for example
be used by IDEs to provide listings of projects to initialize when creating be used by IDEs to provide listings of projects to initialize when creating
a new workspace. a new workspace.
@ -100,9 +102,12 @@ Out of the box, Composer supports four types:
- **composer-plugin:** A package of type `composer-plugin` may provide an - **composer-plugin:** A package of type `composer-plugin` may provide an
installer for other packages that have a custom type. Read more in the installer for other packages that have a custom type. Read more in the
[dedicated article](articles/custom-installers.md). [dedicated article](articles/custom-installers.md).
- **php-ext** and **php-ext-zend**: These names are reserved for PHP extension
packages which are written in C. Do not use these types for packages written
in PHP.
Only use a custom type if you need custom logic during installation. It is Only use a custom type if you need custom logic during installation. It is
recommended to omit this field and have it just default to `library`. recommended to omit this field and have it default to `library`.
### keywords ### keywords
@ -117,11 +122,28 @@ Examples:
- redis - redis
- templating - templating
> **Note**: Some special keywords trigger `composer require` without the
> `--dev` option to prompt users if they would like to add these packages to
> `require-dev` instead of `require`. These are: `dev`, `testing`, `static analysis`.
> **Note**: The range of characters allowed inside the string is restricted to
> unicode letters or numbers, space `" "`, dot `.`, underscore `_` and dash `-`. (Regex: `'{^[\p{N}\p{L} ._-]+$}u'`)
> Using other characters will emit a warning when running `composer validate` and
> will cause the package to fail updating on Packagist.org.
Optional. Optional.
### homepage ### homepage
An URL to the website of the project. A URL to the website of the project.
Optional.
### readme
A relative path to the readme document. Defaults to `README.md`.
This is mainly useful for packages not on GitHub, as for GitHub packages Packagist.org will use the readme API to fetch the one detected by GitHub.
Optional. Optional.
@ -143,20 +165,16 @@ The recommended notation for the most common licenses is (alphabetical):
- BSD-2-Clause - BSD-2-Clause
- BSD-3-Clause - BSD-3-Clause
- BSD-4-Clause - BSD-4-Clause
- GPL-2.0 - GPL-2.0-only / GPL-2.0-or-later
- GPL-2.0+ - GPL-3.0-only / GPL-3.0-or-later
- GPL-3.0 - LGPL-2.1-only / LGPL-2.1-or-later
- GPL-3.0+ - LGPL-3.0-only / LGPL-3.0-or-later
- LGPL-2.1
- LGPL-2.1+
- LGPL-3.0
- LGPL-3.0+
- MIT - MIT
Optional, but it is highly recommended to supply this. More identifiers are Optional, but it is highly recommended to supply this. More identifiers are
listed at the [SPDX Open Source License Registry](https://www.spdx.org/licenses/). listed at the [SPDX Open Source License Registry](https://spdx.org/licenses/).
For closed-source software, you may use `"proprietary"` as the license identifier. > **Note:** For closed-source software, you may use `"proprietary"` as the license identifier.
An Example: An Example:
@ -167,29 +185,29 @@ An Example:
``` ```
For a package, when there is a choice between licenses ("disjunctive license"), For a package, when there is a choice between licenses ("disjunctive license"),
multiple can be specified as array. multiple can be specified as an array.
An Example for disjunctive licenses: An Example for disjunctive licenses:
```json ```json
{ {
"license": [ "license": [
"LGPL-2.1", "LGPL-2.1-only",
"GPL-3.0+" "GPL-3.0-or-later"
] ]
} }
``` ```
Alternatively they can be separated with "or" and enclosed in parenthesis; Alternatively they can be separated with "or" and enclosed in parentheses;
```json ```json
{ {
"license": "(LGPL-2.1 or GPL-3.0+)" "license": "(LGPL-2.1-only or GPL-3.0-or-later)"
} }
``` ```
Similarly when multiple licenses need to be applied ("conjunctive license"), Similarly, when multiple licenses need to be applied ("conjunctive license"),
they should be separated with "and" and enclosed in parenthesis. they should be separated with "and" and enclosed in parentheses.
### authors ### authors
@ -197,10 +215,10 @@ The authors of the package. This is an array of objects.
Each author object can have following properties: Each author object can have following properties:
* **name:** The author's name. Usually his real name. * **name:** The author's name. Usually their real name.
* **email:** The author's email address. * **email:** The author's email address.
* **homepage:** An URL to the author's website. * **homepage:** URL to the author's website.
* **role:** The authors' role in the project (e.g. developer or translator) * **role:** The author's role in the project (e.g. developer or translator)
An example: An example:
@ -210,13 +228,13 @@ An example:
{ {
"name": "Nils Adermann", "name": "Nils Adermann",
"email": "naderman@naderman.de", "email": "naderman@naderman.de",
"homepage": "http://www.naderman.de", "homepage": "https://www.naderman.de",
"role": "Developer" "role": "Developer"
}, },
{ {
"name": "Jordi Boggiano", "name": "Jordi Boggiano",
"email": "j.boggiano@seld.be", "email": "j.boggiano@seld.be",
"homepage": "http://seld.be", "homepage": "https://seld.be",
"role": "Developer" "role": "Developer"
} }
] ]
@ -238,6 +256,9 @@ Support information includes the following:
* **irc:** IRC channel for support, as irc://server/channel. * **irc:** IRC channel for support, as irc://server/channel.
* **source:** URL to browse or download the sources. * **source:** URL to browse or download the sources.
* **docs:** URL to the documentation. * **docs:** URL to the documentation.
* **rss:** URL to the RSS feed.
* **chat:** URL to the chat channel.
* **security:** URL to the vulnerability disclosure policy (VDP).
An example: An example:
@ -252,10 +273,44 @@ An example:
Optional. Optional.
### funding
A list of URLs to provide funding to the package authors for maintenance and
development of new functionality.
Each entry consists of the following
* **type:** The type of funding, or the platform through which funding can be provided, e.g. patreon, opencollective, tidelift or github.
* **url:** URL to a website with details, and a way to fund the package.
An example:
```json
{
"funding": [
{
"type": "patreon",
"url": "https://www.patreon.com/phpdoctrine"
},
{
"type": "tidelift",
"url": "https://tidelift.com/subscription/pkg/packagist-doctrine_doctrine-bundle"
},
{
"type": "other",
"url": "https://www.doctrine-project.org/sponsorship.html"
}
]
}
```
Optional.
### Package links ### Package links
All of the following take an object which maps package names to All of the following take an object which maps package names to
[version constraints](01-basic-usage.md#package-versions). versions of the package via version constraints. Read more about
versions [here](articles/versions.md).
Example: Example:
@ -269,10 +324,11 @@ Example:
All links are optional fields. All links are optional fields.
`require` and `require-dev` additionally support stability flags ([root-only](04-schema.md#root-package)). `require` and `require-dev` additionally support _stability flags_ ([root-only](04-schema.md#root-package)).
They take the form "_constraint_@_stability flag_".
These allow you to further restrict or expand the stability of a package beyond These allow you to further restrict or expand the stability of a package beyond
the scope of the [minimum-stability](#minimum-stability) setting. You can apply the scope of the [minimum-stability](#minimum-stability) setting. You can apply
them to a constraint, or just apply them to an empty constraint if you want to them to a constraint, or apply them to an empty _constraint_ if you want to
allow unstable packages of a dependency for example. allow unstable packages of a dependency for example.
Example: Example:
@ -291,6 +347,10 @@ explicitly require it as well, along with its sufficient stability flag.
Example: Example:
Assuming `doctrine/doctrine-fixtures-bundle` requires `"doctrine/data-fixtures": "dev-master"`
then inside the root composer.json you need to add the second line below to allow dev
releases for the `doctrine/data-fixtures` package :
```json ```json
{ {
"require": { "require": {
@ -303,7 +363,9 @@ Example:
`require` and `require-dev` additionally support explicit references (i.e. `require` and `require-dev` additionally support explicit references (i.e.
commit) for dev versions to make sure they are locked to a given state, even commit) for dev versions to make sure they are locked to a given state, even
when you run update. These only work if you explicitly require a dev version when you run update. These only work if you explicitly require a dev version
and append the reference with `#<ref>`. and append the reference with `#<ref>`. This is also a
[root-only](04-schema.md#root-package) feature and will be ignored in
dependencies.
Example: Example:
@ -316,12 +378,12 @@ Example:
} }
``` ```
> **Note:** While this is convenient at times, it should not be how you use > **Note:** This feature has severe technical limitations, as the
> packages in the long term because it comes with a technical limitation. The
> composer.json metadata will still be read from the branch name you specify > composer.json metadata will still be read from the branch name you specify
> before the hash. Because of that in some cases it will not be a practical > before the hash. You should therefore only use this as a temporary solution
> workaround, and you should always try to switch to tagged releases as soon > during development to remediate transient issues, until you can switch to
> as you can. > tagged releases. The Composer team does not actively support this feature
> and will not accept bug reports related to it.
It is also possible to inline-alias a package constraint so that it matches It is also possible to inline-alias a package constraint so that it matches
a constraint that it otherwise would not. For more information [see the a constraint that it otherwise would not. For more information [see the
@ -334,38 +396,49 @@ Example:
```json ```json
{ {
"require" : { "require": {
"php" : "^5.5 || ^7.0", "php": ">=7.4",
"ext-mbstring": "*" "ext-mbstring": "*"
} }
} }
``` ```
> **Note:** It is important to list PHP extensions your project requires.
> Not all PHP installations are created equal: some may miss extensions you
> may consider as standard (such as `ext-mysqli` which is not installed by
> default in Fedora/CentOS minimal installation systems). Failure to list
> required PHP extensions may lead to a bad user experience: Composer will
> install your package without any errors but it will then fail at run-time.
> The `composer show --platform` command lists all PHP extensions available on
> your system. You may use it to help you compile the list of extensions you
> use and require. Alternatively you may use third party tools to analyze
> your project for the list of extensions used.
#### require #### require
Lists packages required by this package. The package will not be installed Map of packages required by this package. The package will not be installed
unless those requirements can be met. unless those requirements can be met.
#### require-dev <span>([root-only](04-schema.md#root-package))</span> #### require-dev <span>([root-only](04-schema.md#root-package))</span>
Lists packages required for developing this package, or running Map of packages required for developing this package, or running
tests, etc. The dev requirements of the root package are installed by default. tests, etc. The dev requirements of the root package are installed by default.
Both `install` or `update` support the `--no-dev` option that prevents dev Both `install` or `update` support the `--no-dev` option that prevents dev
dependencies from being installed. dependencies from being installed.
#### conflict #### conflict
Lists packages that conflict with this version of this package. They Map of packages that conflict with this version of this package. They
will not be allowed to be installed together with your package. will not be allowed to be installed together with your package.
Note that when specifying ranges like `<1.0 >=1.1` in a `conflict` link, Note that when specifying ranges like `<1.0 >=1.1` in a `conflict` link,
this will state a conflict with all versions that are less than 1.0 *and* equal this will state a conflict with all versions that are less than 1.0 *and* equal
or newer than 1.1 at the same time, which is probably not what you want. You or newer than 1.1 at the same time, which is probably not what you want. You
probably want to go for `<1.0 | >=1.1` in this case. probably want to go for `<1.0 || >=1.1` in this case.
#### replace #### replace
Lists packages that are replaced by this package. This allows you to fork a Map of packages that are replaced by this package. This allows you to fork a
package, publish it under a different name with its own version numbers, while package, publish it under a different name with its own version numbers, while
packages requiring the original package continue to work with your fork because packages requiring the original package continue to work with your fork because
it replaces the original package. it replaces the original package.
@ -383,15 +456,23 @@ that exact version, and not any other version, which would be incorrect.
#### provide #### provide
List of other packages that are provided by this package. This is mostly Map of packages that are provided by this package. This is mostly
useful for common interfaces. A package could depend on some virtual useful for implementations of common interfaces. A package could depend on
`logger` package, any library that implements this logger interface would some virtual package e.g. `psr/log-implementation`, any library that implements
simply list it in `provide`. this logger interface would list it in `provide`. Implementors can then
be [found on Packagist.org](https://packagist.org/providers/psr/log-implementation).
Using `provide` with the name of an actual package rather than a virtual one
implies that the code of that package is also shipped, in which case `replace`
is generally a better choice. A common convention for packages providing an
interface and relying on other packages to provide an implementation (for
instance the PSR interfaces) is to use a `-implementation` suffix for the
name of the virtual package corresponding to the interface package.
#### suggest #### suggest
Suggested packages that can enhance or work well with this package. These are Suggested packages that can enhance or work well with this package. These are
just informational and are displayed after the package is installed, to give informational and are displayed after the package is installed, to give
your users a hint that they could add more packages, even though they are not your users a hint that they could add more packages, even though they are not
strictly required. strictly required.
@ -403,7 +484,8 @@ Example:
```json ```json
{ {
"suggest": { "suggest": {
"monolog/monolog": "Allows more advanced logging of the application flow" "monolog/monolog": "Allows more advanced logging of the application flow",
"ext-xml": "Needed to support XML format in class Foo"
} }
} }
``` ```
@ -412,10 +494,11 @@ Example:
Autoload mapping for a PHP autoloader. Autoload mapping for a PHP autoloader.
Currently [`PSR-0`](http://www.php-fig.org/psr/psr-0/) autoloading, [`PSR-4`](https://www.php-fig.org/psr/psr-4/) and [`PSR-0`](http://www.php-fig.org/psr/psr-0/)
[`PSR-4`](http://www.php-fig.org/psr/psr-4/) autoloading, `classmap` generation and autoloading, `classmap` generation and `files` includes are supported.
`files` includes are supported. PSR-4 is the recommended way though since it offers
greater ease of use (no need to regenerate the autoloader when you add classes). PSR-4 is the recommended way since it offers greater ease of use (no need
to regenerate the autoloader when you add classes).
#### PSR-4 #### PSR-4
@ -550,10 +633,22 @@ Example:
} }
``` ```
Wildcards (`*`) are also supported in a classmap paths, and expand to match any directory name:
Example:
```json
{
"autoload": {
"classmap": ["src/addons/*/lib/", "3rd-party/*", "Something.php"]
}
}
```
#### Files #### Files
If you want to require certain files explicitly on every request then you can use If you want to require certain files explicitly on every request then you can use
the 'files' autoloading mechanism. This is useful if your package includes PHP functions the `files` autoloading mechanism. This is useful if your package includes PHP functions
that cannot be autoloaded by PHP. that cannot be autoloaded by PHP.
Example: Example:
@ -566,9 +661,20 @@ Example:
} }
``` ```
Files autoload rules are included whenever `vendor/autoload.php` is included, right after
the autoloader is registered. The order of inclusion depends on package dependencies so that
if package A depends on B, files in package B will be included first to ensure package B is fully
initialized and ready to be used when files from package A are included.
If two packages have the same amount of dependents or no dependencies, the order is alphabetical.
Files from the root package are always loaded last, and you cannot use files autoloading
yourself to override functions from your dependencies. If you want to achieve that we recommend
you include your own functions *before* including Composer's `vendor/autoload.php`.
#### Exclude files from classmaps #### Exclude files from classmaps
If you want to exclude some files or folders from the classmap you can use the 'exclude-from-classmap' property. If you want to exclude some files or folders from the classmap you can use the `exclude-from-classmap` property.
This might be useful to exclude test classes in your live environment, for example, as those will be skipped This might be useful to exclude test classes in your live environment, for example, as those will be skipped
from the classmap even when building an optimized autoloader. from the classmap even when building an optimized autoloader.
@ -586,9 +692,16 @@ Example:
} }
``` ```
#### Optimizing the autoloader
The autoloader can have quite a substantial impact on your request time
(50-100ms per request in large frameworks using a lot of classes). See the
[article about optimizing the autoloader](articles/autoloader-optimization.md)
for more details on how to reduce this impact.
### autoload-dev <span>([root-only](04-schema.md#root-package))</span> ### autoload-dev <span>([root-only](04-schema.md#root-package))</span>
This section allows to define autoload rules for development purposes. This section allows defining autoload rules for development purposes.
Classes needed to run the test suite should not be included in the main autoload Classes needed to run the test suite should not be included in the main autoload
rules to avoid polluting the autoloader in production and when other people use rules to avoid polluting the autoloader in production and when other people use
@ -667,9 +780,9 @@ it in your file to avoid surprises.
All versions of each package are checked for stability, and those that are less All versions of each package are checked for stability, and those that are less
stable than the `minimum-stability` setting will be ignored when resolving stable than the `minimum-stability` setting will be ignored when resolving
your project dependencies. Specific changes to the stability requirements of your project dependencies. (Note that you can also specify stability requirements
a given package can be done in `require` or `require-dev` (see on a per-package basis using stability flags in the version constraints that you
[package links](#package-links)). specify in a `require` block (see [package links](#package-links) for more details).
Available options (in order of stability) are `dev`, `alpha`, `beta`, `RC`, Available options (in order of stability) are `dev`, `alpha`, `beta`, `RC`,
and `stable`. and `stable`.
@ -687,7 +800,7 @@ Use `"prefer-stable": true` to enable.
Custom package repositories to use. Custom package repositories to use.
By default Composer just uses the packagist repository. By specifying By default Composer only uses the packagist repository. By specifying
repositories you can get packages from elsewhere. repositories you can get packages from elsewhere.
Repositories are not resolved recursively. You can only add them to your main Repositories are not resolved recursively. You can only add them to your main
@ -696,18 +809,16 @@ ignored.
The following repository types are supported: The following repository types are supported:
* **composer:** A Composer repository is simply a `packages.json` file served * **composer:** A Composer repository is a `packages.json` file served
via the network (HTTP, FTP, SSH), that contains a list of `composer.json` via the network (HTTP, FTP, SSH), that contains a list of `composer.json`
objects with additional `dist` and/or `source` information. The `packages.json` objects with additional `dist` and/or `source` information. The `packages.json`
file is loaded using a PHP stream. You can set extra options on that stream file is loaded using a PHP stream. You can set extra options on that stream
using the `options` parameter. using the `options` parameter.
* **vcs:** The version control system repository can fetch packages from git, * **vcs:** The version control system repository can fetch packages from git,
svn and hg repositories. svn, fossil and hg repositories.
* **pear:** With this you can import any pear repository into your Composer
project.
* **package:** If you depend on a project that does not have any support for * **package:** If you depend on a project that does not have any support for
composer whatsoever you can define the package inline using a `package` Composer whatsoever you can define the package inline using a `package`
repository. You basically just inline the `composer.json` object. repository. You basically inline the `composer.json` object.
For more information on any of these, see [Repositories](05-repositories.md). For more information on any of these, see [Repositories](05-repositories.md).
@ -733,17 +844,13 @@ Example:
"type": "vcs", "type": "vcs",
"url": "https://github.com/Seldaek/monolog" "url": "https://github.com/Seldaek/monolog"
}, },
{
"type": "pear",
"url": "https://pear2.php.net"
},
{ {
"type": "package", "type": "package",
"package": { "package": {
"name": "smarty/smarty", "name": "smarty/smarty",
"version": "3.1.7", "version": "3.1.7",
"dist": { "dist": {
"url": "http://www.smarty.net/files/Smarty-3.1.7.zip", "url": "https://www.smarty.net/files/Smarty-3.1.7.zip",
"type": "zip" "type": "zip"
}, },
"source": { "source": {
@ -762,6 +869,20 @@ will look from the first to the last repository, and pick the first match.
By default Packagist is added last which means that custom repositories can By default Packagist is added last which means that custom repositories can
override packages from it. override packages from it.
Using JSON object notation is also possible. However, JSON key/value pairs
are to be considered unordered so consistent behaviour cannot be guaranteed.
```json
{
"repositories": {
"foo": {
"type": "composer",
"url": "http://packages.foo.com"
}
}
}
```
### config <span>([root-only](04-schema.md#root-package))</span> ### config <span>([root-only](04-schema.md#root-package))</span>
A set of configuration options. It is only used for projects. See A set of configuration options. It is only used for projects. See
@ -789,8 +910,8 @@ Optional.
### bin ### bin
A set of files that should be treated as binaries and symlinked into the `bin-dir` A set of files that should be treated as binaries and made available
(from config). into the `bin-dir` (from config).
See [Vendor Binaries](articles/vendor-binaries.md) for more details. See [Vendor Binaries](articles/vendor-binaries.md) for more details.
@ -802,6 +923,21 @@ A set of options for creating package archives.
The following options are supported: The following options are supported:
* **name:** Allows configuring base name for archive.
By default (if not configured, and `--file` is not passed as command-line argument),
`preg_replace('#[^a-z0-9-_]#i', '-', name)` is used.
Example:
```json
{
"name": "org/strangeName",
"archive": {
"name": "Strange_name"
}
}
```
* **exclude:** Allows configuring a list of patterns for excluded paths. The * **exclude:** Allows configuring a list of patterns for excluded paths. The
pattern syntax matches .gitignore files. A leading exclamation mark (!) will pattern syntax matches .gitignore files. A leading exclamation mark (!) will
result in any matching files to be included even if a previous pattern result in any matching files to be included even if a previous pattern
@ -823,6 +959,39 @@ The example will include `/dir/foo/bar/file`, `/foo/bar/baz`, `/file.php`,
Optional. Optional.
### abandoned
Indicates whether this package has been abandoned.
It can be boolean or a package name/URL pointing to a recommended alternative.
Examples:
Use `"abandoned": true` to indicate this package is abandoned.
Use `"abandoned": "monolog/monolog"` to indicate this package is abandoned, and that
the recommended alternative is `monolog/monolog`.
Defaults to false.
Optional.
### _comment
Top level key used as a place to store comments (it can be a string or array of strings).
```json
{
"_comment": [
"The package foo/bar was required for business logic",
"Remove package foo/baz when removing foo/bar"
]
}
```
Defaults to empty.
Optional.
### non-feature-branches ### non-feature-branches
A list of regex patterns of branch names that are non-numeric (e.g. "latest" or something), A list of regex patterns of branch names that are non-numeric (e.g. "latest" or something),
@ -831,12 +1000,12 @@ that will NOT be handled as feature branches. This is an array of strings.
If you have non-numeric branch names, for example like "latest", "current", "latest-stable" If you have non-numeric branch names, for example like "latest", "current", "latest-stable"
or something, that do not look like a version number, then Composer handles such branches or something, that do not look like a version number, then Composer handles such branches
as feature branches. This means it searches for parent branches, that look like a version as feature branches. This means it searches for parent branches, that look like a version
or ends at special branches (like master) and the root package version number becomes the or ends at special branches (like master), and the root package version number becomes the
version of the parent branch or at least master or something. version of the parent branch or at least master or something.
To handle non-numeric named branches as versions instead of searching for a parent branch To handle non-numeric named branches as versions instead of searching for a parent branch
with a valid version or special branch name like master, you can set patterns for branch with a valid version or special branch name like master, you can set patterns for branch
names, that should be handled as dev version branches. names that should be handled as dev version branches.
This is really helpful when you have dependencies using "self.version", so that not dev-master, This is really helpful when you have dependencies using "self.version", so that not dev-master,
but the same branch is installed (in the example: latest-testing). but the same branch is installed (in the example: latest-testing).
@ -844,7 +1013,7 @@ but the same branch is installed (in the example: latest-testing).
An example: An example:
If you have a testing branch, that is heavily maintained during a testing phase and is If you have a testing branch, that is heavily maintained during a testing phase and is
deployed to your staging environment, normally "composer show -s" will give you `versions : * dev-master`. deployed to your staging environment, normally `composer show -s` will give you `versions : * dev-master`.
If you configure `latest-.*` as a pattern for non-feature-branches like this: If you configure `latest-.*` as a pattern for non-feature-branches like this:
@ -854,7 +1023,7 @@ If you configure `latest-.*` as a pattern for non-feature-branches like this:
} }
``` ```
Then "composer show -s" will give you `versions : * dev-latest-testing`. Then `composer show -s` will give you `versions : * dev-latest-testing`.
Optional. Optional.

View File

@ -6,24 +6,24 @@ of repositories are available, and how they work.
## Concepts ## Concepts
Before we look at the different types of repositories that exist, we need to Before we look at the different types of repositories that exist, we need to
understand some of the basic concepts that Composer is built on. understand some basic concepts that Composer is built on.
### Package ### Package
Composer is a dependency manager. It installs packages locally. A package is Composer is a dependency manager. It installs packages locally. A package is
essentially just a directory containing something. In this case it is PHP essentially a directory containing something. In this case it is PHP
code, but in theory it could be anything. And it contains a package code, but in theory it could be anything. And it contains a package
description which has a name and a version. The name and the version are used description which has a name and a version. The name and the version are used
to identify the package. to identify the package.
In fact, internally Composer sees every version as a separate package. While In fact, internally, Composer sees every version as a separate package. While
this distinction does not matter when you are using Composer, it's quite this distinction does not matter when you are using Composer, it's quite
important when you want to change it. important when you want to change it.
In addition to the name and the version, there is useful metadata. The information In addition to the name and the version, there is useful metadata. The
most relevant for installation is the source definition, which describes where information most relevant for installation is the source definition, which
to get the package contents. The package data points to the contents of the describes where to get the package contents. The package data points to the
package. And there are two options here: dist and source. contents of the package. And there are two options here: dist and source.
**Dist:** The dist is a packaged version of the package data. Usually a **Dist:** The dist is a packaged version of the package data. Usually a
released version, usually a stable release. released version, usually a stable release.
@ -41,14 +41,20 @@ be preferred.
A repository is a package source. It's a list of packages/versions. Composer A repository is a package source. It's a list of packages/versions. Composer
will look in all your repositories to find the packages your project requires. will look in all your repositories to find the packages your project requires.
By default only the Packagist repository is registered in Composer. You can By default, only the Packagist.org repository is registered in Composer. You can
add more repositories to your project by declaring them in `composer.json`. add more repositories to your project by declaring them in `composer.json`.
Repositories are only available to the root package and the repositories Repositories are only available to the root package and the repositories
defined in your dependencies will not be loaded. Read the defined in your dependencies will not be loaded. Read the
[FAQ entry](faqs/why-can't-composer-load-repositories-recursively.md) if you [FAQ entry](faqs/why-cant-composer-load-repositories-recursively.md) if you
want to learn why. want to learn why.
When resolving dependencies, packages are looked up from repositories from
top to bottom, and by default, as soon as a package is found in one, Composer
stops looking in other repositories. Read the
[repository priorities](articles/repository-priorities.md) article for more
details and to see how to change this behavior.
## Types ## Types
### Composer ### Composer
@ -57,11 +63,22 @@ The main repository type is the `composer` repository. It uses a single
`packages.json` file that contains all of the package metadata. `packages.json` file that contains all of the package metadata.
This is also the repository type that packagist uses. To reference a This is also the repository type that packagist uses. To reference a
`composer` repository, just supply the path before the `packages.json` file. `composer` repository, supply the path before the `packages.json` file.
In case of packagist, that file is located at `/packages.json`, so the URL of In the 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 the repository would be `repo.packagist.org`. For `example.org/packages.json` the
repository URL would be `example.org`. repository URL would be `example.org`.
```json
{
"repositories": [
{
"type": "composer",
"url": "https://example.org"
}
]
}
```
#### packages #### packages
The only required field is `packages`. The JSON structure is as follows: The only required field is `packages`. The JSON structure is as follows:
@ -93,7 +110,7 @@ Here is a minimal package definition:
"name": "smarty/smarty", "name": "smarty/smarty",
"version": "3.1.7", "version": "3.1.7",
"dist": { "dist": {
"url": "http://www.smarty.net/files/Smarty-3.1.7.zip", "url": "https://www.smarty.net/files/Smarty-3.1.7.zip",
"type": "zip" "type": "zip"
} }
} }
@ -105,7 +122,7 @@ It may include any of the other fields specified in the [schema](04-schema.md).
The `notify-batch` field allows you to specify a URL that will be called The `notify-batch` field allows you to specify a URL that will be called
every time a user installs a package. The URL can be either an absolute path every time a user installs a package. The URL can be either an absolute path
(that will use the same domain as the repository) or a fully qualified URL. (that will use the same domain as the repository), or a fully qualified URL.
An example value: An example value:
@ -132,45 +149,114 @@ number.
This field is optional. This field is optional.
#### includes #### metadata-url, available-packages and available-package-patterns
For larger repositories it is possible to split the `packages.json` into The `metadata-url` field allows you to provide a URL template to serve all
multiple files. The `includes` field allows you to reference these additional packages which are in the repository. It must contain the placeholder
files. `%package%`.
This field is new in Composer v2, and is prioritised over the
`provider-includes` and `providers-url` fields if both are present.
For compatibility with both Composer v1 and v2 you ideally want
to provide both. New repository implementations may only need to
support v2 however.
An example: An example:
```json ```json
{ {
"includes": { "metadata-url": "/p2/%package%.json"
"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 Whenever Composer looks for a package, it will replace `%package%` by the
hash changed. package name, and fetch that URL. If dev stability is allowed for the package,
it will also load the URL again with `$packageName~dev` (e.g.
`/p2/foo/bar~dev.json` to look for `foo/bar`'s dev versions).
This field is optional. You probably don't need it for your own custom The `foo/bar.json` and `foo/bar~dev.json` files containing package versions
repository. MUST contain only versions for the foo/bar package, as
`{"packages":{"foo/bar":[ ... versions here ... ]}}`.
Caching is done via the use of If-Modified-Since header, so make sure you
return Last-Modified headers and that they are accurate.
The array of versions can also optionally be minified using
`Composer\MetadataMinifier\MetadataMinifier::minify()` from
[composer/metadata-minifier](https://packagist.org/packages/composer/metadata-minifier).
If you do that, you should add a `"minified": "composer/2.0"` key
at the top level to indicate to Composer it must expand the version
list back into the original data. See
https://repo.packagist.org/p2/monolog/monolog.json for an example.
Any requested package which does not exist MUST return a 404 status code,
which will indicate to Composer that this package does not exist in your
repository. Make sure the 404 response is fast to avoid blocking Composer.
Avoid redirects to alternative 404 pages.
If your repository only has a small number of packages, and you want to avoid
the 404-requests, you can also specify an `"available-packages"` key in
`packages.json` which should be an array with all the package names that your
repository contains. Alternatively you can specify an
`"available-package-patterns"` key which is an array of package name patterns
(with `*` matching any string, e.g. `vendor/*` would make Composer look up
every matching package name in this repository).
This field is optional.
#### providers-api
The `providers-api` field allows you to provide a URL template to serve all
packages which provide a given package name, but not the package which has
that name. It must contain the placeholder `%package%`.
For example https://packagist.org/providers/monolog/monolog.json lists some
package which have a "provide" rule for monolog/monolog, but it does not list
monolog/monolog itself.
```json
{
"providers-api": "https://packagist.org/providers/%package%.json",
}
```
This field is optional.
#### list
The `list` field allows you to return the names of packages which match a
given filter (or all names if no filter is present). It should accept an
optional `?filter=xx` query param, which can contain `*` as wildcards matching
any substring.
Replace/provide rules should not be considered here.
It must return an array of package names:
```json
{
"packageNames": [
"a/b",
"c/d"
]
}
```
See <https://packagist.org/packages/list.json?filter=composer/*> for example.
This field is optional.
#### provider-includes and providers-url #### provider-includes and providers-url
For very large repositories like packagist.org using the so-called provider The `provider-includes` field allows you to list a set of files that list
files is the preferred method. The `provider-includes` field allows you to package names provided by this repository. The hash should be a sha256 of
list a set of files that list package names provided by this repository. The the files in this case.
hash should be a sha256 of the files in this case.
The `providers-url` describes how provider files are found on the server. It The `providers-url` describes how provider files are found on the server. It
is an absolute path from the repository root. is an absolute path from the repository root. It must contain the placeholders
`%package%` and `%hash%`.
These fields are used by Composer v1, or if your repository does not have the
`metadata-url` field set.
An example: An example:
@ -206,35 +292,59 @@ integrity, for example:
The file above declares that acme/foo and acme/bar can be found in this The file above declares that acme/foo and acme/bar can be found in this
repository, by loading the file referenced by `providers-url`, replacing repository, by loading the file referenced by `providers-url`, replacing
`%package%` by the package name and `%hash%` by the sha256 field. Those files `%package%` by the vendor namespaced package name and `%hash%` by the
themselves just contain package definitions as described [above](#packages). sha256 field. Those files themselves contain package definitions as
described [above](#packages).
This field is optional. You probably don't need it for your own custom These fields are optional. You probably don't need them for your own custom
repository. repository.
#### stream options #### cURL or stream options
The `packages.json` file is loaded using a PHP stream. You can set extra options The repository is accessed either using cURL (Composer 2 with ext-curl enabled)
on that stream using the `options` parameter. You can set any valid PHP stream or PHP streams. You can set extra options using the `options` parameter. For
context option. See [Context options and parameters](https://php.net/manual/en/context.php) PHP streams, you can set any valid PHP stream context option. See [Context
for more information. options and parameters](https://php.net/manual/en/context.php) for more
information. When cURL is used, only a limited set of `http` and `ssl` options
can be configured.
```json
{
"repositories": [
{
"type": "composer",
"url": "https://example.org",
"options": {
"http": {
"timeout": 60
}
}
}
],
"require": {
"acme/package": "^1.0"
}
}
```
### VCS ### VCS
VCS stands for version control system. This includes versioning systems like VCS stands for version control system. This includes versioning systems like
git, svn or hg. Composer has a repository type for installing packages from git, svn, fossil or hg. Composer has a repository type for installing packages
these systems. from these systems.
#### Loading a package from a VCS repository #### Loading a package from a VCS repository
There are a few use cases for this. The most common one is maintaining your There are a few use cases for this. The most common one is maintaining your
own fork of a third party library. If you are using a certain library for your own fork of a third party library. If you are using a certain library for your
project and you decide to change something in the library, you will want your project, and you decide to change something in the library, you will want your
project to use the patched version. If the library is on GitHub (this is the project to use the patched version. If the library is on GitHub (this is the
case most of the time), you can simply fork it there and push your changes to case most of the time), you can fork it there and push your changes to
your fork. After that you update the project's `composer.json`. All you have your fork. After that you update the project's `composer.json`. All you have
to do is add your fork as a repository and update the version constraint to to do is add your fork as a repository and update the version constraint to
point to your custom branch. Your custom branch name must be prefixed with `"dev-"`. For version constraint naming conventions see point to your custom branch. In `composer.json` only, you should prefix your
custom branch name with `"dev-"` (without making it part of the actual branch
name). For version constraint naming conventions see
[Libraries](02-libraries.md) for more information. [Libraries](02-libraries.md) for more information.
Example assuming you patched monolog to fix a bug in the `bugfix` branch: Example assuming you patched monolog to fix a bug in the `bugfix` branch:
@ -264,7 +374,7 @@ package, you should do so in the default (often master) branch and not in a
feature branch, since the package name is taken from the default branch. feature branch, since the package name is taken from the default branch.
Also note that the override will not work if you change the `name` property Also note that the override will not work if you change the `name` property
in your forked repository's composer.json file as this needs to match the in your forked repository's `composer.json` file as this needs to match the
original for the override to work. original for the override to work.
If other dependencies rely on the package you forked, it is possible to If other dependencies rely on the package you forked, it is possible to
@ -274,19 +384,19 @@ For more information [see the aliases article](articles/aliases.md).
#### Using private repositories #### Using private repositories
Exactly the same solution allows you to work with your private repositories at Exactly the same solution allows you to work with your private repositories at
GitHub and BitBucket: GitHub and Bitbucket:
```json ```json
{ {
"require": {
"vendor/my-private-repo": "dev-master"
},
"repositories": [ "repositories": [
{ {
"type": "vcs", "type": "vcs",
"url": "git@bitbucket.org:vendor/my-private-repo.git" "url": "git@bitbucket.org:vendor/my-private-repo.git"
} }
] ],
"require": {
"vendor/my-private-repo": "dev-master"
}
} }
``` ```
@ -299,26 +409,40 @@ The following are supported:
* **Git:** [git-scm.com](https://git-scm.com) * **Git:** [git-scm.com](https://git-scm.com)
* **Subversion:** [subversion.apache.org](https://subversion.apache.org) * **Subversion:** [subversion.apache.org](https://subversion.apache.org)
* **Mercurial:** [mercurial.selenic.com](http://mercurial.selenic.com) * **Mercurial:** [mercurial-scm.org](https://www.mercurial-scm.org)
* **Fossil**: [fossil-scm.org](https://www.fossil-scm.org/)
To get packages from these systems you need to have their respective clients To get packages from these systems you need to have their respective clients
installed. That can be inconvenient. And for this reason there is special installed. That can be inconvenient. And for this reason there is special
support for GitHub and BitBucket that use the APIs provided by these sites, to support for GitHub and Bitbucket that use the APIs provided by these sites, to
fetch the packages without having to install the version control system. The fetch the packages without having to install the version control system. The
VCS repository provides `dist`s for them that fetch the packages as zips. VCS repository provides `dist`s for them that fetch the packages as zips.
* **GitHub:** [github.com](https://github.com) (Git) * **GitHub:** [github.com](https://github.com) (Git)
* **BitBucket:** [bitbucket.org](https://bitbucket.org) (Git and Mercurial) * **Bitbucket:** [bitbucket.org](https://bitbucket.org) (Git)
The VCS driver to be used is detected automatically based on the URL. However, The VCS driver to be used is detected automatically based on the URL. However,
should you need to specify one for whatever reason, you can use `git`, `svn` or should you need to specify one for whatever reason, you can use `bitbucket`,
`hg` as the repository type instead of `vcs`. `github`, `gitlab`, `perforce`, `fossil`, `git`, `svn` or `hg`
as the repository type instead of `vcs`.
If you set the `no-api` key to `true` on a github repository it will clone the If you set the `no-api` key to `true` on a github repository it will clone the
repository as it would with any other git repository instead of using the repository as it would with any other git repository instead of using the
GitHub API. But unlike using the `git` driver directly, Composer will still GitHub API. But unlike using the `git` driver directly, Composer will still
attempt to use github's zip files. attempt to use github's zip files.
Please note:
* **To let Composer choose which driver to use** the repository type needs to be defined as "vcs"
* **If you already used a private repository**, this means Composer should have cloned it in cache. If you want to install the same package with drivers, remember to launch the command `composer clearcache` followed by the command `composer update` to update Composer cache and install the package from dist.
* VCS driver `git-bitbucket` is deprecated in favor of `bitbucket`
#### Bitbucket Driver Configuration
> **Note that the repository endpoint for Bitbucket needs to be https rather than git.**
After setting up your bitbucket repository, you will also need to
[set up authentication](articles/authentication-for-private-packages.md#bitbucket-oauth).
#### Subversion Options #### Subversion Options
Since Subversion has no native concept of branches and tags, Composer assumes Since Subversion has no native concept of branches and tags, Composer assumes
@ -344,7 +468,7 @@ repository like this:
If you have no branches or tags directory you can disable them entirely by If you have no branches or tags directory you can disable them entirely by
setting the `branches-path` or `tags-path` to `false`. setting the `branches-path` or `tags-path` to `false`.
If the package is in a sub-directory, e.g. `/trunk/foo/bar/composer.json` and If the package is in a subdirectory, e.g. `/trunk/foo/bar/composer.json` and
`/tags/1.0/foo/bar/composer.json`, then you can make Composer access it by `/tags/1.0/foo/bar/composer.json`, then you can make Composer access it by
setting the `"package-path"` option to the sub-directory, in this example it setting the `"package-path"` option to the sub-directory, in this example it
would be `"package-path": "foo/bar/"`. would be `"package-path": "foo/bar/"`.
@ -380,90 +504,6 @@ for this server will be overwritten. To change this behavior by setting the
} }
``` ```
### PEAR
It is possible to install packages from any PEAR channel by using the `pear`
repository. Composer will prefix all package names with `pear-{channelName}/` to
avoid conflicts. All packages are also aliased with prefix `pear-{channelAlias}/`
Example using `pear2.php.net`:
```json
{
"repositories": [
{
"type": "pear",
"url": "https://pear2.php.net"
}
],
"require": {
"pear-pear2.php.net/PEAR2_Text_Markdown": "*",
"pear-pear2/PEAR2_HTTP_Request": "*"
}
}
```
In this case the short name of the channel is `pear2`, so the
`PEAR2_HTTP_Request` package name becomes `pear-pear2/PEAR2_HTTP_Request`.
> **Note:** The `pear` repository requires doing quite a few requests per
> package, so this may considerably slow down the installation process.
#### Custom vendor alias
It is possible to alias PEAR channel packages with a custom vendor name.
Example:
Suppose you have a private PEAR repository and wish to use Composer to
incorporate dependencies from a VCS. Your PEAR repository contains the
following packages:
* `BasePackage`
* `IntermediatePackage`, which depends on `BasePackage`
* `TopLevelPackage1` and `TopLevelPackage2` which both depend on `IntermediatePackage`
Without a vendor alias, Composer will use the PEAR channel name as the
vendor portion of the package name:
* `pear-pear.foobar.repo/BasePackage`
* `pear-pear.foobar.repo/IntermediatePackage`
* `pear-pear.foobar.repo/TopLevelPackage1`
* `pear-pear.foobar.repo/TopLevelPackage2`
Suppose at a later time you wish to migrate your PEAR packages to a
Composer repository and naming scheme, and adopt the vendor name of `foobar`.
Projects using your PEAR packages would not see the updated packages, since
they have a different vendor name (`foobar/IntermediatePackage` vs
`pear-pear.foobar.repo/IntermediatePackage`).
By specifying `vendor-alias` for the PEAR repository from the start, you can
avoid this scenario and future-proof your package names.
To illustrate, the following example would get the `BasePackage`,
`TopLevelPackage1`, and `TopLevelPackage2` packages from your PEAR repository
and `IntermediatePackage` from a Github repository:
```json
{
"repositories": [
{
"type": "git",
"url": "https://github.com/foobar/intermediate.git"
},
{
"type": "pear",
"url": "http://pear.foobar.repo",
"vendor-alias": "foobar"
}
],
"require": {
"foobar/TopLevelPackage1": "*",
"foobar/TopLevelPackage2": "*"
}
}
```
### Package ### Package
If you want to use a project that does not support Composer through any of the If you want to use a project that does not support Composer through any of the
@ -486,7 +526,7 @@ Here is an example for the smarty template engine:
"name": "smarty/smarty", "name": "smarty/smarty",
"version": "3.1.7", "version": "3.1.7",
"dist": { "dist": {
"url": "http://www.smarty.net/files/Smarty-3.1.7.zip", "url": "https://www.smarty.net/files/Smarty-3.1.7.zip",
"type": "zip" "type": "zip"
}, },
"source": { "source": {
@ -506,7 +546,15 @@ Here is an example for the smarty template engine:
} }
``` ```
Typically you would leave the source part off, as you don't really need it. Typically, you would leave the source part off, as you don't really need it.
If a source key is included, the reference field should be a reference to the version that will be installed.
Where the type field is `git`, this will the be the commit id, branch or tag name.
> **Note**: It is not recommended to use a git branch name for the reference field. While this is valid since it is supported by `git checkout`,
> branch names are mutable so cannot be locked.
Where the type field is `svn`, the reference field should contain the reference that gets appended to the URL when running `svn co`.
> **Note**: This repository type has a few limitations and should be avoided > **Note**: This repository type has a few limitations and should be avoided
> whenever possible: > whenever possible:
@ -516,10 +564,34 @@ Typically you would leave the source part off, as you don't really need it.
> reference you will have to delete the package to force an update, and will > reference you will have to delete the package to force an update, and will
> have to deal with an unstable lock file. > have to deal with an unstable lock file.
The `"package"` key in a `package` repository may be set to an array to define multiple versions of a package:
```json
{
"repositories": [
{
"type": "package",
"package": [
{
"name": "foo/bar",
"version": "1.0.0",
...
},
{
"name": "foo/bar",
"version": "2.0.0",
...
}
]
}
]
}
```
## Hosting your own ## Hosting your own
While you will probably want to put your packages on packagist most of the time, While you will probably want to put your packages on packagist most of the
there are some use cases for hosting your own repository. time, there are some use cases for hosting your own repository.
* **Private company packages:** If you are part of a company that uses Composer * **Private company packages:** If you are part of a company that uses Composer
for their packages internally, you might want to keep those packages private. for their packages internally, you might want to keep those packages private.
@ -527,32 +599,20 @@ there are some use cases for hosting your own repository.
* **Separate ecosystem:** If you have a project which has its own ecosystem, * **Separate ecosystem:** If you have a project which has its own ecosystem,
and the packages aren't really reusable by the greater PHP community, you and the packages aren't really reusable by the greater PHP community, you
might want to keep them separate to packagist. An example of this would be might want to keep them separate to packagist. An example of this would be
wordpress plugins. WordPress plugins.
For hosting your own packages, a native `composer` type of repository is For hosting your own packages, a native `composer` type of repository is
recommended, which provides the best performance. recommended, which provides the best performance.
There are a few tools that can help you create a `composer` repository. There are a few tools that can help you create a `composer` repository.
### Packagist ### Private Packagist
The underlying application used by packagist is open source. This means that you [Private Packagist](https://packagist.com/) is a hosted or self-hosted
can technically install your own copy of packagist. However it is not a application providing private package hosting as well as mirroring of
supported use case and changes will happen without caring for third parties GitHub, Packagist.org and other package repositories.
using the code.
Packagist is a Symfony2 application, and it is [available on Check out [Packagist.com](https://packagist.com/) for more information.
GitHub](https://github.com/composer/packagist). It uses Composer internally and
acts as a proxy between VCS repositories and the Composer users. It holds a list
of all VCS packages, periodically re-crawls them, and exposes them as a Composer
repository.
### Toran Proxy
[Toran Proxy](https://toranproxy.com/) is a web app much like Packagist but
providing private package hosting as well as mirroring/proxying of GitHub and
packagist.org. Check its homepage and the [Satis/Toran Proxy article](articles/handling-private-packages-with-satis.md)
for more information.
### Satis ### Satis
@ -564,17 +624,17 @@ package repository definitions. It will fetch all the packages that are
`require`d and dump a `packages.json` that is your `composer` repository. `require`d and dump a `packages.json` that is your `composer` repository.
Check [the satis GitHub repository](https://github.com/composer/satis) and Check [the satis GitHub repository](https://github.com/composer/satis) and
the [Satis article](articles/handling-private-packages-with-satis.md) for more the [handling private packages article](articles/handling-private-packages.md) for more
information. information.
### Artifact ### Artifact
There are some cases, when there is no ability to have one of the previously There are some cases, when there is no ability to have one of the previously
mentioned repository types online, even the VCS one. Typical example could be mentioned repository types online, even the VCS one. A typical example could be
cross-organisation library exchange through built artifacts. Of course, most cross-organisation library exchange through build artifacts. Of course, most
of the times they are private. To simplify maintenance, one can simply use a of the time these are private. To use these archives as-is, one can use a
repository of type `artifact` with a folder containing ZIP archives of those repository of type `artifact` with a folder containing ZIP or TAR archives of
private packages: those private packages:
```json ```json
{ {
@ -592,11 +652,12 @@ private packages:
} }
``` ```
Each zip artifact is just a ZIP archive with `composer.json` in root folder: Each zip artifact is a ZIP archive with `composer.json` in root folder:
```sh ```shell
unzip -l acme-corp-parser-10.3.5.zip unzip -l acme-corp-parser-10.3.5.zip
```
```text
composer.json composer.json
... ...
``` ```
@ -609,21 +670,23 @@ update to the latest version.
### Path ### Path
In addition to the artifact repository, you can use the path one, which allows In addition to the artifact repository, you can use the path one, which allows
you to depend on a relative directory. This can be especially useful when dealing you to depend on a local directory, either absolute or relative. This can be
with monolith repositories. especially useful when dealing with monolithic repositories.
For instance, if you have the following directory structure in your repository: For instance, if you have the following directory structure in your repository:
``` ```text
- apps ...
\_ my-app ├── apps
\_ composer.json │ └── my-app
- packages │ └── composer.json
\_ my-package ├── packages
\_ composer.json │ └── my-package
│ └── composer.json
...
``` ```
Then, to add the package `my/package` as a dependency, in your `apps/my-app/composer.json` Then, to add the package `my/package` as a dependency, in your
file, you can use the following configuration: `apps/my-app/composer.json` file, you can use the following configuration:
```json ```json
{ {
@ -639,29 +702,112 @@ file, you can use the following configuration:
} }
``` ```
If the package is a local VCS repository, the version may be inferred by
the branch or tag that is currently checked out. Otherwise, the version should
be explicitly defined in the package's `composer.json` file. If the version
cannot be resolved by these means, it is assumed to be `dev-master`.
When the version cannot be inferred from the local VCS repository, or when you
want to override the version, you can use the `versions` option when declaring
the repository:
```json
{
"repositories": [
{
"type": "path",
"url": "../../packages/my-package",
"options": {
"versions": {
"my/package": "4.2-dev"
}
}
}
]
}
```
The local package will be symlinked if possible, in which case the output in The local package will be symlinked if possible, in which case the output in
the console will read `Symlinked from ../../packages/my-package`. If symlinking the console will read `Symlinking from ../../packages/my-package`. If symlinking
is _not_ possible the package will be copied. In that case, the console will is _not_ possible the package will be copied. In that case, the console will
output `Mirrored from ../../packages/my-package`. output `Mirrored from ../../packages/my-package`.
Instead of using a relative path, an absolute path can also be used. Instead of default fallback strategy you can force to use symlink with
`"symlink": true` or mirroring with `"symlink": false` option. Forcing
mirroring can be useful when deploying or generating package from a
monolithic repository.
> **Note:** Repository paths can also contain wildcards like ``*`` and ``?``. > **Note:** On Windows, directory symlinks are implemented using NTFS junctions
> For details, see the [PHP glob function](http://php.net/glob). > because they can be created by non-admin users. Mirroring will always be used
> on versions below Windows 7 or if `proc_open` has been disabled.
## Disabling Packagist ```json
{
"repositories": [
{
"type": "path",
"url": "../../packages/*",
"options": {
"symlink": false
}
}
]
}
```
You can disable the default Packagist repository by adding this to your Leading tildes are expanded to the current user's home folder, and environment
variables are parsed in both Windows and Linux/Mac notations. For example
`~/git/mypackage` will automatically load the mypackage clone from
`/home/<username>/git/mypackage`, equivalent to `$HOME/git/mypackage` or
`%USERPROFILE%/git/mypackage`.
> **Note:** Repository paths can also contain wildcards like `*` and `?`.
> For details, see the [PHP glob function](https://php.net/glob).
You can configure the way the package's dist reference (which appears in
the composer.lock file) is built.
The following modes exist:
- `none` - reference will be always null. This can help reduce lock file conflicts
in the lock file but reduces clarity as to when the last update happened and whether
the package is in the latest state.
- `config` - reference is built based on a hash of the package's composer.json and repo config
- `auto` (used by default) - reference is built basing on the hash like with `config`, but if
the package folder contains a git repository, the HEAD commit's hash is used as reference instead.
```json
{
"repositories": [
{
"type": "path",
"url": "../../packages/*",
"options": {
"reference": "config"
}
}
]
}
```
## Disabling Packagist.org
You can disable the default Packagist.org repository by adding this to your
`composer.json`: `composer.json`:
```json ```json
{ {
"repositories": [ "repositories": [
{ {
"packagist": false "packagist.org": false
} }
] ]
} }
``` ```
You can disable Packagist.org globally by using the global config flag:
```shell
php composer.phar config -g repo.packagist false
```
&larr; [Schema](04-schema.md) | [Config](06-config.md) &rarr; &larr; [Schema](04-schema.md) | [Config](06-config.md) &rarr;

479
doc/06-config.md Normal file
View File

@ -0,0 +1,479 @@
# Config
This chapter will describe the `config` section of the `composer.json`
[schema](04-schema.md).
## process-timeout
The timeout in seconds for process executions, defaults to 300 (5mins).
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.
To disable the process timeout on a custom command under `scripts`, a static
helper is available:
```json
{
"scripts": {
"test": [
"Composer\\Config::disableProcessTimeout",
"phpunit"
]
}
}
```
## allow-plugins
Defaults to `{}` which does not allow any plugins to be loaded.
As of Composer 2.2.0, the `allow-plugins` option adds a layer of security
allowing you to restrict which Composer plugins are able to execute code during
a Composer run.
When a new plugin is first activated, which is not yet listed in the config option,
Composer will print a warning. If you run Composer interactively it will
prompt you to decide if you want to execute the plugin or not.
Use this setting to allow only packages you trust to execute code. Set it to
an object with package name patterns as keys. The values are **true** to allow
and **false** to disallow while suppressing further warnings and prompts.
```json
{
"config": {
"allow-plugins": {
"third-party/required-plugin": true,
"my-organization/*": true,
"unnecessary/plugin": false
}
}
}
```
You can also set the config option itself to `false` to disallow all plugins, or `true` to allow all plugins to run (NOT recommended). For example:
```json
{
"config": {
"allow-plugins": false
}
}
```
## use-include-path
Defaults to `false`. If `true`, the Composer autoloader will also look for classes
in the PHP include path.
## preferred-install
Defaults to `dist` and can be any of `source`, `dist` or `auto`. This option
allows you to set the install method Composer will prefer to use. Can
optionally be an object with package name patterns for keys for more granular install preferences.
```json
{
"config": {
"preferred-install": {
"my-organization/stable-package": "dist",
"my-organization/*": "source",
"partner-organization/*": "auto",
"*": "dist"
}
}
}
```
- `source` means Composer will install packages from their `source` if there
is one. This is typically a git clone or equivalent checkout of the version
control system the package uses. This is useful if you want to make a bugfix
to a project and get a local git clone of the dependency directly.
- `auto` is the legacy behavior where Composer uses `source` automatically
for dev versions, and `dist` otherwise.
- `dist` (the default as of Composer 2.1) means Composer installs from `dist`,
where possible. This is typically a zip file download, which is faster than
cloning the entire repository.
> **Note:** Order matters. More specific patterns should be earlier than
> more relaxed patterns. When mixing the string notation with the hash
> configuration in global and package configurations the string notation
> is translated to a `*` package pattern.
## audit
Security audit configuration options
### ignore
A list of advisory ids, remote ids or CVE ids that are reported but let the audit command pass.
```json
{
"config": {
"audit": {
"ignore": {
"CVE-1234": "The affected component is not in use.",
"GHSA-xx": "The security fix was applied as a patch.",
"PKSA-yy": "Due to mitigations in place the update can be delayed."
}
}
}
}
```
or
```json
{
"config": {
"audit": {
"ignore": ["CVE-1234", "GHSA-xx", "PKSA-yy"]
}
}
}
```
### abandoned
Defaults to `report` in Composer 2.6, and defaults to `fail` from Composer 2.7 on. Defines whether the audit command reports abandoned packages or not, this has three possible values:
- `ignore` means the audit command does not consider abandoned packages at all.
- `report` means abandoned packages are reported as an error but do not cause the command to exit with a non-zero code.
- `fail` means abandoned packages will cause audits to fail with a non-zero code.
```json
{
"config": {
"audit": {
"abandoned": "report"
}
}
}
```
Since Composer 2.7 the option can be overridden via the [`COMPOSER_AUDIT_ABANDONED`](03-cli.md#composer-audit-abandoned) environment variable.
## use-parent-dir
When running Composer in a directory where there is no composer.json, if there
is one present in a directory above Composer will by default ask you whether
you want to use that directory's composer.json instead.
If you always want to answer yes to this prompt, you can set this config value
to `true`. To never be prompted, set it to `false`. The default is `"prompt"`.
> **Note:** This config must be set in your global user-wide config for it
> to work. Use for example `php composer.phar config --global use-parent-dir true`
> to set it.
## store-auths
What to do after prompting for authentication, one of: `true` (always store),
`false` (do not store) and `"prompt"` (ask every time), defaults to `"prompt"`.
## github-protocols
Defaults to `["https", "ssh", "git"]`. A list of protocols to use when cloning
from github.com, in priority order. By default `git` is present but only if [secure-http](#secure-http)
is disabled, as the git protocol is not encrypted. If you want your origin remote
push URLs to be using https and not ssh (`git@github.com:...`), then set the protocol
list to be only `["https"]` and Composer will stop overwriting the push URL to an ssh
URL.
## github-oauth
A list of domain names and oauth keys. For example using `{"github.com":
"oauthtoken"}` as the value of this option will use `oauthtoken` to access
private repositories on github and to circumvent the low IP-based rate limiting
of their API. Composer may prompt for credentials when needed, but these can also be
manually set. Read more on how to get an OAuth token for GitHub and cli syntax
[here](articles/authentication-for-private-packages.md#github-oauth).
## gitlab-domains
Defaults to `["gitlab.com"]`. A list of domains of GitLab servers.
This is used if you use the `gitlab` repository type.
## gitlab-oauth
A list of domain names and oauth keys. For example using `{"gitlab.com":
"oauthtoken"}` as the value of this option will use `oauthtoken` to access
private repositories on gitlab. Please note: If the package is not hosted at
gitlab.com the domain names must be also specified with the
[`gitlab-domains`](06-config.md#gitlab-domains) option.
Further info can also be found [here](articles/authentication-for-private-packages.md#gitlab-oauth)
## gitlab-token
A list of domain names and private tokens. Private token can be either simple
string, or array with username and token. For example using `{"gitlab.com":
"privatetoken"}` as the value of this option will use `privatetoken` to access
private repositories on gitlab. Using `{"gitlab.com": {"username": "gitlabuser",
"token": "privatetoken"}}` will use both username and token for gitlab deploy
token functionality (https://docs.gitlab.com/ee/user/project/deploy_tokens/)
Please note: If the package is not hosted at
gitlab.com the domain names must be also specified with the
[`gitlab-domains`](06-config.md#gitlab-domains) option. The token must have
`api` or `read_api` scope.
Further info can also be found [here](articles/authentication-for-private-packages.md#gitlab-token)
## gitlab-protocol
A protocol to force use of when creating a repository URL for the `source`
value of the package metadata. One of `git` or `http`. (`https` is treated
as a synonym for `http`.) Helpful when working with projects referencing
private repositories which will later be cloned in GitLab CI jobs with a
[GitLab CI_JOB_TOKEN](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html#predefined-variables-reference)
using HTTP basic auth. By default, Composer will generate a git-over-SSH
URL for private repositories and HTTP(S) only for public.
## disable-tls
Defaults to `false`. If set to true all HTTPS URLs will be tried with HTTP
instead and no network level encryption is performed. Enabling this is a
security risk and is NOT recommended. The better way is to enable the
php_openssl extension in php.ini. Enabling this will implicitly disable the
`secure-http` option.
## secure-http
Defaults to `true`. If set to true only HTTPS URLs are allowed to be
downloaded via Composer. If you really absolutely need HTTP access to something
then you can disable it, but using [Let's Encrypt](https://letsencrypt.org/) to
get a free SSL certificate is generally a better alternative.
## bitbucket-oauth
A list of domain names and consumers. For example using `{"bitbucket.org":
{"consumer-key": "myKey", "consumer-secret": "mySecret"}}`.
Read more [here](articles/authentication-for-private-packages.md#bitbucket-oauth).
## cafile
Location of Certificate Authority file on local filesystem. In PHP 5.6+ you
should rather set this via openssl.cafile in php.ini, although PHP 5.6+ should
be able to detect your system CA file automatically.
## capath
If cafile is not specified or if the certificate is not found there, the
directory pointed to by capath is searched for a suitable certificate.
capath must be a correctly hashed certificate directory.
## http-basic
A list of domain names and username/passwords to authenticate against them. For
example using `{"example.org": {"username": "alice", "password": "foo"}}` as the
value of this option will let Composer authenticate against example.org.
More info can be found [here](articles/authentication-for-private-packages.md#http-basic).
## bearer
A list of domain names and tokens to authenticate against them. For example using
`{"example.org": "foo"}` as the value of this option will let Composer authenticate
against example.org using an `Authorization: Bearer foo` header.
## platform
Lets you fake platform packages (PHP and extensions) so that you can emulate a
production env or define your target platform in the config. Example: `{"php":
"7.0.3", "ext-something": "4.0.3"}`.
This will make sure that no package requiring more than PHP 7.0.3 can be installed
regardless of the actual PHP version you run locally. However it also means
the dependencies are not checked correctly anymore, if you run PHP 5.6 it will
install fine as it assumes 7.0.3, but then it will fail at runtime. This also means if
`{"php":"7.4"}` is specified; no packages will be used that define `7.4.1` as minimum.
Therefore if you use this it is recommended, and safer, to also run the
[`check-platform-reqs`](03-cli.md#check-platform-reqs) command as part of your
deployment strategy.
If a dependency requires some extension that you do not have installed locally
you may ignore it instead by passing `--ignore-platform-req=ext-foo` to `update`,
`install` or `require`. In the long run though you should install required
extensions as if you ignore one now and a new package you add a month later also
requires it, you may introduce issues in production unknowingly.
If you have an extension installed locally but *not* on production, you may want
to artificially hide it from Composer using `{"ext-foo": false}`.
## vendor-dir
Defaults to `vendor`. You can install dependencies into a different directory if
you want to. `$HOME` and `~` will be replaced by your home directory's path in
vendor-dir and all `*-dir` options below.
## bin-dir
Defaults to `vendor/bin`. If a project includes binaries, they will be symlinked
into this directory.
## data-dir
Defaults to `C:\Users\<user>\AppData\Roaming\Composer` on Windows,
`$XDG_DATA_HOME/composer` on unix systems that follow the XDG Base Directory
Specifications, and `$COMPOSER_HOME` on other unix systems. Right now it is only
used for storing past composer.phar files to be able to roll back to older
versions. See also [COMPOSER_HOME](03-cli.md#composer-home).
## cache-dir
Defaults to `C:\Users\<user>\AppData\Local\Composer` on Windows,
`/Users/<user>/Library/Caches/composer` on macOS, `$XDG_CACHE_HOME/composer`
on unix systems that follow the XDG Base Directory Specifications, and
`$COMPOSER_HOME/cache` on other unix systems. Stores all the caches used by
Composer. See also [COMPOSER_HOME](03-cli.md#composer-home).
## cache-files-dir
Defaults to `$cache-dir/files`. Stores the zip archives of packages.
## cache-repo-dir
Defaults to `$cache-dir/repo`. Stores repository metadata for the `composer`
type and the VCS repos of type `svn`, `fossil`, `github` and `bitbucket`.
## cache-vcs-dir
Defaults to `$cache-dir/vcs`. Stores VCS clones for loading VCS repository
metadata for the `git`/`hg` types and to speed up installs.
## cache-files-ttl
Defaults to `15552000` (6 months). Composer caches all dist (zip, tar, ...)
packages that it downloads. Those are purged after six months of being unused by
default. This option allows you to tweak this duration (in seconds) or disable
it completely by setting it to 0.
## cache-files-maxsize
Defaults to `300MiB`. Composer caches all dist (zip, tar, ...) packages that it
downloads. When the garbage collection is periodically ran, this is the maximum
size the cache will be able to use. Older (less used) files will be removed
first until the cache fits.
## cache-read-only
Defaults to `false`. Whether to use the Composer cache in read-only mode.
## bin-compat
Defaults to `auto`. Determines the compatibility of the binaries to be installed.
If it is `auto` then Composer only installs .bat proxy files when on Windows or WSL. If
set to `full` then both .bat files for Windows and scripts for Unix-based
operating systems will be installed for each binary. This is mainly useful if you
run Composer inside a linux VM but still want the `.bat` proxies available for use
in the Windows host OS. If set to `proxy` Composer will only create bash/Unix-style
proxy files and no .bat files even on Windows/WSL.
## prepend-autoloader
Defaults to `true`. If `false`, the Composer autoloader will not be prepended to
existing autoloaders. This is sometimes required to fix interoperability issues
with other autoloaders.
## autoloader-suffix
Defaults to `null`. When set to a non-empty string, this value will be used as a
suffix for the generated Composer autoloader. If set to `null`, the
`content-hash` value from the `composer.lock` file will be used if available;
otherwise, a random suffix will be generated.
## optimize-autoloader
Defaults to `false`. If `true`, always optimize when dumping the autoloader.
## sort-packages
Defaults to `false`. If `true`, the `require` command keeps packages sorted
by name in `composer.json` when adding a new package.
## classmap-authoritative
Defaults to `false`. If `true`, the Composer autoloader will only load classes
from the classmap. Implies `optimize-autoloader`.
## apcu-autoloader
Defaults to `false`. If `true`, the Composer autoloader will check for APCu and
use it to cache found/not-found classes when the extension is enabled.
## github-domains
Defaults to `["github.com"]`. A list of domains to use in github mode. This is
used for GitHub Enterprise setups.
## github-expose-hostname
Defaults to `true`. If `false`, the OAuth tokens created to access the
github API will have a date instead of the machine hostname.
## use-github-api
Defaults to `true`. Similar to the `no-api` key on a specific repository,
setting `use-github-api` to `false` will define the global behavior for all
GitHub repositories to clone the repository as it would with any other git
repository instead of using the GitHub API. But unlike using the `git`
driver directly, Composer will still attempt to use GitHub's zip files.
## 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 behavior.
## discard-changes
Defaults to `false` and can be any of `true`, `false` or `"stash"`. This option
allows you to set the default style of handling dirty updates when in
non-interactive mode. `true` will always discard changes in vendors, while
`"stash"` will try to stash and reapply. Use this for CI servers or deploy
scripts if you tend to have modified vendors.
## archive-format
Defaults to `tar`. Overrides the default format used by the archive command.
## archive-dir
Defaults to `.`. Default destination for archives created by the archive
command.
Example:
```json
{
"config": {
"archive-dir": "/home/user/.composer/repo"
}
}
```
## htaccess-protect
Defaults to `true`. If set to `false`, Composer will not create `.htaccess` files
in the Composer home, cache, and data directories.
## lock
Defaults to `true`. If set to `false`, Composer will not create a `composer.lock`
file and will ignore it if one is present.
## platform-check
Defaults to `php-only` which only checks the PHP version. Set to `true` to also
check the presence of extension. If set to `false`, Composer will not create and
require a `platform_check.php` file as part of the autoloader bootstrap.
## secure-svn-domains
Defaults to `[]`. Lists domains which should be trusted/marked as using a secure
Subversion/SVN transport. By default svn:// protocol is seen as insecure and will
throw, but you can set this config option to `["example.org"]` to allow using svn
URLs on that hostname. This is a better/safer alternative to disabling `secure-http`
altogether.
&larr; [Repositories](05-repositories.md) | [Runtime](07-runtime.md) &rarr;

178
doc/07-runtime.md Normal file
View File

@ -0,0 +1,178 @@
# Runtime Composer utilities
While Composer is mostly used around your project to install its dependencies,
there are a few things which are made available to you at runtime.
If you need to rely on some of these in a specific version, you can require
the `composer-runtime-api` package.
## Autoload
The autoloader is the most used one, and is already covered in our
[basic usage guide](01-basic-usage.md#autoloading). It is available in all
Composer versions.
## Installed versions
composer-runtime-api 2.0 introduced a new `Composer\InstalledVersions` class which offers
a few static methods to inspect which versions are currently installed. This is
automatically available to your code as long as you include the Composer autoloader.
The main use cases for this class are the following:
### Knowing whether package X (or virtual package) is present
```php
\Composer\InstalledVersions::isInstalled('vendor/package'); // returns bool
\Composer\InstalledVersions::isInstalled('psr/log-implementation'); // returns bool
```
As of Composer 2.1, you may also check if something was installed via require-dev or not by
passing false as second argument:
```php
\Composer\InstalledVersions::isInstalled('vendor/package'); // returns true assuming this package is installed
\Composer\InstalledVersions::isInstalled('vendor/package', false); // returns true if vendor/package is in require, false if in require-dev
```
Note that this can not be used to check whether platform packages are installed.
### Knowing whether package X is installed in version Y
> **Note:** To use this, your package must require `"composer/semver": "^3.0"`.
```php
use Composer\Semver\VersionParser;
\Composer\InstalledVersions::satisfies(new VersionParser, 'vendor/package', '2.0.*');
\Composer\InstalledVersions::satisfies(new VersionParser, 'psr/log-implementation', '^1.0');
```
This will return true if e.g. vendor/package is installed in a version matching
`2.0.*`, but also if the given package name is replaced or provided by some other
package.
### Knowing the version of package X
> **Note:** This will return `null` if the package name you ask for is not itself installed
> but merely provided or replaced by another package. We therefore recommend using satisfies()
> in library code at least. In application code you have a bit more control and it is less
> important.
```php
// returns a normalized version (e.g. 1.2.3.0) if vendor/package is installed,
// or null if it is provided/replaced,
// or throws OutOfBoundsException if the package is not installed at all
\Composer\InstalledVersions::getVersion('vendor/package');
```
```php
// returns the original version (e.g. v1.2.3) if vendor/package is installed,
// or null if it is provided/replaced,
// or throws OutOfBoundsException if the package is not installed at all
\Composer\InstalledVersions::getPrettyVersion('vendor/package');
```
```php
// returns the package dist or source reference (e.g. a git commit hash) if vendor/package is installed,
// or null if it is provided/replaced,
// or throws OutOfBoundsException if the package is not installed at all
\Composer\InstalledVersions::getReference('vendor/package');
```
### Knowing a package's own installed version
If you are only interested in getting a package's own version, e.g. in the source of acme/foo you want
to know which version acme/foo is currently running to display that to the user, then it is
acceptable to use getVersion/getPrettyVersion/getReference.
The warning in the section above does not apply in this case as you are sure the package is present
and not being replaced if your code is running.
It is nonetheless a good idea to make sure you handle the `null` return value as gracefully as
possible for safety.
----
A few other methods are available for more complex usages, please refer to the
source/docblocks of [the class itself](https://github.com/composer/composer/blob/main/src/Composer/InstalledVersions.php).
### Knowing the path in which a package is installed
The `getInstallPath` method to retrieve a package's absolute install path.
> **Note:** The path, while absolute, may contain `../` or symlinks. It is
> not guaranteed to be equivalent to a `realpath()` so you should run a
> realpath on it if that matters to you.
```php
// returns an absolute path to the package installation location if vendor/package is installed,
// or null if it is provided/replaced, or the package is a metapackage
// or throws OutOfBoundsException if the package is not installed at all
\Composer\InstalledVersions::getInstallPath('vendor/package');
```
> Available as of Composer 2.1 (i.e. `composer-runtime-api ^2.1`)
### Knowing which packages of a given type are installed
The `getInstalledPackagesByType` method accepts a package type (e.g. foo-plugin) and lists
the packages of that type which are installed. You can then use the methods above to retrieve
more information about each package if needed.
This method should alleviate the need for custom installers placing plugins in a specific path
instead of leaving them in the vendor dir. You can then find plugins to initialize at runtime
via InstalledVersions, including their paths via getInstallPath if needed.
```php
\Composer\InstalledVersions::getInstalledPackagesByType('foo-plugin');
```
> Available as of Composer 2.1 (i.e. `composer-runtime-api ^2.1`)
## Platform check
composer-runtime-api 2.0 introduced a new `vendor/composer/platform_check.php` file, which
is included automatically when you include the Composer autoloader.
It verifies that platform requirements (i.e. php and php extensions) are fulfilled
by the PHP process currently running. If the requirements are not met, the script
prints a warning with the missing requirements and exits with code 104.
To avoid an unexpected white page of death with some obscure PHP extension warning in
production, you can run `composer check-platform-reqs` as part of your
deployment/build and if that returns a non-0 code you should abort.
The default value is `php-only` which only checks the PHP version.
If you for some reason do not want to use this safety check, and would rather
risk runtime errors when your code executes, you can disable this by setting the
[`platform-check`](06-config.md#platform-check) config option to `false`.
If you want the check to include verifying the presence of PHP extensions,
set the config option to `true`. `ext-*` requirements will then be verified
but for performance reasons Composer only checks the extension is present,
not its exact version.
`lib-*` requirements are never supported/checked by the platform check feature.
## Autoloader path in binaries
composer-runtime-api 2.2 introduced a new `$_composer_autoload_path` global
variable set when running binaries installed with Composer. Read more
about this [on the vendor binaries docs](articles/vendor-binaries.md#finding-the-composer-autoloader-from-a-binary).
This is set by the binary proxy and as such is not made available to projects
by Composer's `vendor/autoload.php`, which would be useless as it would point back
to itself.
## Binary (bin-dir) path in binaries
composer-runtime-api 2.2.2 introduced a new `$_composer_bin_dir` global
variable set when running binaries installed with Composer. Read more
about this [on the vendor binaries docs](articles/vendor-binaries.md#finding-the-composer-bin-dir-from-a-binary).
This is set by the binary proxy and as such is not made available to projects
by Composer's `vendor/autoload.php`.
&larr; [Config](06-config.md) | [Community](08-community.md) &rarr;

36
doc/08-community.md Normal file
View File

@ -0,0 +1,36 @@
# Community
There are many people using Composer already, and quite a few of them are
contributing.
## Contributing
If you would like to contribute to Composer, please read the
[README](https://github.com/composer/composer) and
[CONTRIBUTING](https://github.com/composer/composer/blob/main/.github/CONTRIBUTING.md)
documents.
The most important guidelines are described as follows:
> All code contributions - including those of people having commit access - must
> go through a pull request and approved by a core developer before being
> merged. This is to ensure proper review of all the code.
>
> Fork the project, create a feature branch, and send us a pull request.
>
> To ensure a consistent code base, you should make sure the code follows
> the [PSR-12 Coding Standards](https://www.php-fig.org/psr/psr-12/).
## Support
The IRC channel is on irc.libera.chat: [#composer](ircs://irc.libera.chat:6697/composer).
[Stack Overflow](https://stackoverflow.com/questions/tagged/composer-php) and
[GitHub Discussions](https://github.com/composer/composer/discussions) both have a
collection of Composer related questions.
For paid support, we do provide Composer-related support via chat and email to
[Private Packagist](https://packagist.com) customers.
&larr; [Runtime](07-runtime.md)

View File

@ -38,10 +38,14 @@ specifying a `branch-alias` field under `extra` in `composer.json`:
} }
``` ```
The branch version must begin with `dev-` (non-comparable version), the alias If you alias a non-comparable version (such as dev-develop) `dev-` must prefix the
must be a comparable dev version (i.e. start with numbers, and end with branch name. You may also alias a comparable version (i.e. start with numbers,
`.x-dev`). The `branch-alias` must be present on the branch that it references. and end with `.x-dev`), but only as a more specific version.
For `dev-master`, you need to commit it on the `master` branch. For example, 1.x-dev could be aliased as 1.2.x-dev.
The alias must be a comparable dev version, and 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, anyone can now require `1.0.*` and it will happily install As a result, anyone can now require `1.0.*` and it will happily install
`dev-master`. `dev-master`.
@ -56,19 +60,19 @@ 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 use them you need to have control over the source repository, and you need to
commit changes to version control. commit changes to version control.
This is not really fun when you just want to try a bugfix of some library that This is not really fun when you want to try a bugfix of some library that
is a dependency of your local project. is a dependency of your local project.
For this reason, you can alias packages in your `require` and `require-dev` 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 fields. Let's say you found a bug in the `monolog/monolog` package. You cloned
[Monolog](https://github.com/Seldaek/monolog) on GitHub and fixed the issue in [Monolog](https://github.com/Seldaek/monolog) on GitHub and fixed the issue in
a branch named `bugfix`. Now you want to install that version of monolog in your a branch named `bugfix`. Now you want to install that version of monolog in your
local project. local project.
You are using `symfony/monolog-bundle` which requires `monolog/monolog` version You are using `symfony/monolog-bundle` which requires `monolog/monolog` version
`1.*`. So you need your `dev-bugfix` to match that constraint. `1.*`. So you need your `dev-bugfix` to match that constraint.
Just add this to your project's root `composer.json`: Add this to your project's root `composer.json`:
```json ```json
{ {
@ -85,16 +89,23 @@ Just add this to your project's root `composer.json`:
} }
``` ```
Or let Composer add it for you with:
```shell
php composer.phar require "monolog/monolog:dev-bugfix as 1.0.x-dev"
```
That will fetch the `dev-bugfix` version of `monolog/monolog` from your GitHub That will fetch the `dev-bugfix` version of `monolog/monolog` from your GitHub
and alias it to `1.0.x-dev`. and alias it to `1.0.x-dev`.
> **Note:** If a package with inline aliases is required, the alias (right of > **Note:** Inline aliasing is a root-only feature. If a package with inline
> the `as`) is used as the version constraint. The part left of the `as` is > aliases is required, the alias (right of the `as`) is used as the version
> discarded. As a consequence, if A requires B and B requires `monolog/monolog` > constraint. The part left of the `as` is discarded. As a consequence, if
> version `dev-bugfix as 1.0.x-dev`, installing A will make B require > A requires B and B requires `monolog/monolog` version `dev-bugfix as 1.0.x-dev`,
> `1.0.x-dev`, which may exist as a branch alias or an actual `1.0` branch. If > installing A will make B require `1.0.x-dev`, which may exist as a branch
> it does not, it must be re-inline-aliased in A's `composer.json`. > alias or an actual `1.0` branch. If it does not, it must be
> inline-aliased again in A's `composer.json`.
> **Note:** Inline aliasing should be avoided, especially for published > **Note:** Inline aliasing should be avoided, especially for published
> packages. If you found a bug, try and get your fix merged upstream. This > packages/libraries. If you found a bug, try to get your fix merged upstream.
> helps to avoid issues for users of your package. > This helps to avoid issues for users of your package.

View File

@ -0,0 +1,362 @@
<!--
tagline: Access privately hosted packages/repositories
-->
# Authentication for privately hosted packages and repositories
Your [private package server](handling-private-packages.md) or version control system is probably secured with one
or more authentication options. In order to allow your project to have access to these
packages and repositories you will have to tell Composer how to authenticate with the server that hosts them.
# Authentication principles
Whenever Composer encounters a protected Composer repository it will try to authenticate
using already defined credentials first. When none of those credentials apply it will prompt
for credentials and save them (or a token if Composer is able to retrieve one).
|type|Generated by Prompt?|
|---|---|
|[http-basic](#http-basic)|yes|
|[Inline http-basic](#inline-http-basic)|no|
|[HTTP Bearer](#http-bearer)|no|
|[Custom header](#custom-token-authentication)|no|
|[gitlab-oauth](#gitlab-oauth)|yes|
|[gitlab-token](#gitlab-token)|yes|
|[github-oauth](#github-oauth)|yes|
|[bitbucket-oauth](#bitbucket-oauth)|yes|
Sometimes automatic authentication is not possible, or you may want to predefine
authentication credentials.
Credentials can be stored on 4 different places; in an `auth.json` for the project, a global
`auth.json`, in the `composer.json` itself or in the `COMPOSER_AUTH` environment variable.
## Authentication in auth.json per project
In this authentication storage method, an `auth.json` file will be present in the same folder
as the projects' `composer.json` file. You can either create and edit this file using the
command line or manually edit or create it.
> **Note: Make sure the `auth.json` file is in `.gitignore`** to avoid
> leaking credentials into your git history.
## Global authentication credentials
If you don't want to supply credentials for every project you work on, storing your credentials
globally might be a better idea. These credentials are stored in a global `auth.json` in your
Composer home directory.
### Command line global credential editing
For all authentication methods it is possible to edit them using the command line;
- [http-basic](#command-line-http-basic)
- [Inline http-basic](#command-line-inline-http-basic)
- [HTTP Bearer](#http-bearer)
- [gitlab-oauth](#command-line-gitlab-oauth)
- [gitlab-token](#command-line-gitlab-token)
- [github-oauth](#command-line-github-oauth)
- [bitbucket-oauth](#command-line-bitbucket-oauth)
### Manually editing global authentication credentials
> **Note:** It is not recommended to manually edit your authentication options as this might
> result in invalid json. Instead preferably use [the command line](#command-line-global-credential-editing).
To manually edit it, run:
```shell
php composer.phar config --global --editor [--auth]
```
For specific authentication implementations, see their sections;
- [http-basic](#manual-http-basic)
- [Inline http-basic](#manual-inline-http-basic)
- [HTTP Bearer](#http-bearer)
- [custom header](#manual-custom-token-authentication)
- [gitlab-oauth](#manual-gitlab-oauth)
- [gitlab-token](#manual-gitlab-token)
- [github-oauth](#manual-github-oauth)
- [bitbucket-oauth](#manual-bitbucket-oauth)
Manually editing this file instead of using the command line may result in invalid json errors.
To fix this you need to open the file in an editor and fix the error. To find the location of
your global `auth.json`, execute:
```shell
php composer.phar config --global home
```
The folder will contain your global `auth.json` if it exists.
You can open this file in your favorite editor and fix the error.
## Authentication in composer.json file itself
> **Note:** **This is not recommended** as these credentials are visible
> to anyone who has access to the composer.json, either when it is shared through
> a version control system like git or when an attacker gains (read) access to
> your production server files.
It is also possible to add credentials to a `composer.json` on a per-project basis in the `config`
section or directly in the repository definition.
## Authentication using the COMPOSER_AUTH environment variable
> **Note:** Using the command line environment variable method also has security implications.
> These credentials will most likely be stored in memory,
> and may be persisted to a file like `~/.bash_history` (linux) or `ConsoleHost_history.txt`
> (PowerShell on Windows) when closing a session.
The final option to supply Composer with credentials is to use the `COMPOSER_AUTH` environment variable.
These variables can be either passed as command line variables or set in actual environment variables.
Read more about the usage of this environment variable [here](../03-cli.md#composer-auth).
# Authentication methods
## http-basic
### Command line http-basic
```shell
php composer.phar config [--global] http-basic.repo.example.org username password
```
In the above command, the config key `http-basic.repo.example.org` consists of two parts:
- `http-basic` is the authentication method.
- `repo.example.org` is the repository host name, you should replace it with the host name of your repository.
### Manual http-basic
```shell
php composer.phar config [--global] --editor --auth
```
```json
{
"http-basic": {
"example.org": {
"username": "username",
"password": "password"
}
}
}
```
## Inline http-basic
For the inline http-basic authentication method the credentials are not stored in a separate
`auth.json` in the project or globally, but in the `composer.json` or global configuration
in the same place where the Composer repository definition is defined.
Make sure that the username and password are encoded according to [RFC 3986](http://www.faqs.org/rfcs/rfc3986.html) (2.1. Percent-Encoding).
If the username e.g. is an email address it needs to be passed as `name%40example.com`.
### Command line inline http-basic
```shell
php composer.phar config [--global] repositories composer.unique-name https://username:password@repo.example.org
```
### Manual inline http-basic
```shell
php composer.phar config [--global] --editor
```
```json
{
"repositories": [
{
"type": "composer",
"url": "https://username:password@example.org"
}
]
}
```
## HTTP Bearer
### Command line HTTP Bearer authentication
```shell
php composer.phar config [--global] bearer.repo.example.org token
```
In the above command, the config key `bearer.repo.example.org` consists of two parts:
- `bearer` is the authentication method.
- `repo.example.org` is the repository host name, you should replace it with the host name of your repository.
### Manual HTTP Bearer authentication
```shell
php composer.phar config [--global] --editor --auth
```
```json
{
"bearer": {
"example.org": "TOKEN"
}
}
```
## Custom token authentication
### Manual custom token authentication
```shell
php composer.phar config [--global] --editor
```
```json
{
"repositories": [
{
"type": "composer",
"url": "https://example.org",
"options": {
"http": {
"header": [
"API-TOKEN: YOUR-API-TOKEN"
]
}
}
}
]
}
```
## gitlab-oauth
> **Note:** For the gitlab authentication to work on private gitlab instances, the
> [`gitlab-domains`](../06-config.md#gitlab-domains) section should also contain the URL.
### Command line gitlab-oauth
```shell
php composer.phar config [--global] gitlab-oauth.gitlab.example.org token
```
In the above command, the config key `gitlab-oauth.gitlab.example.org` consists of two parts:
- `gitlab-oauth` is the authentication method.
- `gitlab.example.org` is the host name of your GitLab instance, you should replace it with the host name of your GitLab instance or use `gitlab.com` if you don't have a self-hosted GitLab instance.
### Manual gitlab-oauth
```shell
php composer.phar config [--global] --editor --auth
```
```json
{
"gitlab-oauth": {
"example.org": "token"
}
}
```
## gitlab-token
> **Note:** For the gitlab authentication to work on private gitlab instances, the
> [`gitlab-domains`](../06-config.md#gitlab-domains) section should also contain the URL.
To create a new access token, go to your [access tokens section on GitLab](https://gitlab.com/-/profile/personal_access_tokens)
(or the equivalent URL on your private instance) and create a new token. See also [the GitLab access token documentation](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#creating-a-personal-access-token) for more information.
When creating a gitlab token manually, make sure it has either the `read_api` or `api` scope.
### Command line gitlab-token
```shell
php composer.phar config [--global] gitlab-token.gitlab.example.org token
```
In the above command, the config key `gitlab-token.gitlab.example.org` consists of two parts:
- `gitlab-token` is the authentication method.
- `gitlab.example.org` is the host name of your GitLab instance, you should replace it with the host name of your GitLab instance or use `gitlab.com` if you don't have a self-hosted GitLab instance.
### Manual gitlab-token
```shell
php composer.phar config [--global] --editor --auth
```
```json
{
"gitlab-token": {
"example.org": "token"
}
}
```
## github-oauth
To create a new access token, head to your [token settings section on Github](https://github.com/settings/tokens) and [generate a new token](https://github.com/settings/tokens/new).
For public repositories when rate limited, a token *without* any particular scope is sufficient (see `(no scope)` in the [scopes documentation](https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps)). Such tokens grant read-only access to public information.
For private repositories, the `repo` scope is needed. Note that the token will be given broad read/write access to all of your private repositories and much more - see the [scopes documentation](https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps) for a complete list. As of writing (November 2021), it seems not to be possible to further limit permissions for such tokens.
Read more about [Personal Access Tokens](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token), or subscribe to the [roadmap item for better scoped tokens in GitHub](https://github.com/github/roadmap/issues/184).
### Command line github-oauth
```shell
php composer.phar config [--global] github-oauth.github.com token
```
In the above command, the config key `github-oauth.github.com` consists of two parts:
- `github-oauth` is the authentication method.
- `github.com` is the host name for which this token applies. For GitHub you most likely do not need to change this.
### Manual github-oauth
```shell
php composer.phar config [--global] --editor --auth
```
```json
{
"github-oauth": {
"github.com": "token"
}
}
```
## bitbucket-oauth
The BitBucket driver uses OAuth to access your private repositories via the BitBucket REST APIs, and you will need to create an OAuth consumer to use the driver, please refer to [Atlassian's Documentation](https://support.atlassian.com/bitbucket-cloud/docs/use-oauth-on-bitbucket-cloud/). You will need to fill the callback URL with something to satisfy BitBucket, but the address does not need to go anywhere and is not used by Composer.
### Command line bitbucket-oauth
```shell
php composer.phar config [--global] bitbucket-oauth.bitbucket.org consumer-key consumer-secret
```
In the above command, the config key `bitbucket-oauth.bitbucket.org` consists of two parts:
- `bitbucket-oauth` is the authentication method.
- `bitbucket.org` is the host name for which this token applies. Unless you have a private instance you don't need to change this.
### Manual bitbucket-oauth
```shell
php composer.phar config [--global] --editor --auth
```
```json
{
"bitbucket-oauth": {
"bitbucket.org": {
"consumer-key": "key",
"consumer-secret": "secret"
}
}
}
```

View File

@ -0,0 +1,111 @@
<!--
tagline: How to reduce the performance impact of the autoloader
-->
# Autoloader optimization
By default, the Composer autoloader runs relatively fast. However, due to the way
PSR-4 and PSR-0 autoloading rules are set up, it needs to check the filesystem
before resolving a classname conclusively. This slows things down quite a bit,
but it is convenient in development environments because when you add a new class
it can immediately be discovered/used without having to rebuild the autoloader
configuration.
The problem however is in production you generally want things to happen as fast
as possible, as you can rebuild the configuration every time you deploy and
new classes do not appear at random between deploys.
For this reason, Composer offers a few strategies to optimize the autoloader.
> **Note:** You **should not** enable any of these optimizations in **development** as
> they all will cause various problems when adding/removing classes. The performance
> gains are not worth the trouble in a development setting.
## Optimization Level 1: Class map generation
### How to run it?
There are a few options to enable this:
- Set `"optimize-autoloader": true` inside the config key of composer.json
- Call `install` or `update` with `-o` / `--optimize-autoloader`
- Call `dump-autoload` with `-o` / `--optimize`
### What does it do?
Class map generation essentially converts PSR-4/PSR-0 rules into classmap rules.
This makes everything quite a bit faster as for known classes the class map
returns instantly the path, and Composer can guarantee the class is in there so
there is no filesystem check needed.
On PHP 5.6+, the class map is also cached in opcache which improves the initialization
time greatly. If you make sure opcache is enabled, then the class map should load
almost instantly and then class loading is fast.
### Trade-offs
There are no real trade-offs with this method. It should always be enabled in
production.
The only issue is it does not keep track of autoload misses (i.e. when
it cannot find a given class), so those fallback to PSR-4 rules and can still
result in slow filesystem checks. To solve this issue two Level 2 optimization
options exist, and you can decide to enable either if you have a lot of
class_exists checks that are done for classes that do not exist in your project.
## Optimization Level 2/A: Authoritative class maps
### How to run it?
There are a few options to enable this:
- Set `"classmap-authoritative": true` inside the config key of composer.json
- Call `install` or `update` with `-a` / `--classmap-authoritative`
- Call `dump-autoload` with `-a` / `--classmap-authoritative`
### What does it do?
Enabling this automatically enables Level 1 class map optimizations.
This option says that if something is not found in the classmap,
then it does not exist and the autoloader should not attempt to look on the
filesystem according to PSR-4 rules.
### Trade-offs
This option makes the autoloader always return very quickly. On the flipside it
also means that in case a class is generated at runtime for some reason, it will
not be allowed to be autoloaded. If your project or any of your dependencies does that
then you might experience "class not found" issues in production. Enable this with care.
> Note: This cannot be combined with Level 2/B optimizations. You have to choose one as
> they address the same issue in different ways.
## Optimization Level 2/B: APCu cache
### How to run it?
There are a few options to enable this:
- Set `"apcu-autoloader": true` inside the config key of composer.json
- Call `install` or `update` with `--apcu-autoloader`
- Call `dump-autoload` with `--apcu`
### What does it do?
This option adds an APCu cache as a fallback for the class map. It will not
automatically generate the class map though, so you should still enable Level 1
optimizations manually if you so desire.
Whether a class is found or not, that fact is always cached in APCu, so it can be
returned quickly on the next request.
### Trade-offs
This option requires APCu which may or may not be available to you. It also
uses APCu memory for autoloading purposes, but it is safe to use and cannot
result in classes not being found like the authoritative class map
optimization above.
> Note: This cannot be combined with Level 2/A optimizations. You have to choose one as
> they address the same issue in different ways.

View File

@ -0,0 +1,77 @@
<!--
tagline: Making your package depend on specific Composer versions
-->
# Composer platform dependencies
## What are platform dependencies
Composer makes information about the environment Composer runs in available as virtual packages. This allows other
packages to define dependencies ([require](../04-schema.md#require), [conflict](../04-schema.md#conflict),
[provide](../04-schema.md#provide), [replace](../04-schema.md#replace)) on different aspects of the platform, like PHP,
extensions or system libraries, including version constraints.
When you require one of the platform packages no code is installed. The version numbers of platform packages are
derived from the environment Composer is executed in and they cannot be updated or removed. They can however be
overwritten for the purposes of dependency resolution with a [platform configuration](../06-config.md#platform).
**For example:** If you are executing `composer update` with a PHP interpreter in version
`7.4.42`, then Composer automatically adds a package to the pool of available packages
called `php` and assigns version `7.4.42` to it.
That's how packages can add a dependency on the used PHP version:
```json
{
"require": {
"php": ">=7.4"
}
}
```
Composer will check this requirement against the currently used PHP version when running the composer command.
### Different types of platform packages
The following types of platform packages exist and can be depended on:
1. PHP (`php` and the subtypes: `php-64bit`, `php-ipv6`, `php-zts` `php-debug`)
2. PHP Extensions (`ext-*`, e.g. `ext-mbstring`)
3. PHP Libraries (`lib-*`, e.g. `lib-curl`)
4. Composer (`composer`, `composer-plugin-api`, `composer-runtime-api`)
To see the complete list of platform packages available in your environment
you can run `php composer.phar show --platform` (or `show -p` for short).
The differences between the various Composer platform packages are explained further in this document.
## Plugin package `composer-plugin-api`
You can modify Composer's behavior with [plugin](plugins.md) packages. Composer provides a set of versioned APIs for
plugins. Because internal Composer changes may **not** change the plugin APIs, the API version may not increase every
time the Composer version increases. E.g. In Composer version `2.3.12`, the `composer-plugin-api` version could still
be `2.2.0`.
## Runtime package `composer-runtime-api`
When applications which were installed with Composer are run (either on CLI or through a web request), they require the
`vendor/autoload.php` file, typically as one of the first lines of executed code. Invocations of the Composer
autoloader are considered the application "runtime".
Starting with version 2.0, Composer makes [additional features](../07-runtime.md) (besides registering the class autoloader) available to the application runtime environment.
Similar to `composer-plugin-api`, not every Composer release adds new runtime features,
thus the version of `composer-runtime-api` is also increased independently from Composer's version.
## Composer package `composer`
Starting with Composer 2.2.0, a new platform package called `composer` is available, which represents the exact
Composer version that is executed. Packages depending on this platform package can therefore depend on (or conflict
with) individual Composer versions to cover edge cases where neither the `composer-runtime-api` version nor the
`composer-plugin-api` was changed.
Because this option was introduced with Composer 2.2.0, it is recommended to add a `composer-plugin-api` dependency on
at least `>=2.2.0` to provide a more meaningful error message for users running older Composer versions.
In general, depending on `composer-plugin-api` or `composer-runtime-api` is always recommended
over depending on concrete Composer versions with the `composer` platform package.

View File

@ -6,13 +6,23 @@
## Synopsis ## Synopsis
At times it may be necessary for a package to require additional actions during At times, it may be necessary for a package to require additional actions during
installation, such as installing packages outside of the default `vendor` installation, such as installing packages outside of the default `vendor`
library. library.
In these cases you could consider creating a Custom Installer to handle your In these cases you could consider creating a Custom Installer to handle your
specific logic. specific logic.
## Alternative to custom installers with Composer 2.1+
As of Composer 2.1, the `Composer\InstalledVersions` class has a
[`getInstalledPackagesByType`](https://getcomposer.org/doc/07-runtime.md#knowing-which-packages-of-a-given-type-are-installed)
method which can let you figure out at runtime which plugins/modules/extensions are installed.
It is highly recommended to use that instead of building new custom
installers if you are building a new application. This has the advantage of leaving
all vendor code in the vendor directory, and not requiring custom installer code.
## Calling a Custom Installer ## Calling a Custom Installer
Suppose that your project already has a Custom Installer for specific modules Suppose that your project already has a Custom Installer for specific modules
@ -51,7 +61,7 @@ An example composer.json of such a template package would be:
## Creating an Installer ## Creating an Installer
A Custom Installer is defined as a class that implements the A Custom Installer is defined as a class that implements the
[`Composer\Installer\InstallerInterface`][3] and is usually distributed in a [`Composer\Installer\InstallerInterface`][4] and is usually distributed in a
Composer Plugin. Composer Plugin.
A basic Installer Plugin would thus compose of three files: A basic Installer Plugin would thus compose of three files:
@ -68,7 +78,7 @@ requirements:
1. the [type][1] attribute must be `composer-plugin`. 1. the [type][1] attribute must be `composer-plugin`.
2. the [extra][2] attribute must contain an element `class` defining the 2. the [extra][2] attribute must contain an element `class` defining the
class name of the plugin (including namespace). If a package contains class name of the plugin (including namespace). If a package contains
multiple plugins this can be array of class names. multiple plugins, this can be an array of class names.
Example: Example:
@ -84,11 +94,17 @@ Example:
"class": "phpDocumentor\\Composer\\TemplateInstallerPlugin" "class": "phpDocumentor\\Composer\\TemplateInstallerPlugin"
}, },
"require": { "require": {
"composer-plugin-api": "1.0.0" "composer-plugin-api": "^1.0"
},
"require-dev": {
"composer/composer": "^1.3"
} }
} }
``` ```
The example above has Composer itself in its require-dev, which allows you to use
the Composer classes in your test suite for example.
### The Plugin class ### The Plugin class
The class defining the Composer plugin must implement the The class defining the Composer plugin must implement the
@ -141,8 +157,8 @@ source for the exact signature):
invoked with the update argument. invoked with the update argument.
* **uninstall()**, here you can determine the actions that need to be executed * **uninstall()**, here you can determine the actions that need to be executed
when the package needs to be removed. when the package needs to be removed.
* **getInstallPath()**, this method should return the location where the * **getInstallPath()**, this method should return the absolute path where the
package is to be installed, _relative from the location of composer.json._ package is to be installed. The path _must not end with a slash._
Example: Example:
@ -157,9 +173,9 @@ use Composer\Installer\LibraryInstaller;
class TemplateInstaller extends LibraryInstaller class TemplateInstaller extends LibraryInstaller
{ {
/** /**
* {@inheritDoc} * @inheritDoc
*/ */
public function getPackageBasePath(PackageInterface $package) public function getInstallPath(PackageInterface $package)
{ {
$prefix = substr($package->getPrettyName(), 0, 23); $prefix = substr($package->getPrettyName(), 0, 23);
if ('phpdocumentor/template-' !== $prefix) { if ('phpdocumentor/template-' !== $prefix) {
@ -174,7 +190,7 @@ class TemplateInstaller extends LibraryInstaller
} }
/** /**
* {@inheritDoc} * @inheritDoc
*/ */
public function supports($packageType) public function supports($packageType)
{ {
@ -183,7 +199,7 @@ class TemplateInstaller extends LibraryInstaller
} }
``` ```
The example demonstrates that it is quite simple to extend the The example demonstrates that it is possible to extend the
[`Composer\Installer\LibraryInstaller`][5] class to strip a prefix [`Composer\Installer\LibraryInstaller`][5] class to strip a prefix
(`phpdocumentor/template-`) and use the remaining part to assemble a completely (`phpdocumentor/template-`) and use the remaining part to assemble a completely
different installation path. different installation path.
@ -193,6 +209,6 @@ different installation path.
[1]: ../04-schema.md#type [1]: ../04-schema.md#type
[2]: ../04-schema.md#extra [2]: ../04-schema.md#extra
[3]: https://github.com/composer/composer/blob/master/src/Composer/Plugin/PluginInterface.php [3]: https://github.com/composer/composer/blob/main/src/Composer/Plugin/PluginInterface.php
[4]: https://github.com/composer/composer/blob/master/src/Composer/Installer/InstallerInterface.php [4]: https://github.com/composer/composer/blob/main/src/Composer/Installer/InstallerInterface.php
[5]: https://github.com/composer/composer/blob/master/src/Composer/Installer/LibraryInstaller.php [5]: https://github.com/composer/composer/blob/main/src/Composer/Installer/LibraryInstaller.php

View File

@ -0,0 +1,342 @@
<!--
tagline: Hosting and installing private Composer packages
-->
# Handling private packages
# Private Packagist
[Private Packagist](https://packagist.com) is a commercial package hosting product
offering professional support and web based management of private and public packages,
and granular access permissions. Private Packagist provides mirroring for packages' zip
files which makes installs faster and independent from third party systems - e.g.
you can deploy even if GitHub is down because your zip files are mirrored.
Private Packagist is available as a hosted SaaS solution or as an on-premise self-hosted
package, providing an interactive set up experience.
Some of Private Packagist's revenue is used to pay for Composer and Packagist.org
development and hosting so using it is a good way to support the maintenance of
these open source projects financially. You can find more information about how to
set up your own package archive on [Packagist.com](https://packagist.com).
# Satis
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 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](https://github.com/composer/satis) or install via CLI:
php composer.phar create-project composer/satis --stability=dev --keep-vcs
## Setup
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: a json file that lists your curated
[repositories](../05-repositories.md).
The default file name is satis.json but it could be anything you like.
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 it
uses `"require-all": true` which selects all versions of all packages in the
repositories you defined.
The default file Satis looks for is `satis.json` in the root of the repository.
```json
{
"name": "my/repository",
"homepage": "http://packages.example.org",
"repositories": [
{ "type": "vcs", "url": "https://github.com/mycompany/privaterepo" },
{ "type": "vcs", "url": "http://svn.example.org/private/repo" },
{ "type": "vcs", "url": "https://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.
```json
{
"repositories": [
{ "type": "vcs", "url": "https://github.com/mycompany/privaterepo" },
{ "type": "vcs", "url": "http://svn.example.org/private/repo" },
{ "type": "vcs", "url": "https://github.com/mycompany/privaterepo2" }
],
"require": {
"company/package": "*",
"company/package2": "*",
"company/package3": "2.0.0"
}
}
```
Once you've done this, you run:
php bin/satis build <configuration file> <build dir>
When you ironed out that process, what you would typically do is run this
command as a cron job on a server. It would then update all your package info
much like Packagist does.
Note that if your private packages are hosted on GitHub, your server should
have an ssh key that gives it access to those packages, and then you should add
the `--no-interaction` (or `-n`) flag to the command to make sure it falls back
to ssh key authentication instead of prompting for a password. This is also a
good trick for continuous integration servers.
Set up a virtual-host that points to that `web/` directory, let's say it is
`packages.example.org`. Alternatively, with PHP >= 5.4.0, you can use the
built-in CLI server `php -S localhost:port -t satis-output-dir/` for a
temporary solution.
### Partial Updates
You can tell Satis to selectively update only particular packages or process
only a repository with a given URL. This cuts down the time it takes to rebuild
the `package.json` file and is helpful if you use (custom) webhooks to trigger
rebuilds whenever code is pushed into one of your repositories.
To rebuild only particular packages, pass the package names on the command line
like so:
php bin/satis build satis.json web/ this/package that/other-package
Note that this will still need to pull and scan all of your VCS repositories
because any VCS repository might contain (on any branch) one of the selected
packages.
If you want to scan only the selected package and not all VCS repositories you need
to declare a *name* for all your package (this only work on VCS repositories type) :
```json
{
"repositories": [
{ "name": "company/privaterepo", "type": "vcs", "url": "https://github.com/mycompany/privaterepo" },
{ "name": "private/repo", "type": "vcs", "url": "http://svn.example.org/private/repo" },
{ "name": "mycompany/privaterepo2", "type": "vcs", "url": "https://github.com/mycompany/privaterepo2" }
]
}
```
If you want to scan only a single repository and update all packages found in
it, pass the VCS repository URL as an optional argument:
php bin/satis build --repository-url https://only.my/repo.git satis.json web/
## Usage
In your projects all you need to add now is your own Composer repository using
the `packages.example.org` as URL, then you can require your private packages
and everything should work smoothly. You don't need to copy all your
repositories in every project anymore. Only that one unique repository that
will update itself.
```json
{
"repositories": [ { "type": "composer", "url": "http://packages.example.org/" } ],
"require": {
"company/package": "1.2.0",
"company/package2": "1.5.2",
"company/package3": "dev-master"
}
}
```
### Security
To secure your private repository you can host it over SSH or SSL using a client
certificate. In your project you can use the `options` parameter to specify the
connection options for the server.
Example using a custom repository using SSH (requires the SSH2 PECL extension):
```json
{
"repositories": [{
"type": "composer",
"url": "ssh2.sftp://example.org",
"options": {
"ssh2": {
"username": "composer",
"pubkey_file": "/home/composer/.ssh/id_rsa.pub",
"privkey_file": "/home/composer/.ssh/id_rsa"
}
}
}]
}
```
> **Tip:** See [ssh2 context options] for more information.
Example using SSL/TLS (HTTPS) using a client certificate:
```json
{
"repositories": [{
"type": "composer",
"url": "https://example.org",
"options": {
"ssl": {
"local_cert": "/home/composer/.ssl/composer.pem"
}
}
}]
}
```
> **Tip:** See [ssl context options] for more information.
Example using a custom HTTP Header field for token authentication:
```json
{
"repositories": [{
"type": "composer",
"url": "https://example.org",
"options": {
"http": {
"header": [
"API-TOKEN: YOUR-API-TOKEN"
]
}
}
}]
}
```
### Authentication
Authentication can be handled in [several different ways](authentication-for-private-packages.md).
### Downloads
When GitHub, GitLab or BitBucket repositories are mirrored on your local satis, the
build process will include the location of the downloads these platforms make
available. This means that the repository and your setup depend on the
availability of these services.
At the same time, this implies that all code which is hosted somewhere else (on
another service or for example in Subversion) will not have downloads available
and thus installations usually take a lot longer.
To enable your satis installation to create downloads for all (Git, Mercurial
and Subversion) your packages, add the following to your `satis.json`:
```json
{
"archive": {
"directory": "dist",
"format": "tar",
"prefix-url": "https://amazing.cdn.example.org",
"skip-dev": true
}
}
```
#### Options explained
* `directory`: required, the location of the dist files (inside the
`output-dir`)
* `format`: optional, `zip` (default) or `tar`
* `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
* `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.
#### prefix-url
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.
Example: A `prefix-url` of `https://my-bucket.s3.amazonaws.com` (and
`directory` set to `dist`) creates download URLs 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] 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
It is possible to make satis automatically resolve and add all dependencies for
your projects. This can be used with the Downloads functionality to have a
complete local mirror of packages. Add the following to your `satis.json`:
```json
{
"require-dependencies": true,
"require-dev-dependencies": true
}
```
When searching for packages, satis will attempt to resolve all the required
packages from the listed repositories. 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.
### Other options
* `providers`: optional, `false` by default, when enabled (`true`) each
package will be dumped into a separate include file which will be only
loaded by Composer when the package is really required. Speeds up composer
handling for repositories with huge number of packages like f.i. packagist.
* `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 docs on [config schema] for more details.
* `notify-batch`: optional, specify a URL that will be called every time a
user installs a package. See [notify-batch].
[ssh2 context options]: https://secure.php.net/manual/en/wrappers.ssh2.php#refsect1-wrappers.ssh2-options
[ssl context options]: https://secure.php.net/manual/en/context.ssl.php
[Twig]: https://twig.sensiolabs.org/
[config schema]: https://getcomposer.org/doc/04-schema.md#config
[notify-batch]: https://getcomposer.org/doc/05-repositories.md#notify-batch

393
doc/articles/plugins.md Normal file
View File

@ -0,0 +1,393 @@
<!--
tagline: Modify and extend Composer's functionality
-->
# Setting up and using plugins
## Synopsis
You may wish to alter or expand Composer's functionality with your own. For
example if your environment poses special requirements on the behaviour of
Composer which do not apply to the majority of its users or if you wish to
accomplish something with Composer in a way that is not desired by most users.
In these cases you could consider creating a plugin to handle your
specific logic.
## Creating a Plugin
A plugin is a regular Composer package which ships its code as part of the
package and may also depend on further packages.
### Plugin Package
The package file is the same as any other package file but with the following
requirements:
1. The [type][1] attribute must be `composer-plugin`.
2. The [extra][2] attribute must contain an element `class` defining the
class name of the plugin (including namespace). If a package contains
multiple plugins, this can be an array of class names.
3. You must require the special package called `composer-plugin-api`
to define which Plugin API versions your plugin is compatible with.
Requiring this package doesn't actually include any extra dependencies,
it only specifies which version of the plugin API to use.
> **Note:** When developing a plugin, although not required, it's useful to add
> a require-dev dependency on `composer/composer` to have IDE autocompletion on Composer classes.
The required version of the `composer-plugin-api` follows the same [rules][7]
as a normal package's rules.
The current Composer plugin API version is `2.6.0`.
An example of a valid plugin `composer.json` file (with the autoloading
part omitted and an optional require-dev dependency on `composer/composer` for IDE auto completion):
```json
{
"name": "my/plugin-package",
"type": "composer-plugin",
"require": {
"composer-plugin-api": "^2.0"
},
"require-dev": {
"composer/composer": "^2.0"
},
"extra": {
"class": "My\\Plugin"
}
}
```
### Plugin Class
Every plugin has to supply a class which implements the
[`Composer\Plugin\PluginInterface`][3]. The `activate()` method of the plugin
is called after the plugin is loaded and receives an instance of
[`Composer\Composer`][4] as well as an instance of
[`Composer\IO\IOInterface`][5]. Using these two objects all configuration can
be read and all internal objects and state can be manipulated as desired.
Example:
```php
<?php
namespace phpDocumentor\Composer;
use Composer\Composer;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;
class TemplateInstallerPlugin implements PluginInterface
{
public function activate(Composer $composer, IOInterface $io)
{
$installer = new TemplateInstaller($io, $composer);
$composer->getInstallationManager()->addInstaller($installer);
}
}
```
## Event Handler
Furthermore plugins may implement the
[`Composer\EventDispatcher\EventSubscriberInterface`][6] in order to have its
event handlers automatically registered with the `EventDispatcher` when the
plugin is loaded.
To register a method to an event, implement the method `getSubscribedEvents()`
and have it return an array. The array key must be the
[event name](https://getcomposer.org/doc/articles/scripts.md#event-names)
and the value is the name of the method in this class to be called.
> **Note:** If you don't know which event to listen to, you can run a Composer
> command with the COMPOSER_DEBUG_EVENTS=1 environment variable set, which might
> help you identify what event you are looking for.
```php
public static function getSubscribedEvents()
{
return array(
'post-autoload-dump' => 'methodToBeCalled',
// ^ event name ^ ^ method name ^
);
}
```
By default, the priority of an event handler is set to 0. The priority can be
changed by attaching a tuple where the first value is the method name, as
before, and the second value is an integer representing the priority.
Higher integers represent higher priorities. Priority 2 is called before
priority 1, etc.
```php
public static function getSubscribedEvents()
{
return array(
// Will be called before events with priority 0
'post-autoload-dump' => array('methodToBeCalled', 1)
);
}
```
If multiple methods should be called, then an array of tuples can be attached
to each event. The tuples do not need to include the priority. If it is
omitted, it will default to 0.
```php
public static function getSubscribedEvents()
{
return array(
'post-autoload-dump' => array(
array('methodToBeCalled' ), // Priority defaults to 0
array('someOtherMethodName', 1), // This fires first
)
);
}
```
Here's a complete example:
```php
<?php
namespace Naderman\Composer\AWS;
use Composer\Composer;
use Composer\EventDispatcher\EventSubscriberInterface;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;
use Composer\Plugin\PluginEvents;
use Composer\Plugin\PreFileDownloadEvent;
class AwsPlugin implements PluginInterface, EventSubscriberInterface
{
protected $composer;
protected $io;
public function activate(Composer $composer, IOInterface $io)
{
$this->composer = $composer;
$this->io = $io;
}
public function deactivate(Composer $composer, IOInterface $io)
{
}
public function uninstall(Composer $composer, IOInterface $io)
{
}
public static function getSubscribedEvents()
{
return array(
PluginEvents::PRE_FILE_DOWNLOAD => array(
array('onPreFileDownload', 0)
),
);
}
public function onPreFileDownload(PreFileDownloadEvent $event)
{
$protocol = parse_url($event->getProcessedUrl(), PHP_URL_SCHEME);
if ($protocol === 's3') {
// ...
}
}
}
```
## Plugin capabilities
Composer defines a standard set of capabilities which may be implemented by plugins.
Their goal is to make the plugin ecosystem more stable as it reduces the need to mess
with [`Composer\Composer`][4]'s internal state, by providing explicit extension points
for common plugin requirements.
Capable Plugins classes must implement the [`Composer\Plugin\Capable`][8] interface
and declare their capabilities in the `getCapabilities()` method.
This method must return an array, with the _key_ as a Composer Capability class name,
and the _value_ as the Plugin's own implementation class name of said Capability:
```php
<?php
namespace My\Composer;
use Composer\Composer;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;
use Composer\Plugin\Capable;
class Plugin implements PluginInterface, Capable
{
public function activate(Composer $composer, IOInterface $io)
{
}
public function getCapabilities()
{
return array(
'Composer\Plugin\Capability\CommandProvider' => 'My\Composer\CommandProvider',
);
}
}
```
### Command provider
The [`Composer\Plugin\Capability\CommandProvider`][9] capability allows to register
additional commands for Composer:
```php
<?php
namespace My\Composer;
use Composer\Plugin\Capability\CommandProvider as CommandProviderCapability;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Composer\Command\BaseCommand;
class CommandProvider implements CommandProviderCapability
{
public function getCommands()
{
return array(new Command);
}
}
class Command extends BaseCommand
{
protected function configure(): void
{
$this->setName('custom-plugin-command');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$output->writeln('Executing');
return 0;
}
}
```
Now the `custom-plugin-command` is available alongside Composer commands.
> _Composer commands are based on the [Symfony Console Component][10]._
## Running plugins manually
Plugins for an event can be run manually by the `run-script` command. This works the same way as
[running scripts manually](scripts.md#running-scripts-manually).
If it is another type of plugin the best way to test it is probably using a [path repository](../05-repositories.md#path)
to require the plugin in a test project. If you are developing locally and want to test frequently, you can make sure the path repository uses symlinks, as changes are updated immediately. Otherwise, you'll have to run `rm -rf vendor && composer update`
every time you want to install/run it again.
## Using Plugins
Plugin packages are automatically loaded as soon as they are installed and will
be loaded when Composer starts up if they are found in the current project's
list of installed packages. Additionally all plugin packages installed in the
`COMPOSER_HOME` directory using the Composer global command are loaded before
local project plugins are loaded.
> You may pass the `--no-plugins` option to Composer commands to disable all
> installed plugins. This may be particularly helpful if any of the plugins
> causes errors and you wish to update or uninstall it.
## Plugin Helpers
As of Composer 2, due to the fact that DownloaderInterface can sometimes return Promises
and have been split up in more steps than they used to, we provide a [SyncHelper][11]
to make downloading and installing packages easier.
## Plugin Extra Attributes
A few special plugin capabilities can be unlocked using extra attributes in the plugin's composer.json.
### class
[See above](#plugin-package) for an explanation of the class attribute and how it works.
### plugin-modifies-downloads
Some special plugins need to update package download URLs before they get downloaded.
As of Composer 2.0, all packages are downloaded before they get installed. This means
on the first installation, your plugin is not yet installed when the download occurs,
and it does not get a chance to update the URLs on time.
Specifying `{"extra": {"plugin-modifies-downloads": true}}` in your composer.json will
hint to Composer that the plugin should be installed on its own before proceeding with
the rest of the package downloads. This slightly slows down the overall installation
process however, so do not use it in plugins which do not absolutely require it.
### plugin-modifies-install-path
Some special plugins modify the install path of packages.
As of Composer 2.2.9, you can specify `{"extra": {"plugin-modifies-install-path": true}}`
in your composer.json to hint to Composer that the plugin should be activated as soon
as possible to prevent any bad side-effects from Composer assuming packages are installed
in another location than they actually are.
### plugin-optional
Because Composer plugins can be used to perform actions which are necessary for installing
a working application, like modifying which path files get stored in, skipping required
plugins unintentionally can result in broken applications. So, in non-interactive mode,
Composer will fail if a new plugin is not listed in ["allow-plugins"](../06-config.md#allow-plugins)
to force users to decide if they want to execute the plugin, to avoid silent failures.
As of Composer 2.5.3, you can use the setting `{"extra": {"plugin-optional": true}}` on
your plugin, to tell Composer that skipping the plugin has no catastrophic consequences,
and it can safely be disabled in non-interactive mode if it is not yet listed in
"allow-plugins". The next interactive run of Composer will still prompt users to choose if
they want to enable or disable the plugin.
## Plugin Autoloading
Due to plugins being loaded by Composer at runtime, and to ensure that plugins which
depend on other packages can function correctly, a runtime autoloader is created whenever
a plugin is loaded. That autoloader is only configured to load with the plugin dependencies,
so you may not have access to all the packages which are installed.
## Static Analysis support
As of Composer 2.3.7 we ship a `phpstan/rules.neon` PHPStan config file, which provides additional error checking when working on Composer plugins.
### Usage with [PHPStan Extension Installer][13]
The necessary configuration files are automatically loaded, in case your plugin projects declares a dependency to `phpstan/extension-installer`.
### Alternative manual installation
To make use of it, your Composer plugin project needs a [PHPStan config file][12], which includes the `phpstan/rules.neon` file:
```neon
includes:
- vendor/composer/composer/phpstan/rules.neon
// your remaining config..
```
[1]: ../04-schema.md#type
[2]: ../04-schema.md#extra
[3]: https://github.com/composer/composer/blob/main/src/Composer/Plugin/PluginInterface.php
[4]: https://github.com/composer/composer/blob/main/src/Composer/Composer.php
[5]: https://github.com/composer/composer/blob/main/src/Composer/IO/IOInterface.php
[6]: https://github.com/composer/composer/blob/main/src/Composer/EventDispatcher/EventSubscriberInterface.php
[7]: ../01-basic-usage.md#package-versions
[8]: https://github.com/composer/composer/blob/main/src/Composer/Plugin/Capable.php
[9]: https://github.com/composer/composer/blob/main/src/Composer/Plugin/Capability/CommandProvider.php
[10]: https://symfony.com/doc/current/components/console.html
[11]: https://github.com/composer/composer/blob/main/src/Composer/Util/SyncHelper.php
[12]: https://phpstan.org/config-reference#multiple-files
[13]: https://github.com/phpstan/extension-installer#usage

View File

@ -0,0 +1,95 @@
<!--
tagline: Configure which packages are found in which repositories
-->
# Repository priorities
## Canonical repositories
When Composer resolves dependencies, it will look up a given package in the
topmost repository. If that repository does not contain the package, it
goes on to the next one, until one repository contains it and the process ends.
Canonical repositories are better for a few reasons:
- Performance wise, it is more efficient to stop looking for a package once it
has been found somewhere. It also avoids loading duplicate packages in case
the same package is present in several of your repositories.
- Security wise, it is safer to treat them canonically as it means that packages you
expect to come from your most important repositories will never be loaded from
another repository instead. Let's
say you have a private repository which is not canonical, and you require your
private package `foo/bar ^2.0` for example. Now if someone publishes
`foo/bar 2.999` to packagist.org, suddenly Composer will pick that package as it
has a higher version than your latest release (say 2.4.3), and you end up installing
something you may not have meant to. However, if the private repository is canonical,
that 2.999 version from packagist.org will not be considered at all.
There are however a few cases where you may want to specifically load some packages
from a given repository, but not all. Or you may want a given repository to not be
canonical, and to be only preferred if it has higher package versions than the
repositories defined below.
## Default behavior
By default in Composer 2.x all repositories are canonical. Composer 1.x treated
all repositories as non-canonical.
Another default is that the packagist.org repository is always added implicitly
as the last repository, unless you [disable it](../05-repositories.md#disabling-packagist-org).
## Making repositories non-canonical
You can add the canonical option to any repository to disable this default behavior
and make sure Composer keeps looking in other repositories, even if that repository
contains a given package.
```json
{
"repositories": [
{
"type": "composer",
"url": "https://example.org",
"canonical": false
}
]
}
```
## Filtering packages
You can also filter packages which a repository will be able to load, either by
selecting which ones you want, or by excluding those you do not want.
For example here we want to pick only the package `foo/bar` and all the packages from
`some-vendor/` from this Composer repository.
```json
{
"repositories": [
{
"type": "composer",
"url": "https://example.org",
"only": ["foo/bar", "some-vendor/*"]
}
]
}
```
And in this other example we exclude `toy/package` from a repository, which
we may not want to load in this project.
```json
{
"repositories": [
{
"type": "composer",
"url": "https://example.org",
"exclude": ["toy/package"]
}
]
}
```
Both `only` and `exclude` should be arrays of package names, which can also
contain wildcards (`*`), which will match any character.

View File

@ -0,0 +1,154 @@
<!--
tagline: On gracefully resolving conflicts while merging
-->
# Resolving merge conflicts
When working as a team on the same Composer project, you will eventually run into a scenario
where multiple people added, updated or removed something in the `composer.json` and
`composer.lock` files in multiple branches. When those branches are eventually merged
together, you will get merge conflicts. Resolving these merge conflicts is not as straight
forward as on other files, especially not regarding the `composer.lock` file.
> **Note:** It might not immediately be obvious why text based merging is not possible for
> lock files, so let's imagine the following example where we want to merge two branches;
>
> - Branch 1 has added package A which requires package B. Package B is locked at version `1.0.0`.
> - Branch 2 has added package C which conflicts with all versions below `1.2.0` of package B.
>
> A text based merge would result in package A version `1.0.0`, package B version `1.0.0`
> and package C version `1.0.0`. This is an invalid result, as the conflict of package C
> was not considered and would require an upgrade of package B.
## 1. Reapplying changes
The safest method to merge Composer files is to accept the version from one branch and apply
the changes from the other branch.
An example where we have two branches:
1. Package 'A' has been added
2. Package 'B' has been removed and package 'C' is added.
To resolve the conflict when we merge these two branches:
- We choose the branch that has the most changes, and accept the `composer.json` and `composer.lock`
files from that branch. In this case, we choose the Composer files from branch 2.
- We reapply the changes from the other branch (branch 1). In this case we have to run
`composer require package/A` again.
## 2. Validating your merged files
Before committing, make sure the resulting `composer.json` and `composer.lock` files are valid.
To do this, run the following commands:
```shell
php composer.phar validate
php composer.phar install [--dry-run]
```
## Automating merge conflict resolving with git
Some improvement _could_ be made to git's conflict resolving by using a custom git merge driver.
An example of this can be found at [balbuf's composer git merge driver](https://github.com/balbuf/composer-git-merge-driver).
## Important considerations
Keep in mind that whenever merge conflicts occur on the lock file, the information, about the exact version
new packages were locked on for one of the branches, is lost. When package A in branch 1 is constrained
as `^1.2.0` and locked as `1.2.0`, it might get updated when branch 2 is used as baseline and a new
`composer require package/A:^1.2.0` is executed, as that will use the most recent version that the
constraint allows when possible. There might be a version 1.3.0 for that package available by now, which
will now be used instead.
Choosing the correct [version constraints](../articles/versions.md) and making sure the packages adhere
to [semantic versioning](https://semver.org/) when using
[next significant release operators](versions.md#next-significant-release-operators) should make sure
that merging branches does not break anything by accidentally updating a dependency.
# Recovering from incorrectly resolved merge conflicts
If the above steps aren't followed and text based merges have been done anyway,
your Composer project might be in a state where unexpected behaviour is observed
because the `composer.lock` file is not (fully) in sync with the `composer.json` file.
There are two things that can happen here:
1. There are packages in the `require` or `require-dev` section of the `composer.json` file that are not in the lock file and as a result never installed
> **Note:** Starting from Composer release 2.5, having packages that are required but not present in `composer.lock` results in an error when running `install`
2. There are packages in the `composer.lock` file that are not a direct or indirect dependency of any of the packages required. As a result, a package is installed, even though running `composer why vendor/package` says it is not required.
There are several ways to fix these issues;
## A. Start from scratch
The easiest but most impactful option is run a `composer update` to resolve to a correct state from scratch.
A drawback to this is that previously locked package versions are now updated, as the information about previous package versions has been lost. If all your dependencies follow [semantic versioning](https://semver.org/) and your [version constraints](../articles/versions.md) are using [next significant release operators](versions.md#next-significant-release-operators) this should not be an issue, otherwise you might inadvertently break your application.
## B. Reconstruct from the git history
An option that is probably not very feasible in a lot of situations but that deserves an honorable mention;
It might be possible to reconstruct the correct package state by going back into the git history and finding the most recent valid `composer.lock` file, and re-requiring the new dependencies from there.
## C. Resolve issues manually
There is an option to recover from a discrepancy between the `composer.json` and `composer.lock` file without having to dig through the git history or starting from scratch. For that, we need to solve issue 1 and 2 separately.
### 1. Detecting and fixing missing required packages
To detect any package that is required but not installed, you can simply run:
```shell
php composer.phar validate
```
If there are packages that are required but not installed, you should get output similar to this:
```shell
./composer.json is valid but your composer.lock has some errors
# Lock file errors
- Required package "vendor/package-name" is not present in the lock file.
This usually happens when composer files are incorrectly merged or the composer.json file is manually edited.
Read more about correctly resolving merge conflicts https://getcomposer.org/doc/articles/resolving-merge-conflicts.md
and prefer using the "require" command over editing the composer.json file directly https://getcomposer.org/doc/03-cli.md#require
```
To recover from this, simply run `composer update vendor/package-name` for each package listed here. After doing this for each package listed here, running `composer validate` again should result in no lock file errors:
```shell
./composer.json is valid
```
### 2. Detecting and fixing superfluous packages
To detect and fix packages that are locked but not a direct/indirect dependency, you can run the following command:
```shell
php composer.phar remove --unused
```
If there are no packages locked that are not a dependency, the command will have the following output:
```shell
No unused packages to remove
```
If there are packages to be cleaned up, the output will be as follows:
```shell
vendor/package-name is not required in your composer.json and has not been removed
./composer.json has been updated
Running composer update vendor/package-name
Loading composer repositories with package information
Updating dependencies
Lock file operations: 0 installs, 0 updates, 1 removal
- Removing vendor/package-name (1.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Nothing to install, update or remove
```

459
doc/articles/scripts.md Normal file
View File

@ -0,0 +1,459 @@
<!--
tagline: Script are callbacks that are called before/after installing packages
-->
# Scripts
## What is a script?
A script, in Composer's terms, can either be a PHP callback (defined as a
static method) or any command-line executable command. Scripts are useful
for executing a package's custom code or package-specific commands during
the Composer execution process.
As of Composer 2.5 scripts can also be Symfony Console Command classes,
which allows you to easily run them including passing options. This is
however not recommended for handling events.
> **Note:** Only scripts defined in the root package's `composer.json` are
> executed. If a dependency of the root package specifies its own scripts,
> Composer does not execute those additional scripts.
## Event names
Composer fires the following named events during its execution process:
### Command Events
- **pre-install-cmd**: occurs before the `install` command is executed with a
lock file present.
- **post-install-cmd**: occurs after the `install` command has been executed
with a lock file present.
- **pre-update-cmd**: occurs before the `update` command is executed, or before
the `install` command is executed without a lock file present.
- **post-update-cmd**: occurs after the `update` command has been executed, or
after the `install` command has been executed without a lock file present.
- **pre-status-cmd**: occurs before the `status` command is executed.
- **post-status-cmd**: occurs after the `status` command has been executed.
- **pre-archive-cmd**: occurs before the `archive` command is executed.
- **post-archive-cmd**: occurs after the `archive` command has been executed.
- **pre-autoload-dump**: occurs before the autoloader is dumped, either during
`install`/`update`, or via the `dump-autoload` command.
- **post-autoload-dump**: occurs after the autoloader has been dumped, either
during `install`/`update`, or via the `dump-autoload` command.
- **post-root-package-install**: occurs after the root package has been
installed during the `create-project` command (but before its
dependencies are installed).
- **post-create-project-cmd**: occurs after the `create-project` command has
been executed.
### Installer Events
- **pre-operations-exec**: occurs before the install/upgrade/.. operations
are executed when installing a lock file. Plugins that need to hook into
this event will need to be installed globally to be usable, as otherwise
they would not be loaded yet when a fresh install of a project happens.
### Package Events
- **pre-package-install**: occurs before a package is installed.
- **post-package-install**: occurs after a package has been installed.
- **pre-package-update**: occurs before a package is updated.
- **post-package-update**: occurs after a package has been updated.
- **pre-package-uninstall**: occurs before a package is uninstalled.
- **post-package-uninstall**: occurs after a package has been uninstalled.
### Plugin Events
- **init**: occurs after a Composer instance is done being initialized.
- **command**: occurs before any Composer Command is executed on the CLI. It
provides you with access to the input and output objects of the program.
- **pre-file-download**: occurs before files are downloaded and allows
you to manipulate the `HttpDownloader` object prior to downloading files
based on the URL to be downloaded.
- **post-file-download**: occurs after package dist files are downloaded and
allows you to perform additional checks on the file if required.
- **pre-command-run**: occurs before a command is executed and allows you to
manipulate the `InputInterface` object's options and arguments to tweak
a command's behavior.
- **pre-pool-create**: occurs before the Pool of packages is created, and lets
you filter the list of packages that is going to enter the Solver.
> **Note:** Composer makes no assumptions about the state of your dependencies
> prior to `install` or `update`. Therefore, you should not specify scripts
> that require Composer-managed dependencies in the `pre-update-cmd` or
> `pre-install-cmd` event hooks. If you need to execute scripts prior to
> `install` or `update` please make sure they are self-contained within your
> root package.
## Defining scripts
The root JSON object in `composer.json` should have a property called
`"scripts"`, which contains pairs of named events and each event's
corresponding scripts. An event's scripts can be defined as either a string
(only for a single script) or an array (for single or multiple scripts.)
For any given event:
- Scripts execute in the order defined when their corresponding event is fired.
- An array of scripts wired to a single event can contain both PHP callbacks
and command-line executable commands.
- PHP classes and commands containing defined callbacks must be autoloadable
via Composer's autoload functionality.
- Callbacks can only autoload classes from psr-0, psr-4 and classmap
definitions. If a defined callback relies on functions defined outside of a
class, the callback itself is responsible for loading the file containing these
functions.
Script definition example:
```json
{
"scripts": {
"post-update-cmd": "MyVendor\\MyClass::postUpdate",
"post-package-install": [
"MyVendor\\MyClass::postPackageInstall"
],
"post-install-cmd": [
"MyVendor\\MyClass::warmCache",
"phpunit -c app/"
],
"post-autoload-dump": [
"MyVendor\\MyClass::postAutoloadDump"
],
"post-create-project-cmd": [
"php -r \"copy('config/local-example.php', 'config/local.php');\""
]
}
}
```
Using the previous definition example, here's the class `MyVendor\MyClass`
that might be used to execute the PHP callbacks:
```php
<?php
namespace MyVendor;
use Composer\Script\Event;
use Composer\Installer\PackageEvent;
class MyClass
{
public static function postUpdate(Event $event)
{
$composer = $event->getComposer();
// do stuff
}
public static function postAutoloadDump(Event $event)
{
$vendorDir = $event->getComposer()->getConfig()->get('vendor-dir');
require $vendorDir . '/autoload.php';
some_function_from_an_autoloaded_file();
}
public static function postPackageInstall(PackageEvent $event)
{
$installedPackage = $event->getOperation()->getPackage();
// do stuff
}
public static function warmCache(Event $event)
{
// make cache toasty
}
}
```
**Note:** During a Composer `install` or `update` command run, a variable named
`COMPOSER_DEV_MODE` will be added to the environment. If the command was run
with the `--no-dev` flag, this variable will be set to 0, otherwise it will be
set to 1. The variable is also available while `dump-autoload` runs, and it
will be set to the same as the last `install` or `update` was run in.
## Event classes
When an event is fired, your PHP callback receives as first argument a
`Composer\EventDispatcher\Event` object. This object has a `getName()` method
that lets you retrieve the event name.
Depending on the [script types](#event-names) you will get various event
subclasses containing various getters with relevant data and associated
objects:
- Base class: [`Composer\EventDispatcher\Event`](https://github.com/composer/composer/blob/main/src/Composer/EventDispatcher/Event.php)
- Command Events: [`Composer\Script\Event`](https://github.com/composer/composer/blob/main/src/Composer/Script/Event.php)
- Installer Events: [`Composer\Installer\InstallerEvent`](https://github.com/composer/composer/blob/main/src/Composer/Installer/InstallerEvent.php)
- Package Events: [`Composer\Installer\PackageEvent`](https://github.com/composer/composer/blob/main/src/Composer/Installer/PackageEvent.php)
- Plugin Events:
- init: [`Composer\EventDispatcher\Event`](https://github.com/composer/composer/blob/main/src/Composer/EventDispatcher/Event.php)
- command: [`Composer\Plugin\CommandEvent`](https://github.com/composer/composer/blob/main/src/Composer/Plugin/CommandEvent.php)
- pre-file-download: [`Composer\Plugin\PreFileDownloadEvent`](https://github.com/composer/composer/blob/main/src/Composer/Plugin/PreFileDownloadEvent.php)
- post-file-download: [`Composer\Plugin\PostFileDownloadEvent`](https://github.com/composer/composer/blob/main/src/Composer/Plugin/PostFileDownloadEvent.php)
## Running scripts manually
If you would like to run the scripts for an event manually, the syntax is:
```shell
php composer.phar run-script [--dev] [--no-dev] script
```
For example `composer run-script post-install-cmd` will run any
**post-install-cmd** scripts and [plugins](plugins.md) that have been defined.
You can also give additional arguments to the script handler by appending `--`
followed by the handler arguments. e.g.
`composer run-script post-install-cmd -- --check` will pass`--check` along to
the script handler. Those arguments are received as CLI arg by CLI handlers,
and can be retrieved as an array via `$event->getArguments()` by PHP handlers.
## Writing custom commands
If you add custom scripts that do not fit one of the predefined event name
above, you can either run them with run-script or also run them as native
Composer commands. For example the handler defined below is executable by
running `composer test`:
```json
{
"scripts": {
"test": "phpunit",
"do-something": "MyVendor\\MyClass::doSomething"
"my-cmd": "MyVendor\\MyCommand"
}
}
```
Similar to the `run-script` command you can give additional arguments to scripts,
e.g. `composer test -- --filter <pattern>` will pass `--filter <pattern>` along
to the `phpunit` script.
Using a PHP method via `composer do-something arg` lets you execute a
`static function doSomething(\Composer\Script\Event $event)` and `arg` becomes
available in `$event->getArguments()`. This however does not let you easily pass
custom options in the form of `--flags`.
Using a [symfony/console](https://packagist.org/packages/symfony/console) `Command`
class you can define and access arguments and options more easily.
For example with the command below you can then simply call `composer my-cmd
--arbitrary-flag` without even the need for a `--` separator. To be detected
as symfony/console commands the class name must end with `Command` and extend
symfony's `Command` class. Also note that this will run using Composer's built-in
symfony/console version which may not match the one you have required in your
project, and may change between Composer minor releases. If you need more
safety guarantees you should rather use your own binary file that runs your own
symfony/console version in isolation in its own process then.
```php
<?php
namespace MyVendor;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class MyCommand extends Command
{
protected function configure(): void
{
$this->setDefinition([
new InputOption('arbitrary-flag', null, InputOption::VALUE_NONE, 'Example flag'),
new InputArgument('foo', InputArgument::OPTIONAL, 'Optional arg'),
]);
}
public function execute(InputInterface $input, OutputInterface $output): int
{
if ($input->getOption('arbitrary-flag')) {
$output->writeln('The flag was used')
}
return 0;
}
}
```
> **Note:** Before executing scripts, Composer's bin-dir is temporarily pushed
> on top of the PATH environment variable so that binaries of dependencies
> are directly accessible. In this example no matter if the `phpunit` binary is
> actually in `vendor/bin/phpunit` or `bin/phpunit` it will be found and executed.
## Managing the process timeout
Although Composer is not intended to manage long-running processes and other
such aspects of PHP projects, it can sometimes be handy to disable the process
timeout on custom commands. This timeout defaults to 300 seconds and can be
overridden in a variety of ways depending on the desired effect:
- disable it for all commands using the config key `process-timeout`,
- disable it for the current or future invocations of composer using the
environment variable `COMPOSER_PROCESS_TIMEOUT`,
- for a specific invocation using the `--timeout` flag of the `run-script` command,
- using a static helper for specific scripts.
To disable the timeout for specific scripts with the static helper directly in
composer.json:
```json
{
"scripts": {
"test": [
"Composer\\Config::disableProcessTimeout",
"phpunit"
]
}
}
```
To disable the timeout for every script on a given project, you can use the
composer.json configuration:
```json
{
"config": {
"process-timeout": 0
}
}
```
It's also possible to set the global environment variable to disable the timeout
of all following scripts in the current terminal environment:
```shell
export COMPOSER_PROCESS_TIMEOUT=0
```
To disable the timeout of a single script call, you must use the `run-script` composer
command and specify the `--timeout` parameter:
```shell
php composer.phar run-script --timeout=0 test
```
## Referencing scripts
To enable script re-use and avoid duplicates, you can call a script from another
one by prefixing the command name with `@`:
```json
{
"scripts": {
"test": [
"@clearCache",
"phpunit"
],
"clearCache": "rm -rf cache/*"
}
}
```
You can also refer a script and pass it new arguments:
```json
{
"scripts": {
"tests": "phpunit",
"testsVerbose": "@tests -vvv"
}
}
```
## Calling Composer commands
To call Composer commands, you can use `@composer` which will automatically
resolve to whatever composer.phar is currently being used:
```json
{
"scripts": {
"test": [
"@composer install",
"phpunit"
]
}
}
```
One limitation of this is that you can not call multiple composer commands in
a row like `@composer install && @composer foo`. You must split them up in a
JSON array of commands.
## Executing PHP scripts
To execute PHP scripts, you can use `@php` which will automatically
resolve to whatever php process is currently being used:
```json
{
"scripts": {
"test": [
"@php script.php",
"phpunit"
]
}
}
```
One limitation of this is that you can not call multiple commands in
a row like `@php install && @php foo`. You must split them up in a
JSON array of commands.
You can also call a shell/bash script, which will have the path to
the PHP executable available in it as a `PHP_BINARY` env var.
## Setting environment variables
To set an environment variable in a cross-platform way, you can use `@putenv`:
```json
{
"scripts": {
"install-phpstan": [
"@putenv COMPOSER=phpstan-composer.json",
"@composer install --prefer-dist"
]
}
}
```
## Custom descriptions
You can set custom script descriptions with the following in your `composer.json`:
```json
{
"scripts-descriptions": {
"test": "Run all tests!"
}
}
```
The descriptions are used in `composer list` or `composer run -l` commands to
describe what the scripts do when the command is run.
> **Note:** You can only set custom descriptions of custom commands.
## Custom aliases
As of Composer 2.7, you can set custom script aliases with the following in your `composer.json`:
```json
{
"scripts-aliases": {
"phpstan": ["stan", "analyze"]
}
}
```
The aliases provide alternate command names.
> **Note:** You can only set custom aliases of custom commands.

View File

@ -0,0 +1,429 @@
<!--
tagline: Solving problems
-->
# Troubleshooting
This is a list of common pitfalls on using Composer, and how to avoid them.
## General
1. When facing any kind of problems using Composer, be sure to **work with the
latest version**. See [self-update](../03-cli.md#self-update) for details.
2. Before asking anyone, run [`composer diagnose`](../03-cli.md#diagnose) to check
for common problems. If it all checks out, proceed to the next steps.
3. Make sure you have no problems with your setup by running the installer's
checks via `curl -sS https://getcomposer.org/installer | php -- --check`.
4. Try clearing Composer's cache by running `composer clear-cache`.
5. Ensure you're **installing vendors straight from your `composer.json`** via
`rm -rf vendor && composer update -v` when troubleshooting, excluding any
possible interferences with existing vendor installations or `composer.lock`
entries.
## Package not found
1. Double-check you **don't have typos** in your `composer.json` or repository
branches and tag names.
2. Be sure to **set the right
[minimum-stability](../04-schema.md#minimum-stability)**. To get started or be
sure this is no issue, set `minimum-stability` to "dev".
3. Packages **not coming from [Packagist](https://packagist.org/)** should
always be **defined in the root package** (the package depending on all
vendors).
4. Use the **same vendor and package name** throughout all branches and tags of
your repository, especially when maintaining a third party fork and using
`replace`.
5. If you are updating to a recently published version of a package, be aware that
Packagist has a delay of up to 1 minute before new packages are visible to Composer.
6. If you are updating a single package, it may depend on newer versions itself.
In this case add the `--with-dependencies` argument **or** add all dependencies which
need an update to the command.
## Package is not updating to the expected version
Try running `php composer.phar why-not [package-name] [expected-version]`.
## Dependencies on the root package
When your root package depends on a package which ends up depending (directly or
indirectly) back on the root package itself, issues can occur in two cases:
1. During development, if you are on a branch like `dev-main` and the branch has no
[branch-alias](aliases.md#branch-alias) defined, and the dependency on the root package
requires version `^2.0` for example, the `dev-main` version will not satisfy it.
The best solution here is to make sure you first define a branch alias.
2. In CI (Continuous Integration) runs, the problem might be that Composer is not able
to detect the version of the root package properly. If it is a git clone it is
generally alright and Composer will detect the version of the current branch,
but some CIs do shallow clones so that process can fail when testing pull requests
and feature branches. In these cases the branch alias may then not be recognized.
The best solution is to define the version you are on via an environment variable
called `COMPOSER_ROOT_VERSION`. You set it to `dev-main` for example to define
the root package's version as `dev-main`.
Use for example: `COMPOSER_ROOT_VERSION=dev-main composer install` to export
the variable only for the call to composer, or you can define it globally in the
CI env vars.
## Root package version detection
Composer relies on knowing the version of the root package to resolve
dependencies effectively. The version of the root package is determined
using a hierarchical approach:
1. **composer.json Version Field**: Firstly, Composer looks for a `version`
field in the project's root `composer.json` file. If present, this field
specifies the version of the root package directly. This is generally not
recommended as it needs to be constantly updated, but it is an option.
2. **Environment Variable**: Composer then checks for the `COMPOSER_ROOT_VERSION`
environment variable. This variable can be explicitly set by the user to
define the version of the root package, providing a straightforward way to
inform Composer of the exact version, especially in CI/CD environments or
when the VCS method is not applicable.
3. **Version Control System (VCS) Inspection**: Composer then attempts to guess
the version by interfacing with the version control system of the project. For
instance, in projects versioned with Git, Composer executes specific Git
commands to deduce the project's current version based on tags, branches, and
commit history. If a `.git` directory is missing or the history is incomplete
because CI is using a shallow clone for example, this detection may fail to find
the correct version.
4. **Fallback**: If all else fails, Composer uses `1.0.0` as default version.
Note that relying on the default/fallback version might potentially lead to dependency
resolution issues, especially when the root package depends on a package which ends up
depending (directly or indirectly)
[back on the root package itself](#dependencies-on-the-root-package).
## Network timeout issues, curl error
If you see something along the lines of:
```
Failed to download * curl error 28 while downloading * Operation timed out after 300000 milliseconds
```
It means your network is probably so slow that a request took over 300seconds to complete. This is the
minimum timeout Composer will use, but you can increase it by increasing the `default_socket_timeout`
value in your php.ini to something higher.
## Package not found in a Jenkins-build
1. Check the ["Package not found"](#package-not-found) item above.
2. The git-clone / checkout within Jenkins leaves the branch in a "detached HEAD"-state. As
a result, Composer may not able to identify the version of the current checked out branch
and may not be able to resolve a [dependency on the root package](#dependencies-on-the-root-package).
To solve this problem, you can use the "Additional Behaviours" -> "Check out to specific local
branch" in your Git-settings for your Jenkins-job, where your "local branch" shall be the same
branch as you are checking out. Using this, the checkout will not be in detached state any more
and the dependency on the root package should become satisfied.
## I have a dependency which contains a "repositories" definition in its composer.json, but it seems to be ignored.
The [`repositories`](../04-schema.md#repositories) configuration property is defined as [root-only](../04-schema.md#root-package). It is not inherited. You can read more about the reasons behind this in the "[why can't
Composer load repositories recursively?](../faqs/why-cant-composer-load-repositories-recursively.md)" article.
The simplest work-around to this limitation, is moving or duplicating the `repositories` definition into your root
composer.json.
## I have locked a dependency to a specific commit but get unexpected results.
While Composer supports locking dependencies to a specific commit using the `#commit-ref` syntax, there are certain
caveats that one should take into account. The most important one is [documented](../04-schema.md#package-links), but
frequently overlooked:
> **Note:** While this is convenient at times, it should not be how you use
> packages in the long term because it comes with a technical limitation. The
> composer.json metadata will still be read from the branch name you specify
> before the hash. Because of that in some cases it will not be a practical
> workaround, and you should always try to switch to tagged releases as soon
> as you can.
There is no simple work-around to this limitation. It is therefore strongly recommended that you do not use it.
## Need to override a package version
Let's say your project depends on package A, which in turn depends on a specific
version of package B (say 0.1). But you need a different version of said package B (say 0.11).
You can fix this by aliasing version 0.11 to 0.1:
composer.json:
```json
{
"require": {
"A": "0.2",
"B": "0.11 as 0.1"
}
}
```
See [aliases](aliases.md) for more information.
## Figuring out where a config value came from
Use `php composer.phar config --list --source` to see where each config value originated from.
## Memory limit errors
The first thing to do is to make sure you are running Composer 2, and if possible 2.2.0 or above.
Composer 1 used much more memory and upgrading to the latest version will give you much better and faster results.
Composer may sometimes fail on some commands with this message:
`PHP Fatal error: Allowed memory size of XXXXXX bytes exhausted <...>`
In this case, the PHP `memory_limit` should be increased.
> **Note:** Composer internally increases the `memory_limit` to `1.5G`.
To get the current `memory_limit` value, run:
```shell
php -r "echo ini_get('memory_limit').PHP_EOL;"
```
Try increasing the limit in your `php.ini` file (ex. `/etc/php5/cli/php.ini` for
Debian-like systems):
```ini
; Use -1 for unlimited or define an explicit value like 2G
memory_limit = -1
```
Composer also respects a memory limit defined by the `COMPOSER_MEMORY_LIMIT` environment variable:
```shell
COMPOSER_MEMORY_LIMIT=-1 composer.phar <...>
```
Or, you can increase the limit with a command-line argument:
```shell
php -d memory_limit=-1 composer.phar <...>
```
However, please note that setting the memory limit using these methods primarily addresses memory issues within Composer itself and its immediate processes. Child processes or external commands invoked by Composer may still require separate adjustments if they have their own memory requirements.
This issue can also happen on cPanel instances, when the shell fork bomb protection is activated. For more information, see the [documentation](https://documentation.cpanel.net/display/68Docs/Shell+Fork+Bomb+Protection) of the fork bomb feature on the cPanel site.
## Xdebug impact on Composer
To improve performance when the Xdebug extension is enabled, Composer automatically restarts PHP without it.
You can override this behavior by using an environment variable: `COMPOSER_ALLOW_XDEBUG=1`.
Composer will always show a warning if Xdebug is being used, but you can override this with an environment variable:
`COMPOSER_DISABLE_XDEBUG_WARN=1`. If you see this warning unexpectedly, then the restart process has failed:
please report this [issue](https://github.com/composer/composer/issues).
## "The system cannot find the path specified" (Windows)
1. Open regedit.
2. Search for an `AutoRun` key inside `HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor`,
`HKEY_CURRENT_USER\Software\Microsoft\Command Processor`
or `HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Command Processor`.
3. Check if it contains any path to a non-existent file, if it's the case, remove them.
## API rate limit and OAuth tokens
Because of GitHub's rate limits on their API it can happen that Composer prompts
for authentication asking your username and password so it can go ahead with its work.
If you would prefer not to provide your GitHub credentials to Composer you can
manually create a token using the [procedure documented here](authentication-for-private-packages.md#github-oauth).
Now Composer should install/update without asking for authentication.
## proc_open(): fork failed errors
If Composer shows proc_open() fork failed on some commands:
`PHP Fatal error: Uncaught exception 'ErrorException' with message 'proc_open(): fork failed - Cannot allocate memory' in phar`
This could be happening because the VPS runs out of memory and has no Swap space enabled.
```shell
free -m
```
```text
total used free shared buffers cached
Mem: 2048 357 1690 0 0 237
-/+ buffers/cache: 119 1928
Swap: 0 0 0
```
To enable the swap you can use for example:
```shell
/bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=1024
/sbin/mkswap /var/swap.1
/bin/chmod 0600 /var/swap.1
/sbin/swapon /var/swap.1
```
You can make a permanent swap file following this [tutorial](https://www.digitalocean.com/community/tutorials/how-to-add-swap-on-ubuntu-14-04).
## proc_open(): failed to open stream errors (Windows)
If Composer shows proc_open(NUL) errors on Windows:
`proc_open(NUL): failed to open stream: No such file or directory`
This could be happening because you are working in a _OneDrive_ directory and
using a version of PHP that does not support the file system semantics of this
service. The issue was fixed in PHP 7.2.23 and 7.3.10.
Alternatively it could be because the Windows Null Service is not enabled. For
more information, see this [issue](https://github.com/composer/composer/issues/7186#issuecomment-373134916).
## Degraded Mode
Due to some intermittent issues on Travis and other systems, we introduced a
degraded network mode which helps Composer finish successfully but disables
a few optimizations. This is enabled automatically when an issue is first
detected. If you see this issue sporadically you probably don't have to worry
(a slow or overloaded network can also cause those time outs), but if it
appears repeatedly you might want to look at the options below to identify
and resolve it.
If you have been pointed to this page, you want to check a few things:
- If you are using ESET antivirus, go in "Advanced Settings" and disable "HTTP-scanner"
under "web access protection"
- If you are using IPv6, try disabling it. If that solves your issues, get in touch
with your ISP or server host, the problem is not at the Packagist level but in the
routing rules between you and Packagist (i.e. the internet at large). The best way to get
these fixed is to raise awareness to the network engineers that have the power to fix it.
Take a look at the next section for IPv6 workarounds.
- If none of the above helped, please report the error.
## Operation timed out (IPv6 issues)
You may run into errors if IPv6 is not configured correctly. A common error is:
```text
The "https://getcomposer.org/version" file could not be downloaded: failed to
open stream: Operation timed out
```
We recommend you fix your IPv6 setup. If that is not possible, you can try the
following workarounds:
**Generic Workaround:**
Set the [`COMPOSER_IPRESOLVE=4`](../03-cli.md#composer-ipresolve) environment variable which will force curl to resolve
domains using IPv4. This only works when the curl extension is used for downloads.
**Workaround Linux:**
On linux, it seems that running this command helps to make ipv4 traffic have a
higher priority than ipv6, which is a better alternative than disabling ipv6 entirely:
```shell
sudo sh -c "echo 'precedence ::ffff:0:0/96 100' >> /etc/gai.conf"
```
**Workaround Windows:**
On windows the only way is to disable ipv6 entirely I am afraid (either in windows or in your home router).
**Workaround Mac OS X:**
Get name of your network device:
```shell
networksetup -listallnetworkservices
```
Disable IPv6 on that device (in this case "Wi-Fi"):
```shell
networksetup -setv6off Wi-Fi
```
Run Composer ...
You can enable IPv6 again with:
```shell
networksetup -setv6automatic Wi-Fi
```
That said, if this fixes your problem, please talk to your ISP about it to
try to resolve the routing errors. That's the best way to get things resolved
for everyone.
## Composer hangs with SSH ControlMaster
When you try to install packages from a Git repository and you use the `ControlMaster`
setting for your SSH connection, Composer might hang endlessly and you see a `sh`
process in the `defunct` state in your process list.
The reason for this is a SSH Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1988
As a workaround, open a SSH connection to your Git host before running Composer:
```shell
ssh -t git@mygitserver.tld
php composer.phar update
```
See also https://github.com/composer/composer/issues/4180 for more information.
## Zip archives are not unpacked correctly.
Composer can unpack zipballs using either a system-provided `unzip` or `7z` (7-Zip) utility, or PHP's
native `ZipArchive` class. On OSes where ZIP files can contain permissions and symlinks, we recommend
installing `unzip` or `7z` as these features are not supported by `ZipArchive`.
## Disabling the pool optimizer
In Composer, the `Pool` class contains all the packages that are relevant for the dependency
resolving process. That is what is used to generate all the rules which are then
passed on to the dependency solver.
In order to improve performance, Composer tries to optimize this `Pool` by removing useless
package information early on.
If all goes well, you should never notice any issues with it but in case you run into
an unexpected result such as an unresolvable set of dependencies or conflicts where you
think Composer is wrong, you might want to disable the optimizer by using the environment
variable `COMPOSER_POOL_OPTIMIZER` and run the update again like so:
```shell
COMPOSER_POOL_OPTIMIZER=0 php composer.phar update
```
Now double check if the result is still the same. It will take significantly longer and use
a lot more memory to run the dependency resolving process.
If the result is different, you likely hit a problem in the pool optimizer.
Please [report this issue](https://github.com/composer/composer/issues) so it can be fixed.

View File

@ -13,7 +13,6 @@ If a package contains other scripts that are not needed by the package
users (like build or compile scripts) that code should not be listed users (like build or compile scripts) that code should not be listed
as a vendor binary. as a vendor binary.
## How is it defined? ## How is it defined?
It is defined by adding the `bin` key to a project's `composer.json`. It is defined by adding the `bin` key to a project's `composer.json`.
@ -34,16 +33,15 @@ for any project that **depends** on that project.
This is a convenient way to expose useful scripts that would This is a convenient way to expose useful scripts that would
otherwise be hidden deep in the `vendor/` directory. otherwise be hidden deep in the `vendor/` directory.
## What happens when Composer is run on a composer.json that defines vendor binaries? ## What happens when Composer is run on a composer.json that defines vendor binaries?
For the binaries that a package defines directly, nothing happens. For the binaries that a package defines directly, nothing happens.
## What happens when Composer is run on a composer.json that has dependencies with vendor binaries listed? ## What happens when Composer is run on a composer.json that has dependencies with vendor binaries listed?
Composer looks for the binaries defined in all of the dependencies. A Composer looks for the binaries defined in all of the dependencies. A
symlink is created from each dependency's binaries to `vendor/bin`. proxy file (or two on Windows/WSL) is created from each dependency's
binaries to `vendor/bin`.
Say package `my-vendor/project-a` has binaries setup like this: Say package `my-vendor/project-a` has binaries setup like this:
@ -69,12 +67,65 @@ Say project `my-vendor/project-b` has requirements setup like this:
``` ```
Running `composer install` for this `composer.json` will look at Running `composer install` for this `composer.json` will look at
all of project-b's dependencies and install them to `vendor/bin`. all of project-a's binaries and install them to `vendor/bin`.
In this case, Composer will make `vendor/my-vendor/project-a/bin/project-a-bin` In this case, Composer will make `vendor/my-vendor/project-a/bin/project-a-bin`
available as `vendor/bin/project-a-bin`. On a Unix-like platform available as `vendor/bin/project-a-bin`.
this is accomplished by creating a symlink.
## Finding the Composer autoloader from a binary
As of Composer 2.2, a new `$_composer_autoload_path` global variable
is defined by the bin proxy file, so that when your binary gets executed
it can use it to easily locate the project's autoloader.
This global will not be available however when running binaries defined
by the root package itself, so you need to have a fallback in place.
This can look like this for example:
```php
<?php
include $_composer_autoload_path ?? __DIR__ . '/../vendor/autoload.php';
```
If you want to rely on this in your package you should however make sure to
also require `"composer-runtime-api": "^2.2"` to ensure that the package
gets installed with a Composer version supporting the feature.
## Finding the Composer bin-dir from a binary
As of Composer 2.2.2, a new `$_composer_bin_dir` global variable
is defined by the bin proxy file, so that when your binary gets executed
it can use it to easily locate the project's Composer bin directory.
For non-PHP binaries, as of Composer 2.2.6, the bin proxy sets a
`COMPOSER_RUNTIME_BIN_DIR` environment variable.
This global variable will not be available however when running binaries defined
by the root package itself, so you need to have a fallback in place.
This can look like this for example:
```php
<?php
$binDir = $_composer_bin_dir ?? __DIR__ . '/../vendor/bin';
```
```php
#!/bin/bash
if [[ -z "$COMPOSER_RUNTIME_BIN_DIR" ]]; then
BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
else
BIN_DIR="$COMPOSER_RUNTIME_BIN_DIR"
fi
```
If you want to rely on this in your package you should however make sure to
also require `"composer-runtime-api": "^2.2.2"` to ensure that the package
gets installed with a Composer version supporting the feature.
## What about Windows and .bat files? ## What about Windows and .bat files?
@ -83,14 +134,13 @@ Packages managed entirely by Composer do not *need* to contain any
of binaries in a special way when run in a Windows environment: of binaries in a special way when run in a Windows environment:
* A `.bat` file is generated automatically to reference the binary * A `.bat` file is generated automatically to reference the binary
* A Unix-style proxy file with the same name as the binary is generated * A Unix-style proxy file with the same name as the binary is also
automatically (useful for Cygwin or Git Bash) generated, which is useful for WSL, Linux VMs, etc.
Packages that need to support workflows that may not include Composer Packages that need to support workflows that may not include Composer
are welcome to maintain custom `.bat` files. In this case, the package are welcome to maintain custom `.bat` files. In this case, the package
should **not** list the `.bat` file as a binary as it is not needed. should **not** list the `.bat` file as a binary as it is not needed.
## Can vendor binaries be installed somewhere other than vendor/bin? ## Can vendor binaries be installed somewhere other than vendor/bin?
Yes, there are two ways an alternate vendor binary location can be specified: Yes, there are two ways an alternate vendor binary location can be specified:
@ -111,3 +161,5 @@ An example of the former looks like this:
Running `composer install` for this `composer.json` will result in Running `composer install` for this `composer.json` will result in
all of the vendor binaries being installed in `scripts/` instead of all of the vendor binaries being installed in `scripts/` instead of
`vendor/bin/`. `vendor/bin/`.
You can set `bin-dir` to `./` to put binaries in your project root.

260
doc/articles/versions.md Normal file
View File

@ -0,0 +1,260 @@
<!--
tagline: Versions explained.
-->
# Versions and constraints
## Composer Versions vs VCS Versions
Because Composer is heavily geared toward utilizing version control systems
like git, the term "version" can be a little ambiguous. In the sense of a
version control system, a "version" is a specific set of files that contain
specific data. In git terminology, this is a "ref", or a specific commit,
which may be represented by a branch HEAD or a tag. When you check out that
version in your VCS -- for example, tag `v1.1` or commit `e35fa0d` --, you're
asking for a single, known set of files, and you always get the same files back.
In Composer, what's often referred to casually as a version -- that is,
the string that follows the package name in a require line (e.g., `~1.1` or
`1.2.*`) -- is actually more specifically a version constraint. Composer
uses version constraints to figure out which refs in a VCS it should be
checking out (or to verify that a given library is acceptable in
the case of a statically-maintained library with a `version` specification
in `composer.json`).
## VCS Tags and Branches
*For the following discussion, let's assume the following sample library
repository:*
```shell
~/my-library$ git branch
```
```text
v1
v2
my-feature
another-feature
```
```shell
~/my-library$ git tag
```
```text
v1.0
v1.0.1
v1.0.2
v1.1-BETA
v1.1-RC1
v1.1-RC2
v1.1
v1.1.1
v2.0-BETA
v2.0-RC1
v2.0
v2.0.1
v2.0.2
```
### Tags
Normally, Composer deals with tags (as opposed to branches -- if you don't
know what this means, read up on
[version control systems](https://en.wikipedia.org/wiki/Version_control#Common_terminology)).
When you write a version constraint, it may reference a specific tag (e.g.,
`1.1`) or it may reference a valid range of tags (e.g., `>=1.1 <2.0`, or
`~4.0`). To resolve these constraints, Composer first asks the VCS to list
all available tags, then creates an internal list of available versions based
on these tags. In the above example, composer's internal list includes versions
`1.0`, `1.0.1`, `1.0.2`, the beta release of `1.1`, the first and second
release candidates of `1.1`, the final release version `1.1`, etc.... (Note
that Composer automatically removes the 'v' prefix in the actual tagname to
get a valid final version number.)
When Composer has a complete list of available versions from your VCS, it then
finds the highest version that matches all version constraints in your project
(it's possible that other packages require more specific versions of the
library than you do, so the version it chooses may not always be the highest
available version) and it downloads a zip archive of that tag to unpack in the
correct location in your `vendor` directory.
### Branches
If you want Composer to check out a branch instead of a tag, you need to point it to the branch using the special `dev-*` prefix (or sometimes suffix; see below). If you're checking out a branch, it's assumed that you want to *work* on the branch and Composer actually clones the repo into the correct place in your `vendor` directory. For tags, it copies the right files without actually cloning the repo. (You can modify this behavior with --prefer-source and --prefer-dist, see [install options](../03-cli.md#install).)
In the above example, if you wanted to check out the `my-feature` branch, you would specify `dev-my-feature` as the version constraint in your `require` clause. This would result in Composer cloning the `my-library` repository into my `vendor` directory and checking out the `my-feature` branch.
When branch names look like versions, we have to clarify for Composer that we're trying to check out a branch and not a tag. In the above example, we have two version branches: `v1` and `v2`. To get Composer to check out one of these branches, you must specify a version constraint that looks like this: `v1.x-dev`. The `.x` is an arbitrary string that Composer requires to tell it that we're talking about the `v1` branch and not a `v1` tag (alternatively, you can name the branch `v1.x` instead of `v1`). In the case of a branch with a version-like name (`v1`, in this case), you append `-dev` as a suffix, rather than using `dev-` as a prefix.
### Stabilities
Composer recognizes the following stabilities (in order of stability): dev,
alpha, beta, RC, and stable where RC stands for release candidate. The stability
of a version is defined by its suffix e.g version `v1.1-BETA` has a stability of
`beta` and `v1.1-RC1` has a stability of `RC`. If such a suffix is missing
e.g. version `v1.1` then Composer considers that version `stable`. In addition
to that Composer automatically adds a `-dev` suffix to all numeric branches and
prefixes all other branches imported from a VCS repository with `dev-`. In both
cases the stability `dev` gets assigned.
Keeping this in mind will help you in the next section.
### Minimum Stability
There's one more thing that will affect which files are checked out of a library's VCS and added to your project: Composer allows you to specify stability constraints to limit which tags are considered valid. In the above example, note that the library released a beta and two release candidates for version `1.1` before the final official release. To receive these versions when running `composer install` or `composer update`, we have to explicitly tell Composer that we are ok with release candidates and beta releases (and alpha releases, if we want those). This can be done using either a project-wide `minimum-stability` value in `composer.json` or using "stability flags" in version constraints. Read more on the [schema page](../04-schema.md#minimum-stability).
## Writing Version Constraints
Now that you have an idea of how Composer sees versions, let's talk about how
to specify version constraints for your project dependencies.
### Exact Version Constraint
You can specify the exact version of a package. This will tell Composer to
install this version and this version only. If other dependencies require
a different version, the solver will ultimately fail and abort any install
or update procedures.
Example: `1.0.2`
### Version Range
By using comparison operators you can specify ranges of valid versions. Valid
operators are `>`, `>=`, `<`, `<=`, `!=`.
You can define multiple ranges. Ranges separated by a space (<code>&nbsp;</code>)
or comma (`,`) will be treated as a **logical AND**. A double pipe (`||`)
will be treated as a **logical OR**. AND has higher precedence than OR.
> **Note:** Be careful when using unbounded ranges as you might end up
> unexpectedly installing versions that break backwards compatibility.
> Consider using the [caret](#caret-version-range-) operator instead for safety.
<!--blank line followed by comment markup to separate the block quotes-->
> **Note:** In older versions of Composer the single pipe (`|`) was the
> recommended alternative to the **logical OR**. Thus for backwards compatibility
> the single pipe (`|`) will still be treated as a **logical OR**.
Examples:
* `>=1.0`
* `>=1.0 <2.0`
* `>=1.0 <1.1 || >=1.2`
### Hyphenated Version Range (` - `)
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`.
Example: `1.0 - 2.0`
### Wildcard Version Range (`.*`)
You can specify a pattern with a `*` wildcard. `1.0.*` is the equivalent of
`>=1.0 <1.1`.
Example: `1.0.*`
## Next Significant Release Operators
### Tilde Version Range (`~`)
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](https://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.
Example: `~1.2`
> **Note:** Although `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.
### Caret Version Range (`^`)
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` and `^0.0.3` as `>=0.0.3 <0.0.4`.
This is the recommended operator for maximum interoperability when writing
library code.
Example: `^1.2.3`
> **Note:** If you are using PowerShell on Windows, you have to escape
> carets when using them as argument on the CLI for example when using the
> `composer require` command. You have to use four
> subsequent caret operators, e.g. `^^^^1.2.3`, to ensure the caret operator gets
> passed to Composer correctly.
## Stability Constraints
If you are using a constraint that does not explicitly define a stability,
Composer will default internally to `-dev` or `-stable`, depending on the
operator(s) used. This happens transparently.
If you wish to explicitly consider only the stable release in the comparison,
add the suffix `-stable`.
Examples:
Constraint | Internally
------------------- | ------------------------
`1.2.3` | `=1.2.3.0-stable`
`>1.2` | `>1.2.0.0-stable`
`>=1.2` | `>=1.2.0.0-dev`
`>=1.2-stable` | `>=1.2.0.0-stable`
`<1.3` | `<1.3.0.0-dev`
`<=1.3` | `<=1.3.0.0-stable`
`1 - 2` | `>=1.0.0.0-dev <3.0.0.0-dev`
`~1.3` | `>=1.3.0.0-dev <2.0.0.0-dev`
`1.4.*` | `>=1.4.0.0-dev <1.5.0.0-dev`
To allow various stabilities without enforcing them at the constraint level
however, you may use [stability-flags](../04-schema.md#package-links) like
`@<stability>` (e.g. `@dev`) to let Composer know that a given package
can be installed in a different stability than your default minimum-stability
setting. All available stability flags are listed on the minimum-stability
section of the [schema page](../04-schema.md#minimum-stability).
## Summary
```jsonc
"require": {
"vendor/package": "1.3.2", // exactly 1.3.2
// >, <, >=, <= | specify upper / lower bounds
"vendor/package": ">=1.3.2", // anything above or equal to 1.3.2
"vendor/package": "<1.3.2", // anything below 1.3.2
// * | wildcard
"vendor/package": "1.3.*", // >=1.3.0 <1.4.0
// ~ | allows last digit specified to go up
"vendor/package": "~1.3.2", // >=1.3.2 <1.4.0
"vendor/package": "~1.3", // >=1.3.0 <2.0.0
// ^ | doesn't allow breaking changes (major version fixed - following semver)
"vendor/package": "^1.3.2", // >=1.3.2 <2.0.0
"vendor/package": "^0.3.2", // >=0.3.2 <0.4.0 // except if major version is 0
}
```
## Testing Version Constraints
You can test version constraints using [semver.madewithlove.com](https://semver.madewithlove.com).
Fill in a package name and it will autofill the default version constraint
which Composer would add to your `composer.json` file. You can adjust the
version constraint and the tool will highlight all releases that match.

View File

@ -12,6 +12,13 @@ resulting order in which the solver will try to install them.
The rules are to be applied in the order of these descriptions. The rules are to be applied in the order of these descriptions.
### Repository priorities
Packages Repo1.Av1, Repo2.Av1
* priority(Repo1) >= priority(Repo2) => (Repo1.Av1, Repo2.Av1)
* priority(Repo1) < priority(Repo2) => (Repo2.Av1, Repo1.Av1)
### Package versions ### Package versions
Packages: Av1, Av2, Av3 Packages: Av1, Av2, Av3
@ -22,13 +29,6 @@ Request: install A
* (Av3) * (Av3)
### Repository priorities
Packages Repo1.Av1, Repo2.Av1
* priority(Repo1) >= priority(Repo2) => (Repo1.Av1, Repo2.Av1)
* priority(Repo1) < priority(Repo2) => (Repo2.Av1, Repo1.Av1)
### Virtual Packages (provides) ### Virtual Packages (provides)
Packages Av1, Bv1 Packages Av1, Bv1

View File

@ -6,7 +6,8 @@ the default `vendor` folder by using
[composer/installers](https://github.com/composer/installers). [composer/installers](https://github.com/composer/installers).
If you are a **package author** and want your package installed to a custom If you are a **package author** and want your package installed to a custom
directory, simply require `composer/installers` and set the appropriate `type`. directory, require `composer/installers` and set the appropriate `type`.
Specifying the package type, will override the default installer path.
This is common if your package is intended for a specific framework such as This is common if your package is intended for a specific framework such as
CakePHP, Drupal or WordPress. Here is an example composer.json file for a CakePHP, Drupal or WordPress. Here is an example composer.json file for a
WordPress theme: WordPress theme:
@ -23,27 +24,31 @@ WordPress theme:
Now when your theme is installed with Composer it will be placed into Now when your theme is installed with Composer it will be placed into
`wp-content/themes/themename/` folder. Check the `wp-content/themes/themename/` folder. Check the
[current supported types](https://github.com/composer/installers#current-supported-types) [current supported types](https://github.com/composer/installers#current-supported-package-types)
for your package. for your package.
As a **package consumer** you can set or override the install path for a package As a **package consumer** you can set or override the install path for a package
that requires composer/installers by configuring the `installer-paths` extra. A that requires composer/installers by configuring the `installer-paths` extra. A
useful example would be for a Drupal multisite setup where the package should be useful example would be for a Drupal multisite setup where the package should be
installed into your sites subdirectory. Here we are overriding the install path installed into your site's subdirectory. Here we are overriding the install path
for a module that uses composer/installers: for a module that uses composer/installers, as well as putting all packages of type
`drupal-theme` into a themes folder:
```json ```json
{ {
"extra": { "extra": {
"installer-paths": { "installer-paths": {
"sites/example.com/modules/{$name}": ["vendor/package"] "sites/example.com/modules/{$name}": ["vendor/package"],
"sites/example.com/themes/{$name}": ["type:drupal-theme"]
} }
} }
} }
``` ```
Now the package would be installed to your folder location, rather than the default Now the package would be installed to your folder location, rather than the default
composer/installers determined location. composer/installers determined location. In addition, `installer-paths` is
order-dependent, which means moving a package by name should come before the installer
path of a `type:*` that matches the same package.
> **Note:** You cannot use this to change the path of any package. This is only > **Note:** You cannot use this to change the path of any package. This is only
> applicable to packages that require `composer/installers` and use a custom type > applicable to packages that require `composer/installers` and use a custom type

View File

@ -0,0 +1,42 @@
# How do I install Composer programmatically?
As noted on the download page, the installer script contains a
checksum which changes when the installer code changes and as such
it should not be relied upon in the long term.
An alternative is to use this script which only works with UNIX utilities:
```shell
#!/bin/sh
EXPECTED_CHECKSUM="$(php -r 'copy("https://composer.github.io/installer.sig", "php://stdout");')"
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"
if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]
then
>&2 echo 'ERROR: Invalid installer checksum'
rm composer-setup.php
exit 1
fi
php composer-setup.php --quiet
RESULT=$?
rm composer-setup.php
exit $RESULT
```
The script will exit with 1 in case of failure, or 0 on success, and is quiet
if no error occurs.
Alternatively, if you want to rely on an exact copy of the installer, you can fetch
a specific version from GitHub's history. The commit hash should be enough to
give it uniqueness and authenticity as long as you can trust the GitHub servers.
For example:
```shell
wget https://raw.githubusercontent.com/composer/getcomposer.org/76a7060ccb93902cd7576b67264ad91c8a2700e2/web/installer -O - -q | php -- --quiet
```
You may replace the commit hash by whatever the last commit hash is on
https://github.com/composer/getcomposer.org/commits/main

View File

@ -0,0 +1,41 @@
# How do I install untrusted packages safely? Is it safe to run Composer as superuser or root?
## Why am I seeing a "Do not run Composer as root/super user" warning/error?
It was always discouraged to run Composer as root for the reasons detailed below.
As of Composer 2.4.2, plugins are disabled automatically when running as root and
there is no sign that the user is consciously doing this. There are two ways this user consent
can be given:
- If you run interactively, Composer will prompt if you are sure that you want to continue
running as root. If you run non-interactively, plugins will be disabled, unless..
- If you set the [COMPOSER_ALLOW_SUPERUSER](../03-cli.md#composer-allow-superuser) environment
variable to `1`, this also indicates that you intended to run Composer as root and are accepting
the risks of doing so.
## Is it safe to run Composer as superuser or root?
Certain Composer commands, including `exec`, `install`, and `update` allow third party code to
execute on your system. This is from its "plugins" and "scripts" features. Plugins and scripts have
full access to the user account which runs Composer. For this reason, it is strongly advised to
**avoid running Composer as super-user/root**. All commands also dispatch events which can be
caught by plugins so unless explicitly disabled installed plugins will be loaded/executed by **every**
Composer command.
You can disable plugins and scripts during package installation or updates with the following
syntax so only Composer's code, and no third party code, will execute:
```shell
php composer.phar install --no-plugins --no-scripts ...
php composer.phar update --no-plugins --no-scripts ...
```
Depending on the operating system we have seen cases where it is possible to trigger execution
of files in the repository using specially crafted `composer.json`. So in general if you do want
to install untrusted dependencies you should sandbox them completely in a container or equivalent.
Also note that the `exec` command will always run third party code as the user which runs `composer`.
See the [COMPOSER_ALLOW_SUPERUSER](../03-cli.md#composer-allow-superuser) environment variable for
more info on how to disable the warnings.

View File

@ -24,8 +24,9 @@ If you really feel like you must do this, you have a few options:
[config](../04-schema.md#config). [config](../04-schema.md#config).
3. Remove the `.git` directory of every dependency after the installation, then 3. Remove the `.git` directory of every dependency after the installation, then
you can add them to your git repo. You can do that with `rm -rf vendor/**/.git` you can add them to your git repo. You can do that with `rm -rf vendor/**/.git`
but this means you will have to delete those dependencies from disk before in ZSH or `find vendor/ -type d -name ".git" -exec rm -rf {} \;` in Bash.
running composer update. But this means you will have to delete those dependencies from disk before
4. Add a .gitignore rule (`vendor/.git`) to ignore all the vendor `.git` folders. running `composer update`.
4. Add a .gitignore rule (`/vendor/**/.git`) to ignore all the vendor `.git` folders.
This approach does not require that you delete dependencies from disk prior to This approach does not require that you delete dependencies from disk prior to
running a composer update. running a `composer update`.

View File

@ -0,0 +1,4 @@
# Which version numbering system does Composer itself use?
Composer uses [Semantic Versioning (aka SemVer)
2.0.0](https://semver.org/spec/v2.0.0.html).

View File

@ -5,17 +5,17 @@ A version constraint without an upper bound such as `*`, `>=3.4` or
This includes major versions breaking backward compatibility. This includes major versions breaking backward compatibility.
Once a release of your package is tagged, you cannot tweak its dependencies Once a release of your package is tagged, you cannot tweak its dependencies
anymore in case a dependency breaks BC - you have to do a new release but the anymore in case a dependency breaks BC - you have to do a new release, but the
previous one stays broken. previous one stays broken.
The only good alternative is to define an upper bound on your constraints, The only good alternative is to define an upper bound on your constraints,
which you can increase in a new release after testing that your package is which you can increase in a new release after testing that your package is
compatible with the new major version of your dependency. compatible with the new major version of your dependency.
For example instead of using `>=3.4` you should use `~3.4` which allows all For example instead of using `>=3.4` you should use `^3.4` which allows all
versions up to `3.999` but does not include `4.0` and above. The `~` operator versions up to `3.999` but does not include `4.0` and above. The `^` operator
works very well with libraries follow [semantic versioning](http://semver.org). works very well with libraries following [semantic versioning](https://semver.org).
**Note:** As a package maintainer, you can make the life of your users easier **Note:** As a package maintainer, you can help your users
by providing an [alias version](../articles/aliases.md) for your development by providing an [alias version](../articles/aliases.md) for your development
branch to allow it to match bound constraints. branch to allow it to match bound constraints.

View File

@ -16,6 +16,6 @@ but it is not possible to determine if when you wrote that you were thinking
of a package in version 3.0.0 or not. Should it match because you asked for of a package in version 3.0.0 or not. Should it match because you asked for
`>=2` or should it not match because you asked for a `2.*`? `>=2` or should it not match because you asked for a `2.*`?
For this reason, Composer just throws an error and says that this is invalid. For this reason, Composer throws an error and says that this is invalid.
The easy way to fix it is to think about what you really mean, and use only The way to fix it is to think about what you really mean, and use only
one of those rules. one of those rules.

View File

@ -8,13 +8,14 @@ Before going into details as to why this is like that, you have to understand
that the main use of custom VCS & package repositories is to temporarily try that the main use of custom VCS & package repositories is to temporarily try
some things, or use a fork of a project until your pull request is merged, etc. some things, or use a fork of a project until your pull request is merged, etc.
You should not use them to keep track of private packages. For that you should You should not use them to keep track of private packages. For that you should
look into [setting up Satis](../articles/handling-private-packages-with-satis.md) rather look into [Private Packagist](https://packagist.com) which lets you
for your company or even for yourself. configure all your private packages in one place, and avoids the slow-downs
associated with inline VCS repositories.
There are three ways the dependency solver could work with custom repositories: There are three ways the dependency solver could work with custom repositories:
- Fetch the repositories of root package, get all the packages from the defined - Fetch the repositories of root package, get all the packages from the defined
repositories, resolve requirements. This is the current state and it works well repositories, then resolve requirements. This is the current state and it works well
except for the limitation of not loading repositories recursively. except for the limitation of not loading repositories recursively.
- Fetch the repositories of root package, while initializing packages from the - Fetch the repositories of root package, while initializing packages from the
@ -23,12 +24,12 @@ their package's packages, etc, then resolve requirements. It could work, but it
slows down the initialization a lot since VCS repos can each take a few seconds, slows down the initialization a lot since VCS repos can each take a few seconds,
and it could end up in a completely broken state since many versions of a package and it could end up in a completely broken state since many versions of a package
could define the same packages inside a package repository, but with different could define the same packages inside a package repository, but with different
dist/source. There are many many ways this could go wrong. dist/source. There are many ways this could go wrong.
- Fetch the repositories of root package, then fetch the repositories of the - Fetch the repositories of root package, then fetch the repositories of the
first level dependencies, then fetch the repositories of their dependencies, etc, first level dependencies, then fetch the repositories of their dependencies, etc,
then resolve requirements. This sounds more efficient, but it suffers from the then resolve requirements. This sounds more efficient, but it suffers from the
same problems than the second solution, because loading the repositories of the same problems as the second solution, because loading the repositories of the
dependencies is not as easy as it sounds. You need to load all the repos of all dependencies is not as easy as it sounds. You need to load all the repos of all
the potential matches for a requirement, which again might have conflicting the potential matches for a requirement, which again might have conflicting
package definitions. package definitions.

21
doc/fixtures/fixtures.md Normal file
View File

@ -0,0 +1,21 @@
# `Composer` type repository fixtures
This directory contains some examples of what `composer` type repositories can
look like. They serve as illustrating examples accompanying the docs, but can
also be used as (initial) fixtures for tests.
* `repo-composer-plain` is a basic, plain `packages.json` file
* `repo-composer-with-includes` uses the `includes` mechanism
* `repo-composer-with-providers` uses the `providers` mechanism
## Sample Packages used in these fixtures
All these repositories contain the following packages.
* `foo/bar` versions `1.0.0`, `1.0.1` and `1.1.0`; `dev-default` and `1.0.x-dev` branches.
On `dev-default` and in `1.1.0`, `bar/baz` `~1.0` is required.
* `qux/quux` only has a `dev-default` branch. It `replace`s `gar/nix`.
* `gar/nix` has a `1.0.0` version and a `dev-default` branch. It is being replaced
by `qux/quux`.
* `bar/baz` has a `1.0.0` version and `1.0.x-dev` as well as `dev-default` branches.
Additionally, `1.1.x-dev` is a branch alias for `dev-default`.

View File

@ -0,0 +1,158 @@
{
"packages": {
"bar/baz": {
"1.0.0": {
"name": "bar/baz",
"version": "1.0.0",
"version_normalized": "1.0.0.0",
"source": {
"type": "hg",
"url": "http://some.where/over/the/rainbow/",
"reference": "35810817c14d"
},
"time": "2014-10-13 12:04:55",
"type": "library"
},
"1.0.x-dev": {
"name": "bar/baz",
"version": "1.0.x-dev",
"version_normalized": "1.0.9999999.9999999-dev",
"source": {
"type": "hg",
"url": "http://some.where/over/the/rainbow/",
"reference": "ffff9aae6ed5"
},
"time": "2014-10-13 12:05:37",
"type": "library"
},
"dev-default": {
"name": "bar/baz",
"version": "dev-default",
"version_normalized": "9999999-dev",
"source": {
"type": "hg",
"url": "http://some.where/over/the/rainbow/",
"reference": "f317e556f2e2"
},
"time": "2014-10-13 12:06:45",
"type": "library",
"extra": {
"branch-alias": {
"dev-default": "1.1.x-dev"
}
}
}
},
"foo/bar": {
"1.0.0": {
"name": "foo/bar",
"version": "1.0.0",
"version_normalized": "1.0.0.0",
"source": {
"type": "hg",
"url": "http://some.where/over/the/rainbow/",
"reference": "249dec95a52a"
},
"time": "2014-10-11 15:42:00",
"type": "library"
},
"1.0.1": {
"name": "foo/bar",
"version": "1.0.1",
"version_normalized": "1.0.1.0",
"source": {
"type": "hg",
"url": "http://some.where/over/the/rainbow/",
"reference": "21e3328295d4"
},
"time": "2014-10-11 15:45:56",
"type": "library"
},
"1.0.x-dev": {
"name": "foo/bar",
"version": "1.0.x-dev",
"version_normalized": "1.0.9999999.9999999-dev",
"source": {
"type": "hg",
"url": "http://some.where/over/the/rainbow/",
"reference": "14dc17c8e860"
},
"time": "2014-10-11 15:45:59",
"type": "library"
},
"1.1.0": {
"name": "foo/bar",
"version": "1.1.0",
"version_normalized": "1.1.0.0",
"source": {
"type": "hg",
"url": "http://some.where/over/the/rainbow/",
"reference": "d2fa3e69ad5b"
},
"require": {
"bar/baz": "~1.0"
},
"time": "2014-10-11 15:43:16",
"type": "library"
},
"dev-default": {
"name": "foo/bar",
"version": "dev-default",
"version_normalized": "9999999-dev",
"source": {
"type": "hg",
"url": "http://some.where/over/the/rainbow/",
"reference": "8e5a5c224336"
},
"require": {
"bar/baz": "~1.0"
},
"time": "2014-10-11 15:43:18",
"type": "library"
}
},
"gar/nix": {
"1.0.0": {
"name": "gar/nix",
"version": "1.0.0",
"version_normalized": "1.0.0.0",
"source": {
"type": "hg",
"url": "http://some.where/over/the/rainbow/",
"reference": "44977145d64e"
},
"time": "2014-10-13 12:03:33",
"type": "library"
},
"dev-default": {
"name": "gar/nix",
"version": "dev-default",
"version_normalized": "9999999-dev",
"source": {
"type": "hg",
"url": "http://some.where/over/the/rainbow/",
"reference": "51cca95a31c2"
},
"time": "2014-10-13 12:03:35",
"type": "library"
}
},
"qux/quux": {
"dev-default": {
"name": "qux/quux",
"version": "dev-default",
"version_normalized": "9999999-dev",
"source": {
"type": "hg",
"url": "http://some.where/over/the/rainbow/",
"reference": "4a10a567baa5"
},
"replace": {
"gar/nix": "1.0.*"
},
"time": "2014-10-11 15:48:15",
"type": "library"
}
}
}
}

View File

@ -0,0 +1,50 @@
{
"packages": {
"bar\/baz": {
"1.0.0": {
"name": "bar\/baz",
"version": "1.0.0",
"version_normalized": "1.0.0.0",
"source": {
"type": "hg",
"url": "http:\/\/some.where\/over\/the\/rainbow\/",
"reference": "35810817c14d"
},
"time": "2014-10-13 12:04:55",
"type": "library",
"uid": 0
},
"1.0.x-dev": {
"name": "bar\/baz",
"version": "1.0.x-dev",
"version_normalized": "1.0.9999999.9999999-dev",
"source": {
"type": "hg",
"url": "http:\/\/some.where\/over\/the\/rainbow\/",
"reference": "ffff9aae6ed5"
},
"time": "2014-10-13 12:05:37",
"type": "library",
"uid": 1
},
"dev-default": {
"name": "bar\/baz",
"version": "dev-default",
"version_normalized": "9999999-dev",
"source": {
"type": "hg",
"url": "http:\/\/some.where\/over\/the\/rainbow\/",
"reference": "f317e556f2e2"
},
"time": "2014-10-13 12:06:45",
"type": "library",
"extra": {
"branch-alias": {
"dev-default": "1.1.x-dev"
}
},
"uid": 2
}
}
}
}

View File

@ -0,0 +1,77 @@
{
"packages": {
"foo\/bar": {
"1.0.0": {
"name": "foo\/bar",
"version": "1.0.0",
"version_normalized": "1.0.0.0",
"source": {
"type": "hg",
"url": "http:\/\/some.where\/over\/the\/rainbow\/",
"reference": "249dec95a52a"
},
"time": "2014-10-11 15:42:00",
"type": "library",
"uid": 3
},
"1.0.1": {
"name": "foo\/bar",
"version": "1.0.1",
"version_normalized": "1.0.1.0",
"source": {
"type": "hg",
"url": "http:\/\/some.where\/over\/the\/rainbow\/",
"reference": "21e3328295d4"
},
"time": "2014-10-11 15:45:56",
"type": "library",
"uid": 4
},
"1.0.x-dev": {
"name": "foo\/bar",
"version": "1.0.x-dev",
"version_normalized": "1.0.9999999.9999999-dev",
"source": {
"type": "hg",
"url": "http:\/\/some.where\/over\/the\/rainbow\/",
"reference": "14dc17c8e860"
},
"time": "2014-10-11 15:45:59",
"type": "library",
"uid": 5
},
"1.1.0": {
"name": "foo\/bar",
"version": "1.1.0",
"version_normalized": "1.1.0.0",
"source": {
"type": "hg",
"url": "http:\/\/some.where\/over\/the\/rainbow\/",
"reference": "d2fa3e69ad5b"
},
"require": {
"bar\/baz": "~1.0"
},
"time": "2014-10-11 15:43:16",
"type": "library",
"uid": 6
},
"dev-default": {
"name": "foo\/bar",
"version": "dev-default",
"version_normalized": "9999999-dev",
"source": {
"type": "hg",
"url": "http:\/\/some.where\/over\/the\/rainbow\/",
"reference": "8e5a5c224336"
},
"require": {
"bar\/baz": "~1.0"
},
"time": "2014-10-11 15:43:18",
"type": "library",
"uid": 7
}
}
}
}

View File

@ -0,0 +1,50 @@
{
"packages": {
"qux\/quux": {
"dev-default": {
"name": "qux\/quux",
"version": "dev-default",
"version_normalized": "9999999-dev",
"source": {
"type": "hg",
"url": "http:\/\/some.where\/over\/the\/rainbow\/",
"reference": "4a10a567baa5"
},
"replace": {
"gar\/nix": "1.0.*"
},
"time": "2014-10-11 15:48:15",
"type": "library",
"uid": 10
}
},
"gar\/nix": {
"1.0.0": {
"name": "gar\/nix",
"version": "1.0.0",
"version_normalized": "1.0.0.0",
"source": {
"type": "hg",
"url": "http:\/\/some.where\/over\/the\/rainbow\/",
"reference": "44977145d64e"
},
"time": "2014-10-13 12:03:33",
"type": "library",
"uid": 8
},
"dev-default": {
"name": "gar\/nix",
"version": "dev-default",
"version_normalized": "9999999-dev",
"source": {
"type": "hg",
"url": "http:\/\/some.where\/over\/the\/rainbow\/",
"reference": "51cca95a31c2"
},
"time": "2014-10-13 12:03:35",
"type": "library",
"uid": 9
}
}
}
}

View File

@ -0,0 +1,16 @@
{
"providers": {
"bar\/baz": {
"sha256": "923363b3c22e73abb2e3fd891c8156dd4d0821a97fd3e428bc910833e3e46dbe"
},
"foo\/bar": {
"sha256": "4baabb3303afa3e34a4d3af18fb138e5f3b79029c1f8d9ab5b477ea15776ba0a"
},
"gar\/nix": {
"sha256": "5d210670cb46c8364c8e3fb449967b9bea558b971e5b082f330ae4f1d484c321"
},
"qux\/quux": {
"sha256": "c142d1a07ca354be46b613f59f1d601923a5a00ccc5fcce50a77ecdd461eb72d"
}
}
}

View File

@ -0,0 +1,22 @@
{
"packages": {
"qux\/quux": {
"dev-default": {
"name": "qux\/quux",
"version": "dev-default",
"version_normalized": "9999999-dev",
"source": {
"type": "hg",
"url": "http:\/\/some.where\/over\/the\/rainbow\/",
"reference": "4a10a567baa5"
},
"replace": {
"gar\/nix": "1.0.*"
},
"time": "2014-10-11 15:48:15",
"type": "library",
"uid": 10
}
}
}
}

View File

@ -0,0 +1,9 @@
{
"packages": [],
"providers-url": "\/p\/%package%$%hash%.json",
"provider-includes": {
"p\/provider-active$1893a061e579543822389ecd12d791c612db0c05e22d90e9286e233cacd86ed8.json": {
"sha256": "1893a061e579543822389ecd12d791c612db0c05e22d90e9286e233cacd86ed8"
}
}
}

View File

@ -1,171 +0,0 @@
# Introduction
Composer is a tool for dependency management in PHP. It allows you to declare
the libraries your project depends on and it will manage (install/update) them
for you.
## Dependency management
Composer is **not** a package manager in the same sense as Yum or Apt are. Yes,
it deals with "packages" or libraries, but it manages them on a per-project
basis, installing them in a directory (e.g. `vendor`) inside your project. By
default it will never install anything globally. Thus, it is a dependency
manager.
This idea is not new and Composer is strongly inspired by node's
[npm](https://npmjs.org/) and ruby's [bundler](http://bundler.io/).
Suppose:
a) You have a project that depends on a number of libraries.
b) Some of those libraries depend on other libraries.
Composer:
c) Enables you to declare the libraries you depend on.
d) Finds out which versions of which packages can and need to be installed, and
installs them (meaning it downloads them into your project).
See the [Basic usage](01-basic-usage.md) chapter for more details on declaring
dependencies.
## System Requirements
Composer requires PHP 5.3.2+ to run. A few sensitive php settings and compile
flags are also required, but when using the installer you will be warned about
any incompatibilities.
To install packages from sources instead of simple zip archives, you will need
git, svn or hg depending on how the package is version-controlled.
Composer is multi-platform and we strive to make it run equally well on Windows,
Linux and OSX.
## Installation - Linux / Unix / OSX
### Downloading the Composer Executable
Composer offers a convenient installer that you can execute directly from the
commandline. Feel free to [download this file](https://getcomposer.org/installer)
or review it on [GitHub](https://github.com/composer/getcomposer.org/blob/master/web/installer)
if you wish to know more about the inner workings of the installer. The source
is plain PHP.
There are in short, two ways to install Composer. Locally as part of your
project, or globally as a system wide executable.
#### Locally
Installing Composer locally is a matter of just running the installer in your
project directory:
```sh
curl -sS https://getcomposer.org/installer | php
```
> **Note:** If the above fails for some reason, you can download the installer
> with `php` instead:
```sh
php -r "readfile('https://getcomposer.org/installer');" | php
```
The installer will just check a few PHP settings and then download
`composer.phar` to your working directory. This file is the Composer binary. It
is a PHAR (PHP archive), which is an archive format for PHP which can be run on
the command line, amongst other things.
Now just run `php composer.phar` in order to run Composer.
You can install Composer to a specific directory by using the `--install-dir`
option and additionally (re)name it as well using the `--filename` option:
```sh
curl -sS https://getcomposer.org/installer | php -- --install-dir=bin --filename=composer
```
Now just run `php bin/composer` in order to run Composer.
#### Globally
You can place the Composer PHAR anywhere you wish. If you put it in a directory
that is part of your `PATH`, you can access it globally. On unixy systems you
can even make it executable and invoke it without directly using the `php`
interpreter.
Run these commands to globally install `composer` on your system:
```sh
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
```
> **Note:** If the above fails due to permissions, run the `mv` line again
> with sudo.
A quick copy-paste version including sudo:
```sh
curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer
```
> **Note:** On some versions of OSX 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 the directory manually before proceeding:
> `mkdir -p /usr/local/bin`.
> **Note:** For information on changing your PATH, please read the
> [Wikipedia article](https://en.wikipedia.org/wiki/PATH_(variable)) and/or use Google.
Now just run `composer` in order to run Composer instead of `php composer.phar`.
## Installation - Windows
### Using the Installer
This is the easiest way to get Composer set up on your machine.
Download and run
[Composer-Setup.exe](https://getcomposer.org/Composer-Setup.exe). It will
install the latest Composer version and set up your PATH so that you can just
call `composer` from any directory in your command line.
> **Note:** Close your current terminal. Test usage with a new terminal: This is
> important since the PATH only gets loaded when the terminal starts.
### Manual Installation
Change to a directory on your `PATH` and run the install snippet to download
`composer.phar`:
```sh
C:\Users\username>cd C:\bin
C:\bin>php -r "readfile('https://getcomposer.org/installer');" | php
```
> **Note:** If the above fails due to readfile, use the `http` url or enable
> php_openssl.dll in php.ini
Create a new `composer.bat` file alongside `composer.phar`:
```sh
C:\bin>echo @php "%~dp0composer.phar" %*>composer.bat
```
Add the directory to your PATH environment variable if it isn't already.
Close your current terminal. Test usage with a new terminal:
```sh
C:\Users\username>composer -V
Composer version 27d8904
```
## Using Composer
Now that you've installed Composer, you are ready to use it! Head on over to the
next chapter for a short and simple demonstration.
[Basic usage](01-basic-usage.md) &rarr;

View File

@ -1,207 +0,0 @@
# Basic usage
## Introduction
For our basic usage introduction, we will be installing `monolog/monolog`,
a logging library. If you have not yet installed Composer, refer to the
[Intro](00-intro.md) chapter.
> **Note:** for the sake of simplicity, this introduction will assume you
> have performed a [local](00-intro.md#locally) install of Composer.
## `composer.json`: Project Setup
To start using Composer in your project, all you need is a `composer.json`
file. This file describes the dependencies of your project and may contain
other metadata as well.
### The `require` Key
The first (and often only) thing you specify in `composer.json` is the
[`require`](04-schema.md#require) key. You're simply telling Composer which
packages your project depends on.
```json
{
"require": {
"monolog/monolog": "1.0.*"
}
}
```
As you can see, [`require`](04-schema.md#require) takes an object that maps
**package names** (e.g. `monolog/monolog`) to **version constraints** (e.g.
`1.0.*`).
### Package Names
The package name consists of a vendor name and the project's name. Often these
will be identical - the vendor name just exists to prevent naming clashes. It
allows two different people to create a library named `json`, which would then
just be named `igorw/json` and `seldaek/json`.
Here we are requiring `monolog/monolog`, so the vendor name is the same as the
project's name. For projects with a unique name this is recommended. It also
allows adding more related projects under the same namespace later on. If you
are maintaining a library, this would make it really easy to split it up into
smaller decoupled parts.
### Package Versions
In the previous example we were requiring version
[`1.0.*`](http://semver.mwl.be/#?package=monolog%2Fmonolog&version=1.0.*) of
Monolog. This means any version in the `1.0` development branch. It is the
equivalent of saying versions that match `>=1.0 <1.1`.
Version constraints can be specified in several ways, read
[versions](articles/versions.md) for more in-depth information on this topic.
### Stability
By default only stable releases are taken into consideration. If you would
like to also get RC, beta, alpha or dev versions of your dependencies you can
do so using [stability flags](04-schema.md#package-links). To change that for
all packages instead of doing per dependency you can also use the
[minimum-stability](04-schema.md#minimum-stability) setting.
## Installing Dependencies
To install the defined dependencies for your project, just run the
[`install`](03-cli.md#install) command.
```sh
php composer.phar install
```
This will find the latest version of `monolog/monolog` that matches the
supplied version constraint and download it into the `vendor` directory.
It's a convention to put third party code into a directory named `vendor`.
In case of Monolog it will put it into `vendor/monolog/monolog`.
> **Tip:** If you are using git for your project, you probably want to add
> `vendor` in your `.gitignore`. You really don't want to add all of that
> code to your repository.
You will notice the [`install`](03-cli.md#install) command also created a
`composer.lock` file.
## `composer.lock` - The Lock File
After installing the dependencies, Composer writes the list of the exact
versions it installed into a `composer.lock` file. This locks the project
to those specific versions.
**Commit your application's `composer.lock` (along with `composer.json`)
into version control.**
This is important because the [`install`](03-cli.md#install) command checks
if a lock file is present, and if it is, it downloads the versions specified
there (regardless of what `composer.json` says).
This means that anyone who sets up the project will download the exact same
version of the dependencies. Your CI server, production machines, other
developers in your team, everything and everyone runs on the same dependencies,
which mitigates the potential for bugs affecting only some parts of the
deployments. Even if you develop alone, in six months when reinstalling the
project you can feel confident the dependencies installed are still working even
if your dependencies released many new versions since then.
If no `composer.lock` file exists, Composer will read the dependencies and
versions from `composer.json` and create the lock file after executing the
[`update`](03-cli.md#update) or the [`install`](03-cli.md#install) command.
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 the
[`update`](03-cli.md#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.
```sh
php composer.phar update
```
> **Note:** Composer will display a Warning when executing an `install` command
> if `composer.lock` and `composer.json` are not synchronized.
If you only want to install or update one dependency, you can whitelist them:
```sh
php composer.phar update monolog/monolog [...]
```
> **Note:** For libraries it is not necessary to commit the lock
> file, see also: [Libraries - Lock file](02-libraries.md#lock-file).
## Packagist
[Packagist](https://packagist.org/) is the main Composer repository. A Composer
repository is basically a package source: a place where you can get packages
from. Packagist aims to be the central repository that everybody uses. This
means that you can automatically `require` any package that is available there.
If you go to the [Packagist website](https://packagist.org/) (packagist.org),
you can browse and search for packages.
Any open source project using Composer is recommended to publish their packages
on Packagist. A library doesn't need to be on Packagist to be used by Composer,
but it enables discovery and adoption by other developers more quickly.
## Autoloading
For libraries that specify autoload information, Composer generates a
`vendor/autoload.php` file. You can simply include this file and you will get
autoloading for free.
```php
require __DIR__ . '/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 will be
autoloaded.
```php
$log = new Monolog\Logger('name');
$log->pushHandler(new Monolog\Handler\StreamHandler('app.log', Monolog\Logger::WARNING));
$log->addWarning('Foo');
```
You can even add your own code to the autoloader by adding an
[`autoload`](04-schema.md#autoload) field to `composer.json`.
```json
{
"autoload": {
"psr-4": {"Acme\\": "src/"}
}
}
```
Composer will register a [PSR-4](http://www.php-fig.org/psr/psr-4/) autoloader
for the `Acme` namespace.
You define a mapping from namespaces to directories. The `src` directory would
be in your project root, on the same level as `vendor` directory is. An example
filename would be `src/Foo.php` containing an `Acme\Foo` class.
After adding the [`autoload`](04-schema.md#autoload) field, you have to re-run
[`dump-autoload`](03-cli.md#dump-autoload) to re-generate 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.
```php
$loader = require __DIR__ . '/vendor/autoload.php';
$loader->add('Acme\\Test\\', __DIR__);
```
In addition to PSR-4 autoloading, Composer also supports PSR-0, classmap and
files autoloading. See the [`autoload`](04-schema.md#autoload) reference for
more information.
> **Note:** Composer provides its own autoloader. If you don't want to use that
> one, you can just include `vendor/composer/autoload_*.php` files, which return
> associative arrays allowing you to configure your own autoloader.
&larr; [Intro](00-intro.md) | [Libraries](02-libraries.md) &rarr;

View File

@ -1,212 +0,0 @@
# Libraries
This chapter will tell you how to make your library installable through
Composer.
## Every project is a package
As soon as you have a `composer.json` in a directory, that directory is a
package. When you add a [`require`](04-schema.md#require) to a project, you are
making a package that depends on other packages. The only difference between
your project and libraries is that your project is a package without a name.
In order to make that package installable you need to give it a name. You do
this by adding the [`name`](04-schema.md#name) property in `composer.json`:
```json
{
"name": "acme/hello-world",
"require": {
"monolog/monolog": "1.0.*"
}
}
```
In this case the project name is `acme/hello-world`, where `acme` is the vendor
name. Supplying a vendor name is mandatory.
> **Note:** If you don't know what to use as a vendor name, your GitHub
> username is usually a good bet. While package names are case insensitive, the
> convention is all lowercase and dashes for word separation.
## Platform packages
Composer has platform packages, which are virtual packages for things that are
installed on the system but are not actually installable by Composer. This
includes PHP itself, PHP extensions and some system libraries.
* `php` represents the PHP version of the user, allowing you to apply
constraints, e.g. `>=5.4.0`. To require a 64bit version of php, you can
require the `php-64bit` package.
* `hhvm` represents the version of the HHVM runtime (aka HipHop Virtual
Machine) and allows you to apply a constraint, e.g., '>=2.3.3'.
* `ext-<name>` allows you to require PHP extensions (includes core
extensions). Versioning can be quite inconsistent here, so it's often
a good idea to just set the constraint to `*`. An example of an extension
package name is `ext-gd`.
* `lib-<name>` allows constraints to be made on versions of libraries used by
PHP. The following are available: `curl`, `iconv`, `icu`, `libxml`,
`openssl`, `pcre`, `uuid`, `xsl`.
You can use [`show --platform`](03-cli.md#show) to get a list of your locally
available platform packages.
## Specifying the version
When you publish your package on Packagist, it is able to infer the version
from the VCS (git, svn, hg) information. This means you don't have to
explicitly declare it. Read [tags](#tags) and [branches](#branches) to see how
version numbers are extracted from these.
If you are creating packages by hand and really have to specify it explicitly,
you can just add a `version` field:
```json
{
"version": "1.0.0"
}
```
> **Note:** You should avoid specifying the version field explicitly, because
> for tags the value must match the tag name.
### Tags
For every tag that looks like a version, a package version of that tag will be
created. It should match 'X.Y.Z' or 'vX.Y.Z', with an optional suffix of
`-patch` (`-p`), `-alpha` (`-a`), `-beta` (`-b`) or `-RC`. The suffix can also
be followed by a number.
Here are a few examples of valid tag names:
- 1.0.0
- v1.0.0
- 1.10.5-RC1
- v4.4.4-beta2
- v2.0.0-alpha
- v2.0.4-p1
> **Note:** Even if your tag is prefixed with `v`, a
> [version constraint](01-basic-usage.md#package-versions) in a `require`
> statement has to be specified without prefix (e.g. tag `v1.0.0` will result
> in version `1.0.0`).
### Branches
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,
the branch `2.0` will get the `2.0.x-dev` version (the `.x` is added for
technical reasons, to make sure it is recognized as a branch). The `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.x
- 1.0 (equals 1.0.x)
- 1.1.x
> **Note:** When you install a development version, it will be automatically
> pulled from its `source`. See the [`install`](03-cli.md#install) command
> for more details.
### Aliases
It is possible to 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
can help your team to always test against the same dependency versions.
However, this lock file will not have any effect on other projects that depend
on it. It only has an effect on the main project.
If you do not want to commit the lock file and you are using git, add it to
the `.gitignore`.
## Publishing to a VCS
Once you have a VCS repository (version control system, e.g. git) containing a
`composer.json` file, your library is already composer-installable. In this
example we will publish the `acme/hello-world` library on GitHub under
`github.com/username/hello-world`.
Now, to test installing the `acme/hello-world` package, we create a new
project locally. We will call it `acme/blog`. This blog will depend on
`acme/hello-world`, which in turn depends on `monolog/monolog`. We can
accomplish this by creating a new `blog` directory somewhere, containing a
`composer.json`:
```json
{
"name": "acme/blog",
"require": {
"acme/hello-world": "dev-master"
}
}
```
The name is not needed in this case, since we don't want to publish the blog
as a library. It is added here to clarify which `composer.json` is being
described.
Now we need to tell the blog app where to find the `hello-world` dependency.
We do this by adding a package repository specification to the blog's
`composer.json`:
```json
{
"name": "acme/blog",
"repositories": [
{
"type": "vcs",
"url": "https://github.com/username/hello-world"
}
],
"require": {
"acme/hello-world": "dev-master"
}
}
```
For more details on how package repositories work and what other types are
available, see [Repositories](05-repositories.md).
That's all. You can now install the dependencies by running Composer's
[`install`](03-cli.md#install) command!
**Recap:** Any git/svn/hg repository containing a `composer.json` can be added
to your project by specifying the package repository and declaring the
dependency in the [`require`](04-schema.md#require) field.
## Publishing to packagist
Alright, so now you can publish packages. But specifying the VCS repository
every time is cumbersome. You don't want to force all your users to do that.
The other thing that you may have noticed is that we did not specify a package
repository for `monolog/monolog`. How did that work? The answer is Packagist.
[Packagist](https://packagist.org/) is the main package repository for
Composer, and it is enabled by default. Anything that is published on
Packagist is available automatically through Composer. Since
[Monolog is on Packagist](https://packagist.org/packages/monolog/monolog), we
can depend on it without having to specify any additional repositories.
If we wanted to share `hello-world` with the world, we would publish it on
Packagist as well. Doing so is really easy.
You simply visit [Packagist](https://packagist.org) and hit the "Submit". This
will prompt you to sign up if you haven't already, and then allows you to
submit the URL to your VCS repository, at which point Packagist will start
crawling it. Once it is done, your package will be available to anyone!
&larr; [Basic usage](01-basic-usage.md) | [Command-line interface](03-cli.md) &rarr;

View File

@ -1,701 +0,0 @@
# Command-line interface / Commands
You've already learned how to use the command-line interface to do some
things. This chapter documents all the available commands.
To get help from the command-line, simply call `composer` or `composer list`
to see the complete list of commands, then `--help` combined with any of those
can give you more information.
## Global Options
The following options are available with every command:
* **--verbose (-v):** Increase verbosity of messages.
* **--help (-h):** Display help information.
* **--quiet (-q):** Do not output any message.
* **--no-interaction (-n):** Do not ask any interactive question.
* **--working-dir (-d):** If specified, use the given directory as working directory.
* **--profile:** Display timing and memory usage information
* **--ansi:** Force ANSI output.
* **--no-ansi:** Disable ANSI output.
* **--version (-V):** Display this application version.
## Process Exit Codes
* **0:** OK
* **1:** Generic/unknown error code
* **2:** Dependency solving error code
## init
In the [Libraries](02-libraries.md) chapter we looked at how to create a
`composer.json` by hand. There is also an `init` command available that makes
it a bit easier to do this.
When you run the command it will interactively ask you to fill in the fields,
while using some smart defaults.
```sh
php composer.phar init
```
### Options
* **--name:** Name of the package.
* **--description:** Description of the package.
* **--author:** Author name of the package.
* **--homepage:** Homepage of the package.
* **--require:** Package to require with a version constraint. Should be
in format `foo/bar:1.0.0`.
* **--require-dev:** Development requirements, see **--require**.
* **--stability (-s):** Value for the `minimum-stability` field.
## install
The `install` command reads the `composer.json` file from the current
directory, resolves the dependencies, and installs them into `vendor`.
```sh
php composer.phar install
```
If there is a `composer.lock` file in the current directory, it will use the
exact versions from there instead of resolving them. This ensures that
everyone using the library will get the same versions of the dependencies.
If there is no `composer.lock` file, Composer will create one after dependency
resolution.
### Options
* **--prefer-source:** There are two ways of downloading a package: `source`
and `dist`. For stable versions Composer will use the `dist` by default.
The `source` is a version control repository. If `--prefer-source` is
enabled, Composer will install from `source` if there is one. This is
useful if you want to make a bugfix to a project and get a local git
clone of the dependency directly.
* **--prefer-dist:** Reverse of `--prefer-source`, Composer will install
from `dist` if possible. This can speed up installs substantially on build
servers and other use cases where you typically do not run updates of the
vendors. It is also a way to circumvent problems with git if you do not
have a proper setup.
* **--ignore-platform-reqs:** ignore `php`, `hhvm`, `lib-*` and `ext-*`
requirements and force the installation even if the local machine does not
fulfill these. See also the [`platform`](06-config.md#platform) config option.
* **--dry-run:** If you want to run through an installation without actually
installing a package, you can use `--dry-run`. This will simulate the
installation and show you what would happen.
* **--dev:** Install packages listed in `require-dev` (this is the default behavior).
* **--no-dev:** Skip installing packages listed in `require-dev`. The autoloader
generation skips the `autoload-dev` rules.
* **--no-autoloader:** Skips autoloader generation.
* **--no-scripts:** Skips execution of scripts defined in `composer.json`.
* **--no-plugins:** Disables plugins.
* **--no-progress:** Removes the progress display that can mess with some
terminals or scripts which don't handle backspace characters.
* **--optimize-autoloader (-o):** Convert PSR-0/4 autoloading to classmap to get a faster
autoloader. This is recommended especially for production, but can take
a bit of time to run so it is currently not done by default.
* **--classmap-authoritative (-a):** Autoload classes from the classmap only.
Implicitly enables `--optimize-autoloader`.
## update
In order to get the latest versions of the dependencies and to update the
`composer.lock` file, you should use the `update` command.
```sh
php composer.phar update
```
This will resolve all dependencies of the project and write the exact versions
into `composer.lock`.
If you just want to update a few packages and not all, you can list them as such:
```sh
php composer.phar update vendor/package vendor/package2
```
You can also use wildcards to update a bunch of packages at once:
```sh
php composer.phar update vendor/*
```
### Options
* **--prefer-source:** Install packages from `source` when available.
* **--prefer-dist:** Install packages from `dist` when available.
* **--ignore-platform-reqs:** ignore `php`, `hhvm`, `lib-*` and `ext-*`
requirements and force the installation even if the local machine does not
fulfill these. See also the [`platform`](06-config.md#platform) config option.
* **--dry-run:** Simulate the command without actually doing anything.
* **--dev:** Install packages listed in `require-dev` (this is the default behavior).
* **--no-dev:** Skip installing packages listed in `require-dev`. The autoloader generation skips the `autoload-dev` rules.
* **--no-autoloader:** Skips autoloader generation.
* **--no-scripts:** Skips execution of scripts defined in `composer.json`.
* **--no-plugins:** Disables plugins.
* **--no-progress:** Removes the progress display that can mess with some
terminals or scripts which don't handle backspace characters.
* **--optimize-autoloader (-o):** Convert PSR-0/4 autoloading to classmap to get a faster
autoloader. This is recommended especially for production, but can take
a bit of time to run so it is currently not done by default.
* **--classmap-authoritative (-a):** Autoload classes from the classmap only.
Implicitly enables `--optimize-autoloader`.
* **--lock:** Only updates the lock file hash to suppress warning about the
lock file being out of date.
* **--with-dependencies:** Add also all dependencies of whitelisted packages to the whitelist.
* **--prefer-stable:** Prefer stable versions of dependencies.
* **--prefer-lowest:** Prefer lowest versions of dependencies. Useful for testing minimal
versions of requirements, generally used with `--prefer-stable`.
## require
The `require` command adds new packages to the `composer.json` file from
the current directory. If no file exists one will be created on the fly.
```sh
php composer.phar require
```
After adding/changing the requirements, the modified requirements will be
installed or updated.
If you do not want to choose requirements interactively, you can just pass them
to the command.
```sh
php composer.phar require vendor/package:2.* vendor/package2:dev-master
```
### Options
* **--prefer-source:** Install packages from `source` when available.
* **--prefer-dist:** Install packages from `dist` when available.
* **--ignore-platform-reqs:** ignore `php`, `hhvm`, `lib-*` and `ext-*`
requirements and force the installation even if the local machine does not
fulfill these. See also the [`platform`](06-config.md#platform) config option.
* **--dev:** Add packages to `require-dev`.
* **--no-update:** Disables the automatic update of the dependencies.
* **--no-progress:** Removes the progress display that can mess with some
terminals or scripts which don't handle backspace characters.
* **--update-no-dev:** Run the dependency update with the `--no-dev` option.
* **--update-with-dependencies:** Also update dependencies of the newly
required packages.
* **--sort-packages:** Keep packages sorted in `composer.json`.
* **--optimize-autoloader (-o):** Convert PSR-0/4 autoloading to classmap to
get a faster autoloader. This is recommended especially for production, but
can take a bit of time to run so it is currently not done by default.
* **--classmap-authoritative (-a):** Autoload classes from the classmap only.
Implicitly enables `--optimize-autoloader`.
## remove
The `remove` command removes packages from the `composer.json` file from
the current directory.
```sh
php composer.phar remove vendor/package vendor/package2
```
After removing the requirements, the modified requirements will be
uninstalled.
### Options
* **--ignore-platform-reqs:** ignore `php`, `hhvm`, `lib-*` and `ext-*`
requirements and force the installation even if the local machine does not
fulfill these. See also the [`platform`](06-config.md#platform) config option.
* **--dev:** Remove packages from `require-dev`.
* **--no-update:** Disables the automatic update of the dependencies.
* **--no-progress:** Removes the progress display that can mess with some
terminals or scripts which don't handle backspace characters.
* **--update-no-dev:** Run the dependency update with the --no-dev option.
* **--update-with-dependencies:** Also update dependencies of the removed packages.
* **--optimize-autoloader (-o):** Convert PSR-0/4 autoloading to classmap to
get a faster autoloader. This is recommended especially for production, but
can take a bit of time to run so it is currently not done by default.
* **--classmap-authoritative (-a):** Autoload classes from the classmap only.
Implicitly enables `--optimize-autoloader`.
## global
The global command allows you to run other commands like `install`, `require`
or `update` as if you were running them from the [COMPOSER_HOME](#composer-home)
directory.
This can be used to install CLI utilities globally and if you add
`$COMPOSER_HOME/vendor/bin` to your `$PATH` environment variable. Here is an
example:
```sh
php composer.phar global require fabpot/php-cs-fixer:dev-master
```
Now the `php-cs-fixer` binary is available globally (assuming you adjusted
your PATH). If you wish to update the binary later on you can just run a
global update:
```sh
php composer.phar global update
```
## search
The search command allows you to search through the current project's package
repositories. Usually this will be just packagist. You simply pass it the
terms you want to search for.
```sh
php composer.phar search monolog
```
You can also search for more than one term by passing multiple arguments.
### Options
* **--only-name (-N):** Search only in name.
## show
To list all of the available packages, you can use the `show` command.
```sh
php composer.phar show
```
If you want to see the details of a certain package, you can pass the package
name.
```sh
php composer.phar show monolog/monolog
name : monolog/monolog
versions : master-dev, 1.0.2, 1.0.1, 1.0.0, 1.0.0-RC1
type : library
names : monolog/monolog
source : [git] https://github.com/Seldaek/monolog.git 3d4e60d0cbc4b888fe5ad223d77964428b1978da
dist : [zip] https://github.com/Seldaek/monolog/zipball/3d4e60d0cbc4b888fe5ad223d77964428b1978da 3d4e60d0cbc4b888fe5ad223d77964428b1978da
license : MIT
autoload
psr-0
Monolog : src/
requires
php >=5.3.0
```
You can even pass the package version, which will tell you the details of that
specific version.
```sh
php composer.phar show monolog/monolog 1.0.2
```
### Options
* **--installed (-i):** List the packages that are installed.
* **--platform (-p):** List only platform packages (php & extensions).
* **--self (-s):** List the root package info.
* **--tree (-t):** List the dependencies as a tree. Only usable when giving a single package name or combined with `-i`.
## browse / home
The `browse` (aliased to `home`) opens a package's repository URL or homepage
in your browser.
### Options
* **--homepage (-H):** Open the homepage instead of the repository URL.
## suggests
Lists all packages suggested by currently installed set of packages. You can
optionally pass one or multiple package names in the format of `vendor/package`
to limit output to suggestions made by those packages only.
### Options
* **--no-dev:** Excludes suggestions from `require-dev` packages.
* **--verbose (-v):** Increased verbosity adds suggesting package name and
reason for suggestion.
## depends
The `depends` command tells you which other packages depend on a certain
package. You can specify which link types (`require`, `require-dev`)
should be included in the listing. By default both are used.
```sh
php composer.phar depends --link-type=require monolog/monolog
nrk/monolog-fluent requires monolog/monolog (~1.8)
poc/poc requires monolog/monolog (^1.6)
propel/propel requires monolog/monolog (1.*)
symfony/monolog-bridge requires monolog/monolog (>=1.2)
symfony/symfony requires monolog/monolog (~1)
```
### Options
* **--link-type:** The link types to match on, can be specified multiple
times.
## validate
You should always run the `validate` command before you commit your
`composer.json` file, and before you tag a release. It will check if your
`composer.json` is valid.
```sh
php composer.phar validate
```
### Options
* **--no-check-all:** Do not emit a warning if requirements in `composer.json` use unbound version constraints.
* **--no-check-lock:** Do not emit an error if `composer.lock` exists and is not up to date.
* **--no-check-publish:** Do not emit an error if `composer.json` is unsuitable for publishing as a package on Packagist but is otherwise valid.
## status
If you often need to modify the code of your dependencies and they are
installed from source, the `status` command allows you to check if you have
local changes in any of them.
```sh
php composer.phar status
```
With the `--verbose` option you get some more information about what was
changed:
```sh
php composer.phar status -v
You have changes in the following dependencies:
vendor/seld/jsonlint:
M README.mdown
```
## self-update
To update Composer itself to the latest version, just run the `self-update`
command. It will replace your `composer.phar` with the latest version.
```sh
php composer.phar self-update
```
If you would like to instead update to a specific release simply specify it:
```sh
php composer.phar self-update 1.0.0-alpha7
```
If you have installed Composer for your entire system (see [global installation](00-intro.md#globally)),
you may have to run the command with `root` privileges
```sh
sudo composer self-update
```
### Options
* **--rollback (-r):** Rollback to the last version you had installed.
* **--clean-backups:** Delete old backups during an update. This makes the
current version of Composer the only backup available after the update.
## config
The `config` command allows you to edit some basic Composer settings in either
the local composer.json file or the global config.json file.
```sh
php composer.phar config --list
```
### Usage
`config [options] [setting-key] [setting-value1] ... [setting-valueN]`
`setting-key` is a configuration option name and `setting-value1` is a
configuration value. For settings that can take an array of values (like
`github-protocols`), more than one setting-value arguments are allowed.
See the [Config](06-config.md) chapter for valid configuration options.
### Options
* **--global (-g):** Operate on the global config file located at
`$COMPOSER_HOME/config.json` by default. Without this option, this command
affects the local composer.json file or a file specified by `--file`.
* **--editor (-e):** Open the local composer.json file using in a text editor as
defined by the `EDITOR` env variable. With the `--global` option, this opens
the global config file.
* **--unset:** Remove the configuration element named by `setting-key`.
* **--list (-l):** Show the list of current config variables. With the `--global`
option this lists the global configuration only.
* **--file="..." (-f):** Operate on a specific file instead of composer.json. Note
that this cannot be used in conjunction with the `--global` option.
* **--absolute:** Returns absolute paths when fetching *-dir config values
instead of relative.
### Modifying Repositories
In addition to modifying the config section, the `config` command also supports making
changes to the repositories section by using it the following way:
```sh
php composer.phar config repositories.foo vcs https://github.com/foo/bar
```
## create-project
You can use Composer to create new projects from an existing package. This is
the equivalent of doing a git clone/svn checkout followed by a "composer install"
of the vendors.
There are several applications for this:
1. You can deploy application packages.
2. You can check out any package and start developing on patches for example.
3. Projects with multiple developers can use this feature to bootstrap the
initial application for development.
To create a new project using Composer you can use the "create-project" command.
Pass it a package name, and the directory to create the project in. You can also
provide a version as third argument, otherwise the latest version is used.
If the directory does not currently exist, it will be created during installation.
```sh
php composer.phar create-project doctrine/orm path 2.2.*
```
It is also possible to run the command without params in a directory with an
existing `composer.json` file to bootstrap a project.
By default the command checks for the packages on packagist.org.
### Options
* **--repository-url:** Provide a custom repository to search for the package,
which will be used instead of packagist. Can be either an HTTP URL pointing
to a `composer` repository, or a path to a local `packages.json` file.
* **--stability (-s):** Minimum stability of package. Defaults to `stable`.
* **--prefer-source:** Install packages from `source` when available.
* **--prefer-dist:** Install packages from `dist` when available.
* **--dev:** Install packages listed in `require-dev`.
* **--no-install:** Disables installation of the vendors.
* **--no-plugins:** Disables plugins.
* **--no-scripts:** Disables the execution of the scripts defined in the root
package.
* **--no-progress:** Removes the progress display that can mess with some
terminals or scripts which don't handle backspace characters.
* **--keep-vcs:** Skip the deletion of the VCS metadata for the created
project. This is mostly useful if you run the command in non-interactive
mode.
* **--ignore-platform-reqs:** ignore `php`, `hhvm`, `lib-*` and `ext-*`
requirements and force the installation even if the local machine does not
fulfill these.
## dump-autoload
If you need to update the autoloader because of new classes in a classmap
package for example, you can use "dump-autoload" to do that without having to
go through an install or update.
Additionally, it can dump an optimized autoloader that converts PSR-0/4 packages
into classmap ones for performance reasons. In large applications with many
classes, the autoloader can take up a substantial portion of every request's
time. Using classmaps for everything is less convenient in development, but
using this option you can still use PSR-0/4 for convenience and classmaps for
performance.
### Options
* **--optimize (-o):** Convert PSR-0/4 autoloading to classmap to get a faster
autoloader. This is recommended especially for production, but can take
a bit of time to run so it is currently not done by default.
* **--classmap-authoritative (-a):** Autoload classes from the classmap only.
Implicitly enables `--optimize`.
* **--no-dev:** Disables autoload-dev rules.
## clear-cache
Deletes all content from Composer's cache directories.
## licenses
Lists the name, version and license of every package installed. Use
`--format=json` to get machine readable output.
### Options
* **--no-dev:** Remove dev dependencies from the output
* **--format:** Format of the output: text or json (default: "text")
## run-script
### Options
* **--no-dev:** Disable dev mode
* **--list:** List user defined scripts
To run [scripts](articles/scripts.md) manually you can use this command,
just give it the script name and optionally any required arguments.
## diagnose
If you think you found a bug, or something is behaving strangely, you might
want to run the `diagnose` command to perform automated checks for many common
problems.
```sh
php composer.phar diagnose
```
## archive
This command is used to generate a zip/tar archive for a given package in a
given version. It can also be used to archive your entire project without
excluded/ignored files.
```sh
php composer.phar archive vendor/package 2.0.21 --format=zip
```
### Options
* **--format (-f):** Format of the resulting archive: tar or zip (default:
"tar")
* **--dir:** Write the archive to this directory (default: ".")
## help
To get more information about a certain command, just use `help`.
```sh
php composer.phar help install
```
## Environment variables
You can set a number of environment variables that override certain settings.
Whenever possible it is recommended to specify these settings in the `config`
section of `composer.json` instead. It is worth noting that the env vars will
always take precedence over the values specified in `composer.json`.
### COMPOSER
By setting the `COMPOSER` env variable it is possible to set the filename of
`composer.json` to something else.
For example:
```sh
COMPOSER=composer-other.json php composer.phar install
```
The generated lock file will use the same name: `composer-other.lock` in this example.
### COMPOSER_ROOT_VERSION
By setting this var you can specify the version of the root package, if it can
not be guessed from VCS info and is not present in `composer.json`.
### COMPOSER_VENDOR_DIR
By setting this var you can make Composer install the dependencies into a
directory other than `vendor`.
### COMPOSER_BIN_DIR
By setting this option you can change the `bin` ([Vendor Binaries](articles/vendor-binaries.md))
directory to something other than `vendor/bin`.
### http_proxy or HTTP_PROXY
If you are using Composer from behind an HTTP proxy, you can use the standard
`http_proxy` or `HTTP_PROXY` env vars. Simply set it to the URL of your proxy.
Many operating systems already set this variable for you.
Using `http_proxy` (lowercased) or even defining both might be preferable since
some tools like git or curl will only use the lower-cased `http_proxy` version.
Alternatively you can also define the git proxy using
`git config --global http.proxy <proxy url>`.
### no_proxy
If you are behind a proxy and would like to disable it for certain domains, you
can use the `no_proxy` env var. Simply set it to a comma separated list of
domains the proxy should *not* be used for.
The env var accepts domains, IP addresses, and IP address blocks in CIDR
notation. You can restrict the filter to a particular port (e.g. `:80`). You
can also set it to `*` to ignore the proxy for all HTTP requests.
### HTTP_PROXY_REQUEST_FULLURI
If you use a proxy but it does not support the request_fulluri flag, then you
should set this env var to `false` or `0` to prevent Composer from setting the
request_fulluri option.
### HTTPS_PROXY_REQUEST_FULLURI
If you use a proxy but it does not support the request_fulluri flag for HTTPS
requests, then you should set this env var to `false` or `0` to prevent Composer
from setting the request_fulluri option.
### 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_HOME/config.json
You may put a `config.json` file into the location which `COMPOSER_HOME` points
to. Composer will merge this configuration with your project's `composer.json`
when you run the `install` and `update` commands.
This file allows you to set [repositories](05-repositories.md) and
[configuration](06-config.md) for the user's projects.
In case global configuration matches _local_ configuration, the _local_
configuration in the project's `composer.json` always wins.
### COMPOSER_CACHE_DIR
The `COMPOSER_CACHE_DIR` var allows you to change the Composer cache directory,
which is also configurable via the [`cache-dir`](06-config.md#cache-dir) option.
By default it points to $COMPOSER_HOME/cache on \*nix and OSX, and
`C:\Users\<user>\AppData\Local\Composer` (or `%LOCALAPPDATA%/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).
### COMPOSER_DISCARD_CHANGES
This env var controls the [`discard-changes`](06-config.md#discard-changes) config option.
### COMPOSER_NO_INTERACTION
If set to 1, this env var will make Composer behave as if you passed the
`--no-interaction` flag to every command. This can be set on build boxes/CI.
### COMPOSER_DISABLE_XDEBUG_WARN
If set to 1, this env disables the warning about having xdebug enabled.
&larr; [Libraries](02-libraries.md) | [Schema](04-schema.md) &rarr;

View File

@ -1,189 +0,0 @@
# Config
This chapter will describe the `config` section of the `composer.json`
[schema](04-schema.md).
## 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.
## use-include-path
Defaults to `false`. If `true`, the Composer autoloader will also look for classes
in the PHP include path.
## preferred-install
Defaults to `auto` and can be any of `source`, `dist` or `auto`. This option
allows you to set the install method Composer will prefer to use.
## store-auths
What to do after prompting for authentication, one of: `true` (always store),
`false` (do not store) and `"prompt"` (ask every time), defaults to `"prompt"`.
## github-protocols
Defaults to `["git", "https", "ssh"]`. A list of protocols to use when cloning
from github.com, in priority order. You can reconfigure it to for example
prioritize the https protocol if you are behind a proxy or have somehow bad
performances with the git protocol.
## github-oauth
A list of domain names and oauth keys. For example using `{"github.com":
"oauthtoken"}` as the value of this option will use `oauthtoken` to access
private repositories on github and to circumvent the low IP-based rate limiting
of their API. [Read
more](articles/troubleshooting.md#api-rate-limit-and-oauth-tokens) on how to get
an OAuth token for GitHub.
## http-basic
A list of domain names and username/passwords to authenticate against them. For
example using `{"example.org": {"username": "alice", "password": "foo"}` as the
value of this option will let Composer authenticate against example.org.
> **Note:** Authentication-related config options like `http-basic` and
> `github-oauth` can also be specified inside a `auth.json` file that goes
> besides your `composer.json`. That way you can gitignore it and every
> developer can place their own credentials in there.
## platform
Lets you fake platform packages (PHP and extensions) so that you can emulate a
production env or define your target platform in the config. Example: `{"php":
"5.4", "ext-something": "4.0"}`.
## vendor-dir
Defaults to `vendor`. You can install dependencies into a different directory if
you want to. `$HOME` and `~` will be replaced by your home directory's path in
vendor-dir and all `*-dir` options below.
## bin-dir
Defaults to `vendor/bin`. If a project includes binaries, they will be symlinked
into this directory.
## cache-dir
Defaults to `$COMPOSER_HOME/cache` on unix systems and
`C:\Users\<user>\AppData\Local\Composer` on Windows. Stores all the caches used
by Composer. See also [COMPOSER_HOME](03-cli.md#composer-home).
## cache-files-dir
Defaults to `$cache-dir/files`. Stores the zip archives of packages.
## cache-repo-dir
Defaults to `$cache-dir/repo`. Stores repository metadata for the `composer`
type and the VCS repos of type `svn`, `github` and `bitbucket`.
## cache-vcs-dir
Defaults to `$cache-dir/vcs`. Stores VCS clones for loading VCS repository
metadata for the `git`/`hg` types and to speed up installs.
## cache-files-ttl
Defaults to `15552000` (6 months). Composer caches all dist (zip, tar, ..)
packages that it downloads. Those are purged after six months of being unused by
default. This option allows you to tweak this duration (in seconds) or disable
it completely by setting it to 0.
## cache-files-maxsize
Defaults to `300MiB`. Composer caches all dist (zip, tar, ..) packages that it
downloads. When the garbage collection is periodically ran, this is the maximum
size the cache will be able to use. Older (less used) files will be removed
first until the cache fits.
## bin-compat
Defaults to `auto`. Determines the compatibility of the binaries to be installed.
If it is `auto` then Composer only installs .bat proxy files when on Windows. If
set to `full` then both .bat files for Windows and scripts for Unix-based
operating systems will be installed for each binary. This is mainly useful if you
run Composer inside a linux VM but still want the .bat proxies available for use
in the Windows host OS.
## prepend-autoloader
Defaults to `true`. If `false`, the Composer autoloader will not be prepended to
existing autoloaders. This is sometimes required to fix interoperability issues
with other autoloaders.
## autoloader-suffix
Defaults to `null`. String to be used as a suffix for the generated Composer
autoloader. When null a random one will be generated.
## optimize-autoloader
Defaults to `false`. If `true`, always optimize when dumping the autoloader.
## sort-packages
Defaults to `false`. If `true`, the `require` command keeps packages sorted
by name in `composer.json` when adding a new package.
## classmap-authoritative
Defaults to `false`. If `true`, the Composer autoloader will only load classes
from the classmap. Implies `optimize-autoloader`.
## github-domains
Defaults to `["github.com"]`. A list of domains to use in github mode. This is
used for GitHub Enterprise setups.
## github-expose-hostname
Defaults to `true`. If `false`, the OAuth tokens created to access the
github API will have a date instead of the machine hostname.
## gitlab-domains
Defaults to `["gitlab.com"]`. A list of domains of GitLab servers.
This is used if you use the `gitlab` repository type.
## 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.
## discard-changes
Defaults to `false` and can be any of `true`, `false` or `"stash"`. This option
allows you to set the default style of handling dirty updates when in
non-interactive mode. `true` will always discard changes in vendors, while
`"stash"` will try to stash and reapply. Use this for CI servers or deploy
scripts if you tend to have modified vendors.
## archive-format
Defaults to `tar`. Composer allows you to add a default archive format when the
workflow needs to create a dedicated archiving format.
## archive-dir
Defaults to `.`. Composer allows you to add a default archive directory when the
workflow needs to create a dedicated archiving format. Or for easier development
between modules.
Example:
```json
{
"config": {
"archive-dir": "/home/user/.composer/repo"
}
}
```
&larr; [Repositories](05-repositories.md) | [Community](07-community.md) &rarr;

View File

@ -1,35 +0,0 @@
# Community
There are many people using Composer already, and quite a few of them are
contributing.
## Contributing
If you would like to contribute to Composer, please read the
[README](https://github.com/composer/composer) and
[CONTRIBUTING](https://github.com//composer/composer/blob/master/CONTRIBUTING.md)
documents.
The most important guidelines are described as follows:
> All code contributions - including those of people having commit access - must
> go through a pull request and approved by a core developer before being
> merged. This is to ensure proper review of all the code.
>
> Fork the project, create a feature branch, and send us a pull request.
>
> To ensure a consistent code base, you should make sure the code follows
> the [PSR-2 Coding Standards](http://www.php-fig.org/psr/psr-2/).
## IRC / mailing list
Mailing lists for [user support](https://groups.google.com/group/composer-users) and
[development](https://groups.google.com/group/composer-dev).
IRC channels are on irc.freenode.org: [#composer](irc://irc.freenode.org/composer)
for users and [#composer-dev](irc://irc.freenode.org/composer-dev) for development.
Stack Overflow has a growing collection of
[Composer related questions](https://stackoverflow.com/questions/tagged/composer-php).
&larr; [Config](06-config.md)

View File

@ -1,200 +0,0 @@
<!--
tagline: Host your own composer repository
-->
# Handling private packages with Satis
Satis is a static `composer` 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 private packages, or your own. It basically acts as
a micro-packagist. You can get it from
[GitHub](http://github.com/composer/satis) or install via CLI:
`composer.phar create-project composer/satis --stability=dev`.
## Setup
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: a json file with an arbitrary name that lists your curated
[repositories](../05-repositories.md).
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 it
uses `"require-all": true` which selects all versions of all packages in the
repositories you defined.
The default file Satis looks for is `satis.json` in the root of the repository.
```json
{
"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.
```json
{
"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": {
"company/package": "*",
"company/package2": "*",
"company/package3": "2.0.0"
}
}
```
Once you did this, you just run `php bin/satis build <configuration file> <build dir>`.
For example `php bin/satis build config.json web/` would read the `config.json`
file and build a static repository inside the `web/` directory.
When you ironed out that process, what you would typically do is run this
command as a cron job on a server. It would then update all your package info
much like Packagist does.
Note that if your private packages are hosted on GitHub, your server should have
an ssh key that gives it access to those packages, and then you should add
the `--no-interaction` (or `-n`) flag to the command to make sure it falls back
to ssh key authentication instead of prompting for a password. This is also a
good trick for continuous integration servers.
Set up a virtual-host that points to that `web/` directory, let's say it is
`packages.example.org`. Alternatively, with PHP >= 5.4.0, you can use the built-in
CLI server `php -S localhost:port -t satis-output-dir/` for a temporary solution.
## Usage
In your projects all you need to add now is your own composer repository using
the `packages.example.org` as URL, then you can require your private packages and
everything should work smoothly. You don't need to copy all your repositories
in every project anymore. Only that one unique repository that will update
itself.
```json
{
"repositories": [ { "type": "composer", "url": "http://packages.example.org/" } ],
"require": {
"company/package": "1.2.0",
"company/package2": "1.5.2",
"company/package3": "dev-master"
}
}
```
### Security
To secure your private repository you can host it over SSH or SSL using a client
certificate. In your project you can use the `options` parameter to specify the
connection options for the server.
Example using a custom repository using SSH (requires the SSH2 PECL extension):
```json
{
"repositories": [
{
"type": "composer",
"url": "ssh2.sftp://example.org",
"options": {
"ssh2": {
"username": "composer",
"pubkey_file": "/home/composer/.ssh/id_rsa.pub",
"privkey_file": "/home/composer/.ssh/id_rsa"
}
}
}
]
}
```
> **Tip:** See [ssh2 context options](http://www.php.net/manual/en/wrappers.ssh2.php#refsect1-wrappers.ssh2-options) for more information.
Example using HTTP over SSL using a client certificate:
```json
{
"repositories": [
{
"type": "composer",
"url": "https://example.org",
"options": {
"ssl": {
"local_cert": "/home/composer/.ssl/composer.pem"
}
}
}
]
}
```
> **Tip:** See [ssl context options](http://www.php.net/manual/en/context.ssl.php) for more information.
### Downloads
When GitHub or BitBucket repositories are mirrored on your local satis, the build process will include
the location of the downloads these platforms make available. This means that the repository and your setup depend
on the availability of these services.
At the same time, this implies that all code which is hosted somewhere else (on another service or for example in
Subversion) will not have downloads available and thus installations usually take a lot longer.
To enable your satis installation to create downloads for all (Git, Mercurial and Subversion) your packages, add the
following to your `satis.json`:
```json
{
"archive": {
"directory": "dist",
"format": "tar",
"prefix-url": "https://amazing.cdn.example.org",
"skip-dev": true
}
}
```
#### Options explained
* `directory`: the location of the dist files (inside the `output-dir`)
* `format`: optional, `zip` (default) or `tar`
* `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
Once enabled, all downloads (include those from GitHub and BitBucket) will be replaced with a _local_ version.
#### prefix-url
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.
Example: A `prefix-url` of `http://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`.
### Resolving dependencies
It is possible to make satis automatically resolve and add all dependencies for your projects. This can be used
with the Downloads functionality to have a complete local mirror of packages. Just add the following
to your `satis.json`:
```json
{
"require-dependencies": true
}
```
When searching for packages, satis will attempt to resolve all the required packages from the listed repositories.
Therefore, if you are requiring a package from Packagist, you will need to define it in your `satis.json`.

View File

@ -1,160 +0,0 @@
<!--
tagline: Modify and extend Composer's functionality
-->
# Setting up and using plugins
## Synopsis
You may wish to alter or expand Composer's functionality with your own. For
example if your environment poses special requirements on the behaviour of
Composer which do not apply to the majority of its users or if you wish to
accomplish something with composer in a way that is not desired by most users.
In these cases you could consider creating a plugin to handle your
specific logic.
## Creating a Plugin
A plugin is a regular composer package which ships its code as part of the
package and may also depend on further packages.
### Plugin Package
The package file is the same as any other package file but with the following
requirements:
1. the [type][1] attribute must be `composer-plugin`.
2. the [extra][2] attribute must contain an element `class` defining the
class name of the plugin (including namespace). If a package contains
multiple plugins this can be array of class names.
Additionally you must require the special package called `composer-plugin-api`
to define which composer API versions your plugin is compatible with. The
current composer plugin API version is 1.0.0.
For example
```json
{
"name": "my/plugin-package",
"type": "composer-plugin",
"require": {
"composer-plugin-api": "1.0.0"
}
}
```
### Plugin Class
Every plugin has to supply a class which implements the
[`Composer\Plugin\PluginInterface`][3]. The `activate()` method of the plugin
is called after the plugin is loaded and receives an instance of
[`Composer\Composer`][4] as well as an instance of
[`Composer\IO\IOInterface`][5]. Using these two objects all configuration can
be read and all internal objects and state can be manipulated as desired.
Example:
```php
<?php
namespace phpDocumentor\Composer;
use Composer\Composer;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;
class TemplateInstallerPlugin implements PluginInterface
{
public function activate(Composer $composer, IOInterface $io)
{
$installer = new TemplateInstaller($io, $composer);
$composer->getInstallationManager()->addInstaller($installer);
}
}
```
## Event Handler
Furthermore plugins may implement the
[`Composer\EventDispatcher\EventSubscriberInterface`][6] in order to have its
event handlers automatically registered with the `EventDispatcher` when the
plugin is loaded.
The events available for plugins are:
* **COMMAND**, is called at the beginning of all commands that load plugins.
It provides you with access to the input and output objects of the program.
* **PRE_FILE_DOWNLOAD**, is triggered before files are downloaded and allows
you to manipulate the `RemoteFilesystem` object prior to downloading files
based on the URL to be downloaded.
> A plugin can also subscribe to [script events][7].
Example:
```php
<?php
namespace Naderman\Composer\AWS;
use Composer\Composer;
use Composer\EventDispatcher\EventSubscriberInterface;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;
use Composer\Plugin\PluginEvents;
use Composer\Plugin\PreFileDownloadEvent;
class AwsPlugin implements PluginInterface, EventSubscriberInterface
{
protected $composer;
protected $io;
public function activate(Composer $composer, IOInterface $io)
{
$this->composer = $composer;
$this->io = $io;
}
public static function getSubscribedEvents()
{
return array(
PluginEvents::PRE_FILE_DOWNLOAD => array(
array('onPreFileDownload', 0)
),
);
}
public function onPreFileDownload(PreFileDownloadEvent $event)
{
$protocol = parse_url($event->getProcessedUrl(), PHP_URL_SCHEME);
if ($protocol === 's3') {
$awsClient = new AwsClient($this->io, $this->composer->getConfig());
$s3RemoteFilesystem = new S3RemoteFilesystem($this->io, $event->getRemoteFilesystem()->getOptions(), $awsClient);
$event->setRemoteFilesystem($s3RemoteFilesystem);
}
}
}
```
## Using Plugins
Plugin packages are automatically loaded as soon as they are installed and will
be loaded when composer starts up if they are found in the current project's
list of installed packages. Additionally all plugin packages installed in the
`COMPOSER_HOME` directory using the composer global command are loaded before
local project plugins are loaded.
> You may pass the `--no-plugins` option to composer commands to disable all
> installed commands. This may be particularly helpful if any of the plugins
> causes errors and you wish to update or uninstall it.
[1]: ../04-schema.md#type
[2]: ../04-schema.md#extra
[3]: https://github.com/composer/composer/blob/master/src/Composer/Plugin/PluginInterface.php
[4]: https://github.com/composer/composer/blob/master/src/Composer/Composer.php
[5]: https://github.com/composer/composer/blob/master/src/Composer/IO/IOInterface.php
[6]: https://github.com/composer/composer/blob/master/src/Composer/EventDispatcher/EventSubscriberInterface.php
[7]: ./scripts.md#event-names

View File

@ -1,133 +0,0 @@
<!--
tagline: Script are callbacks that are called before/after installing packages
-->
# Scripts
## What is a script?
A script, in Composer's terms, can either be a PHP callback (defined as a
static method) or any command-line executable command. Scripts are useful
for executing a package's custom code or package-specific commands during
the Composer execution process.
**NOTE: Only scripts defined in the root package's `composer.json` are
executed. If a dependency of the root package specifies its own scripts,
Composer does not execute those additional scripts.**
## Event names
Composer fires the following named events during its execution process:
- **pre-install-cmd**: occurs before the `install` command is executed.
- **post-install-cmd**: occurs after the `install` command is executed.
- **pre-update-cmd**: occurs before the `update` command is executed.
- **post-update-cmd**: occurs after the `update` command is executed.
- **pre-status-cmd**: occurs before the `status` command is executed.
- **post-status-cmd**: occurs after the `status` command is executed.
- **pre-package-install**: occurs before a package is installed.
- **post-package-install**: occurs after a package is installed.
- **pre-package-update**: occurs before a package is updated.
- **post-package-update**: occurs after a package is updated.
- **pre-package-uninstall**: occurs before a package has been uninstalled.
- **post-package-uninstall**: occurs after a package has been uninstalled.
- **pre-autoload-dump**: occurs before the autoloader is dumped, either
during `install`/`update`, or via the `dump-autoload` command.
- **post-autoload-dump**: occurs after the autoloader is dumped, either
during `install`/`update`, or via the `dump-autoload` command.
- **post-root-package-install**: occurs after the root package has been
installed, during the `create-project` command.
- **post-create-project-cmd**: occurs after the `create-project` command is
executed.
- **pre-archive-cmd**: occurs before the `archive` command is executed.
- **post-archive-cmd**: occurs after the `archive` command is executed.
**NOTE: Composer makes no assumptions about the state of your dependencies
prior to `install` or `update`. Therefore, you should not specify scripts that
require Composer-managed dependencies in the `pre-update-cmd` or
`pre-install-cmd` event hooks. If you need to execute scripts prior to
`install` or `update` please make sure they are self-contained within your
root package.**
## Defining scripts
The root JSON object in `composer.json` should have a property called
`"scripts"`, which contains pairs of named events and each event's
corresponding scripts. An event's scripts can be defined as either as a string
(only for a single script) or an array (for single or multiple scripts.)
For any given event:
- Scripts execute in the order defined when their corresponding event is fired.
- An array of scripts wired to a single event can contain both PHP callbacks
and command-line executables commands.
- PHP classes containing defined callbacks must be autoloadable via Composer's
autoload functionality.
Script definition example:
```json
{
"scripts": {
"post-update-cmd": "MyVendor\\MyClass::postUpdate",
"post-package-install": [
"MyVendor\\MyClass::postPackageInstall"
],
"post-install-cmd": [
"MyVendor\\MyClass::warmCache",
"phpunit -c app/"
]
}
}
```
Using the previous definition example, here's the class `MyVendor\MyClass`
that might be used to execute the PHP callbacks:
```php
<?php
namespace MyVendor;
use Composer\Script\Event;
class MyClass
{
public static function postUpdate(Event $event)
{
$composer = $event->getComposer();
// do stuff
}
public static function postPackageInstall(Event $event)
{
$installedPackage = $event->getOperation()->getPackage();
// do stuff
}
public static function warmCache(Event $event)
{
// make cache toasty
}
}
```
When an event is fired, Composer's internal event handler receives a
`Composer\Script\Event` object, which is passed as the first argument to your
PHP callback. This `Event` object has getters for other contextual objects:
- `getComposer()`: returns the current instance of `Composer\Composer`
- `getName()`: returns the name of the event being fired as a string
- `getIO()`: returns the current input/output stream which implements
`Composer\IO\IOInterface` for writing to the console
## Running scripts manually
If you would like to run the scripts for an event manually, the syntax is:
```sh
composer run-script [--dev] [--no-dev] script
```
For example `composer run-script post-install-cmd` will run any **post-install-cmd** scripts that have been defined.

View File

@ -1,153 +0,0 @@
<!--
tagline: Solving problems
-->
# Troubleshooting
This is a list of common pitfalls on using Composer, and how to avoid them.
## General
1. Before asking anyone, run [`composer diagnose`](../03-cli.md#diagnose) to check
for common problems. If it all checks out, proceed to the next steps.
2. When facing any kind of problems using Composer, be sure to **work with the
latest version**. See [self-update](../03-cli.md#self-update) for details.
3. Make sure you have no problems with your setup by running the installer's
checks via `curl -sS https://getcomposer.org/installer | php -- --check`.
4. Ensure you're **installing vendors straight from your `composer.json`** via
`rm -rf vendor && composer update -v` when troubleshooting, excluding any
possible interferences with existing vendor installations or `composer.lock`
entries.
## Package not found
1. Double-check you **don't have typos** in your `composer.json` or repository
branches and tag names.
2. Be sure to **set the right
[minimum-stability](../04-schema.md#minimum-stability)**. To get started or be
sure this is no issue, set `minimum-stability` to "dev".
3. Packages **not coming from [Packagist](https://packagist.org/)** should
always be **defined in the root package** (the package depending on all
vendors).
4. Use the **same vendor and package name** throughout all branches and tags of
your repository, especially when maintaining a third party fork and using
`replace`.
## Package not found on travis-ci.org
1. Check the ["Package not found"](#package-not-found) item above.
2. If the package tested is a dependency of one of its dependencies (cyclic
dependency), the problem might be that composer is not able to detect the version
of the package properly. If it is a git clone it is generally alright and Composer
will detect the version of the current branch, but travis does shallow clones so
that process can fail when testing pull requests and feature branches in general.
The best solution is to define the version you are on via an environment variable
called COMPOSER_ROOT_VERSION. You set it to `dev-master` for example to define
the root package's version as `dev-master`.
Use: `before_script: COMPOSER_ROOT_VERSION=dev-master composer install` to export
the variable for the call to composer.
## Need to override a package version
Let say your project depends on package A which in turn depends on a specific
version of package B (say 0.1) and you need a different version of that
package - version 0.11.
You can fix this by aliasing version 0.11 to 0.1:
composer.json:
```json
{
"require": {
"A": "0.2",
"B": "0.11 as 0.1"
}
}
```
See [aliases](aliases.md) for more information.
## Memory limit errors
If composer shows memory errors on some commands:
`PHP Fatal error: Allowed memory size of XXXXXX bytes exhausted <...>`
The PHP `memory_limit` should be increased.
> **Note:** Composer internally increases the `memory_limit` to `512M`.
> If you have memory issues when using composer, please consider [creating
> an issue ticket](https://github.com/composer/composer/issues) so we can look into it.
To get the current `memory_limit` value, run:
```sh
php -r "echo ini_get('memory_limit').PHP_EOL;"
```
Try increasing the limit in your `php.ini` file (ex. `/etc/php5/cli/php.ini` for
Debian-like systems):
```ini
; Use -1 for unlimited or define an explicit value like 512M
memory_limit = -1
```
Or, you can increase the limit with a command-line argument:
```sh
php -d memory_limit=-1 composer.phar <...>
```
## "The system cannot find the path specified" (Windows)
1. Open regedit.
2. Search for an ```AutoRun``` key inside ```HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor```
or ```HKEY_CURRENT_USER\Software\Microsoft\Command Processor```.
3. Check if it contains any path to non-existent file, if it's the case, just remove them.
## API rate limit and OAuth tokens
Because of GitHub's rate limits on their API it can happen that Composer prompts
for authentication asking your username and password so it can go ahead with its work.
If you would prefer not to provide your GitHub credentials to Composer you can
manually create a token using the following procedure:
1. [Create](https://github.com/settings/applications) an OAuth token on GitHub.
[Read more](https://github.com/blog/1509-personal-api-tokens) on this.
2. Add it to the configuration running `composer config -g github-oauth.github.com <oauthtoken>`
Now Composer should install/update without asking for authentication.
## proc_open(): fork failed errors
If composer shows proc_open() fork failed on some commands:
`PHP Fatal error: Uncaught exception 'ErrorException' with message 'proc_open(): fork failed - Cannot allocate memory' in phar`
This could be happening because the VPS runs out of memory and has no Swap space enabled.
```sh
free -m
total used free shared buffers cached
Mem: 2048 357 1690 0 0 237
-/+ buffers/cache: 119 1928
Swap: 0 0 0
```
To enable the swap you can use for example:
```sh
/bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=1024
/sbin/mkswap /var/swap.1
/sbin/swapon /var/swap.1
```