1
0
Fork 0

Merge branch 'docs-improve'

* docs-improve:
  Docs: cleanup version branches section
  Docs: those/these composer/Composer
  Docs: notice => note
  Docs: Fix shell sample output
  Docs: Add back a second clear note about hardcoded versions in VCS
  Docs: HHVM is not called HipHop
  Docs: versions plural, and update == rm lock&install
  Docs: don't use short forms, it => composer
  Docs: composer.lock lists versions, not constraints
  Docs: superfluous comma & it => Composer
  The confusing part is probably rather constraints and how versions work, not what they are
  Docs: Clarify what "It" stands for
  Finished reworking docs to clarify points about versioning (fixes #6088)
  Updated basic usage and versions pages to clarify how versioning and package resolution works (refs #6088)
  Added some useful overview information about repositories in the Basic Usage documentation.
pull/6093/merge
Nils Adermann 2017-03-08 11:21:05 +01:00
commit 001fe8afcf
4 changed files with 232 additions and 152 deletions

View File

@ -18,7 +18,7 @@ other metadata as well.
### The `require` Key ### The `require` Key
The first (and often only) thing you specify in `composer.json` is the 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 [`require`](04-schema.md#require) key. You are simply telling Composer which
packages your project depends on. packages your project depends on.
```json ```json
@ -33,36 +33,56 @@ 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. **package names** (e.g. `monolog/monolog`) to **version constraints** (e.g.
`1.0.*`). `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, the default package respository. 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. (See more
about Packagist [below](#packagist), or read more about repositories
[here](05-repositories.md).
### Package Names ### Package Names
The package name consists of a vendor name and the project's name. Often these 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 will be identical - the vendor name just exists to prevent naming clashes. For
allows two different people to create a library named `json`, which would then example, it would allow two different people to create a library named `json`.
just be named `igorw/json` and `seldaek/json`. One might be named `igorw/json` while the other might be `seldaek/json`.
Here we are requiring `monolog/monolog`, so the vendor name is the same as the Read more about publishing packages and package naming [here](02-libraries.md).
project's name. For projects with a unique name this is recommended. It also (Note that you can also specify "platform packages" as dependencies, allowing
allows adding more related projects under the same namespace later on. If you you to require certain versions of server software. See
are maintaining a library, this would make it really easy to split it up into [platform packages](#platform-packages) below.)
smaller decoupled parts.
### Package Versions ### Package Version Constraints
In the previous example we were requiring version In our example, we are requesting the Monolog package with the version constraint
[`1.0.*`](http://semver.mwl.be/#?package=monolog%2Fmonolog&version=1.0.*) of [`1.0.*`](http://semver.mwl.be/#?package=monolog%2Fmonolog&version=1.0.*).
Monolog. This means any version in the `1.0` development branch. It is the This means any version in the `1.0` development branch, or any version that is
equivalent of saying versions that match `>=1.0 <1.1`. greater than or equal to 1.0 and less than 1.1 (`>=1.0 <1.1`).
Version constraints can be specified in several ways, read Please read [versions](articles/versions.md) for more in-depth information on
[versions](articles/versions.md) for more in-depth information on this topic. versions, how versions relate to each other, and on version constraints.
### Stability > **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 (more [below](#packagist)).
>
> When Composer finds the right package, either in Packagist 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).
By default only stable releases are taken into consideration. If you would > **Note:** If you are trying to require a package but Composer throws an error
like to also get RC, beta, alpha or dev versions of your dependencies you can > regarding package stability, the version you have specified may not meet your
do so using [stability flags](04-schema.md#package-links). To change that for > default minimum stability requirements. By default only stable releases are taken
all packages instead of doing per dependency you can also use the > into consideration when searching for valid package versions in your VCS.
[minimum-stability](04-schema.md#minimum-stability) setting. >
> 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 ## Installing Dependencies
@ -73,48 +93,63 @@ To install the defined dependencies for your project, just run the
php composer.phar install php composer.phar install
``` ```
This will find the latest version of `monolog/monolog` that matches the When you run this command, one of two things may happen:
supplied version constraint and download it into the `vendor` directory.
It's a convention to put third party code into a directory named `vendor`. ### Installing Without `composer.lock`
In case of Monolog it will put it into `vendor/monolog/monolog`.
If you have never run the command before and there is also no `composer.lock` file present,
Composer simply resolves all dependencies listed in your `composer.json` file and downloads
the latest version of their 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/`. If Monolog listed any dependencies, those would also be in
folders under `vendor/`.
> **Tip:** If you are using git for your project, you probably want to add > **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 > `vendor` in your `.gitignore`. You really don't want to add all of that
> code to your repository. > third-party code to your versioned repository.
You will notice the [`install`](03-cli.md#install) command also created a When Composer has finished installing, it writes all of the packages and the exact versions
`composer.lock` file. of them that it downloaded 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).
## `composer.lock` - The Lock File ### Installing With `composer.lock`
After installing the dependencies, Composer writes the list of the exact This brings us to the second scenario. If there is already a `composer.lock` file as well as a
versions it installed into a `composer.lock` file. This locks the project `composer.json` file when you run `composer install`, it means either you ran the
to those specific versions. `install` command before, or someone else on the project ran the `install` command and
committed the `composer.lock` file to the project (which is good).
**Commit your application's `composer.lock` (along with `composer.json`) Either way, running `install` when a `composer.lock` file is present resolves and installs
into version control.** 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, it ensures that your project does not break because of
unexpected changes in dependencies.
This is important because the [`install`](03-cli.md#install) command checks ### Commit Your `composer.lock` File to Version Control
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 Committing this file to VC is important because it will cause anyone who sets
version of the dependencies. Your CI server, production machines, other up the project to use the exact same
developers in your team, everything and everyone runs on the same dependencies, versions of the dependencies that you are using. Your CI server, production
which mitigates the potential for bugs affecting only some parts of the machines, other developers in your team, everything and everyone runs on the
deployments. Even if you develop alone, in six months when reinstalling the same dependencies, which mitigates the potential for bugs affecting only some
project you can feel confident the dependencies installed are still working even parts of the deployments. Even if you develop alone, in six months when
if your dependencies released many new versions since then. reinstalling the project you can feel confident the dependencies installed are
still working even if your dependencies released many new versions since then.
(See note below about using the `update` command.)
If no `composer.lock` file exists, Composer will read the dependencies and ## Updating Dependencies to their Latest Versions
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 As mentioned above, the `composer.lock` file prevents you from automatically getting
updates automatically. To update to the new version, use the the latest versions of your dependencies. To update to the latest versions, use the
[`update`](03-cli.md#update) command. This will fetch the latest matching [`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 versions (according to your `composer.json` file) and update the lock file
with the new version. with the new versions. (This is equivalent to deleting the `composer.lock` file
and running `install` again.)
```sh ```sh
php composer.phar update php composer.phar update
@ -136,30 +171,50 @@ php composer.phar update monolog/monolog [...]
[Packagist](https://packagist.org/) is the main Composer repository. A Composer [Packagist](https://packagist.org/) is the main Composer repository. A Composer
repository is basically a package source: a place where you can get packages 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 from. Packagist aims to be the central repository that everybody uses. This
means that you can automatically `require` any package that is available there. 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 website](https://packagist.org/) (packagist.org), If you go to the [Packagist website](https://packagist.org/) (packagist.org),
you can browse and search for packages. you can browse and search for packages.
Any open source project using Composer is recommended to publish their 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, 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. 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. `>=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 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.
## Autoloading ## Autoloading
For libraries that specify autoload information, Composer generates a For libraries that specify autoload information, Composer generates a
`vendor/autoload.php` file. You can simply include this file and you will get `vendor/autoload.php` file. You can simply include this file and start
autoloading for free. using the classes that those libraries provide without any extra work:
```php ```php
require __DIR__ . '/vendor/autoload.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 = new Monolog\Logger('name');
$log->pushHandler(new Monolog\Handler\StreamHandler('app.log', Monolog\Logger::WARNING)); $log->pushHandler(new Monolog\Handler\StreamHandler('app.log', Monolog\Logger::WARNING));
$log->addWarning('Foo'); $log->addWarning('Foo');

View File

@ -8,7 +8,7 @@ Composer.
As soon as you have a `composer.json` in a directory, that directory is a 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 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 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. 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 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`: this by adding the [`name`](04-schema.md#name) property in `composer.json`:
@ -29,40 +29,18 @@ name. Supplying a vendor name is mandatory.
> username is usually a good bet. While package names are case insensitive, the > username is usually a good bet. While package names are case insensitive, the
> convention is all lowercase and dashes for word separation. > convention is all lowercase and dashes for word separation.
## Platform packages ## Library Versioning
Composer has platform packages, which are virtual packages for things that are In the vast majority of cases, you will be maintaining your library using some
installed on the system but are not actually installable by Composer. This sort of version control system like git, svn, hg or fossil. In these cases,
includes PHP itself, PHP extensions and some system libraries. 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.)
* `php` represents the PHP version of the user, allowing you to apply If you are maintaining packages by hand (i.e., without a VCS), you'll need to
constraints, e.g. `>=5.4.0`. To require a 64bit version of php, you can specify the version explicitly by adding a `version` value in your `composer.json`
require the `php-64bit` package. file:
* `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, fossil) 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 ```json
{ {
@ -70,57 +48,19 @@ you can just add a `version` field:
} }
``` ```
> **Note:** You should avoid specifying the version field explicitly, because > **Note:** When you add a hardcoded version to a VCS, the version will conflict
> for tags the value must match the tag name. > with tag names. Composer will not be able to determine the version number.
### Tags ### VCS Versioning
For every tag that looks like a version, a package version of that tag will be Composer uses your VCS's branch and tag features to resolve the version
created. It should match 'X.Y.Z' or 'vX.Y.Z', with an optional suffix of constraints you specify in your `require` field to specific sets of files.
`-patch` (`-p`), `-alpha` (`-a`), `-beta` (`-b`) or `-RC`. The suffix can also When determining valid available versions, Composer looks at all of your tags
be followed by a number. and branches and translates their names into an internal list of options that
it then matches against the version constraint you provided.
Here are a few examples of valid tag names: For more on how Composer treats tags and branches and how it resolves package
version constraints, read the [versions](articles/versions.md) article.
- 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 ## Lock file

View File

@ -255,7 +255,8 @@ 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:
@ -688,9 +689,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`.

View File

@ -1,10 +1,93 @@
<!-- <!--
tagline: Version constraints explained. tagline: Versions explained.
--> -->
# Versions # Versions
## Basic 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 simply 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:*
```sh
~/my-library$ git branch
v1
v2
my-feature
nother-feature
~/my-library$ git tag
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_vocabulary)).
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 just 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 just 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.
### 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 Basic 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 ### Exact
@ -87,7 +170,7 @@ library code.
Example: `^1.2.3` Example: `^1.2.3`
## Stability ## Stability Constraints
If you are using a constraint that does not explicitly define a stability, If you are using a constraint that does not explicitly define a stability,
Composer will default internally to `-dev` or `-stable`, depending on the Composer will default internally to `-dev` or `-stable`, depending on the
@ -113,8 +196,9 @@ Examples:
To allow various stabilities without enforcing them at the constraint level To allow various stabilities without enforcing them at the constraint level
however, you may use [stability-flags](../04-schema.md#package-links) like however, you may use [stability-flags](../04-schema.md#package-links) like
`@<stability>` (e.g. `@dev`) to let composer know that a given package `@<stability>` (e.g. `@dev`) to let composer know that a given package
can be installed in a different stability than your default can be installed in a different stability than your default minimum-stability
[minimum-stability](../04-schema.md#minimum-stability) setting. setting. All available stability flags are listed on the minimum-stability
section of the [schema page](../04-schema.md#minimum-stability).
## Test version constraints ## Test version constraints