1
0
Fork 0

Finished reworking docs to clarify points about versioning (fixes #6088)

pull/6097/head
Kael Shipman 2017-01-23 13:06:51 -06:00
parent a0d2934946
commit c8c7619a4a
4 changed files with 118 additions and 156 deletions

View File

@ -48,7 +48,10 @@ 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`. 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`. 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) 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 ### Package Version Constraints
@ -57,8 +60,8 @@ In our example, we're requesting the Monolog package with the version constraint
This means any version in the `1.0` development branch, or any version that is 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`). greater than or equal to 1.0 and less than 1.1 (`>=1.0 <1.1`).
Version can be a little confusing in Composer, and version constraints can be specified (What the term "version" actually means can be a little confusing in Composer.
in several ways. Please read [versions](articles/versions.md) for more in-depth information. Please read [versions](articles/versions.md) for more in-depth information.)
> **How does Composer download the right files?** When you specify a dependency in > **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've requested > `composer.json`, Composer, first takes the name of the package that you've requested
@ -69,7 +72,7 @@ in several ways. Please read [versions](articles/versions.md) for more in-depth
> >
> When it finds the right package, either in Packagist or in a repo you've specified, > When it finds the right package, either in Packagist or in a repo you've specified,
> it then uses the versioning features of the package's VCS (i.e., branches and tags) > 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 you've specified. Be sure to read > to attempt to find the best match for the version constraint you've specified. Be sure to read
> about versions and package resolution in the [versions article](articles/versions.md). > about versions and package resolution in the [versions article](articles/versions.md).
> **Note:** If you're trying to require a package but Composer throws an error > **Note:** If you're trying to require a package but Composer throws an error
@ -108,7 +111,8 @@ folders under `vendor/`.
When Composer has finished installing, it writes all of the packages and the exact versions 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 of them that it downloaded to the `composer.lock` file, locking the project to those specific
versions. 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` ### Installing With `composer.lock`
@ -122,7 +126,7 @@ all dependencies that you've listed in `composer.json`, but it uses the version
that it finds in `composer.lock` to ensure that the package versions are consistent for everyone that it finds in `composer.lock` to ensure that the package versions are consistent for everyone
working on your project. The result is that you have all dependencies requested by your working on your project. The result is that you have all dependencies requested by your
`composer.json` file, but that they may not all be at the very latest available versions (since `composer.json` file, but that they may not all be at the very latest available versions (since
some of the dependencies listed in the `composer.lock` file may have released new versions since some of the dependencies listed in the `composer.lock` file may have released newer versions since
the file was created). This is by design, as it ensures that your project never breaks because of the file was created). This is by design, as it ensures that your project never breaks because of
unexpected changes in dependencies. unexpected changes in dependencies.
@ -176,6 +180,31 @@ 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 doesn't 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 (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.
## Autoloading ## Autoloading
For libraries that specify autoload information, Composer generates a For libraries that specify autoload information, Composer generates a

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,16 @@ you can just add a `version` field:
} }
``` ```
> **Note:** You should avoid specifying the version field explicitly, because ### VCS Versioning
> for tags the value must match the tag name.
### Tags 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've provided.
For every tag that looks like a version, a package version of that tag will be For more on how Composer treats tags and branches and how it resolves package
created. It should match 'X.Y.Z' or 'vX.Y.Z', with an optional suffix of version constraints, read the [versions](articles/versions.md) article.
`-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 ## 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:
@ -680,9 +681,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

@ -14,84 +14,79 @@ 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 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. asking for a single, known set of files, and you always get the same files back.
In Composer, what's usually referred to casually as a version -- that is, 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 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 `1.2.*`) -- is actually more specifically a version constraint. Composer
uses version constraints to figure out which refs in a VCS it should be uses version constraints to figure out which refs in a VCS it should be
checking out. 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`).
### Tags vs Branches ## VCS Tags and Branches
*For the following discussion, let's assume the following sample library
repository:*
```sh
~/my-library$ git branch
~/my-library$
~/my-library$ v1
~/my-library$ v2
~/my-library$ my-feature
~/my-library$ nother-feature
~/my-library$
~/my-library$ git tag
~/my-library$
~/my-library$ v1.0
~/my-library$ v1.0.1
~/my-library$ v1.0.2
~/my-library$ v1.1-BETA
~/my-library$ v1.1-RC1
~/my-library$ v1.1-RC2
~/my-library$ v1.1
~/my-library$ v1.1.1
~/my-library$ v2.0-BETA
~/my-library$ v2.0-RC1
~/my-library$ v2.0
~/my-library$ v2.0.1
~/my-library$ v2.0.2
```
### Tags
Normally, Composer deals with tags (as opposed to branches -- if you don't Normally, Composer deals with tags (as opposed to branches -- if you don't
know what this means, read up on know what this means, read up on
[version control systems](https://en.wikipedia.org/wiki/Version_control#Common_vocabulary)). [version control systems](https://en.wikipedia.org/wiki/Version_control#Common_vocabulary)).
When referencing a tag, it may reference a specific tag (e.g., `1.1`) or it When you write a version constraint, it may reference a specific tag (e.g.,
may reference a valid range of tags (e.g., `>=1.1 <2.0`). Furthermore, you `1.1`) or it may reference a valid range of tags (e.g., `>=1.1 <2.0`, or
can add "stability specifiers" to let Composer know that you are or aren't `~4.0`). To resolve these constraints, Composer first asks the VCS to list
interested in certain tags, like alpha releases, beta releases, or release all available tags, then creates an internal list of available versions based
candidates, even if they're technically within the numeric range specified on these tags. In the above example, composer's internal list includes versions
by the version constraint (these releases are usually considered "unstable", `1.0`, `1.0.1`, `1.0.2`, the beta release of `1.1`, the first and second
hence the term "stability specifier"). 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.)
If you want Composer to check out a branch instead of a tag, you use the When it has a complete list of available versions from your VCS, it then
special syntax described [here](02-libraries.md#branches). In short, if finds the highest version that matches all version constraints in your project
you're checking out a branch, it's assumed that you want to *work* on the (it's possible that other packages require more specific versions of the
branch and Composer simply clones the repo into the correct place in your library than you do, so the version it chooses may not always be the highest
`vendor` directory. (For tags, it just copies the right files without actually available version) and it downloads a zip archive of that tag to unpack in the
cloning the repo.) This can be very convenient for libraries under development, correct location in your `vendor` directory.
as you can make changes to the dependency files your project is actually using
and still commit them to their respective repos as patches or other updates.
Let's look at an example. Suppose you've published a library whose git repo ### Branches
looks like this:
```sh If you want Composer to check out a branch instead of a tag, there's a special syntax. 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.) To get Composer to do this, you need to point it to the branch using the special `dev-*` prefix (or sometimes suffix; see below).
$ git branch
$
$ v1
$ v2
$ my-feature
$ nother-feature
$
$ 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
```
Now assume you've got a project that depends on this library and you've been In the above example, if I wanted to check out the `my-feature` branch, I would specify `dev-my-feature` as the version constraint in my `require` clause. This would result in Composer cloning the `my-library` repository into my `vendor` directory and checking out the `my-feature` branch.
running `composer update` in that project since the `v1.0` release. If you
specified `~1.0` in Composer (the tilde modifier, among others, is detailed
below), and you don't add a [`minimum-stability`](04-schema.md#minimum-stability)
key elsewhere in the file, then Composer will default to "stable" as a minimum
stability setting and you will receive only the `v1.0`, `v1.0.1`, `v1.0.2`,
`v1.1` and `v1.1.1` tags as the tags are created in your VCS. If you set the
`minimum-stability` key to `RC`, you would receive the aforementioned tags as
they're released, plus the `v1.1-RC1` and `v1.1-RC2` tags, but not `v1.1-BETA`.
(You can see the available stability constraints in order on the
[schema page](04-schema.md#minimum-stability).
The final important detail here is how branches are handled. In git, a branch The exception to this is when branch names look like versions. In that case, 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`. There are two things to notice here. First, the `.x`: this is an arbitrary string that Composer requires us to append 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`). Second, notice that in the case of a branch with a version-like name (`v1`, in this case), you append `-dev` as a suffix, rather than `dev-` as a prefix.
simply represents a series of commits, with the current "HEAD" of the branch
pointing at the most recent in the chain. A tag is a specific commit, independent
of branch. By default composer checks out the tag that best matches the version
constraint you've specified. However, if you specify the version constraint as
"v1-dev" (or sometimes "dev-my-branch" -- see the [libraries page](02-libraries.md#branches)
for syntax details), then Composer will clone the repo into your `vendor`
directory, checking out the `v1` branch.
## Basic Version Constraints ### 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, notice that the library released a beta and two release candidates for version `1.1` before the final official release. In order to receive those versions when we run `composer install` or `composer update`, we have to explicitly tell composer that we're 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 Now that you have an idea of how Composer sees versions, let's talk about how
to specify version constraints for your project dependencies. to specify version constraints for your project dependencies.