530 lines
18 KiB
Markdown
530 lines
18 KiB
Markdown
# Repositories
|
|
|
|
This chapter will explain the concept of packages and repositories, what kinds
|
|
of repositories are available, and how they work.
|
|
|
|
## Concepts
|
|
|
|
Before we look at the different types of repositories that exist, we need to
|
|
understand some of the basic concepts that composer is built on.
|
|
|
|
### Package
|
|
|
|
Composer is a dependency manager. It installs packages locally. A package is
|
|
essentially just a directory containing something. In this case it is PHP
|
|
code, but in theory it could be anything. And it contains a package
|
|
description which has a name and a version. The name and the version are used
|
|
to identify the package.
|
|
|
|
In fact, internally composer sees every version as a separate package. While
|
|
this distinction does not matter when you are using composer, it's quite
|
|
important when you want to change it.
|
|
|
|
In addition to the name and the version, there is useful metadata. The information
|
|
most relevant for installation is the source definition, which describes where
|
|
to get the package contents. The package data points to the contents of the
|
|
package. And there are two options here: dist and source.
|
|
|
|
**Dist:** The dist is a packaged version of the package data. Usually a
|
|
released version, usually a stable release.
|
|
|
|
**Source:** The source is used for development. This will usually originate
|
|
from a source code repository, such as git. You can fetch this when you want
|
|
to modify the downloaded package.
|
|
|
|
Packages can supply either of these, or even both. Depending on certain
|
|
factors, such as user-supplied options and stability of the package, one will
|
|
be preferred.
|
|
|
|
### Repository
|
|
|
|
A repository is a package source. It's a list of packages/versions. Composer
|
|
will look in all your repositories to find the packages your project requires.
|
|
|
|
By default only the Packagist repository is registered in Composer. You can
|
|
add more repositories to your project by declaring them in `composer.json`.
|
|
|
|
Repositories are only available to the root package and the repositories
|
|
defined in your dependencies will not be loaded. Read the
|
|
[FAQ entry](faqs/why-can't-composer-load-repositories-recursively.md) if you
|
|
want to learn why.
|
|
|
|
## Types
|
|
|
|
### Composer
|
|
|
|
The main repository type is the `composer` repository. It uses a single
|
|
`packages.json` file that contains all of the package metadata.
|
|
|
|
This is also the repository type that packagist uses. To reference a
|
|
`composer` repository, just supply the path before the `packages.json` file.
|
|
In case of packagist, that file is located at `/packages.json`, so the URL of
|
|
the repository would be `packagist.org`. For `example.org/packages.json` the
|
|
repository URL would be `example.org`.
|
|
|
|
#### packages
|
|
|
|
The only required field is `packages`. The JSON structure is as follows:
|
|
|
|
{
|
|
"packages": {
|
|
"vendor/package-name": {
|
|
"dev-master": { @composer.json },
|
|
"1.0.x-dev": { @composer.json },
|
|
"0.0.1": { @composer.json },
|
|
"1.0.0": { @composer.json }
|
|
}
|
|
}
|
|
}
|
|
|
|
The `@composer.json` marker would be the contents of the `composer.json` from
|
|
that package version including as a minimum:
|
|
|
|
* name
|
|
* version
|
|
* dist or source
|
|
|
|
Here is a minimal package definition:
|
|
|
|
{
|
|
"name": "smarty/smarty",
|
|
"version": "3.1.7",
|
|
"dist": {
|
|
"url": "http://www.smarty.net/files/Smarty-3.1.7.zip",
|
|
"type": "zip"
|
|
}
|
|
}
|
|
|
|
It may include any of the other fields specified in the [schema](04-schema.md).
|
|
|
|
#### notify-batch
|
|
|
|
The `notify-batch` field allows you to specify an URL that will be called
|
|
every time a user installs a package. The URL can be either an absolute path
|
|
(that will use the same domain as the repository) or a fully qualified URL.
|
|
|
|
An example value:
|
|
|
|
{
|
|
"notify-batch": "/downloads/"
|
|
}
|
|
|
|
For `example.org/packages.json` containing a `monolog/monolog` package, this
|
|
would send a `POST` request to `example.org/downloads/` with following
|
|
JSON request body:
|
|
|
|
{
|
|
"downloads": [
|
|
{"name": "monolog/monolog", "version": "1.2.1.0"},
|
|
]
|
|
}
|
|
|
|
The version field will contain the normalized representation of the version
|
|
number.
|
|
|
|
This field is optional.
|
|
|
|
#### includes
|
|
|
|
For larger repositories it is possible to split the `packages.json` into
|
|
multiple files. The `includes` field allows you to reference these additional
|
|
files.
|
|
|
|
An example:
|
|
|
|
{
|
|
"includes": {
|
|
"packages-2011.json": {
|
|
"sha1": "525a85fb37edd1ad71040d429928c2c0edec9d17"
|
|
},
|
|
"packages-2012-01.json": {
|
|
"sha1": "897cde726f8a3918faf27c803b336da223d400dd"
|
|
},
|
|
"packages-2012-02.json": {
|
|
"sha1": "26f911ad717da26bbcac3f8f435280d13917efa5"
|
|
}
|
|
}
|
|
}
|
|
|
|
The SHA-1 sum of the file allows it to be cached and only re-requested if the
|
|
hash changed.
|
|
|
|
This field is optional. You probably don't need it for your own custom
|
|
repository.
|
|
|
|
#### provider-includes and providers-url
|
|
|
|
For very large repositories like packagist.org using the so-called provider
|
|
files is the preferred method. The `provider-includes` field allows you to
|
|
list a set of files that list package names provided by this repository. The
|
|
hash should be a sha256 of the files in this case.
|
|
|
|
The `providers-url` describes how provider files are found on the server. It
|
|
is an absolute path from the repository root.
|
|
|
|
An example:
|
|
|
|
{
|
|
"provider-includes": {
|
|
"providers-a.json": {
|
|
"sha256": "f5b4bc0b354108ef08614e569c1ed01a2782e67641744864a74e788982886f4c"
|
|
},
|
|
"providers-b.json": {
|
|
"sha256": "b38372163fac0573053536f5b8ef11b86f804ea8b016d239e706191203f6efac"
|
|
}
|
|
},
|
|
"providers-url": "/p/%package%$%hash%.json"
|
|
}
|
|
|
|
Those files contain lists of package names and hashes to verify the file
|
|
integrity, for example:
|
|
|
|
{
|
|
"providers": {
|
|
"acme/foo": {
|
|
"sha256": "38968de1305c2e17f4de33aea164515bc787c42c7e2d6e25948539a14268bb82"
|
|
},
|
|
"acme/bar": {
|
|
"sha256": "4dd24c930bd6e1103251306d6336ac813b563a220d9ca14f4743c032fb047233"
|
|
}
|
|
}
|
|
}
|
|
|
|
The file above declares that acme/foo and acme/bar can be found in this
|
|
repository, by loading the file referenced by `providers-url`, replacing
|
|
`%name%` by the package name and `%hash%` by the sha256 field. Those files
|
|
themselves just contain package definitions as described [above](#packages).
|
|
|
|
This field is optional. You probably don't need it for your own custom
|
|
repository.
|
|
|
|
#### stream options
|
|
|
|
The `packages.json` file is loaded using a PHP stream. You can set extra options
|
|
on that stream using the `options` parameter. You can set any valid PHP stream
|
|
context option. See [Context options and parameters](http://php.net/manual/en/context.php)
|
|
for more information.
|
|
|
|
### VCS
|
|
|
|
VCS stands for version control system. This includes versioning systems like
|
|
git, svn or hg. Composer has a repository type for installing packages from
|
|
these systems.
|
|
|
|
#### Loading a package from a VCS repository
|
|
|
|
There are a few use cases for this. The most common one is maintaining your
|
|
own fork of a third party library. If you are using a certain library for your
|
|
project and you decide to change something in the library, you will want your
|
|
project to use the patched version. If the library is on GitHub (this is the
|
|
case most of the time), you can simply fork it there and push your changes to
|
|
your fork. After that you update the project's `composer.json`. All you have
|
|
to do is add your fork as a repository and update the version constraint to
|
|
point to your custom branch. For version constraint naming conventions see
|
|
[Libraries](02-libraries.md) for more information.
|
|
|
|
Example assuming you patched monolog to fix a bug in the `bugfix` branch:
|
|
|
|
{
|
|
"repositories": [
|
|
{
|
|
"type": "vcs",
|
|
"url": "https://github.com/igorw/monolog"
|
|
}
|
|
],
|
|
"require": {
|
|
"monolog/monolog": "dev-bugfix"
|
|
}
|
|
}
|
|
|
|
When you run `php composer.phar update`, you should get your modified version
|
|
of `monolog/monolog` instead of the one from packagist.
|
|
|
|
It is possible to inline-alias a package constraint so that it matches a
|
|
constraint that it otherwise would not. For more information [see the
|
|
aliases article](articles/aliases.md).
|
|
|
|
#### Using private repositories
|
|
|
|
Exactly the same solution allows you to work with your private repositories at
|
|
GitHub and BitBucket:
|
|
|
|
{
|
|
"require": {
|
|
"vendor/my-private-repo": "dev-master"
|
|
},
|
|
"repositories": [
|
|
{
|
|
"type": "vcs",
|
|
"url": "git@bitbucket.org:vendor/my-private-repo.git"
|
|
}
|
|
]
|
|
}
|
|
|
|
The only requirement is the installation of SSH keys for a git client.
|
|
|
|
#### Git alternatives
|
|
|
|
Git is not the only version control system supported by the VCS repository.
|
|
The following are supported:
|
|
|
|
* **Git:** [git-scm.com](http://git-scm.com)
|
|
* **Subversion:** [subversion.apache.org](http://subversion.apache.org)
|
|
* **Mercurial:** [mercurial.selenic.com](http://mercurial.selenic.com)
|
|
|
|
To get packages from these systems you need to have their respective clients
|
|
installed. That can be inconvenient. And for this reason there is special
|
|
support for GitHub and BitBucket that use the APIs provided by these sites, to
|
|
fetch the packages without having to install the version control system. The
|
|
VCS repository provides `dist`s for them that fetch the packages as zips.
|
|
|
|
* **GitHub:** [github.com](https://github.com) (Git)
|
|
* **BitBucket:** [bitbucket.org](https://bitbucket.org) (Git and Mercurial)
|
|
|
|
The VCS driver to be used is detected automatically based on the URL. However,
|
|
should you need to specify one for whatever reason, you can use `git`, `svn` or
|
|
`hg` as the repository type instead of `vcs`.
|
|
|
|
#### Subversion Options
|
|
|
|
Since Subversion has no native concept of branches and tags, Composer assumes
|
|
by default that code is located in `$url/trunk`, `$url/branches` and
|
|
`$url/tags`. If your repository has a different layout you can change those
|
|
values. For example if you used capitalized names you could configure the
|
|
repository like this:
|
|
|
|
{
|
|
"repositories": [
|
|
{
|
|
"type": "vcs",
|
|
"url": "http://svn.example.org/projectA/",
|
|
"trunk-path": "Trunk",
|
|
"branches-path": "Branches",
|
|
"tags-path": "Tags"
|
|
}
|
|
]
|
|
}
|
|
|
|
If you have no branches or tags directory you can disable them entirely by
|
|
setting the `branches-path` or `tags-path` to `false`.
|
|
|
|
### PEAR
|
|
|
|
It is possible to install packages from any PEAR channel by using the `pear`
|
|
repository. Composer will prefix all package names with `pear-{channelName}/` to
|
|
avoid conflicts. All packages are also aliased with prefix `pear-{channelAlias}/`
|
|
|
|
Example using `pear2.php.net`:
|
|
|
|
{
|
|
"repositories": [
|
|
{
|
|
"type": "pear",
|
|
"url": "http://pear2.php.net"
|
|
}
|
|
],
|
|
"require": {
|
|
"pear-pear2.php.net/PEAR2_Text_Markdown": "*",
|
|
"pear-pear2/PEAR2_HTTP_Request": "*"
|
|
}
|
|
}
|
|
|
|
In this case the short name of the channel is `pear2`, so the
|
|
`PEAR2_HTTP_Request` package name becomes `pear-pear2/PEAR2_HTTP_Request`.
|
|
|
|
> **Note:** The `pear` repository requires doing quite a few requests per
|
|
> package, so this may considerably slow down the installation process.
|
|
|
|
#### Custom vendor alias
|
|
|
|
It is possible to alias PEAR channel packages with a custom vendor name.
|
|
|
|
Example:
|
|
|
|
Suppose you have a private PEAR repository and wish to use Composer to
|
|
incorporate dependencies from a VCS. Your PEAR repository contains the
|
|
following packages:
|
|
|
|
* `BasePackage`
|
|
* `IntermediatePackage`, which depends on `BasePackage`
|
|
* `TopLevelPackage1` and `TopLevelPackage2` which both depend on `IntermediatePackage`
|
|
|
|
Without a vendor alias, Composer will use the PEAR channel name as the
|
|
vendor portion of the package name:
|
|
|
|
* `pear-pear.foobar.repo/BasePackage`
|
|
* `pear-pear.foobar.repo/IntermediatePackage`
|
|
* `pear-pear.foobar.repo/TopLevelPackage1`
|
|
* `pear-pear.foobar.repo/TopLevelPackage2`
|
|
|
|
Suppose at a later time you wish to migrate your PEAR packages to a
|
|
Composer repository and naming scheme, and adopt the vendor name of `foobar`.
|
|
Projects using your PEAR packages would not see the updated packages, since
|
|
they have a different vendor name (`foobar/IntermediatePackage` vs
|
|
`pear-pear.foobar.repo/IntermediatePackage`).
|
|
|
|
By specifying `vendor-alias` for the PEAR repository from the start, you can
|
|
avoid this scenario and future-proof your package names.
|
|
|
|
To illustrate, the following example would get the `BasePackage`,
|
|
`TopLevelPackage1`, and `TopLevelPackage2` packages from your PEAR repository
|
|
and `IntermediatePackage` from a Github repository:
|
|
|
|
{
|
|
"repositories": [
|
|
{
|
|
"type": "git",
|
|
"url": "https://github.com/foobar/intermediate.git"
|
|
},
|
|
{
|
|
"type": "pear",
|
|
"url": "http://pear.foobar.repo",
|
|
"vendor-alias": "foobar"
|
|
}
|
|
],
|
|
"require": {
|
|
"foobar/TopLevelPackage1": "*",
|
|
"foobar/TopLevelPackage2": "*"
|
|
}
|
|
}
|
|
|
|
### Package
|
|
|
|
If you want to use a project that does not support composer through any of the
|
|
means above, you still can define the package yourself by using a `package`
|
|
repository.
|
|
|
|
Basically, you define the same information that is included in the `composer`
|
|
repository's `packages.json`, but only for a single package. Again, the
|
|
minimum required fields are `name`, `version`, and either of `dist` or
|
|
`source`.
|
|
|
|
Here is an example for the smarty template engine:
|
|
|
|
{
|
|
"repositories": [
|
|
{
|
|
"type": "package",
|
|
"package": {
|
|
"name": "smarty/smarty",
|
|
"version": "3.1.7",
|
|
"dist": {
|
|
"url": "http://www.smarty.net/files/Smarty-3.1.7.zip",
|
|
"type": "zip"
|
|
},
|
|
"source": {
|
|
"url": "http://smarty-php.googlecode.com/svn/",
|
|
"type": "svn",
|
|
"reference": "tags/Smarty_3_1_7/distribution/"
|
|
},
|
|
"autoload": {
|
|
"classmap": ["libs/"]
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"require": {
|
|
"smarty/smarty": "3.1.*"
|
|
}
|
|
}
|
|
|
|
Typically you would leave the source part off, as you don't really need it.
|
|
|
|
## Hosting your own
|
|
|
|
While you will probably want to put your packages on packagist most of the time,
|
|
there are some use cases for hosting your own repository.
|
|
|
|
* **Private company packages:** If you are part of a company that uses composer
|
|
for their packages internally, you might want to keep those packages private.
|
|
|
|
* **Separate ecosystem:** If you have a project which has its own ecosystem,
|
|
and the packages aren't really reusable by the greater PHP community, you
|
|
might want to keep them separate to packagist. An example of this would be
|
|
wordpress plugins.
|
|
|
|
When hosting your own package repository it is recommended to use a `composer`
|
|
one. This is type that is native to composer and yields the best performance.
|
|
|
|
There are a few tools that can help you create a `composer` repository.
|
|
|
|
### Packagist
|
|
|
|
The underlying application used by packagist is open source. This means that you
|
|
can just install your own copy of packagist, re-brand, and use it. It's really
|
|
quite straight-forward to do. However due to its size and complexity, for most
|
|
small and medium sized companies willing to track a few packages will be better
|
|
off using Satis.
|
|
|
|
Packagist is a Symfony2 application, and it is [available on
|
|
GitHub](https://github.com/composer/packagist). It uses composer internally and
|
|
acts as a proxy between VCS repositories and the composer users. It holds a list
|
|
of all VCS packages, periodically re-crawls them, and exposes them as a composer
|
|
repository.
|
|
|
|
To set your own copy, simply follow the instructions from the [packagist
|
|
github repository](https://github.com/composer/packagist).
|
|
|
|
### Satis
|
|
|
|
Satis is a static `composer` repository generator. It is a bit like an ultra-
|
|
lightweight, static file-based version of packagist.
|
|
|
|
You give it a `composer.json` containing repositories, typically VCS and
|
|
package repository definitions. It will fetch all the packages that are
|
|
`require`d and dump a `packages.json` that is your `composer` repository.
|
|
|
|
Check [the satis GitHub repository](https://github.com/composer/satis) and
|
|
the [Satis article](articles/handling-private-packages-with-satis.md) for more
|
|
information.
|
|
|
|
### Artifact
|
|
|
|
There are some cases, when there is no ability to have one of the previously
|
|
mentioned repository types online, even the VCS one. Typical example could be
|
|
cross-organisation library exchange through built artifacts. Of course, most
|
|
of the times they are private. To simplify maintainance, one can simply specify
|
|
repository of type `artifact` with a folder containing ZIP archives of those
|
|
private packages:
|
|
|
|
{
|
|
"repositories": [
|
|
{
|
|
"type": "artifact",
|
|
"url": "path/to/directory/with/zips/"
|
|
}
|
|
],
|
|
"require": {
|
|
"private-vendor-one/core": "15.6.2",
|
|
"private-vendor-two/connectivity": "*",
|
|
"acme-corp/parser": "10.3.5"
|
|
}
|
|
}
|
|
|
|
Each zip artifact is just a ZIP archive with `composer.json` in root folder:
|
|
|
|
$ tar -tf acme-corp-parser-10.3.5.zip
|
|
composer.json
|
|
...
|
|
|
|
If there is two archives with different versions of a package, they would be
|
|
imported both. If archive with newer version would be put to artifact folder and
|
|
`update` command would be triggered, that version would replace previous, at it
|
|
logically seems.
|
|
|
|
## Disabling Packagist
|
|
|
|
You can disable the default Packagist repository by adding this to your
|
|
`composer.json`:
|
|
|
|
{
|
|
"repositories": [
|
|
{
|
|
"packagist": false
|
|
}
|
|
]
|
|
}
|
|
|
|
|
|
← [Schema](04-schema.md) | [Community](06-community.md) →
|