Browse Source

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

Kael Shipman 8 years ago
parent
commit
c8c7619a4a
4 changed files with 122 additions and 160 deletions
  1. 35 6
      doc/01-basic-usage.md
  2. 19 82
      doc/02-libraries.md
  3. 5 4
      doc/04-schema.md
  4. 63 68
      doc/articles/versions.md

+ 35 - 6
doc/01-basic-usage.md

@@ -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
-in several ways. Please read [versions](articles/versions.md) for more in-depth information.
+(What the term "version" actually means can be a little confusing in Composer.
+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

+ 19 - 82
doc/02-libraries.md

@@ -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
-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
 ```json
 {
 {
@@ -70,57 +48,16 @@ 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.
-
-### 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've 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
 ## Lock file
 
 

+ 5 - 4
doc/04-schema.md

@@ -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
-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`,
 Available options (in order of stability) are `dev`, `alpha`, `beta`, `RC`,
 and `stable`.
 and `stable`.

+ 63 - 68
doc/articles/versions.md

@@ -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
-may reference a valid range of tags (e.g., `>=1.1 <2.0`). Furthermore, you
-can add "stability specifiers" to let Composer know that you are or aren't
-interested in certain tags, like alpha releases, beta releases, or release
-candidates, even if they're technically within the numeric range specified
-by the version constraint (these releases are usually considered "unstable",
-hence the term "stability specifier"). 
-
-If you want Composer to check out a branch instead of a tag, you use the
-special syntax described [here](02-libraries.md#branches). In short, if
-you're checking out a branch, it's assumed that you want to *work* on the
-branch and Composer simply clones the repo into the correct place in your
-`vendor` directory. (For tags, it just copies the right files without actually
-cloning the repo.) This can be very convenient for libraries under development,
-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
-looks like this:
+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.)
 
 
-```sh
-$ 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
-```
+When it 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, 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). 
+
+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.
+
+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.
+
+### 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).
 
 
-Now assume you've got a project that depends on this library and you've been
-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
-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
+## 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.