从官方网站上拉取最新的英文文档到本地。
This commit is contained in:
parent
6384707a14
commit
e712385ede
|
@ -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/
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
||||||
|
|
|
@ -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) →
|
|
@ -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.
|
||||||
|
|
||||||
|
← [Intro](00-intro.md) | [Libraries](02-libraries.md) →
|
|
@ -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.
|
||||||
|
|
||||||
|
← [Basic usage](01-basic-usage.md) | [Command-line interface](03-cli.md) →
|
File diff suppressed because it is too large
Load Diff
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
```
|
||||||
|
|
||||||
← [Schema](04-schema.md) | [Config](06-config.md) →
|
← [Schema](04-schema.md) | [Config](06-config.md) →
|
|
@ -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.
|
||||||
|
|
||||||
|
← [Repositories](05-repositories.md) | [Runtime](07-runtime.md) →
|
|
@ -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`.
|
||||||
|
|
||||||
|
← [Config](06-config.md) | [Community](08-community.md) →
|
|
@ -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.
|
||||||
|
|
||||||
|
|
||||||
|
← [Runtime](07-runtime.md)
|
|
@ -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,7 +60,7 @@ 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`
|
||||||
|
@ -68,7 +72,7 @@ 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.
|
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
|
@ -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.
|
|
@ -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.
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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.
|
|
@ -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
|
||||||
|
```
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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> </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.
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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.
|
|
@ -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`.
|
|
@ -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).
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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`.
|
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"providers": {
|
||||||
|
"bar\/baz": {
|
||||||
|
"sha256": "923363b3c22e73abb2e3fd891c8156dd4d0821a97fd3e428bc910833e3e46dbe"
|
||||||
|
},
|
||||||
|
"foo\/bar": {
|
||||||
|
"sha256": "4baabb3303afa3e34a4d3af18fb138e5f3b79029c1f8d9ab5b477ea15776ba0a"
|
||||||
|
},
|
||||||
|
"gar\/nix": {
|
||||||
|
"sha256": "5d210670cb46c8364c8e3fb449967b9bea558b971e5b082f330ae4f1d484c321"
|
||||||
|
},
|
||||||
|
"qux\/quux": {
|
||||||
|
"sha256": "c142d1a07ca354be46b613f59f1d601923a5a00ccc5fcce50a77ecdd461eb72d"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"packages": [],
|
||||||
|
"providers-url": "\/p\/%package%$%hash%.json",
|
||||||
|
"provider-includes": {
|
||||||
|
"p\/provider-active$1893a061e579543822389ecd12d791c612db0c05e22d90e9286e233cacd86ed8.json": {
|
||||||
|
"sha256": "1893a061e579543822389ecd12d791c612db0c05e22d90e9286e233cacd86ed8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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) →
|
|
|
@ -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.
|
|
||||||
|
|
||||||
← [Intro](00-intro.md) | [Libraries](02-libraries.md) →
|
|
|
@ -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!
|
|
||||||
|
|
||||||
← [Basic usage](01-basic-usage.md) | [Command-line interface](03-cli.md) →
|
|
701
en-doc/03-cli.md
701
en-doc/03-cli.md
|
@ -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.
|
|
||||||
|
|
||||||
← [Libraries](02-libraries.md) | [Schema](04-schema.md) →
|
|
|
@ -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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
← [Repositories](05-repositories.md) | [Community](07-community.md) →
|
|
|
@ -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).
|
|
||||||
|
|
||||||
← [Config](06-config.md)
|
|
|
@ -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`.
|
|
|
@ -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
|
|
|
@ -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.
|
|
|
@ -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
|
|
||||||
```
|
|
Loading…
Reference in New Issue