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.
main
Nils Adermann 7 years ago
commit 001fe8afcf

@ -18,7 +18,7 @@ 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
[`require`](04-schema.md#require) key. You are simply telling Composer which
packages your project depends on.
```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.
`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
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.
will be identical - the vendor name just 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 [here](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
[`1.0.*`](http://semver.mwl.be/#?package=monolog%2Fmonolog&version=1.0.*).
This means any version in the `1.0` development branch, or any version that is
greater than or equal to 1.0 and less than 1.1 (`>=1.0 <1.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 (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).
> **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
@ -73,48 +93,63 @@ To install the defined dependencies for your project, just run the
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.**
When you run this command, one of two things may happen:
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).
### Installing Without `composer.lock`
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 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/`.
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
> **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.
When Composer has finished installing, it writes all of the packages and the exact versions
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).
### Installing With `composer.lock`
This brings us to the second scenario. If there is already a `composer.lock` file as well as a
`composer.json` file when you run `composer install`, it means either you ran the
`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).
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, it ensures that your project does not break because of
unexpected changes in dependencies.
### Commit Your `composer.lock` File to Version Control
Committing this file to VC 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 the dependencies installed are
still working even if your dependencies released many new versions since then.
(See note below about using the `update` command.)
## 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) command. This will fetch the latest matching
versions (according to your `composer.json` file) and also update the lock file
with the new version.
versions (according to your `composer.json` file) and update the lock file
with the new versions. (This is equivalent to deleting the `composer.lock` file
and running `install` again.)
```sh
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
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.
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),
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,
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. `>=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
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.
`vendor/autoload.php` file. You can simply include this file and start
using the classes that those libraries provide without any extra work:
```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');

@ -8,7 +8,7 @@ Composer.
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.
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`:
@ -29,40 +29,18 @@ name. Supplying a vendor name is mandatory.
> username is usually a good bet. While package names are case insensitive, the
> 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
installed on the system but are not actually installable by Composer. This
includes PHP itself, PHP extensions and some system libraries.
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.)
* `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, 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:
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
{
@ -70,57 +48,19 @@ you can just add a `version` field:
}
```
> **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.
> **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.
### Aliases
### VCS Versioning
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.
Composer uses your VCS's branch and tag features to resolve the version
constraints you specify in your `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.
See [Aliases](articles/aliases.md) for more information.
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

@ -255,7 +255,8 @@ Optional.
### Package links
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:
@ -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
stable than the `minimum-stability` setting will be ignored when resolving
your project dependencies. Specific changes to the stability requirements of
a given package can be done in `require` or `require-dev` (see
[package links](#package-links)).
your project dependencies. (Note that you can also specify stability requirements
on a per-package basis using stability flags in the version constraints that you
specify in a `require` block (see [package links](#package-links) for more details).
Available options (in order of stability) are `dev`, `alpha`, `beta`, `RC`,
and `stable`.

@ -1,10 +1,93 @@
<!--
tagline: Version constraints explained.
tagline: Versions explained.
-->
# 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
@ -87,7 +170,7 @@ library code.
Example: `^1.2.3`
## Stability
## 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
@ -113,8 +196,9 @@ Examples:
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](../04-schema.md#minimum-stability) setting.
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).
## Test version constraints

Loading…
Cancel
Save