This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| \documentclass[letterpaper]{book} | |
| \title{Composer} | |
| \author{The Composer Community} | |
| \usepackage[letterpaper,margin=1.5in]{geometry} | |
| \usepackage{hyperref} | |
| \usepackage{url} | |
| \usepackage{enumerate} | |
| \usepackage{listings} | |
| \usepackage{microtype} | |
| \usepackage[htt]{hyphenat} | |
| \usepackage[utf8]{inputenc} | |
| \usepackage[T1]{fontenc} | |
| \usepackage{textcomp} | |
| \usepackage{tgpagella} | |
| \usepackage{longtable} | |
| \lstset{ | |
| breaklines=true, | |
| basicstyle=\ttfamily | |
| } | |
| \raggedbottom | |
| \begin{document} | |
| \setlength{\parindent}{0cm} | |
| \setlength{\parskip}{0.1cm} | |
| \maketitle | |
| \tableofcontents | |
| \setlength{\parskip}{0.4cm} | |
| \section{Introduction}\label{introduction} | |
| Composer is a tool for dependency management in PHP. It allows you to | |
| declare the dependent libraries your project needs and it will install | |
| them in your project for you. | |
| \subsection{Dependency management}\label{dependency-management} | |
| Composer is not a package manager. Yes, it deals with ``packages'' or | |
| libraries, but it manages them on a per-project basis, installing them | |
| in a directory (e.g. \texttt{vendor}) inside your project. By default it | |
| will never install anything globally. Thus, it is a dependency manager. | |
| This idea is not new and Composer is strongly inspired by node's | |
| \href{http://npmjs.org/}{npm} and ruby's | |
| \href{http://gembundler.com/}{bundler}. But there has not been such a | |
| tool for PHP. | |
| The problem that Composer solves is this: | |
| \begin{enumerate} | |
| \def\labelenumi{\alph{enumi})} | |
| \item | |
| You have a project that depends on a number of libraries. | |
| \item | |
| Some of those libraries depend on other libraries. | |
| \item | |
| You declare the things you depend on. | |
| \item | |
| Composer finds out which versions of which packages need to be | |
| installed, and installs them (meaning it downloads them into your | |
| project). | |
| \end{enumerate} | |
| \hyperdef{}{declaring-dependencies}{\subsection{Declaring | |
| dependencies}\label{declaring-dependencies}} | |
| Let's say you are creating a project, and you need a library that does | |
| logging. You decide to use | |
| \href{https://github.com/Seldaek/monolog}{monolog}. In order to add it | |
| to your project, all you need to do is create a \texttt{composer.json} | |
| file which describes the project's dependencies. | |
| \begin{verbatim} | |
| { | |
| "require": { | |
| "monolog/monolog": "1.2.*" | |
| } | |
| } | |
| \end{verbatim} | |
| We are simply stating that our project requires some | |
| \texttt{monolog/monolog} package, any version beginning with | |
| \texttt{1.2}. | |
| \subsection{System Requirements}\label{system-requirements} | |
| Composer requires PHP 5.3.2+ to run. A few sensitive php settings and | |
| compile flags are also required, but the installer will warn you about | |
| any incompatibilities. | |
| To install packages from sources instead of simple zip archives, you | |
| will need git, svn or hg depending on how the package is | |
| version-controlled. | |
| Composer is multi-platform and we strive to make it run equally well on | |
| Windows, Linux and OSX. | |
| \subsection{Installation - *nix}\label{installation---nix} | |
| \subsubsection{Downloading the Composer | |
| Executable}\label{downloading-the-composer-executable} | |
| \paragraph{Locally}\label{locally} | |
| To actually get Composer, we need to do two things. The first one is | |
| installing Composer (again, this means downloading it into your | |
| project): | |
| \begin{verbatim} | |
| $ curl -sS https://getcomposer.org/installer | php | |
| \end{verbatim} | |
| This will just check a few PHP settings and then download | |
| \texttt{composer.phar} to your working directory. This file is the | |
| Composer binary. It is a PHAR (PHP archive), which is an archive format | |
| for PHP which can be run on the command line, amongst other things. | |
| You can install Composer to a specific directory by using the | |
| \texttt{-{}-install-dir} option and providing a target directory (it can | |
| be an absolute or relative path): | |
| \begin{verbatim} | |
| $ curl -sS https://getcomposer.org/installer | php -- --install-dir=bin | |
| \end{verbatim} | |
| \paragraph{Globally}\label{globally} | |
| You can place this file anywhere you wish. If you put it in your | |
| \texttt{PATH}, you can access it globally. On unixy systems you can even | |
| make it executable and invoke it without \texttt{php}. | |
| You can run these commands to easily access \texttt{composer} from | |
| anywhere on your system: | |
| \begin{verbatim} | |
| $ curl -sS https://getcomposer.org/installer | php | |
| $ mv composer.phar /usr/local/bin/composer | |
| \end{verbatim} | |
| \begin{quote} | |
| \textbf{Note:} If the above fails due to permissions, run the | |
| \texttt{mv} line again with sudo. | |
| \end{quote} | |
| Then, just run \texttt{composer} in order to run Composer instead of | |
| \texttt{php composer.phar}. | |
| \subsection{Installation - Windows}\label{installation---windows} | |
| \subsubsection{Using the Installer}\label{using-the-installer} | |
| This is the easiest way to get Composer set up on your machine. | |
| Download and run | |
| \href{https://getcomposer.org/Composer-Setup.exe}{Composer-Setup.exe}, | |
| it will install the latest Composer version and set up your PATH so that | |
| you can just call \texttt{composer} from any directory in your command | |
| line. | |
| \subsubsection{Manual Installation}\label{manual-installation} | |
| Change to a directory on your \texttt{PATH} and run the install snippet | |
| to download composer.phar: | |
| \begin{verbatim} | |
| C:\Users\username>cd C:\bin | |
| C:\bin>php -r "eval('?>'.file_get_contents('https://getcomposer.org/installer'));" | |
| \end{verbatim} | |
| \begin{quote} | |
| \textbf{Note:} If the above fails due to file\_get\_contents, use the | |
| \texttt{http} url or enable php\_openssl.dll in php.ini | |
| \end{quote} | |
| Create a new \texttt{composer.bat} file alongside | |
| \texttt{composer.phar}: | |
| \begin{verbatim} | |
| C:\bin>echo @php "%~dp0composer.phar" %*>composer.bat | |
| \end{verbatim} | |
| Close your current terminal. Test usage with a new terminal: | |
| \begin{verbatim} | |
| C:\Users\username>composer -V | |
| Composer version 27d8904 | |
| C:\Users\username> | |
| \end{verbatim} | |
| \subsection{Using Composer}\label{using-composer} | |
| We will now use Composer to install the dependencies of the project. If | |
| you don't have a \texttt{composer.json} file in the current directory | |
| please skip to the \href{01-basic-usage.md}{Basic Usage} chapter. | |
| To resolve and download dependencies, run the \texttt{install} command: | |
| \begin{verbatim} | |
| $ php composer.phar install | |
| \end{verbatim} | |
| If you did a global install and do not have the phar in that directory | |
| run this instead: | |
| \begin{verbatim} | |
| $ composer install | |
| \end{verbatim} | |
| Following the \hyperref[declaring-dependencies]{example above}, this | |
| will download monolog into the \texttt{vendor/monolog/monolog} | |
| directory. | |
| \subsection{Autoloading}\label{autoloading} | |
| Besides downloading the library, Composer also prepares an autoload file | |
| that's capable of autoloading all of the classes in any of the libraries | |
| that it downloads. To use it, just add the following line to your code's | |
| bootstrap process: | |
| \begin{verbatim} | |
| require 'vendor/autoload.php'; | |
| \end{verbatim} | |
| Woah! Now start using monolog! To keep learning more about Composer, | |
| keep reading the ``Basic Usage'' chapter. | |
| \href{01-basic-usage.md}{Basic Usage} → | |
| \section{Basic usage}\label{basic-usage} | |
| \subsection{Installation}\label{installation} | |
| To install Composer, you just need to download the | |
| \texttt{composer.phar} executable. | |
| \begin{verbatim} | |
| $ curl -sS https://getcomposer.org/installer | php | |
| \end{verbatim} | |
| For the details, see the \href{00-intro.md}{Introduction} chapter. | |
| To check if Composer is working, just run the PHAR through \texttt{php}: | |
| \begin{verbatim} | |
| $ php composer.phar | |
| \end{verbatim} | |
| This should give you a list of available commands. | |
| \begin{quote} | |
| \textbf{Note:} You can also perform the checks only without downloading | |
| Composer by using the \texttt{-{}-check} option. For more information, | |
| just use \texttt{-{}-help}. | |
| \begin{verbatim} | |
| $ curl -sS https://getcomposer.org/installer | php -- --help | |
| \end{verbatim} | |
| \end{quote} | |
| \subsection{\texttt{composer.json}: Project | |
| Setup}\label{composer.json-project-setup} | |
| To start using Composer in your project, all you need is a | |
| \texttt{composer.json} file. This file describes the dependencies of | |
| your project and may contain other metadata as well. | |
| The \href{http://json.org/}{JSON format} is quite easy to write. It | |
| allows you to define nested structures. | |
| \subsubsection{The \texttt{require} Key}\label{the-require-key} | |
| The first (and often only) thing you specify in \texttt{composer.json} | |
| is the \texttt{require} key. You're simply telling Composer which | |
| packages your project depends on. | |
| \begin{verbatim} | |
| { | |
| "require": { | |
| "monolog/monolog": "1.0.*" | |
| } | |
| } | |
| \end{verbatim} | |
| As you can see, \texttt{require} takes an object that maps | |
| \textbf{package names} (e.g. \texttt{monolog/monolog}) to | |
| \textbf{package versions} (e.g. \texttt{1.0.*}). | |
| \subsubsection{Package Names}\label{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 | |
| \texttt{json}, which would then just be named \texttt{igorw/json} and | |
| \texttt{seldaek/json}. | |
| Here we are requiring \texttt{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. | |
| \subsubsection{Package Versions}\label{package-versions} | |
| In the previous example we were requiring version \texttt{1.0.*} of | |
| monolog. This means any version in the \texttt{1.0} development branch. | |
| It would match \texttt{1.0.0}, \texttt{1.0.2} or \texttt{1.0.20}. | |
| Version constraints can be specified in a few different ways. | |
| \begin{longtable}[c]{@{}lll@{}} | |
| \hline\noalign{\medskip} | |
| Name & Example & Description | |
| \\\noalign{\medskip} | |
| \hline\noalign{\medskip} | |
| Exact version & \texttt{1.0.2} & You can specify the exact version of a | |
| package. | |
| \\\noalign{\medskip} | |
| Range & \texttt{\textgreater{}=1.0} | |
| \texttt{\textgreater{}=1.0,\textless{}2.0} | |
| \texttt{\textgreater{}=1.0,\textless{}1.1 \textbar{} \textgreater{}=1.2} | |
| & By using comparison operators you can specify ranges of valid | |
| versions. Valid operators are \texttt{\textgreater{}}, | |
| \texttt{\textgreater{}=}, \texttt{\textless{}}, \texttt{\textless{}=}, | |
| \texttt{!=}. You can define multiple ranges, separated by a comma, which | |
| will be treated as a \textbf{logical AND}. A pipe symbol | |
| \texttt{\textbar{}} will be treated as a \textbf{logical OR}. AND has | |
| higher precedence than OR. | |
| \\\noalign{\medskip} | |
| Wildcard & \texttt{1.0.*} & You can specify a pattern with a \texttt{*} | |
| wildcard. \texttt{1.0.*} is the equivalent of | |
| \texttt{\textgreater{}=1.0,\textless{}1.1}. | |
| \\\noalign{\medskip} | |
| Tilde Operator & \texttt{\textasciitilde{}1.2} & Very useful for | |
| projects that follow semantic versioning. \texttt{\textasciitilde{}1.2} | |
| is equivalent to \texttt{\textgreater{}=1.2,\textless{}2.0}. For more | |
| details, read the next section below. | |
| \\\noalign{\medskip} | |
| \hline | |
| \end{longtable} | |
| \subsubsection{Next Significant Release (Tilde | |
| Operator)}\label{next-significant-release-tilde-operator} | |
| The \texttt{\textasciitilde{}} operator is best explained by example: | |
| \texttt{\textasciitilde{}1.2} is equivalent to | |
| \texttt{\textgreater{}=1.2,\textless{}2.0}, while | |
| \texttt{\textasciitilde{}1.2.3} is equivalent to | |
| \texttt{\textgreater{}=1.2.3,\textless{}1.3}. As you can see it is | |
| mostly useful for projects respecting \href{http://semver.org/}{semantic | |
| versioning}. A common usage would be to mark the minimum minor version | |
| you depend on, like \texttt{\textasciitilde{}1.2} (which allows anything | |
| up to, but not including, 2.0). Since in theory there should be no | |
| backwards compatibility breaks until 2.0, that works well. Another way | |
| of looking at it is that using \texttt{\textasciitilde{}} specifies a | |
| minimum version, but allows the last digit specified to go up. | |
| \subsubsection{Stability}\label{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 | |
| \href{04-schema.md\#package-links}{stability flags}. To change that for | |
| all packages instead of doing per dependency you can also use the | |
| \href{04-schema.md\#minimum-stability}{minimum-stability} setting. | |
| \subsection{Installing Dependencies}\label{installing-dependencies} | |
| To fetch the defined dependencies into your local project, just run the | |
| \texttt{install} command of \texttt{composer.phar}. | |
| \begin{verbatim} | |
| $ php composer.phar install | |
| \end{verbatim} | |
| This will find the latest version of \texttt{monolog/monolog} that | |
| matches the supplied version constraint and download it into the | |
| \texttt{vendor} directory. It's a convention to put third party code | |
| into a directory named \texttt{vendor}. In case of monolog it will put | |
| it into \texttt{vendor/monolog/monolog}. | |
| \begin{quote} | |
| \textbf{Tip:} If you are using git for your project, you probably want | |
| to add \texttt{vendor} into your \texttt{.gitignore}. You really don't | |
| want to add all of that code to your repository. | |
| \end{quote} | |
| Another thing that the \texttt{install} command does is it adds a | |
| \texttt{composer.lock} file into your project root. | |
| \subsection{\texttt{composer.lock} - The Lock | |
| File}\label{composer.lock---the-lock-file} | |
| After installing the dependencies, Composer writes the list of the exact | |
| versions it installed into a \texttt{composer.lock} file. This locks the | |
| project to those specific versions. | |
| \textbf{Commit your application's \texttt{composer.lock} (along with | |
| \texttt{composer.json}) into version control.} | |
| This is important because the \texttt{install} command checks if a lock | |
| file is present, and if it is, it downloads the versions specified there | |
| (regardless of what \texttt{composer.json} says). | |
| 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 no \texttt{composer.lock} file exists, Composer will read the | |
| dependencies and versions from \texttt{composer.json} and create the | |
| lock file. | |
| 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 | |
| \texttt{update} command. This will fetch the latest matching versions | |
| (according to your \texttt{composer.json} file) and also update the lock | |
| file with the new version. | |
| \begin{verbatim} | |
| $ php composer.phar update | |
| \end{verbatim} | |
| If you only want to install or update one dependency, you can whitelist | |
| them: | |
| \begin{verbatim} | |
| $ php composer.phar update monolog/monolog [...] | |
| \end{verbatim} | |
| \begin{quote} | |
| \textbf{Note:} For libraries it is not necessarily recommended to commit | |
| the lock file, see also: \href{02-libraries.md\#lock-file}{Libraries - | |
| Lock file}. | |
| \end{quote} | |
| \subsection{Packagist}\label{packagist} | |
| \href{https://packagist.org/}{Packagist} 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 | |
| \texttt{require} any package that is available there. | |
| If you go to the \href{https://packagist.org/}{packagist website} | |
| (packagist.org), you can browse and search for packages. | |
| Any open source project using Composer should publish their packages on | |
| packagist. A library doesn't need to be on packagist to be used by | |
| Composer, but it makes life quite a bit simpler. | |
| \subsection{Autoloading}\label{autoloading} | |
| For libraries that specify autoload information, Composer generates a | |
| \texttt{vendor/autoload.php} file. You can simply include this file and | |
| you will get autoloading for free. | |
| \begin{verbatim} | |
| require 'vendor/autoload.php'; | |
| \end{verbatim} | |
| 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. | |
| \begin{verbatim} | |
| $log = new Monolog\Logger('name'); | |
| $log->pushHandler(new Monolog\Handler\StreamHandler('app.log', Monolog\Logger::WARNING)); | |
| $log->addWarning('Foo'); | |
| \end{verbatim} | |
| You can even add your own code to the autoloader by adding an | |
| \texttt{autoload} field to \texttt{composer.json}. | |
| \begin{verbatim} | |
| { | |
| "autoload": { | |
| "psr-0": {"Acme\\": "src/"} | |
| } | |
| } | |
| \end{verbatim} | |
| Composer will register a | |
| \href{https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md}{PSR-0} | |
| autoloader for the \texttt{Acme} namespace. | |
| You define a mapping from namespaces to directories. The \texttt{src} | |
| directory would be in your project root, on the same level as | |
| \texttt{vendor} directory is. An example filename would be | |
| \texttt{src/Acme/Foo.php} containing an \texttt{Acme\textbackslash{}Foo} | |
| class. | |
| After adding the \texttt{autoload} field, you have to re-run | |
| \texttt{install} to re-generate the \texttt{vendor/autoload.php} file. | |
| Including that file will also return the autoloader instance, so you can | |
| store the return value of the include call in a variable and add more | |
| namespaces. This can be useful for autoloading classes in a test suite, | |
| for example. | |
| \begin{verbatim} | |
| $loader = require 'vendor/autoload.php'; | |
| $loader->add('Acme\\Test\\', __DIR__); | |
| \end{verbatim} | |
| In addition to PSR-0 autoloading, classmap is also supported. This | |
| allows classes to be autoloaded even if they do not conform to PSR-0. | |
| See the \href{04-schema.md\#autoload}{autoload reference} for more | |
| details. | |
| \begin{quote} | |
| \textbf{Note:} Composer provides its own autoloader. If you don't want | |
| to use that one, you can just include | |
| \texttt{vendor/composer/autoload\_namespaces.php}, which returns an | |
| associative array mapping namespaces to directories. | |
| \end{quote} | |
| ← \href{00-intro.md}{Intro} \textbar{} \href{02-libraries.md}{Libraries} | |
| → | |
| \section{Libraries}\label{libraries} | |
| This chapter will tell you how to make your library installable through | |
| Composer. | |
| \subsection{Every project is a | |
| package}\label{every-project-is-a-package} | |
| As soon as you have a \texttt{composer.json} in a directory, that | |
| directory is a package. When you add a \texttt{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. | |
| In order to make that package installable you need to give it a name. | |
| You do this by adding a \texttt{name} to \texttt{composer.json}: | |
| \begin{verbatim} | |
| { | |
| "name": "acme/hello-world", | |
| "require": { | |
| "monolog/monolog": "1.0.*" | |
| } | |
| } | |
| \end{verbatim} | |
| In this case the project name is \texttt{acme/hello-world}, where | |
| \texttt{acme} is the vendor name. Supplying a vendor name is mandatory. | |
| \begin{quote} | |
| \textbf{Note:} If you don't know what to use as a vendor name, your | |
| GitHub username is usually a good bet. While package names are case | |
| insensitive, the convention is all lowercase and dashes for word | |
| separation. | |
| \end{quote} | |
| \subsection{Platform packages}\label{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. | |
| \begin{itemize} | |
| \item | |
| \texttt{php} represents the PHP version of the user, allowing you to | |
| apply constraints, e.g. \texttt{\textgreater{}=5.4.0}. To require a | |
| 64bit version of php, you can require the \texttt{php-64bit} package. | |
| \item | |
| \texttt{ext-\textless{}name\textgreater{}} 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 \texttt{*}. An example of an extension package name is | |
| \texttt{ext-gd}. | |
| \item | |
| \texttt{lib-\textless{}name\textgreater{}} allows constraints to be | |
| made on versions of libraries used by PHP. The following are | |
| available: \texttt{curl}, \texttt{iconv}, \texttt{libxml}, | |
| \texttt{openssl}, \texttt{pcre}, \texttt{uuid}, \texttt{xsl}. | |
| \end{itemize} | |
| You can use \texttt{composer show -{}-platform} to get a list of your | |
| locally available platform packages. | |
| \subsection{Specifying the version}\label{specifying-the-version} | |
| You need to specify the package's version some way. When you publish | |
| your package on Packagist, it is able to infer the version from the VCS | |
| (git, svn, hg) information, so in that case you do not have to specify | |
| it, and it is recommended not to. See \hyperref[tags]{tags} and | |
| \hyperref[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 \texttt{version} field: | |
| \begin{verbatim} | |
| { | |
| "version": "1.0.0" | |
| } | |
| \end{verbatim} | |
| \begin{quote} | |
| \textbf{Note:} You should avoid specifying the version field explicitly, | |
| because for tags the value must match the tag name. | |
| \end{quote} | |
| \hyperdef{}{tags}{\subsubsection{Tags}\label{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 \texttt{-dev}, \texttt{-patch}, \texttt{-alpha}, | |
| \texttt{-beta} or \texttt{-RC}. The patch, alpha, beta and RC suffixes | |
| can also be followed by a number. | |
| Here are a few examples of valid tag names: | |
| \begin{verbatim} | |
| 1.0.0 | |
| v1.0.0 | |
| 1.10.5-RC1 | |
| v4.4.4beta2 | |
| v2.0.0-alpha | |
| v2.0.4-p1 | |
| \end{verbatim} | |
| \hyperdef{}{branches}{\subsubsection{Branches}\label{branches}} | |
| For every branch, a package development version will be created. If the | |
| branch name looks like a version, the version will be | |
| \texttt{\{branchname\}-dev}. For example a branch \texttt{2.0} will get | |
| a version \texttt{2.0.x-dev} (the \texttt{.x} is added for technical | |
| reasons, to make sure it is recognized as a branch, a \texttt{2.0.x} | |
| branch would also be valid and be turned into \texttt{2.0.x-dev} as | |
| well. If the branch does not look like a version, it will be | |
| \texttt{dev-\{branchname\}}. \texttt{master} results in a | |
| \texttt{dev-master} version. | |
| Here are some examples of version branch names: | |
| \begin{verbatim} | |
| 1.x | |
| 1.0 (equals 1.0.x) | |
| 1.1.x | |
| \end{verbatim} | |
| \begin{quote} | |
| \textbf{Note:} When you install a development version, it will be | |
| automatically pulled from its \texttt{source}. See the | |
| \href{03-cli.md\#install}{\texttt{install}} command for more details. | |
| \end{quote} | |
| \subsubsection{Aliases}\label{aliases} | |
| It is possible to alias branch names to versions. For example, you could | |
| alias \texttt{dev-master} to \texttt{1.0.x-dev}, which would allow you | |
| to require \texttt{1.0.x-dev} in all the packages. | |
| See \href{articles/aliases.md}{Aliases} for more information. | |
| \subsection{Lock file}\label{lock-file} | |
| For your library you may commit the \texttt{composer.lock} file if you | |
| want to. This can help your team to always test against the same | |
| dependency versions. However, this lock file will not have any effect on | |
| other projects that depend on it. It only has an effect on the main | |
| project. | |
| If you do not want to commit the lock file and you are using git, add it | |
| to the \texttt{.gitignore}. | |
| \subsection{Publishing to a VCS}\label{publishing-to-a-vcs} | |
| Once you have a vcs repository (version control system, e.g.~git) | |
| containing a \texttt{composer.json} file, your library is already | |
| composer-installable. In this example we will publish the | |
| \texttt{acme/hello-world} library on GitHub under | |
| \texttt{github.com/username/hello-world}. | |
| Now, to test installing the \texttt{acme/hello-world} package, we create | |
| a new project locally. We will call it \texttt{acme/blog}. This blog | |
| will depend on \texttt{acme/hello-world}, which in turn depends on | |
| \texttt{monolog/monolog}. We can accomplish this by creating a new | |
| \texttt{blog} directory somewhere, containing a \texttt{composer.json}: | |
| \begin{verbatim} | |
| { | |
| "name": "acme/blog", | |
| "require": { | |
| "acme/hello-world": "dev-master" | |
| } | |
| } | |
| \end{verbatim} | |
| The name is not needed in this case, since we don't want to publish the | |
| blog as a library. It is added here to clarify which | |
| \texttt{composer.json} is being described. | |
| Now we need to tell the blog app where to find the \texttt{hello-world} | |
| dependency. We do this by adding a package repository specification to | |
| the blog's \texttt{composer.json}: | |
| \begin{verbatim} | |
| { | |
| "name": "acme/blog", | |
| "repositories": [ | |
| { | |
| "type": "vcs", | |
| "url": "https://github.com/username/hello-world" | |
| } | |
| ], | |
| "require": { | |
| "acme/hello-world": "dev-master" | |
| } | |
| } | |
| \end{verbatim} | |
| For more details on how package repositories work and what other types | |
| are available, see \href{05-repositories.md}{Repositories}. | |
| That's all. You can now install the dependencies by running Composer's | |
| \texttt{install} command! | |
| \textbf{Recap:} Any git/svn/hg repository containing a | |
| \texttt{composer.json} can be added to your project by specifying the | |
| package repository and declaring the dependency in the \texttt{require} | |
| field. | |
| \subsection{Publishing to packagist}\label{publishing-to-packagist} | |
| Alright, so now you can publish packages. But specifying the vcs | |
| repository every time is cumbersome. You don't want to force all your | |
| users to do that. | |
| The other thing that you may have noticed is that we did not specify a | |
| package repository for \texttt{monolog/monolog}. How did that work? The | |
| answer is packagist. | |
| \href{https://packagist.org/}{Packagist} is the main package repository | |
| for Composer, and it is enabled by default. Anything that is published | |
| on packagist is available automatically through Composer. Since monolog | |
| \href{https://packagist.org/packages/monolog/monolog}{is on packagist}, | |
| we can depend on it without having to specify any additional | |
| repositories. | |
| If we wanted to share \texttt{hello-world} with the world, we would | |
| publish it on packagist as well. Doing so is really easy. | |
| You simply hit the big ``Submit Package'' button and sign up. Then you | |
| submit the URL to your VCS repository, at which point packagist will | |
| start crawling it. Once it is done, your package will be available to | |
| anyone. | |
| ← \href{01-basic-usage.md}{Basic usage} \textbar{} | |
| \href{03-cli.md}{Command-line interface} → | |
| \section{Command-line interface}\label{command-line-interface} | |
| You've already learned how to use the command-line interface to do some | |
| things. This chapter documents all the available commands. | |
| To get help from the command-line, simply call \texttt{composer} or | |
| \texttt{composer list} to see the complete list of commands, then | |
| \texttt{-{}-help} combined with any of those can give you more | |
| information. | |
| \subsection{Global Options}\label{global-options} | |
| The following options are available with every command: | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{--verbose (-v):} Increase verbosity of messages. | |
| \item | |
| \textbf{--help (-h):} Display help information. | |
| \item | |
| \textbf{--quiet (-q):} Do not output any message. | |
| \item | |
| \textbf{--no-interaction (-n):} Do not ask any interactive question. | |
| \item | |
| \textbf{--working-dir (-d):} If specified, use the given directory as | |
| working directory. | |
| \item | |
| \textbf{--profile:} Display timing and memory usage information | |
| \item | |
| \textbf{--ansi:} Force ANSI output. | |
| \item | |
| \textbf{--no-ansi:} Disable ANSI output. | |
| \item | |
| \textbf{--version (-V):} Display this application version. | |
| \end{itemize} | |
| \subsection{Process Exit Codes}\label{process-exit-codes} | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{0:} OK | |
| \item | |
| \textbf{1:} Generic/unknown error code | |
| \item | |
| \textbf{2:} Dependency solving error code | |
| \end{itemize} | |
| \subsection{init}\label{init} | |
| In the \href{02-libraries.md}{Libraries} chapter we looked at how to | |
| create a \texttt{composer.json} by hand. There is also an \texttt{init} | |
| command available that makes it a bit easier to do this. | |
| When you run the command it will interactively ask you to fill in the | |
| fields, while using some smart defaults. | |
| \begin{verbatim} | |
| $ php composer.phar init | |
| \end{verbatim} | |
| \subsubsection{Options}\label{options} | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{--name:} Name of the package. | |
| \item | |
| \textbf{--description:} Description of the package. | |
| \item | |
| \textbf{--author:} Author name of the package. | |
| \item | |
| \textbf{--homepage:} Homepage of the package. | |
| \item | |
| \textbf{--require:} Package to require with a version constraint. | |
| Should be in format \texttt{foo/bar:1.0.0}. | |
| \item | |
| \textbf{--require-dev:} Development requirements, see | |
| \textbf{--require}. | |
| \item | |
| \textbf{--stability (-s):} Value for the \texttt{minimum-stability} | |
| field. | |
| \end{itemize} | |
| \subsection{install}\label{install} | |
| The \texttt{install} command reads the \texttt{composer.json} file from | |
| the current directory, resolves the dependencies, and installs them into | |
| \texttt{vendor}. | |
| \begin{verbatim} | |
| $ php composer.phar install | |
| \end{verbatim} | |
| If there is a \texttt{composer.lock} file in the current directory, it | |
| will use the exact versions from there instead of resolving them. This | |
| ensures that everyone using the library will get the same versions of | |
| the dependencies. | |
| If there is no \texttt{composer.lock} file, composer will create one | |
| after dependency resolution. | |
| \subsubsection{Options}\label{options-1} | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{--prefer-source:} There are two ways of downloading a package: | |
| \texttt{source} and \texttt{dist}. For stable versions composer will | |
| use the \texttt{dist} by default. The \texttt{source} is a version | |
| control repository. If \texttt{-{}-prefer-source} is enabled, composer | |
| will install from \texttt{source} if there is one. This is useful if | |
| you want to make a bugfix to a project and get a local git clone of | |
| the dependency directly. | |
| \item | |
| \textbf{--prefer-dist:} Reverse of \texttt{-{}-prefer-source}, | |
| composer will install from \texttt{dist} if possible. This can speed | |
| up installs substantially on build servers and other use cases where | |
| you typically do not run updates of the vendors. It is also a way to | |
| circumvent problems with git if you do not have a proper setup. | |
| \item | |
| \textbf{--dry-run:} If you want to run through an installation without | |
| actually installing a package, you can use \texttt{-{}-dry-run}. This | |
| will simulate the installation and show you what would happen. | |
| \item | |
| \textbf{--dev:} Install packages listed in \texttt{require-dev} (this | |
| is the default behavior). | |
| \item | |
| \textbf{--no-dev:} Skip installing packages listed in | |
| \texttt{require-dev}. | |
| \item | |
| \textbf{--no-scripts:} Skips execution of scripts defined in | |
| \texttt{composer.json}. | |
| \item | |
| \textbf{--no-plugins:} Disables plugins. | |
| \item | |
| \textbf{--no-progress:} Removes the progress display that can mess | |
| with some terminals or scripts which don't handle backspace | |
| characters. | |
| \item | |
| \textbf{--optimize-autoloader (-o):} Convert PSR-0 autoloading to | |
| classmap to get a faster autoloader. This is recommended especially | |
| for production, but can take a bit of time to run so it is currently | |
| not done by default. | |
| \end{itemize} | |
| \subsection{update}\label{update} | |
| In order to get the latest versions of the dependencies and to update | |
| the \texttt{composer.lock} file, you should use the \texttt{update} | |
| command. | |
| \begin{verbatim} | |
| $ php composer.phar update | |
| \end{verbatim} | |
| This will resolve all dependencies of the project and write the exact | |
| versions into \texttt{composer.lock}. | |
| If you just want to update a few packages and not all, you can list them | |
| as such: | |
| \begin{verbatim} | |
| $ php composer.phar update vendor/package vendor/package2 | |
| \end{verbatim} | |
| You can also use wildcards to update a bunch of packages at once: | |
| \begin{verbatim} | |
| $ php composer.phar update vendor/* | |
| \end{verbatim} | |
| \subsubsection{Options}\label{options-2} | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{--prefer-source:} Install packages from \texttt{source} when | |
| available. | |
| \item | |
| \textbf{--prefer-dist:} Install packages from \texttt{dist} when | |
| available. | |
| \item | |
| \textbf{--dry-run:} Simulate the command without actually doing | |
| anything. | |
| \item | |
| \textbf{--dev:} Install packages listed in \texttt{require-dev} (this | |
| is the default behavior). | |
| \item | |
| \textbf{--no-dev:} Skip installing packages listed in | |
| \texttt{require-dev}. | |
| \item | |
| \textbf{--no-scripts:} Skips execution of scripts defined in | |
| \texttt{composer.json}. | |
| \item | |
| \textbf{--no-plugins:} Disables plugins. | |
| \item | |
| \textbf{--no-progress:} Removes the progress display that can mess | |
| with some terminals or scripts which don't handle backspace | |
| characters. | |
| \item | |
| \textbf{--optimize-autoloader (-o):} Convert PSR-0 autoloading to | |
| classmap to get a faster autoloader. This is recommended especially | |
| for production, but can take a bit of time to run so it is currently | |
| not done by default. | |
| \item | |
| \textbf{--lock:} Only updates the lock file hash to suppress warning | |
| about the lock file being out of date | |
| \end{itemize} | |
| \subsection{require}\label{require} | |
| The \texttt{require} command adds new packages to the | |
| \texttt{composer.json} file from the current directory. | |
| \begin{verbatim} | |
| $ php composer.phar require | |
| \end{verbatim} | |
| After adding/changing the requirements, the modified requirements will | |
| be installed or updated. | |
| If you do not want to choose requirements interactively, you can just | |
| pass them to the command. | |
| \begin{verbatim} | |
| $ php composer.phar require vendor/package:2.* vendor/package2:dev-master | |
| \end{verbatim} | |
| \subsubsection{Options}\label{options-3} | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{--prefer-source:} Install packages from \texttt{source} when | |
| available. | |
| \item | |
| \textbf{--prefer-dist:} Install packages from \texttt{dist} when | |
| available. | |
| \item | |
| \textbf{--dev:} Add packages to \texttt{require-dev}. | |
| \item | |
| \textbf{--no-update:} Disables the automatic update of the | |
| dependencies. | |
| \item | |
| \textbf{--no-progress:} Removes the progress display that can mess | |
| with some terminals or scripts which don't handle backspace | |
| characters. | |
| \end{itemize} | |
| \subsection{global}\label{global} | |
| The global command allows you to run other commands like | |
| \texttt{install}, \texttt{require} or \texttt{update} as if you were | |
| running them from the \hyperref[COMPOSER_HOME]{COMPOSER\_HOME} | |
| directory. | |
| This can be used to install CLI utilities globally and if you add | |
| \texttt{\$COMPOSER\_HOME/vendor/bin} to your \texttt{\$PATH} environment | |
| variable. Here is an example: | |
| \begin{verbatim} | |
| $ php composer.phar global require fabpot/php-cs-fixer:dev-master | |
| \end{verbatim} | |
| Now the \texttt{php-cs-fixer} binary is available globally (assuming you | |
| adjusted your PATH). If you wish to update the binary later on you can | |
| just run a global update: | |
| \begin{verbatim} | |
| $ php composer.phar global update | |
| \end{verbatim} | |
| \subsection{search}\label{search} | |
| The search command allows you to search through the current project's | |
| package repositories. Usually this will be just packagist. You simply | |
| pass it the terms you want to search for. | |
| \begin{verbatim} | |
| $ php composer.phar search monolog | |
| \end{verbatim} | |
| You can also search for more than one term by passing multiple | |
| arguments. | |
| \subsubsection{Options}\label{options-4} | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{--only-name (-N):} Search only in name. | |
| \end{itemize} | |
| \subsection{show}\label{show} | |
| To list all of the available packages, you can use the \texttt{show} | |
| command. | |
| \begin{verbatim} | |
| $ php composer.phar show | |
| \end{verbatim} | |
| If you want to see the details of a certain package, you can pass the | |
| package name. | |
| \begin{verbatim} | |
| $ php composer.phar show monolog/monolog | |
| name : monolog/monolog | |
| versions : master-dev, 1.0.2, 1.0.1, 1.0.0, 1.0.0-RC1 | |
| type : library | |
| names : monolog/monolog | |
| source : [git] http://github.com/Seldaek/monolog.git 3d4e60d0cbc4b888fe5ad223d77964428b1978da | |
| dist : [zip] http://github.com/Seldaek/monolog/zipball/3d4e60d0cbc4b888fe5ad223d77964428b1978da 3d4e60d0cbc4b888fe5ad223d77964428b1978da | |
| license : MIT | |
| autoload | |
| psr-0 | |
| Monolog : src/ | |
| requires | |
| php >=5.3.0 | |
| \end{verbatim} | |
| You can even pass the package version, which will tell you the details | |
| of that specific version. | |
| \begin{verbatim} | |
| $ php composer.phar show monolog/monolog 1.0.2 | |
| \end{verbatim} | |
| \subsubsection{Options}\label{options-5} | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{--installed (-i):} List the packages that are installed. | |
| \item | |
| \textbf{--platform (-p):} List only platform packages (php \& | |
| extensions). | |
| \item | |
| \textbf{--self (-s):} List the root package info. | |
| \end{itemize} | |
| \subsection{depends}\label{depends} | |
| The \texttt{depends} command tells you which other packages depend on a | |
| certain package. You can specify which link types (\texttt{require}, | |
| \texttt{require-dev}) should be included in the listing. By default both | |
| are used. | |
| \begin{verbatim} | |
| $ php composer.phar depends --link-type=require monolog/monolog | |
| nrk/monolog-fluent | |
| poc/poc | |
| propel/propel | |
| symfony/monolog-bridge | |
| symfony/symfony | |
| \end{verbatim} | |
| \subsubsection{Options}\label{options-6} | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{--link-type:} The link types to match on, can be specified | |
| multiple times. | |
| \end{itemize} | |
| \subsection{validate}\label{validate} | |
| You should always run the \texttt{validate} command before you commit | |
| your \texttt{composer.json} file, and before you tag a release. It will | |
| check if your \texttt{composer.json} is valid. | |
| \begin{verbatim} | |
| $ php composer.phar validate | |
| \end{verbatim} | |
| \subsection{status}\label{status} | |
| If you often need to modify the code of your dependencies and they are | |
| installed from source, the \texttt{status} command allows you to check | |
| if you have local changes in any of them. | |
| \begin{verbatim} | |
| $ php composer.phar status | |
| \end{verbatim} | |
| With the \texttt{-{}-verbose} option you get some more information about | |
| what was changed: | |
| \begin{verbatim} | |
| $ php composer.phar status -v | |
| You have changes in the following dependencies: | |
| vendor/seld/jsonlint: | |
| M README.mdown | |
| \end{verbatim} | |
| \subsection{self-update}\label{self-update} | |
| To update composer itself to the latest version, just run the | |
| \texttt{self-update} command. It will replace your | |
| \texttt{composer.phar} with the latest version. | |
| \begin{verbatim} | |
| $ php composer.phar self-update | |
| \end{verbatim} | |
| If you have installed composer for your entire system (see | |
| \href{00-intro.md\#globally}{global installation}), you have to run the | |
| command with \texttt{root} privileges | |
| \begin{verbatim} | |
| $ sudo composer self-update | |
| \end{verbatim} | |
| \subsection{config}\label{config} | |
| The \texttt{config} command allows you to edit some basic composer | |
| settings in either the local composer.json file or the global | |
| config.json file. | |
| \begin{verbatim} | |
| $ php composer.phar config --list | |
| \end{verbatim} | |
| \subsubsection{Usage}\label{usage} | |
| \texttt{config {[}options{]} {[}setting-key{]} {[}setting-value1{]} ... {[}setting-valueN{]}} | |
| \texttt{setting-key} is a configuration option name and | |
| \texttt{setting-value1} is a configuration value. For settings that can | |
| take an array of values (like \texttt{github-protocols}), more than one | |
| setting-value arguments are allowed. | |
| See the \href{04-schema.md\#config}{config schema section} for valid | |
| configuration options. | |
| \subsubsection{Options}\label{options-7} | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{--global (-g):} Operate on the global config file located at | |
| \texttt{\$COMPOSER\_HOME/config.json} by default. Without this option, | |
| this command affects the local composer.json file or a file specified | |
| by \texttt{-{}-file}. | |
| \item | |
| \textbf{--editor (-e):} Open the local composer.json file using in a | |
| text editor as defined by the \texttt{EDITOR} env variable. With the | |
| \texttt{-{}-global} option, this opens the global config file. | |
| \item | |
| \textbf{--unset:} Remove the configuration element named by | |
| \texttt{setting-key}. | |
| \item | |
| \textbf{--list (-l):} Show the list of current config variables. With | |
| the \texttt{-{}-global} option this lists the global configuration | |
| only. | |
| \item | |
| \textbf{--file=``\ldots{}'' (-f):} Operate on a specific file instead | |
| of composer.json. Note that this cannot be used in conjunction with | |
| the \texttt{-{}-global} option. | |
| \end{itemize} | |
| \subsubsection{Modifying Repositories}\label{modifying-repositories} | |
| In addition to modifying the config section, the \texttt{config} command | |
| also supports making changes to the repositories section by using it the | |
| following way: | |
| \begin{verbatim} | |
| $ php composer.phar config repositories.foo vcs http://github.com/foo/bar | |
| \end{verbatim} | |
| \subsection{create-project}\label{create-project} | |
| You can use Composer to create new projects from an existing package. | |
| This is the equivalent of doing a git clone/svn checkout followed by a | |
| composer install of the vendors. | |
| There are several applications for this: | |
| \begin{enumerate} | |
| \def\labelenumi{\arabic{enumi}.} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| You can deploy application packages. | |
| \item | |
| You can check out any package and start developing on patches for | |
| example. | |
| \item | |
| Projects with multiple developers can use this feature to bootstrap | |
| the initial application for development. | |
| \end{enumerate} | |
| To create a new project using composer you can use the | |
| ``create-project'' command. Pass it a package name, and the directory to | |
| create the project in. You can also provide a version as third argument, | |
| otherwise the latest version is used. | |
| If the directory does not currently exist, it will be created during | |
| installation. | |
| \begin{verbatim} | |
| php composer.phar create-project doctrine/orm path 2.2.0 | |
| \end{verbatim} | |
| It is also possible to run the command without params in a directory | |
| with an existing \texttt{composer.json} file to bootstrap a project. | |
| By default the command checks for the packages on packagist.org. | |
| \subsubsection{Options}\label{options-8} | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{--repository-url:} Provide a custom repository to search for | |
| the package, which will be used instead of packagist. Can be either an | |
| HTTP URL pointing to a \texttt{composer} repository, or a path to a | |
| local \texttt{packages.json} file. | |
| \item | |
| \textbf{--stability (-s):} Minimum stability of package. Defaults to | |
| \texttt{stable}. | |
| \item | |
| \textbf{--prefer-source:} Install packages from \texttt{source} when | |
| available. | |
| \item | |
| \textbf{--prefer-dist:} Install packages from \texttt{dist} when | |
| available. | |
| \item | |
| \textbf{--dev:} Install packages listed in \texttt{require-dev}. | |
| \item | |
| \textbf{--no-install:} Disables installation of the vendors. | |
| \item | |
| \textbf{--no-plugins:} Disables plugins. | |
| \item | |
| \textbf{--no-scripts:} Disables the execution of the scripts defined | |
| in the root package. | |
| \item | |
| \textbf{--no-progress:} Removes the progress display that can mess | |
| with some terminals or scripts which don't handle backspace | |
| characters. | |
| \item | |
| \textbf{--keep-vcs:} Skip the deletion of the VCS metadata for the | |
| created project. This is mostly useful if you run the command in | |
| non-interactive mode. | |
| \end{itemize} | |
| \subsection{dump-autoload}\label{dump-autoload} | |
| If you need to update the autoloader because of new classes in a | |
| classmap package for example, you can use ``dump-autoload'' to do that | |
| without having to go through an install or update. | |
| Additionally, it can dump an optimized autoloader that converts PSR-0 | |
| packages into classmap ones for performance reasons. In large | |
| applications with many classes, the autoloader can take up a substantial | |
| portion of every request's time. Using classmaps for everything is less | |
| convenient in development, but using this option you can still use PSR-0 | |
| for convenience and classmaps for performance. | |
| \subsubsection{Options}\label{options-9} | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{--optimize (-o):} Convert PSR-0 autoloading to classmap to get | |
| a faster autoloader. This is recommended especially for production, | |
| but can take a bit of time to run so it is currently not done by | |
| default. | |
| \end{itemize} | |
| \subsection{licenses}\label{licenses} | |
| Lists the name, version and license of every package installed. Use | |
| \texttt{-{}-format=json} to get machine readable output. | |
| \subsection{run-script}\label{run-script} | |
| To run \href{articles/scripts.md}{scripts} manually you can use this | |
| command, just give it the script name and optionally --no-dev to disable | |
| the dev mode. | |
| \subsection{diagnose}\label{diagnose} | |
| If you think you found a bug, or something is behaving strangely, you | |
| might want to run the \texttt{diagnose} command to perform automated | |
| checks for many common problems. | |
| \begin{verbatim} | |
| $ php composer.phar diagnose | |
| \end{verbatim} | |
| \subsection{help}\label{help} | |
| To get more information about a certain command, just use \texttt{help}. | |
| \begin{verbatim} | |
| $ php composer.phar help install | |
| \end{verbatim} | |
| \subsection{Environment variables}\label{environment-variables} | |
| You can set a number of environment variables that override certain | |
| settings. Whenever possible it is recommended to specify these settings | |
| in the \texttt{config} section of \texttt{composer.json} instead. It is | |
| worth noting that the env vars will always take precedence over the | |
| values specified in \texttt{composer.json}. | |
| \subsubsection{COMPOSER}\label{composer} | |
| By setting the \texttt{COMPOSER} env variable it is possible to set the | |
| filename of \texttt{composer.json} to something else. | |
| For example: | |
| \begin{verbatim} | |
| $ COMPOSER=composer-other.json php composer.phar install | |
| \end{verbatim} | |
| \subsubsection{COMPOSER\_ROOT\_VERSION}\label{composer_root_version} | |
| By setting this var you can specify the version of the root package, if | |
| it can not be guessed from VCS info and is not present in | |
| \texttt{composer.json}. | |
| \subsubsection{COMPOSER\_VENDOR\_DIR}\label{composer_vendor_dir} | |
| By setting this var you can make composer install the dependencies into | |
| a directory other than \texttt{vendor}. | |
| \subsubsection{COMPOSER\_BIN\_DIR}\label{composer_bin_dir} | |
| By setting this option you can change the \texttt{bin} | |
| (\href{articles/vendor-binaries.md}{Vendor Binaries}) directory to | |
| something other than \texttt{vendor/bin}. | |
| \subsubsection{http\_proxy or | |
| HTTP\_PROXY}\label{http_proxy-or-http_proxy} | |
| If you are using composer from behind an HTTP proxy, you can use the | |
| standard \texttt{http\_proxy} or \texttt{HTTP\_PROXY} env vars. Simply | |
| set it to the URL of your proxy. Many operating systems already set this | |
| variable for you. | |
| Using \texttt{http\_proxy} (lowercased) or even defining both might be | |
| preferable since some tools like git or curl will only use the | |
| lower-cased \texttt{http\_proxy} version. Alternatively you can also | |
| define the git proxy using | |
| \texttt{git config -{}-global http.proxy \textless{}proxy url\textgreater{}}. | |
| \subsubsection{no\_proxy}\label{no_proxy} | |
| If you are behind a proxy and would like to disable it for certain | |
| domains, you can use the \texttt{no\_proxy} env var. Simply set it to a | |
| comma separated list of domains the proxy should \emph{not} be used for. | |
| The env var accepts domains, IP addresses, and IP address blocks in CIDR | |
| notation. You can restrict the filter to a particular port (e.g. | |
| \texttt{:80}). You can also set it to \texttt{*} to ignore the proxy for | |
| all HTTP requests. | |
| \subsubsection{HTTP\_PROXY\_REQUEST\_FULLURI}\label{http_proxy_request_fulluri} | |
| If you use a proxy but it does not support the request\_fulluri flag, | |
| then you should set this env var to \texttt{false} or \texttt{0} to | |
| prevent composer from setting the request\_fulluri option. | |
| \subsubsection{HTTPS\_PROXY\_REQUEST\_FULLURI}\label{https_proxy_request_fulluri} | |
| If you use a proxy but it does not support the request\_fulluri flag for | |
| HTTPS requests, then you should set this env var to \texttt{false} or | |
| \texttt{0} to prevent composer from setting the request\_fulluri option. | |
| \subsubsection{COMPOSER\_HOME}\label{composer_home} | |
| The \texttt{COMPOSER\_HOME} var allows you to change the composer home | |
| directory. This is a hidden, global (per-user on the machine) directory | |
| that is shared between all projects. | |
| By default it points to | |
| \texttt{/home/\textless{}user\textgreater{}/.composer} on *nix, | |
| \texttt{/Users/\textless{}user\textgreater{}/.composer} on OSX and | |
| \texttt{C:\textbackslash{}Users\textbackslash{}\textless{}user\textgreater{}\textbackslash{}AppData\textbackslash{}Roaming\textbackslash{}Composer} | |
| on Windows. | |
| \paragraph{COMPOSER\_HOME/config.json}\label{composer_homeconfig.json} | |
| You may put a \texttt{config.json} file into the location which | |
| \texttt{COMPOSER\_HOME} points to. Composer will merge this | |
| configuration with your project's \texttt{composer.json} when you run | |
| the \texttt{install} and \texttt{update} commands. | |
| This file allows you to set \href{04-schema.md\#config}{configuration} | |
| and \href{05-repositories.md}{repositories} for the user's projects. | |
| In case global configuration matches \emph{local} configuration, the | |
| \emph{local} configuration in the project's \texttt{composer.json} | |
| always wins. | |
| \subsubsection{COMPOSER\_CACHE\_DIR}\label{composer_cache_dir} | |
| The \texttt{COMPOSER\_CACHE\_DIR} var allows you to change the composer | |
| cache directory, which is also configurable via the | |
| \href{04-schema.md\#config}{\texttt{cache-dir}} option. | |
| By default it points to \$COMPOSER\_HOME/cache on *nix and OSX, and | |
| \texttt{C:\textbackslash{}Users\textbackslash{}\textless{}user\textgreater{}\textbackslash{}AppData\textbackslash{}Local\textbackslash{}Composer} | |
| (or \texttt{\%LOCALAPPDATA\%/Composer}) on Windows. | |
| \subsubsection{COMPOSER\_PROCESS\_TIMEOUT}\label{composer_process_timeout} | |
| This env var controls the time composer waits for commands (such as git | |
| commands) to finish executing. The default value is 300 seconds (5 | |
| minutes). | |
| \subsubsection{COMPOSER\_DISCARD\_CHANGES}\label{composer_discard_changes} | |
| This env var controls the discard-changes | |
| \href{04-schema.md\#config}{config option}. | |
| \subsubsection{COMPOSER\_NO\_INTERACTION}\label{composer_no_interaction} | |
| If set to 1, this env var will make composer behave as if you passed the | |
| \texttt{-{}-no-interaction} flag to every command. This can be set on | |
| build boxes/CI. | |
| ← \href{02-libraries.md}{Libraries} \textbar{} | |
| \href{04-schema.md}{Schema} → | |
| \section{composer.json}\label{composer.json} | |
| This chapter will explain all of the fields available in | |
| \texttt{composer.json}. | |
| \subsection{JSON schema}\label{json-schema} | |
| We have a \href{http://json-schema.org}{JSON schema} that documents the | |
| format and can also be used to validate your \texttt{composer.json}. In | |
| fact, it is used by the \texttt{validate} command. You can find it at: | |
| \href{https://github.com/composer/composer/blob/master/res/composer-schema.json}{\texttt{res/composer-schema.json}}. | |
| \subsection{Root Package}\label{root-package} | |
| The root package is the package defined by the \texttt{composer.json} at | |
| the root of your project. It is the main \texttt{composer.json} that | |
| defines your project requirements. | |
| Certain fields only apply when in the root package context. One example | |
| of this is the \texttt{config} field. Only the root package can define | |
| configuration. The config of dependencies is ignored. This makes the | |
| \texttt{config} field \texttt{root-only}. | |
| If you clone one of those dependencies to work on it, then that package | |
| is the root package. The \texttt{composer.json} is identical, but the | |
| context is different. | |
| \begin{quote} | |
| \textbf{Note:} A package can be the root package or not, depending on | |
| the context. For example, if your project depends on the | |
| \texttt{monolog} library, your project is the root package. However, if | |
| you clone \texttt{monolog} from GitHub in order to fix a bug in it, then | |
| \texttt{monolog} is the root package. | |
| \end{quote} | |
| \subsection{Properties}\label{properties} | |
| \subsubsection{name}\label{name} | |
| The name of the package. It consists of vendor name and project name, | |
| separated by \texttt{/}. | |
| Examples: | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| monolog/monolog | |
| \item | |
| igorw/event-source | |
| \end{itemize} | |
| Required for published packages (libraries). | |
| \subsubsection{description}\label{description} | |
| A short description of the package. Usually this is just one line long. | |
| Required for published packages (libraries). | |
| \subsubsection{version}\label{version} | |
| The version of the package. In most cases this is not required and | |
| should be omitted (see below). | |
| This must follow the format of \texttt{X.Y.Z} or \texttt{vX.Y.Z} with an | |
| optional suffix of \texttt{-dev}, \texttt{-patch}, \texttt{-alpha}, | |
| \texttt{-beta} or \texttt{-RC}. The patch, alpha, beta and RC suffixes | |
| can also be followed by a number. | |
| Examples: | |
| \begin{verbatim} | |
| 1.0.0 | |
| 1.0.2 | |
| 1.1.0 | |
| 0.2.5 | |
| 1.0.0-dev | |
| 1.0.0-alpha3 | |
| 1.0.0-beta2 | |
| 1.0.0-RC5 | |
| \end{verbatim} | |
| Optional if the package repository can infer the version from somewhere, | |
| such as the VCS tag name in the VCS repository. In that case it is also | |
| recommended to omit it. | |
| \begin{quote} | |
| \textbf{Note:} Packagist uses VCS repositories, so the statement above | |
| is very much true for Packagist as well. Specifying the version yourself | |
| will most likely end up creating problems at some point due to human | |
| error. | |
| \end{quote} | |
| \subsubsection{type}\label{type} | |
| The type of the package. It defaults to \texttt{library}. | |
| Package types are used for custom installation logic. If you have a | |
| package that needs some special logic, you can define a custom type. | |
| This could be a \texttt{symfony-bundle}, a \texttt{wordpress-plugin} or | |
| a \texttt{typo3-module}. These types will all be specific to certain | |
| projects, and they will need to provide an installer capable of | |
| installing packages of that type. | |
| Out of the box, composer supports three types: | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{library:} This is the default. It will simply copy the files | |
| to \texttt{vendor}. | |
| \item | |
| \textbf{project:} This denotes a project rather than a library. For | |
| example application shells like the | |
| \href{https://github.com/symfony/symfony-standard}{Symfony standard | |
| edition}, CMSs like the | |
| \href{https://github.com/silverstripe/silverstripe-installer}{SilverStripe | |
| installer} or full fledged applications distributed as packages. This | |
| can for example be used by IDEs to provide listings of projects to | |
| initialize when creating a new workspace. | |
| \item | |
| \textbf{metapackage:} An empty package that contains requirements and | |
| will trigger their installation, but contains no files and will not | |
| write anything to the filesystem. As such, it does not require a dist | |
| or source key to be installable. | |
| \item | |
| \textbf{composer-plugin:} A package of type \texttt{composer-plugin} | |
| may provide an installer for other packages that have a custom type. | |
| Read more in the \href{articles/custom-installers.md}{dedicated | |
| article}. | |
| \end{itemize} | |
| Only use a custom type if you need custom logic during installation. It | |
| is recommended to omit this field and have it just default to | |
| \texttt{library}. | |
| \subsubsection{keywords}\label{keywords} | |
| An array of keywords that the package is related to. These can be used | |
| for searching and filtering. | |
| Examples: | |
| \begin{verbatim} | |
| logging | |
| events | |
| database | |
| redis | |
| templating | |
| \end{verbatim} | |
| Optional. | |
| \subsubsection{homepage}\label{homepage} | |
| An URL to the website of the project. | |
| Optional. | |
| \subsubsection{time}\label{time} | |
| Release date of the version. | |
| Must be in \texttt{YYYY-MM-DD} or \texttt{YYYY-MM-DD HH:MM:SS} format. | |
| Optional. | |
| \subsubsection{license}\label{license} | |
| The license of the package. This can be either a string or an array of | |
| strings. | |
| The recommended notation for the most common licenses is (alphabetical): | |
| \begin{verbatim} | |
| Apache-2.0 | |
| BSD-2-Clause | |
| BSD-3-Clause | |
| BSD-4-Clause | |
| GPL-2.0 | |
| GPL-2.0+ | |
| GPL-3.0 | |
| GPL-3.0+ | |
| LGPL-2.1 | |
| LGPL-2.1+ | |
| LGPL-3.0 | |
| LGPL-3.0+ | |
| MIT | |
| \end{verbatim} | |
| Optional, but it is highly recommended to supply this. More identifiers | |
| are listed at the \href{http://www.spdx.org/licenses/}{SPDX Open Source | |
| License Registry}. | |
| For closed-source software, you may use \texttt{"proprietary"} as the | |
| license identifier. | |
| An Example: | |
| \begin{verbatim} | |
| { | |
| "license": "MIT" | |
| } | |
| \end{verbatim} | |
| For a package, when there is a choice between licenses (``disjunctive | |
| license''), multiple can be specified as array. | |
| An Example for disjunctive licenses: | |
| \begin{verbatim} | |
| { | |
| "license": [ | |
| "LGPL-2.1", | |
| "GPL-3.0+" | |
| ] | |
| } | |
| \end{verbatim} | |
| Alternatively they can be separated with ``or'' and enclosed in | |
| parenthesis; | |
| \begin{verbatim} | |
| { | |
| "license": "(LGPL-2.1 or GPL-3.0+)" | |
| } | |
| \end{verbatim} | |
| Similarly when multiple licenses need to be applied (``conjunctive | |
| license''), they should be separated with ``and'' and enclosed in | |
| parenthesis. | |
| \subsubsection{authors}\label{authors} | |
| The authors of the package. This is an array of objects. | |
| Each author object can have following properties: | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{name:} The author's name. Usually his real name. | |
| \item | |
| \textbf{email:} The author's email address. | |
| \item | |
| \textbf{homepage:} An URL to the author's website. | |
| \item | |
| \textbf{role:} The authors' role in the project (e.g.~developer or | |
| translator) | |
| \end{itemize} | |
| An example: | |
| \begin{verbatim} | |
| { | |
| "authors": [ | |
| { | |
| "name": "Nils Adermann", | |
| "email": "naderman@naderman.de", | |
| "homepage": "http://www.naderman.de", | |
| "role": "Developer" | |
| }, | |
| { | |
| "name": "Jordi Boggiano", | |
| "email": "j.boggiano@seld.be", | |
| "homepage": "http://seld.be", | |
| "role": "Developer" | |
| } | |
| ] | |
| } | |
| \end{verbatim} | |
| Optional, but highly recommended. | |
| \subsubsection{support}\label{support} | |
| Various information to get support about the project. | |
| Support information includes the following: | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{email:} Email address for support. | |
| \item | |
| \textbf{issues:} URL to the Issue Tracker. | |
| \item | |
| \textbf{forum:} URL to the Forum. | |
| \item | |
| \textbf{wiki:} URL to the Wiki. | |
| \item | |
| \textbf{irc:} IRC channel for support, as irc://server/channel. | |
| \item | |
| \textbf{source:} URL to browse or download the sources. | |
| \end{itemize} | |
| An example: | |
| \begin{verbatim} | |
| { | |
| "support": { | |
| "email": "support@example.org", | |
| "irc": "irc://irc.freenode.org/composer" | |
| } | |
| } | |
| \end{verbatim} | |
| Optional. | |
| \hyperdef{}{package-links}{\subsubsection{Package | |
| links}\label{package-links}} | |
| All of the following take an object which maps package names to | |
| \href{01-basic-usage.md\#package-versions}{version constraints}. | |
| Example: | |
| \begin{verbatim} | |
| { | |
| "require": { | |
| "monolog/monolog": "1.0.*" | |
| } | |
| } | |
| \end{verbatim} | |
| All links are optional fields. | |
| \texttt{require} and \texttt{require-dev} additionally support stability | |
| flags (root-only). These allow you to further restrict or expand the | |
| stability of a package beyond the scope of the | |
| \hyperref[minimum-stability]{minimum-stability} setting. You can apply | |
| them to a constraint, or just apply them to an empty constraint if you | |
| want to allow unstable packages of a dependency for example. | |
| Example: | |
| \begin{verbatim} | |
| { | |
| "require": { | |
| "monolog/monolog": "1.0.*@beta", | |
| "acme/foo": "@dev" | |
| } | |
| } | |
| \end{verbatim} | |
| If one of your dependencies has a dependency on an unstable package you | |
| need to explicitly require it as well, along with its sufficient | |
| stability flag. | |
| Example: | |
| \begin{verbatim} | |
| { | |
| "require": { | |
| "doctrine/doctrine-fixtures-bundle": "dev-master", | |
| "doctrine/data-fixtures": "@dev" | |
| } | |
| } | |
| \end{verbatim} | |
| \texttt{require} and \texttt{require-dev} additionally support explicit | |
| references (i.e.~commit) for dev versions to make sure they are locked | |
| to a given state, even when you run update. These only work if you | |
| explicitly require a dev version and append the reference with | |
| \texttt{\#\textless{}ref\textgreater{}}. Note that while this is | |
| convenient at times, it should not really be how you use packages in the | |
| long term. You should always try to switch to tagged releases as soon as | |
| you can, especially if the project you work on will not be touched for a | |
| while. | |
| Example: | |
| \begin{verbatim} | |
| { | |
| "require": { | |
| "monolog/monolog": "dev-master#2eb0c0978d290a1c45346a1955188929cb4e5db7", | |
| "acme/foo": "1.0.x-dev#abc123" | |
| } | |
| } | |
| \end{verbatim} | |
| It is possible to inline-alias a package constraint so that it matches a | |
| constraint that it otherwise would not. For more information | |
| \href{articles/aliases.md}{see the aliases article}. | |
| \paragraph{require}\label{require} | |
| Lists packages required by this package. The package will not be | |
| installed unless those requirements can be met. | |
| \paragraph{require-dev {(root-only)}}\label{require-dev-root-only} | |
| Lists packages required for developing this package, or running tests, | |
| etc. The dev requirements of the root package are installed by default. | |
| Both \texttt{install} or \texttt{update} support the \texttt{-{}-no-dev} | |
| option that prevents dev dependencies from being installed. | |
| \paragraph{conflict}\label{conflict} | |
| Lists packages that conflict with this version of this package. They | |
| will not be allowed to be installed together with your package. | |
| Note that when specifying ranges like | |
| \texttt{\textless{}1.0, \textgreater{}= 1.1} in a \texttt{conflict} | |
| link, this will state a conflict with all versions that are less than | |
| 1.0 \emph{and} equal or newer than 1.1 at the same time, which is | |
| probably not what you want. You probably want to go for | |
| \texttt{\textless{}1.0 \textbar{} \textgreater{}= 1.1} in this case. | |
| \paragraph{replace}\label{replace} | |
| Lists packages that are replaced by this package. This allows you to | |
| fork a package, publish it under a different name with its own version | |
| numbers, while packages requiring the original package continue to work | |
| with your fork because it replaces the original package. | |
| This is also useful for packages that contain sub-packages, for example | |
| the main symfony/symfony package contains all the Symfony Components | |
| which are also available as individual packages. If you require the main | |
| package it will automatically fulfill any requirement of one of the | |
| individual components, since it replaces them. | |
| Caution is advised when using replace for the sub-package purpose | |
| explained above. You should then typically only replace using | |
| \texttt{self.version} as a version constraint, to make sure the main | |
| package only replaces the sub-packages of that exact version, and not | |
| any other version, which would be incorrect. | |
| \paragraph{provide}\label{provide} | |
| List of other packages that are provided by this package. This is mostly | |
| useful for common interfaces. A package could depend on some virtual | |
| \texttt{logger} package, any library that implements this logger | |
| interface would simply list it in \texttt{provide}. | |
| \subsubsection{suggest}\label{suggest} | |
| Suggested packages that can enhance or work well with this package. | |
| These are just informational and are displayed after the package is | |
| installed, to give your users a hint that they could add more packages, | |
| even though they are not strictly required. | |
| The format is like package links above, except that the values are free | |
| text and not version constraints. | |
| Example: | |
| \begin{verbatim} | |
| { | |
| "suggest": { | |
| "monolog/monolog": "Allows more advanced logging of the application flow" | |
| } | |
| } | |
| \end{verbatim} | |
| \subsubsection{autoload}\label{autoload} | |
| Autoload mapping for a PHP autoloader. | |
| Currently | |
| \href{https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md}{\texttt{PSR-0}} | |
| autoloading, \texttt{classmap} generation and \texttt{files} are | |
| supported. PSR-0 is the recommended way though since it offers greater | |
| flexibility (no need to regenerate the autoloader when you add classes). | |
| \paragraph{PSR-0}\label{psr-0} | |
| Under the \texttt{psr-0} key you define a mapping from namespaces to | |
| paths, relative to the package root. Note that this also supports the | |
| PEAR-style non-namespaced convention. | |
| Please note namespace declarations should end in | |
| \texttt{\textbackslash{}\textbackslash{}} to make sure the autoloader | |
| responds exactly. For example \texttt{Foo} would match in | |
| \texttt{FooBar} so the trailing backslashes solve the problem: | |
| \texttt{Foo\textbackslash{}\textbackslash{}} and | |
| \texttt{FooBar\textbackslash{}\textbackslash{}} are distinct. | |
| The PSR-0 references are all combined, during install/update, into a | |
| single key =\textgreater{} value array which may be found in the | |
| generated file \texttt{vendor/composer/autoload\_namespaces.php}. | |
| Example: | |
| \begin{verbatim} | |
| { | |
| "autoload": { | |
| "psr-0": { | |
| "Monolog\\": "src/", | |
| "Vendor\\Namespace\\": "src/", | |
| "Vendor_Namespace_": "src/" | |
| } | |
| } | |
| } | |
| \end{verbatim} | |
| If you need to search for a same prefix in multiple directories, you can | |
| specify them as an array as such: | |
| \begin{verbatim} | |
| { | |
| "autoload": { | |
| "psr-0": { "Monolog\\": ["src/", "lib/"] } | |
| } | |
| } | |
| \end{verbatim} | |
| The PSR-0 style is not limited to namespace declarations only but may be | |
| specified right down to the class level. This can be useful for | |
| libraries with only one class in the global namespace. If the php source | |
| file is also located in the root of the package, for example, it may be | |
| declared like this: | |
| \begin{verbatim} | |
| { | |
| "autoload": { | |
| "psr-0": { "UniqueGlobalClass": "" } | |
| } | |
| } | |
| \end{verbatim} | |
| If you want to have a fallback directory where any namespace can be, you | |
| can use an empty prefix like: | |
| \begin{verbatim} | |
| { | |
| "autoload": { | |
| "psr-0": { "": "src/" } | |
| } | |
| } | |
| \end{verbatim} | |
| \paragraph{Classmap}\label{classmap} | |
| The \texttt{classmap} references are all combined, during | |
| install/update, into a single key =\textgreater{} value array which may | |
| be found in the generated file | |
| \texttt{vendor/composer/autoload\_classmap.php}. This map is built by | |
| scanning for classes in all \texttt{.php} and \texttt{.inc} files in the | |
| given directories/files. | |
| You can use the classmap generation support to define autoloading for | |
| all libraries that do not follow PSR-0. To configure this you specify | |
| all directories or files to search for classes. | |
| Example: | |
| \begin{verbatim} | |
| { | |
| "autoload": { | |
| "classmap": ["src/", "lib/", "Something.php"] | |
| } | |
| } | |
| \end{verbatim} | |
| \paragraph{Files}\label{files} | |
| If you want to require certain files explicitly on every request then | |
| you can use the `files' autoloading mechanism. This is useful if your | |
| package includes PHP functions that cannot be autoloaded by PHP. | |
| Example: | |
| \begin{verbatim} | |
| { | |
| "autoload": { | |
| "files": ["src/MyLibrary/functions.php"] | |
| } | |
| } | |
| \end{verbatim} | |
| \subsubsection{include-path}\label{include-path} | |
| \begin{quote} | |
| \textbf{DEPRECATED}: This is only present to support legacy projects, | |
| and all new code should preferably use autoloading. As such it is a | |
| deprecated practice, but the feature itself will not likely disappear | |
| from Composer. | |
| \end{quote} | |
| A list of paths which should get appended to PHP's | |
| \texttt{include\_path}. | |
| Example: | |
| \begin{verbatim} | |
| { | |
| "include-path": ["lib/"] | |
| } | |
| \end{verbatim} | |
| Optional. | |
| \subsubsection{target-dir}\label{target-dir} | |
| Defines the installation target. | |
| In case the package root is below the namespace declaration you cannot | |
| autoload properly. \texttt{target-dir} solves this problem. | |
| An example is Symfony. There are individual packages for the components. | |
| The Yaml component is under | |
| \texttt{Symfony\textbackslash{}Component\textbackslash{}Yaml}. The | |
| package root is that \texttt{Yaml} directory. To make autoloading | |
| possible, we need to make sure that it is not installed into | |
| \texttt{vendor/symfony/yaml}, but instead into | |
| \texttt{vendor/symfony/yaml/Symfony/Component/Yaml}, so that the | |
| autoloader can load it from \texttt{vendor/symfony/yaml}. | |
| To do that, \texttt{autoload} and \texttt{target-dir} are defined as | |
| follows: | |
| \begin{verbatim} | |
| { | |
| "autoload": { | |
| "psr-0": { "Symfony\\Component\\Yaml\\": "" } | |
| }, | |
| "target-dir": "Symfony/Component/Yaml" | |
| } | |
| \end{verbatim} | |
| Optional. | |
| \subsubsection{minimum-stability | |
| {(root-only)}}\label{minimum-stability-root-only} | |
| This defines the default behavior for filtering packages by stability. | |
| This defaults to \texttt{stable}, so if you rely on a \texttt{dev} | |
| package, you should specify it in your file to avoid surprises. | |
| All versions of each package are checked for stability, and those that | |
| are less stable than the \texttt{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 | |
| \texttt{require} or \texttt{require-dev} (see | |
| \hyperref[package-links]{package links}). | |
| Available options (in order of stability) are \texttt{dev}, | |
| \texttt{alpha}, \texttt{beta}, \texttt{RC}, and \texttt{stable}. | |
| \subsubsection{prefer-stable | |
| {(root-only)}}\label{prefer-stable-root-only} | |
| When this is enabled, Composer will prefer more stable packages over | |
| unstable ones when finding compatible stable packages is possible. If | |
| you require a dev version or only alphas are available for a package, | |
| those will still be selected granted that the minimum-stability allows | |
| for it. | |
| Use \texttt{"prefer-stable": true} to enable. | |
| \subsubsection{repositories {(root-only)}}\label{repositories-root-only} | |
| Custom package repositories to use. | |
| By default composer just uses the packagist repository. By specifying | |
| repositories you can get packages from elsewhere. | |
| Repositories are not resolved recursively. You can only add them to your | |
| main \texttt{composer.json}. Repository declarations of dependencies' | |
| \texttt{composer.json}s are ignored. | |
| The following repository types are supported: | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{composer:} A composer repository is simply a | |
| \texttt{packages.json} file served via the network (HTTP, FTP, SSH), | |
| that contains a list of \texttt{composer.json} objects with additional | |
| \texttt{dist} and/or \texttt{source} information. The | |
| \texttt{packages.json} file is loaded using a PHP stream. You can set | |
| extra options on that stream using the \texttt{options} parameter. | |
| \item | |
| \textbf{vcs:} The version control system repository can fetch packages | |
| from git, svn and hg repositories. | |
| \item | |
| \textbf{pear:} With this you can import any pear repository into your | |
| composer project. | |
| \item | |
| \textbf{package:} If you depend on a project that does not have any | |
| support for composer whatsoever you can define the package inline | |
| using a \texttt{package} repository. You basically just inline the | |
| \texttt{composer.json} object. | |
| \end{itemize} | |
| For more information on any of these, see | |
| \href{05-repositories.md}{Repositories}. | |
| Example: | |
| \begin{verbatim} | |
| { | |
| "repositories": [ | |
| { | |
| "type": "composer", | |
| "url": "http://packages.example.com" | |
| }, | |
| { | |
| "type": "composer", | |
| "url": "https://packages.example.com", | |
| "options": { | |
| "ssl": { | |
| "verify_peer": "true" | |
| } | |
| } | |
| }, | |
| { | |
| "type": "vcs", | |
| "url": "https://github.com/Seldaek/monolog" | |
| }, | |
| { | |
| "type": "pear", | |
| "url": "http://pear2.php.net" | |
| }, | |
| { | |
| "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/" | |
| } | |
| } | |
| } | |
| ] | |
| } | |
| \end{verbatim} | |
| \begin{quote} | |
| \textbf{Note:} Order is significant here. When looking for a package, | |
| Composer will look from the first to the last repository, and pick the | |
| first match. By default Packagist is added last which means that custom | |
| repositories can override packages from it. | |
| \end{quote} | |
| \subsubsection{config {(root-only)}}\label{config-root-only} | |
| A set of configuration options. It is only used for projects. | |
| The following options are supported: | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{process-timeout:} Defaults to \texttt{300}. The duration | |
| processes like git clones can run before Composer assumes they died | |
| out. You may need to make this higher if you have a slow connection or | |
| huge vendors. | |
| \item | |
| \textbf{use-include-path:} Defaults to \texttt{false}. If true, the | |
| Composer autoloader will also look for classes in the PHP include | |
| path. | |
| \item | |
| \textbf{preferred-install:} Defaults to \texttt{auto} and can be any | |
| of \texttt{source}, \texttt{dist} or \texttt{auto}. This option allows | |
| you to set the install method Composer will prefer to use. | |
| \item | |
| \textbf{github-protocols:} Defaults to \texttt{{[}"git", "https"{]}}. | |
| A list of protocols to use when cloning from github.com, in priority | |
| order. You can reconfigure it to prioritize the https protocol if you | |
| are behind a proxy or have somehow bad performances with the git | |
| protocol. | |
| \item | |
| \textbf{github-oauth:} A list of domain names and oauth keys. For | |
| example using \texttt{\{"github.com": "oauthtoken"\}} as the value of | |
| this option will use \texttt{oauthtoken} to access private | |
| repositories on github and to circumvent the low IP-based rate | |
| limiting of their API. | |
| \item | |
| \textbf{vendor-dir:} Defaults to \texttt{vendor}. You can install | |
| dependencies into a different directory if you want to. | |
| \item | |
| \textbf{bin-dir:} Defaults to \texttt{vendor/bin}. If a project | |
| includes binaries, they will be symlinked into this directory. | |
| \item | |
| \textbf{cache-dir:} Defaults to \texttt{\$home/cache} on unix systems | |
| and | |
| \texttt{C:\textbackslash{}Users\textbackslash{}\textless{}user\textgreater{}\textbackslash{}AppData\textbackslash{}Local\textbackslash{}Composer} | |
| on Windows. Stores all the caches used by composer. See also | |
| \href{03-cli.md\#composer-home}{COMPOSER\_HOME}. | |
| \item | |
| \textbf{cache-files-dir:} Defaults to \texttt{\$cache-dir/files}. | |
| Stores the zip archives of packages. | |
| \item | |
| \textbf{cache-repo-dir:} Defaults to \texttt{\$cache-dir/repo}. Stores | |
| repository metadata for the \texttt{composer} type and the VCS repos | |
| of type \texttt{svn}, \texttt{github} and \texttt{bitbucket}. | |
| \item | |
| \textbf{cache-vcs-dir:} Defaults to \texttt{\$cache-dir/vcs}. Stores | |
| VCS clones for loading VCS repository metadata for the | |
| \texttt{git}/\texttt{hg} types and to speed up installs. | |
| \item | |
| \textbf{cache-files-ttl:} Defaults to \texttt{15552000} (6 months). | |
| Composer caches all dist (zip, tar, ..) packages that it downloads. | |
| Those are purged after six months of being unused by default. This | |
| option allows you to tweak this duration (in seconds) or disable it | |
| completely by setting it to 0. | |
| \item | |
| \textbf{cache-files-maxsize:} Defaults to \texttt{300MiB}. Composer | |
| caches all dist (zip, tar, ..) packages that it downloads. When the | |
| garbage collection is periodically ran, this is the maximum size the | |
| cache will be able to use. Older (less used) files will be removed | |
| first until the cache fits. | |
| \item | |
| \textbf{notify-on-install:} Defaults to \texttt{true}. Composer allows | |
| repositories to define a notification URL, so that they get notified | |
| whenever a package from that repository is installed. This option | |
| allows you to disable that behaviour. | |
| \item | |
| \textbf{discard-changes:} Defaults to \texttt{false} and can be any of | |
| \texttt{true}, \texttt{false} or \texttt{"stash"}. This option allows | |
| you to set the default style of handling dirty updates when in | |
| non-interactive mode. \texttt{true} will always discard changes in | |
| vendors, while \texttt{"stash"} will try to stash and reapply. Use | |
| this for CI servers or deploy scripts if you tend to have modified | |
| vendors. | |
| \end{itemize} | |
| Example: | |
| \begin{verbatim} | |
| { | |
| "config": { | |
| "bin-dir": "bin" | |
| } | |
| } | |
| \end{verbatim} | |
| \subsubsection{scripts {(root-only)}}\label{scripts-root-only} | |
| Composer allows you to hook into various parts of the installation | |
| process through the use of scripts. | |
| See \href{articles/scripts.md}{Scripts} for events details and examples. | |
| \subsubsection{extra}\label{extra} | |
| Arbitrary extra data for consumption by \texttt{scripts}. | |
| This can be virtually anything. To access it from within a script event | |
| handler, you can do: | |
| \begin{verbatim} | |
| $extra = $event->getComposer()->getPackage()->getExtra(); | |
| \end{verbatim} | |
| Optional. | |
| \subsubsection{bin}\label{bin} | |
| A set of files that should be treated as binaries and symlinked into the | |
| \texttt{bin-dir} (from config). | |
| See \href{articles/vendor-binaries.md}{Vendor Binaries} for more | |
| details. | |
| Optional. | |
| \subsubsection{archive}\label{archive} | |
| A set of options for creating package archives. | |
| The following options are supported: | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{exclude:} Allows configuring a list of patterns for excluded | |
| paths. The pattern syntax matches .gitignore files. A leading | |
| exclamation mark (!) will result in any matching files to be included | |
| even if a previous pattern excluded them. A leading slash will only | |
| match at the beginning of the project relative path. An asterisk will | |
| not expand to a directory separator. | |
| \end{itemize} | |
| Example: | |
| \begin{verbatim} | |
| { | |
| "archive": { | |
| "exclude": ["/foo/bar", "baz", "/*.test", "!/foo/bar/baz"] | |
| } | |
| } | |
| \end{verbatim} | |
| The example will include \texttt{/dir/foo/bar/file}, | |
| \texttt{/foo/bar/baz}, \texttt{/file.php}, \texttt{/foo/my.test} but it | |
| will exclude \texttt{/foo/bar/any}, \texttt{/foo/baz}, and | |
| \texttt{/my.test}. | |
| Optional. | |
| ← \href{03-cli.md}{Command-line interface} \textbar{} | |
| \href{05-repositories.md}{Repositories} → | |
| \section{Repositories}\label{repositories} | |
| This chapter will explain the concept of packages and repositories, what | |
| kinds of repositories are available, and how they work. | |
| \subsection{Concepts}\label{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. | |
| \subsubsection{Package}\label{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. | |
| \textbf{Dist:} The dist is a packaged version of the package data. | |
| Usually a released version, usually a stable release. | |
| \textbf{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. | |
| \subsubsection{Repository}\label{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 | |
| \texttt{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. | |
| \subsection{Types}\label{types} | |
| \subsubsection{Composer}\label{composer} | |
| The main repository type is the \texttt{composer} repository. It uses a | |
| single \texttt{packages.json} file that contains all of the package | |
| metadata. | |
| This is also the repository type that packagist uses. To reference a | |
| \texttt{composer} repository, just supply the path before the | |
| \texttt{packages.json} file. In case of packagist, that file is located | |
| at \texttt{/packages.json}, so the URL of the repository would be | |
| \texttt{packagist.org}. For \texttt{example.org/packages.json} the | |
| repository URL would be \texttt{example.org}. | |
| \hyperdef{}{packages}{\paragraph{packages}\label{packages}} | |
| The only required field is \texttt{packages}. The JSON structure is as | |
| follows: | |
| \begin{verbatim} | |
| { | |
| "packages": { | |
| "vendor/package-name": { | |
| "dev-master": { @composer.json }, | |
| "1.0.x-dev": { @composer.json }, | |
| "0.0.1": { @composer.json }, | |
| "1.0.0": { @composer.json } | |
| } | |
| } | |
| } | |
| \end{verbatim} | |
| The \texttt{@composer.json} marker would be the contents of the | |
| \texttt{composer.json} from that package version including as a minimum: | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| name | |
| \item | |
| version | |
| \item | |
| dist or source | |
| \end{itemize} | |
| Here is a minimal package definition: | |
| \begin{verbatim} | |
| { | |
| "name": "smarty/smarty", | |
| "version": "3.1.7", | |
| "dist": { | |
| "url": "http://www.smarty.net/files/Smarty-3.1.7.zip", | |
| "type": "zip" | |
| } | |
| } | |
| \end{verbatim} | |
| It may include any of the other fields specified in the | |
| \href{04-schema.md}{schema}. | |
| \paragraph{notify-batch}\label{notify-batch} | |
| The \texttt{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: | |
| \begin{verbatim} | |
| { | |
| "notify-batch": "/downloads/" | |
| } | |
| \end{verbatim} | |
| For \texttt{example.org/packages.json} containing a | |
| \texttt{monolog/monolog} package, this would send a \texttt{POST} | |
| request to \texttt{example.org/downloads/} with following JSON request | |
| body: | |
| \begin{verbatim} | |
| { | |
| "downloads": [ | |
| {"name": "monolog/monolog", "version": "1.2.1.0"}, | |
| ] | |
| } | |
| \end{verbatim} | |
| The version field will contain the normalized representation of the | |
| version number. | |
| This field is optional. | |
| \paragraph{includes}\label{includes} | |
| For larger repositories it is possible to split the | |
| \texttt{packages.json} into multiple files. The \texttt{includes} field | |
| allows you to reference these additional files. | |
| An example: | |
| \begin{verbatim} | |
| { | |
| "includes": { | |
| "packages-2011.json": { | |
| "sha1": "525a85fb37edd1ad71040d429928c2c0edec9d17" | |
| }, | |
| "packages-2012-01.json": { | |
| "sha1": "897cde726f8a3918faf27c803b336da223d400dd" | |
| }, | |
| "packages-2012-02.json": { | |
| "sha1": "26f911ad717da26bbcac3f8f435280d13917efa5" | |
| } | |
| } | |
| } | |
| \end{verbatim} | |
| 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. | |
| \paragraph{provider-includes and | |
| providers-url}\label{provider-includes-and-providers-url} | |
| For very large repositories like packagist.org using the so-called | |
| provider files is the preferred method. The \texttt{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 \texttt{providers-url} describes how provider files are found on the | |
| server. It is an absolute path from the repository root. | |
| An example: | |
| \begin{verbatim} | |
| { | |
| "provider-includes": { | |
| "providers-a.json": { | |
| "sha256": "f5b4bc0b354108ef08614e569c1ed01a2782e67641744864a74e788982886f4c" | |
| }, | |
| "providers-b.json": { | |
| "sha256": "b38372163fac0573053536f5b8ef11b86f804ea8b016d239e706191203f6efac" | |
| } | |
| }, | |
| "providers-url": "/p/%package%$%hash%.json" | |
| } | |
| \end{verbatim} | |
| Those files contain lists of package names and hashes to verify the file | |
| integrity, for example: | |
| \begin{verbatim} | |
| { | |
| "providers": { | |
| "acme/foo": { | |
| "sha256": "38968de1305c2e17f4de33aea164515bc787c42c7e2d6e25948539a14268bb82" | |
| }, | |
| "acme/bar": { | |
| "sha256": "4dd24c930bd6e1103251306d6336ac813b563a220d9ca14f4743c032fb047233" | |
| } | |
| } | |
| } | |
| \end{verbatim} | |
| The file above declares that acme/foo and acme/bar can be found in this | |
| repository, by loading the file referenced by \texttt{providers-url}, | |
| replacing \texttt{\%name\%} by the package name and \texttt{\%hash\%} by | |
| the sha256 field. Those files themselves just contain package | |
| definitions as described \hyperref[packages]{above}. | |
| This field is optional. You probably don't need it for your own custom | |
| repository. | |
| \paragraph{stream options}\label{stream-options} | |
| The \texttt{packages.json} file is loaded using a PHP stream. You can | |
| set extra options on that stream using the \texttt{options} parameter. | |
| You can set any valid PHP stream context option. See | |
| \href{http://php.net/manual/en/context.php}{Context options and | |
| parameters} for more information. | |
| \subsubsection{VCS}\label{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. | |
| \paragraph{Loading a package from a VCS | |
| repository}\label{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 \texttt{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 | |
| \href{02-libraries.md}{Libraries} for more information. | |
| Example assuming you patched monolog to fix a bug in the \texttt{bugfix} | |
| branch: | |
| \begin{verbatim} | |
| { | |
| "repositories": [ | |
| { | |
| "type": "vcs", | |
| "url": "https://github.com/igorw/monolog" | |
| } | |
| ], | |
| "require": { | |
| "monolog/monolog": "dev-bugfix" | |
| } | |
| } | |
| \end{verbatim} | |
| When you run \texttt{php composer.phar update}, you should get your | |
| modified version of \texttt{monolog/monolog} instead of the one from | |
| packagist. | |
| Note that you should not rename the package unless you really intend to | |
| fork it in the long term, and completely move away from the original | |
| package. Composer will correctly pick your package over the original one | |
| since the custom repository has priority over packagist. If you want to | |
| rename the package, you should do so in the default (often master) | |
| branch and not in a feature branch, since the package name is taken from | |
| the default branch. | |
| If other dependencies rely on the package you forked, it is possible to | |
| inline-alias it so that it matches a constraint that it otherwise would | |
| not. For more information \href{articles/aliases.md}{see the aliases | |
| article}. | |
| \paragraph{Using private repositories}\label{using-private-repositories} | |
| Exactly the same solution allows you to work with your private | |
| repositories at GitHub and BitBucket: | |
| \begin{verbatim} | |
| { | |
| "require": { | |
| "vendor/my-private-repo": "dev-master" | |
| }, | |
| "repositories": [ | |
| { | |
| "type": "vcs", | |
| "url": "git@bitbucket.org:vendor/my-private-repo.git" | |
| } | |
| ] | |
| } | |
| \end{verbatim} | |
| The only requirement is the installation of SSH keys for a git client. | |
| \paragraph{Git alternatives}\label{git-alternatives} | |
| Git is not the only version control system supported by the VCS | |
| repository. The following are supported: | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{Git:} \href{http://git-scm.com}{git-scm.com} | |
| \item | |
| \textbf{Subversion:} | |
| \href{http://subversion.apache.org}{subversion.apache.org} | |
| \item | |
| \textbf{Mercurial:} | |
| \href{http://mercurial.selenic.com}{mercurial.selenic.com} | |
| \end{itemize} | |
| 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 \texttt{dist}s for | |
| them that fetch the packages as zips. | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{GitHub:} \href{https://github.com}{github.com} (Git) | |
| \item | |
| \textbf{BitBucket:} \href{https://bitbucket.org}{bitbucket.org} (Git | |
| and Mercurial) | |
| \end{itemize} | |
| 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 | |
| \texttt{git}, \texttt{svn} or \texttt{hg} as the repository type instead | |
| of \texttt{vcs}. | |
| \paragraph{Subversion Options}\label{subversion-options} | |
| Since Subversion has no native concept of branches and tags, Composer | |
| assumes by default that code is located in \texttt{\$url/trunk}, | |
| \texttt{\$url/branches} and \texttt{\$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: | |
| \begin{verbatim} | |
| { | |
| "repositories": [ | |
| { | |
| "type": "vcs", | |
| "url": "http://svn.example.org/projectA/", | |
| "trunk-path": "Trunk", | |
| "branches-path": "Branches", | |
| "tags-path": "Tags" | |
| } | |
| ] | |
| } | |
| \end{verbatim} | |
| If you have no branches or tags directory you can disable them entirely | |
| by setting the \texttt{branches-path} or \texttt{tags-path} to | |
| \texttt{false}. | |
| If the package is in a sub-directory, e.g. | |
| \texttt{/trunk/foo/bar/composer.json} and | |
| \texttt{/tags/1.0/foo/bar/composer.json}, then you can make composer | |
| access it by setting the \texttt{"package-path"} option to the | |
| sub-directory, in this example it would be | |
| \texttt{"package-path": "foo/bar/"}. | |
| \subsubsection{PEAR}\label{pear} | |
| It is possible to install packages from any PEAR channel by using the | |
| \texttt{pear} repository. Composer will prefix all package names with | |
| \texttt{pear-\{channelName\}/} to avoid conflicts. All packages are also | |
| aliased with prefix \texttt{pear-\{channelAlias\}/} | |
| Example using \texttt{pear2.php.net}: | |
| \begin{verbatim} | |
| { | |
| "repositories": [ | |
| { | |
| "type": "pear", | |
| "url": "http://pear2.php.net" | |
| } | |
| ], | |
| "require": { | |
| "pear-pear2.php.net/PEAR2_Text_Markdown": "*", | |
| "pear-pear2/PEAR2_HTTP_Request": "*" | |
| } | |
| } | |
| \end{verbatim} | |
| In this case the short name of the channel is \texttt{pear2}, so the | |
| \texttt{PEAR2\_HTTP\_Request} package name becomes | |
| \texttt{pear-pear2/PEAR2\_HTTP\_Request}. | |
| \begin{quote} | |
| \textbf{Note:} The \texttt{pear} repository requires doing quite a few | |
| requests per package, so this may considerably slow down the | |
| installation process. | |
| \end{quote} | |
| \paragraph{Custom vendor alias}\label{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: | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \texttt{BasePackage} | |
| \item | |
| \texttt{IntermediatePackage}, which depends on \texttt{BasePackage} | |
| \item | |
| \texttt{TopLevelPackage1} and \texttt{TopLevelPackage2} which both | |
| depend on \texttt{IntermediatePackage} | |
| \end{itemize} | |
| Without a vendor alias, Composer will use the PEAR channel name as the | |
| vendor portion of the package name: | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \texttt{pear-pear.foobar.repo/BasePackage} | |
| \item | |
| \texttt{pear-pear.foobar.repo/IntermediatePackage} | |
| \item | |
| \texttt{pear-pear.foobar.repo/TopLevelPackage1} | |
| \item | |
| \texttt{pear-pear.foobar.repo/TopLevelPackage2} | |
| \end{itemize} | |
| 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 | |
| \texttt{foobar}. Projects using your PEAR packages would not see the | |
| updated packages, since they have a different vendor name | |
| (\texttt{foobar/IntermediatePackage} vs | |
| \texttt{pear-pear.foobar.repo/IntermediatePackage}). | |
| By specifying \texttt{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 \texttt{BasePackage}, | |
| \texttt{TopLevelPackage1}, and \texttt{TopLevelPackage2} packages from | |
| your PEAR repository and \texttt{IntermediatePackage} from a Github | |
| repository: | |
| \begin{verbatim} | |
| { | |
| "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": "*" | |
| } | |
| } | |
| \end{verbatim} | |
| \subsubsection{Package}\label{package-1} | |
| 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 | |
| \texttt{package} repository. | |
| Basically, you define the same information that is included in the | |
| \texttt{composer} repository's \texttt{packages.json}, but only for a | |
| single package. Again, the minimum required fields are \texttt{name}, | |
| \texttt{version}, and either of \texttt{dist} or \texttt{source}. | |
| Here is an example for the smarty template engine: | |
| \begin{verbatim} | |
| { | |
| "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.*" | |
| } | |
| } | |
| \end{verbatim} | |
| Typically you would leave the source part off, as you don't really need | |
| it. | |
| \begin{quote} | |
| \textbf{Note}: This repository type has a few limitations and should be | |
| avoided whenever possible: | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| Composer will not update the package unless you change the | |
| \texttt{version} field. | |
| \item | |
| Composer will not update the commit references, so if you use | |
| \texttt{master} as reference you will have to delete the package to | |
| force an update, and will have to deal with an unstable lock file. | |
| \end{itemize} | |
| \end{quote} | |
| \subsection{Hosting your own}\label{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. | |
| \begin{itemize} | |
| \item | |
| \textbf{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. | |
| \item | |
| \textbf{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. | |
| \end{itemize} | |
| When hosting your own package repository it is recommended to use a | |
| \texttt{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 \texttt{composer} | |
| repository. | |
| \subsubsection{Packagist}\label{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 | |
| \href{https://github.com/composer/packagist}{available on GitHub}. 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 | |
| \href{https://github.com/composer/packagist}{packagist github | |
| repository}. | |
| \subsubsection{Satis}\label{satis} | |
| Satis is a static \texttt{composer} repository generator. It is a bit | |
| like an ultra- lightweight, static file-based version of packagist. | |
| You give it a \texttt{composer.json} containing repositories, typically | |
| VCS and package repository definitions. It will fetch all the packages | |
| that are \texttt{require}d and dump a \texttt{packages.json} that is | |
| your \texttt{composer} repository. | |
| Check \href{https://github.com/composer/satis}{the satis GitHub | |
| repository} and the | |
| \href{articles/handling-private-packages-with-satis.md}{Satis article} | |
| for more information. | |
| \subsubsection{Artifact}\label{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 | |
| maintenance, one can simply use a repository of type \texttt{artifact} | |
| with a folder containing ZIP archives of those private packages: | |
| \begin{verbatim} | |
| { | |
| "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" | |
| } | |
| } | |
| \end{verbatim} | |
| Each zip artifact is just a ZIP archive with \texttt{composer.json} in | |
| root folder: | |
| \begin{verbatim} | |
| $ unzip -l acme-corp-parser-10.3.5.zip | |
| composer.json | |
| ... | |
| \end{verbatim} | |
| If there are two archives with different versions of a package, they are | |
| both imported. When an archive with a newer version is added in the | |
| artifact folder and you run \texttt{update}, that version will be | |
| imported as well and Composer will update to the latest version. | |
| \subsection{Disabling Packagist}\label{disabling-packagist} | |
| You can disable the default Packagist repository by adding this to your | |
| \texttt{composer.json}: | |
| \begin{verbatim} | |
| { | |
| "repositories": [ | |
| { | |
| "packagist": false | |
| } | |
| ] | |
| } | |
| \end{verbatim} | |
| ← \href{04-schema.md}{Schema} \textbar{} | |
| \href{06-community.md}{Community} → | |
| \section{Community}\label{community} | |
| There are many people using composer already, and quite a few of them | |
| are contributing. | |
| \subsection{Contributing}\label{contributing} | |
| If you would like to contribute to composer, please read the | |
| \href{https://github.com/composer/composer}{README}. | |
| The most important guidelines are described as follows: | |
| \begin{quote} | |
| All code contributions - including those of people having commit access | |
| - must go through a pull request and approved by a core developer before | |
| being merged. This is to ensure proper review of all the code. | |
| Fork the project, create a feature branch, and send us a pull request. | |
| To ensure a consistent code base, you should make sure the code follows | |
| the | |
| \href{http://symfony.com/doc/2.0/contributing/code/standards.html}{Coding | |
| Standards} which we borrowed from Symfony. | |
| \end{quote} | |
| \subsection{IRC / mailing list}\label{irc-mailing-list} | |
| Mailing lists for | |
| \href{http://groups.google.com/group/composer-users}{user support} and | |
| \href{http://groups.google.com/group/composer-dev}{development}. | |
| IRC channels are on irc.freenode.org: | |
| \href{irc://irc.freenode.org/composer}{\#composer} for users and | |
| \href{irc://irc.freenode.org/composer-dev}{\#composer-dev} for | |
| development. | |
| Stack Overflow has a growing collection of | |
| \href{http://stackoverflow.com/questions/tagged/composer-php}{Composer | |
| related questions}. | |
| ← \href{05-repositories.md}{Repositories} | |
| \chapter{Articles} | |
| \section{Aliases}\label{aliases} | |
| \subsection{Why aliases?}\label{why-aliases} | |
| When you are using a VCS repository, you will only get comparable | |
| versions for branches that look like versions, such as \texttt{2.0}. For | |
| your \texttt{master} branch, you will get a \texttt{dev-master} version. | |
| For your \texttt{bugfix} branch, you will get a \texttt{dev-bugfix} | |
| version. | |
| If your \texttt{master} branch is used to tag releases of the | |
| \texttt{1.0} development line, i.e. \texttt{1.0.1}, \texttt{1.0.2}, | |
| \texttt{1.0.3}, etc., any package depending on it will probably require | |
| version \texttt{1.0.*}. | |
| If anyone wants to require the latest \texttt{dev-master}, they have a | |
| problem: Other packages may require \texttt{1.0.*}, so requiring that | |
| dev version will lead to conflicts, since \texttt{dev-master} does not | |
| match the \texttt{1.0.*} constraint. | |
| Enter aliases. | |
| \subsection{Branch alias}\label{branch-alias} | |
| The \texttt{dev-master} branch is one in your main VCS repo. It is | |
| rather common that someone will want the latest master dev version. | |
| Thus, Composer allows you to alias your \texttt{dev-master} branch to a | |
| \texttt{1.0.x-dev} version. It is done by specifying a | |
| \texttt{branch-alias} field under \texttt{extra} in | |
| \texttt{composer.json}: | |
| \begin{verbatim} | |
| { | |
| "extra": { | |
| "branch-alias": { | |
| "dev-master": "1.0.x-dev" | |
| } | |
| } | |
| } | |
| \end{verbatim} | |
| The branch version must begin with \texttt{dev-} (non-comparable | |
| version), the alias must be a comparable dev version (i.e.~start with | |
| numbers, and end with \texttt{.x-dev}). The \texttt{branch-alias} must | |
| be present on the branch that it references. For \texttt{dev-master}, | |
| you need to commit it on the \texttt{master} branch. | |
| As a result, anyone can now require \texttt{1.0.*} and it will happily | |
| install \texttt{dev-master}. | |
| In order to use branch aliasing, you must own the repository of the | |
| package being aliased. If you want to alias a third party package | |
| without maintaining a fork of it, use inline aliases as described below. | |
| \subsection{Require inline alias}\label{require-inline-alias} | |
| Branch aliases are great for aliasing main development lines. But in | |
| order to use them you need to have control over the source repository, | |
| and you need to commit changes to version control. | |
| This is not really fun when you just want to try a bugfix of some | |
| library that is a dependency of your local project. | |
| For this reason, you can alias packages in your \texttt{require} and | |
| \texttt{require-dev} fields. Let's say you found a bug in the | |
| \texttt{monolog/monolog} package. You cloned Monolog on GitHub and fixed | |
| the issue in a branch named \texttt{bugfix}. Now you want to install | |
| that version of monolog in your local project. | |
| You are using \texttt{symfony/monolog-bundle} which requires | |
| \texttt{monolog/monolog} version \texttt{1.*}. So you need your | |
| \texttt{dev-bugfix} to match that constraint. | |
| Just add this to your project's root \texttt{composer.json}: | |
| \begin{verbatim} | |
| { | |
| "repositories": [ | |
| { | |
| "type": "vcs", | |
| "url": "https://github.com/you/monolog" | |
| } | |
| ], | |
| "require": { | |
| "symfony/monolog-bundle": "2.0", | |
| "monolog/monolog": "dev-bugfix as 1.0.x-dev" | |
| } | |
| } | |
| \end{verbatim} | |
| That will fetch the \texttt{dev-bugfix} version of | |
| \texttt{monolog/monolog} from your GitHub and alias it to | |
| \texttt{1.0.x-dev}. | |
| \begin{quote} | |
| \textbf{Note:} If a package with inline aliases is required, the alias | |
| (right of the \texttt{as}) is used as the version constraint. The part | |
| left of the \texttt{as} is discarded. As a consequence, if A requires B | |
| and B requires \texttt{monolog/monolog} version | |
| \texttt{dev-bugfix as 1.0.x-dev}, installing A will make B require | |
| \texttt{1.0.x-dev}, which may exist as a branch alias or an actual | |
| \texttt{1.0} branch. If it does not, it must be re-inline-aliased in A's | |
| \texttt{composer.json}. | |
| \end{quote} | |
| \begin{quote} | |
| \textbf{Note:} Inline aliasing should be avoided, especially for | |
| published packages. If you found a bug, try and get your fix merged | |
| upstream. This helps to avoid issues for users of your package. | |
| \end{quote} | |
| \section{Setting up and using custom | |
| installers}\label{setting-up-and-using-custom-installers} | |
| \subsection{Synopsis}\label{synopsis} | |
| At times it may be necessary for a package to require additional actions | |
| during installation, such as installing packages outside of the default | |
| \texttt{vendor} library. | |
| In these cases you could consider creating a Custom Installer to handle | |
| your specific logic. | |
| \subsection{Calling a Custom | |
| Installer}\label{calling-a-custom-installer} | |
| Suppose that your project already has a Custom Installer for specific | |
| modules then invoking that installer is a matter of defining the correct | |
| \href{../04-schema.md\#type}{type} in your package file. | |
| \begin{quote} | |
| \emph{See the next chapter for an instruction how to create Custom | |
| Installers.} | |
| \end{quote} | |
| Every Custom Installer defines which \href{../04-schema.md\#type}{type} | |
| string it will recognize. Once recognized it will completely override | |
| the default installer and only apply its own logic. | |
| An example use-case would be: | |
| \begin{quote} | |
| phpDocumentor features Templates that need to be installed outside of | |
| the default /vendor folder structure. As such they have chosen to adopt | |
| the \texttt{phpdocumentor-template} \href{../04-schema.md\#type}{type} | |
| and create a plugin providing the Custom Installer to send these | |
| templates to the correct folder. | |
| \end{quote} | |
| An example composer.json of such a template package would be: | |
| \begin{verbatim} | |
| { | |
| "name": "phpdocumentor/template-responsive", | |
| "type": "phpdocumentor-template", | |
| "require": { | |
| "phpdocumentor/template-installer-plugin": "*" | |
| } | |
| } | |
| \end{verbatim} | |
| \begin{quote} | |
| \textbf{IMPORTANT}: to make sure that the template installer is present | |
| at the time the template package is installed, template packages should | |
| require the plugin package. | |
| \end{quote} | |
| \subsection{Creating an Installer}\label{creating-an-installer} | |
| A Custom Installer is defined as a class that implements the | |
| \href{https://github.com/composer/composer/blob/master/src/Composer/Plugin/PluginInterface.php}{\texttt{Composer\textbackslash{}Installer\textbackslash{}InstallerInterface}} | |
| and is usually distributed in a Composer Plugin. | |
| A basic Installer Plugin would thus compose of three files: | |
| \begin{enumerate} | |
| \def\labelenumi{\arabic{enumi}.} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| the package file: composer.json | |
| \item | |
| The Plugin class, e.g.: | |
| \texttt{My\textbackslash{}Project\textbackslash{}Composer\textbackslash{}Plugin.php}, | |
| containing a class that implements | |
| \texttt{Composer\textbackslash{}Plugin\textbackslash{}PluginInterface}. | |
| \item | |
| The Installer class, e.g.: | |
| \texttt{My\textbackslash{}Project\textbackslash{}Composer\textbackslash{}Installer.php}, | |
| containing a class that implements | |
| \texttt{Composer\textbackslash{}Installer\textbackslash{}InstallerInterface}. | |
| \end{enumerate} | |
| \subsubsection{composer.json}\label{composer.json} | |
| The package file is the same as any other package file but with the | |
| following requirements: | |
| \begin{enumerate} | |
| \def\labelenumi{\arabic{enumi}.} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| the \href{../04-schema.md\#type}{type} attribute must be | |
| \texttt{composer-plugin}. | |
| \item | |
| the \href{../04-schema.md\#extra}{extra} attribute must contain an | |
| element \texttt{class} defining the class name of the plugin | |
| (including namespace). If a package contains multiple plugins this can | |
| be array of class names. | |
| \end{enumerate} | |
| Example: | |
| \begin{verbatim} | |
| { | |
| "name": "phpdocumentor/template-installer-plugin", | |
| "type": "composer-plugin", | |
| "license": "MIT", | |
| "autoload": { | |
| "psr-0": {"phpDocumentor\\Composer": "src/"} | |
| }, | |
| "extra": { | |
| "class": "phpDocumentor\\Composer\\TemplateInstallerPlugin" | |
| }, | |
| "require": { | |
| "composer-plugin-api": "1.0.0" | |
| } | |
| } | |
| \end{verbatim} | |
| \subsubsection{The Plugin class}\label{the-plugin-class} | |
| The class defining the Composer plugin must implement the | |
| \href{https://github.com/composer/composer/blob/master/src/Composer/Plugin/PluginInterface.php}{\texttt{Composer\textbackslash{}Plugin\textbackslash{}PluginInterface}}. | |
| It can then register the Custom Installer in its \texttt{activate()} | |
| method. | |
| The class may be placed in any location and have any name, as long as it | |
| is autoloadable and matches the \texttt{extra.class} element in the | |
| package definition. | |
| Example: | |
| \begin{verbatim} | |
| namespace phpDocumentor\Composer; | |
| use Composer\Composer; | |
| use Composer\IO\IOInterface; | |
| use Composer\Plugin\PluginInterface; | |
| class TemplateInstallerPlugin implements PluginInterface | |
| { | |
| public function activate(Composer $composer, IOInterface $io) | |
| { | |
| $installer = new TemplateInstaller($io, $composer); | |
| $composer->getInstallationManager()->addInstaller($installer); | |
| } | |
| } | |
| \end{verbatim} | |
| \subsubsection{The Custom Installer | |
| class}\label{the-custom-installer-class} | |
| The class that executes the custom installation should implement the | |
| \href{https://github.com/composer/composer/blob/master/src/Composer/Installer/InstallerInterface.php}{\texttt{Composer\textbackslash{}Installer\textbackslash{}InstallerInterface}} | |
| (or extend another installer that implements that interface). It defines | |
| the \href{../04-schema.md\#type}{type} string as it will be recognized | |
| by packages that will use this installer in the \texttt{supports()} | |
| method. | |
| \begin{quote} | |
| \textbf{NOTE}: \emph{choose your \href{../04-schema.md\#type}{type} name | |
| carefully, it is recommended to follow the format: | |
| \texttt{vendor-type}}. For example: \texttt{phpdocumentor-template}. | |
| \end{quote} | |
| The InstallerInterface class defines the following methods (please see | |
| the source for the exact signature): | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{supports()}, here you test whether the passed | |
| \href{../04-schema.md\#type}{type} matches the name that you declared | |
| for this installer (see the example). | |
| \item | |
| \textbf{isInstalled()}, determines whether a supported package is | |
| installed or not. | |
| \item | |
| \textbf{install()}, here you can determine the actions that need to be | |
| executed upon installation. | |
| \item | |
| \textbf{update()}, here you define the behavior that is required when | |
| Composer is invoked with the update argument. | |
| \item | |
| \textbf{uninstall()}, here you can determine the actions that need to | |
| be executed when the package needs to be removed. | |
| \item | |
| \textbf{getInstallPath()}, this method should return the location | |
| where the package is to be installed, \emph{relative from the location | |
| of composer.json.} | |
| \end{itemize} | |
| Example: | |
| \begin{verbatim} | |
| namespace phpDocumentor\Composer; | |
| use Composer\Package\PackageInterface; | |
| use Composer\Installer\LibraryInstaller; | |
| class TemplateInstaller extends LibraryInstaller | |
| { | |
| /** | |
| * {@inheritDoc} | |
| */ | |
| public function getPackageBasePath(PackageInterface $package) | |
| { | |
| $prefix = substr($package->getPrettyName(), 0, 23); | |
| if ('phpdocumentor/template-' !== $prefix) { | |
| throw new \InvalidArgumentException( | |
| 'Unable to install template, phpdocumentor templates ' | |
| .'should always start their package name with ' | |
| .'"phpdocumentor/template-"' | |
| ); | |
| } | |
| return 'data/templates/'.substr($package->getPrettyName(), 23); | |
| } | |
| /** | |
| * {@inheritDoc} | |
| */ | |
| public function supports($packageType) | |
| { | |
| return 'phpdocumentor-template' === $packageType; | |
| } | |
| } | |
| \end{verbatim} | |
| The example demonstrates that it is quite simple to extend the | |
| \href{https://github.com/composer/composer/blob/master/src/Composer/Installer/LibraryInstaller.php}{\texttt{Composer\textbackslash{}Installer\textbackslash{}LibraryInstaller}} | |
| class to strip a prefix (\texttt{phpdocumentor/template-}) and use the | |
| remaining part to assemble a completely different installation path. | |
| \begin{quote} | |
| \emph{Instead of being installed in \texttt{/vendor} any package | |
| installed using this Installer will be put in the | |
| \texttt{/data/templates/\textless{}stripped name\textgreater{}} folder.} | |
| \end{quote} | |
| \section{Handling private packages with | |
| Satis}\label{handling-private-packages-with-satis} | |
| Satis is a static \texttt{composer} repository generator. It is a bit | |
| like an ultra- lightweight, static file-based version of packagist and | |
| can be used to host the metadata of your company's private packages, or | |
| your own. It basically acts as a micro-packagist. You can get it from | |
| \href{http://github.com/composer/satis}{GitHub} or install via CLI: | |
| \texttt{composer.phar create-project composer/satis -{}-stability=dev}. | |
| \subsection{Setup}\label{setup} | |
| For example let's assume you have a few packages you want to reuse | |
| across your company but don't really want to open-source. You would | |
| first define a Satis configuration: a json file with an arbitrary name | |
| that lists your curated \href{../05-repositories.md}{repositories}. | |
| Here is an example configuration, you see that it holds a few VCS | |
| repositories, but those could be any types of | |
| \href{../05-repositories.md}{repositories}. Then it uses | |
| \texttt{"require-all": true} which selects all versions of all packages | |
| in the repositories you defined. | |
| The default file Satis looks for is \texttt{satis.json} in the root of | |
| the repository. | |
| \begin{verbatim} | |
| { | |
| "name": "My Repository", | |
| "homepage": "http://packages.example.org", | |
| "repositories": [ | |
| { "type": "vcs", "url": "http://github.com/mycompany/privaterepo" }, | |
| { "type": "vcs", "url": "http://svn.example.org/private/repo" }, | |
| { "type": "vcs", "url": "http://github.com/mycompany/privaterepo2" } | |
| ], | |
| "require-all": true | |
| } | |
| \end{verbatim} | |
| If you want to cherry pick which packages you want, you can list all the | |
| packages you want to have in your satis repository inside the classic | |
| composer \texttt{require} key, using a \texttt{"*"} constraint to make | |
| sure all versions are selected, or another constraint if you want really | |
| specific versions. | |
| \begin{verbatim} | |
| { | |
| "repositories": [ | |
| { "type": "vcs", "url": "http://github.com/mycompany/privaterepo" }, | |
| { "type": "vcs", "url": "http://svn.example.org/private/repo" }, | |
| { "type": "vcs", "url": "http://github.com/mycompany/privaterepo2" } | |
| ], | |
| "require": { | |
| "company/package": "*", | |
| "company/package2": "*", | |
| "company/package3": "2.0.0" | |
| } | |
| } | |
| \end{verbatim} | |
| Once you did this, you just run | |
| \texttt{php bin/satis build \textless{}configuration file\textgreater{} \textless{}build dir\textgreater{}}. | |
| For example \texttt{php bin/satis build config.json web/} would read the | |
| \texttt{config.json} file and build a static repository inside the | |
| \texttt{web/} directory. | |
| When you ironed out that process, what you would typically do is run | |
| this command as a cron job on a server. It would then update all your | |
| package info much like Packagist does. | |
| Note that if your private packages are hosted on GitHub, your server | |
| should have an ssh key that gives it access to those packages, and then | |
| you should add the \texttt{-{}-no-interaction} (or \texttt{-n}) flag to | |
| the command to make sure it falls back to ssh key authentication instead | |
| of prompting for a password. This is also a good trick for continuous | |
| integration servers. | |
| Set up a virtual-host that points to that \texttt{web/} directory, let's | |
| say it is \texttt{packages.example.org}. Alternatively, with PHP | |
| \textgreater{}= 5.4.0, you can use the built-in CLI server | |
| \texttt{php -S localhost:port -t satis-output-dir/} for a temporary | |
| solution. | |
| \subsection{Usage}\label{usage} | |
| In your projects all you need to add now is your own composer repository | |
| using the \texttt{packages.example.org} as URL, then you can require | |
| your private packages and everything should work smoothly. You don't | |
| need to copy all your repositories in every project anymore. Only that | |
| one unique repository that will update itself. | |
| \begin{verbatim} | |
| { | |
| "repositories": [ { "type": "composer", "url": "http://packages.example.org/" } ], | |
| "require": { | |
| "company/package": "1.2.0", | |
| "company/package2": "1.5.2", | |
| "company/package3": "dev-master" | |
| } | |
| } | |
| \end{verbatim} | |
| \subsubsection{Security}\label{security} | |
| To secure your private repository you can host it over SSH or SSL using | |
| a client certificate. In your project you can use the \texttt{options} | |
| parameter to specify the connection options for the server. | |
| Example using a custom repository using SSH (requires the SSH2 PECL | |
| extension): | |
| \begin{verbatim} | |
| { | |
| "repositories": [ | |
| { | |
| "type": "composer", | |
| "url": "ssh2.sftp://example.org", | |
| "options": { | |
| "ssh2": { | |
| "username": "composer", | |
| "pubkey_file": "/home/composer/.ssh/id_rsa.pub", | |
| "privkey_file": "/home/composer/.ssh/id_rsa" | |
| } | |
| } | |
| } | |
| ] | |
| } | |
| \end{verbatim} | |
| \begin{quote} | |
| \textbf{Tip:} See | |
| \href{http://www.php.net/manual/en/wrappers.ssh2.php\#refsect1-wrappers.ssh2-options}{ssh2 | |
| context options} for more information. | |
| \end{quote} | |
| Example using HTTP over SSL using a client certificate: | |
| \begin{verbatim} | |
| { | |
| "repositories": [ | |
| { | |
| "type": "composer", | |
| "url": "https://example.org", | |
| "options": { | |
| "ssl": { | |
| "local_cert": "/home/composer/.ssl/composer.pem" | |
| } | |
| } | |
| } | |
| ] | |
| } | |
| \end{verbatim} | |
| \begin{quote} | |
| \textbf{Tip:} See | |
| \href{http://www.php.net/manual/en/context.ssl.php}{ssl context options} | |
| for more information. | |
| \end{quote} | |
| \subsubsection{Downloads}\label{downloads} | |
| When GitHub or BitBucket repositories are mirrored on your local satis, | |
| the build process will include the location of the downloads these | |
| platforms make available. This means that the repository and your setup | |
| depend on the availability of these services. | |
| At the same time, this implies that all code which is hosted somewhere | |
| else (on another service or for example in Subversion) will not have | |
| downloads available and thus installations usually take a lot longer. | |
| To enable your satis installation to create downloads for all (Git, | |
| Mercurial and Subversion) your packages, add the following to your | |
| \texttt{satis.json}: | |
| \begin{verbatim} | |
| { | |
| "archive": { | |
| "directory": "dist", | |
| "format": "tar", | |
| "prefix-url": "https://amazing.cdn.example.org", | |
| "skip-dev": true | |
| } | |
| } | |
| \end{verbatim} | |
| \paragraph{Options explained}\label{options-explained} | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \texttt{directory}: the location of the dist files (inside the | |
| \texttt{output-dir}) | |
| \item | |
| \texttt{format}: optional, \texttt{zip} (default) or \texttt{tar} | |
| \item | |
| \texttt{prefix-url}: optional, location of the downloads, homepage | |
| (from \texttt{satis.json}) followed by \texttt{directory} by default | |
| \item | |
| \texttt{skip-dev}: optional, \texttt{false} by default, when enabled | |
| (\texttt{true}) satis will not create downloads for branches | |
| \end{itemize} | |
| Once enabled, all downloads (include those from GitHub and BitBucket) | |
| will be replaced with a \emph{local} version. | |
| \paragraph{prefix-url}\label{prefix-url} | |
| Prefixing the URL with another host is especially helpful if the | |
| downloads end up in a private Amazon S3 bucket or on a CDN host. A CDN | |
| would drastically improve download times and therefore package | |
| installation. | |
| Example: A \texttt{prefix-url} of | |
| \texttt{http://my-bucket.s3.amazonaws.com} (and \texttt{directory} set | |
| to \texttt{dist}) creates download URLs which look like the following: | |
| \texttt{http://my-bucket.s3.amazonaws.com/dist/vendor-package-version-ref.zip}. | |
| \section{Setting up and using | |
| plugins}\label{setting-up-and-using-plugins} | |
| \subsection{Synopsis}\label{synopsis} | |
| You may wish to alter or expand Composer's functionality with your own. | |
| For example if your environment poses special requirements on the | |
| behaviour of Composer which do not apply to the majority of its users or | |
| if you wish to accomplish something with composer in a way that is not | |
| desired by most users. | |
| In these cases you could consider creating a plugin to handle your | |
| specific logic. | |
| \subsection{Creating a Plugin}\label{creating-a-plugin} | |
| A plugin is a regular composer package which ships its code as part of | |
| the package and may also depend on further packages. | |
| \subsubsection{Plugin Package}\label{plugin-package} | |
| The package file is the same as any other package file but with the | |
| following requirements: | |
| \begin{enumerate} | |
| \def\labelenumi{\arabic{enumi}.} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| the \href{../04-schema.md\#type}{type} attribute must be | |
| \texttt{composer-plugin}. | |
| \item | |
| the \href{../04-schema.md\#extra}{extra} attribute must contain an | |
| element \texttt{class} defining the class name of the plugin | |
| (including namespace). If a package contains multiple plugins this can | |
| be array of class names. | |
| \end{enumerate} | |
| Additionally you must require the special package called | |
| \texttt{composer-plugin-api} to define which composer API versions your | |
| plugin is compatible with. The current composer plugin API version is | |
| 1.0.0. | |
| For example | |
| \begin{verbatim} | |
| { | |
| "name": "my/plugin-package", | |
| "type": "composer-plugin", | |
| "require": { | |
| "composer-plugin-api": "1.0.0" | |
| } | |
| } | |
| \end{verbatim} | |
| \subsubsection{Plugin Class}\label{plugin-class} | |
| Every plugin has to supply a class which implements the | |
| \href{https://github.com/composer/composer/blob/master/src/Composer/Plugin/PluginInterface.php}{\texttt{Composer\textbackslash{}Plugin\textbackslash{}PluginInterface}}. | |
| The \texttt{activate()} method of the plugin is called after the plugin | |
| is loaded and receives an instance of | |
| \href{https://github.com/composer/composer/blob/master/src/Composer/Composer.php}{\texttt{Composer\textbackslash{}Composer}} | |
| as well as an instance of | |
| \href{https://github.com/composer/composer/blob/master/src/Composer/IO/IOInterface.php}{\texttt{Composer\textbackslash{}IO\textbackslash{}IOInterface}}. | |
| Using these two objects all configuration can be read and all internal | |
| objects and state can be manipulated as desired. | |
| Example: | |
| \begin{verbatim} | |
| namespace phpDocumentor\Composer; | |
| use Composer\Composer; | |
| use Composer\IO\IOInterface; | |
| use Composer\Plugin\PluginInterface; | |
| class TemplateInstallerPlugin implements PluginInterface | |
| { | |
| public function activate(Composer $composer, IOInterface $io) | |
| { | |
| $installer = new TemplateInstaller($io, $composer); | |
| $composer->getInstallationManager()->addInstaller($installer); | |
| } | |
| } | |
| \end{verbatim} | |
| \subsection{Event Handler}\label{event-handler} | |
| Furthermore plugins may implement the | |
| \href{https://github.com/composer/composer/blob/master/src/Composer/EventDispatcher/EventSubscriberInterface.php}{\texttt{Composer\textbackslash{}EventDispatcher\textbackslash{}EventSubscriberInterface}} | |
| in order to have its event handlers automatically registered with the | |
| \texttt{EventDispatcher} when the plugin is loaded. | |
| The events available for plugins are: | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{COMMAND}, is called at the beginning of all commands that load | |
| plugins. It provides you with access to the input and output objects | |
| of the program. | |
| \item | |
| \textbf{PRE\_FILE\_DOWNLOAD}, is triggered before files are downloaded | |
| and allows you to manipulate the \texttt{RemoteFilesystem} object | |
| prior to downloading files based on the URL to be downloaded. | |
| \end{itemize} | |
| Example: | |
| \begin{verbatim} | |
| namespace Naderman\Composer\AWS; | |
| use Composer\Composer; | |
| use Composer\EventDispatcher\EventSubscriberInterface; | |
| use Composer\IO\IOInterface; | |
| use Composer\Plugin\PluginInterface; | |
| use Composer\Plugin\PluginEvents; | |
| use Composer\Plugin\PreFileDownloadEvent; | |
| class AwsPlugin implements PluginInterface, EventSubscriberInterface | |
| { | |
| protected $composer; | |
| protected $io; | |
| public function activate(Composer $composer, IOInterface $io) | |
| { | |
| $this->composer = $composer; | |
| $this->io = $io; | |
| } | |
| public static function getSubscribedEvents() | |
| { | |
| return array( | |
| PluginEvents::PRE_FILE_DOWNLOAD => array( | |
| array('onPreFileDownload', 0) | |
| ), | |
| ); | |
| } | |
| public function onPreFileDownload(PreFileDownloadEvent $event) | |
| { | |
| $protocol = parse_url($event->getProcessedUrl(), PHP_URL_SCHEME); | |
| if ($protocol === 's3') { | |
| $awsClient = new AwsClient($this->io, $this->composer->getConfig()); | |
| $s3RemoteFilesystem = new S3RemoteFilesystem($this->io, $event->getRemoteFilesystem()->getOptions(), $awsClient); | |
| $event->setRemoteFilesystem($s3RemoteFilesystem); | |
| } | |
| } | |
| } | |
| \end{verbatim} | |
| \subsection{Using Plugins}\label{using-plugins} | |
| Plugin packages are automatically loaded as soon as they are installed | |
| and will be loaded when composer starts up if they are found in the | |
| current project's list of installed packages. Additionally all plugin | |
| packages installed in the \texttt{COMPOSER\_HOME} directory using the | |
| composer global command are loaded before local project plugins are | |
| loaded. | |
| \begin{quote} | |
| You may pass the \texttt{-{}-no-plugins} option to composer commands to | |
| disable all installed commands. This may be particularly helpful if any | |
| of the plugins causes errors and you wish to update or uninstall it. | |
| \end{quote} | |
| \section{Scripts}\label{scripts} | |
| \subsection{What is a script?}\label{what-is-a-script} | |
| A script, in Composer's terms, can either be a PHP callback (defined as | |
| a static method) or any command-line executable command. Scripts are | |
| useful for executing a package's custom code or package-specific | |
| commands during the Composer execution process. | |
| \textbf{NOTE: Only scripts defined in the root package's | |
| \texttt{composer.json} are executed. If a dependency of the root package | |
| specifies its own scripts, Composer does not execute those additional | |
| scripts.} | |
| \subsection{Event names}\label{event-names} | |
| Composer fires the following named events during its execution process: | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \textbf{pre-install-cmd}: occurs before the \texttt{install} command | |
| is executed. | |
| \item | |
| \textbf{post-install-cmd}: occurs after the \texttt{install} command | |
| is executed. | |
| \item | |
| \textbf{pre-update-cmd}: occurs before the \texttt{update} command is | |
| executed. | |
| \item | |
| \textbf{post-update-cmd}: occurs after the \texttt{update} command is | |
| executed. | |
| \item | |
| \textbf{pre-status-cmd}: occurs before the \texttt{status} command is | |
| executed. | |
| \item | |
| \textbf{post-status-cmd}: occurs after the \texttt{status} command is | |
| executed. | |
| \item | |
| \textbf{pre-package-install}: occurs before a package is installed. | |
| \item | |
| \textbf{post-package-install}: occurs after a package is installed. | |
| \item | |
| \textbf{pre-package-update}: occurs before a package is updated. | |
| \item | |
| \textbf{post-package-update}: occurs after a package is updated. | |
| \item | |
| \textbf{pre-package-uninstall}: occurs before a package has been | |
| uninstalled. | |
| \item | |
| \textbf{post-package-uninstall}: occurs after a package has been | |
| uninstalled. | |
| \item | |
| \textbf{pre-autoload-dump}: occurs before the autoloader is dumped, | |
| either during \texttt{install}/\texttt{update}, or via the | |
| \texttt{dump-autoload} command. | |
| \item | |
| \textbf{post-autoload-dump}: occurs after the autoloader is dumped, | |
| either during \texttt{install}/\texttt{update}, or via the | |
| \texttt{dump-autoload} command. | |
| \item | |
| \textbf{post-root-package-install}: occurs after the root package has | |
| been installed, during the \texttt{create-project} command. | |
| \item | |
| \textbf{post-create-project-cmd}: occurs after the | |
| \texttt{create-project} command is executed. | |
| \end{itemize} | |
| \subsection{Defining scripts}\label{defining-scripts} | |
| The root JSON object in \texttt{composer.json} should have a property | |
| called \texttt{"scripts"}, which contains pairs of named events and each | |
| event's corresponding scripts. An event's scripts can be defined as | |
| either as a string (only for a single script) or an array (for single or | |
| multiple scripts.) | |
| For any given event: | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| Scripts execute in the order defined when their corresponding event is | |
| fired. | |
| \item | |
| An array of scripts wired to a single event can contain both PHP | |
| callbacks and command-line executables commands. | |
| \item | |
| PHP classes containing defined callbacks must be autoloadable via | |
| Composer's autoload functionality. | |
| \end{itemize} | |
| Script definition example: | |
| \begin{verbatim} | |
| { | |
| "scripts": { | |
| "post-update-cmd": "MyVendor\\MyClass::postUpdate", | |
| "post-package-install": [ | |
| "MyVendor\\MyClass::postPackageInstall" | |
| ], | |
| "post-install-cmd": [ | |
| "MyVendor\\MyClass::warmCache", | |
| "phpunit -c app/" | |
| ] | |
| } | |
| } | |
| \end{verbatim} | |
| Using the previous definition example, here's the class | |
| \texttt{MyVendor\textbackslash{}MyClass} that might be used to execute | |
| the PHP callbacks: | |
| \begin{verbatim} | |
| <?php | |
| namespace MyVendor; | |
| use Composer\Script\Event; | |
| class MyClass | |
| { | |
| public static function postUpdate(Event $event) | |
| { | |
| $composer = $event->getComposer(); | |
| // do stuff | |
| } | |
| public static function postPackageInstall(Event $event) | |
| { | |
| $installedPackage = $event->getOperation()->getPackage(); | |
| // do stuff | |
| } | |
| public static function warmCache(Event $event) | |
| { | |
| // make cache toasty | |
| } | |
| } | |
| \end{verbatim} | |
| When an event is fired, Composer's internal event handler receives a | |
| \texttt{Composer\textbackslash{}Script\textbackslash{}Event} object, | |
| which is passed as the first argument to your PHP callback. This | |
| \texttt{Event} object has getters for other contextual objects: | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \texttt{getComposer()}: returns the current instance of | |
| \texttt{Composer\textbackslash{}Composer} | |
| \item | |
| \texttt{getName()}: returns the name of the event being fired as a | |
| string | |
| \item | |
| \texttt{getIO()}: returns the current input/output stream which | |
| implements | |
| \texttt{Composer\textbackslash{}IO\textbackslash{}IOInterface} for | |
| writing to the console | |
| \end{itemize} | |
| \section{Troubleshooting}\label{troubleshooting} | |
| This is a list of common pitfalls on using Composer, and how to avoid | |
| them. | |
| \subsection{General}\label{general} | |
| \begin{enumerate} | |
| \def\labelenumi{\arabic{enumi}.} | |
| \item | |
| Before asking anyone, run | |
| \href{../03-cli.md\#diagnose}{\texttt{composer diagnose}} to check for | |
| common problems. If it all checks out, proceed to the next steps. | |
| \item | |
| When facing any kind of problems using Composer, be sure to | |
| \textbf{work with the latest version}. See | |
| \href{../03-cli.md\#self-update}{self-update} for details. | |
| \item | |
| Make sure you have no problems with your setup by running the | |
| installer's checks via | |
| \texttt{curl -sS https://getcomposer.org/installer \textbar{} php -{}- -{}-check}. | |
| \item | |
| Ensure you're \textbf{installing vendors straight from your | |
| \texttt{composer.json}} via | |
| \texttt{rm -rf vendor \&\& composer update -v} when troubleshooting, | |
| excluding any possible interferences with existing vendor | |
| installations or \texttt{composer.lock} entries. | |
| \end{enumerate} | |
| \hyperdef{}{package-not-found}{\subsection{Package not | |
| found}\label{package-not-found}} | |
| \begin{enumerate} | |
| \def\labelenumi{\arabic{enumi}.} | |
| \item | |
| Double-check you \textbf{don't have typos} in your | |
| \texttt{composer.json} or repository branches and tag names. | |
| \item | |
| Be sure to \textbf{set the right | |
| \href{../04-schema.md\#minimum-stability}{minimum-stability}}. To get | |
| started or be sure this is no issue, set \texttt{minimum-stability} to | |
| ``dev''. | |
| \item | |
| Packages \textbf{not coming from | |
| \href{https://packagist.org/}{Packagist}} should always be | |
| \textbf{defined in the root package} (the package depending on all | |
| vendors). | |
| \item | |
| Use the \textbf{same vendor and package name} throughout all branches | |
| and tags of your repository, especially when maintaining a third party | |
| fork and using \texttt{replace}. | |
| \end{enumerate} | |
| \subsection{Package not found on | |
| travis-ci.org}\label{package-not-found-on-travis-ci.org} | |
| \begin{enumerate} | |
| \def\labelenumi{\arabic{enumi}.} | |
| \item | |
| Check the \hyperref[package-not-found]{``Package not found''} item | |
| above. | |
| \item | |
| If the package tested is a dependency of one of its dependencies | |
| (cyclic dependency), the problem might be that composer is not able to | |
| detect the version of the package properly. If it is a git clone it is | |
| generally alright and Composer will detect the version of the current | |
| branch, but travis does shallow clones so that process can fail when | |
| testing pull requests and feature branches in general. The best | |
| solution is to define the version you are on via an environment | |
| variable called COMPOSER\_ROOT\_VERSION. You set it to | |
| \texttt{dev-master} for example to define the root package's version | |
| as \texttt{dev-master}. Use: | |
| \texttt{before\_script: COMPOSER\_ROOT\_VERSION=dev-master composer install} | |
| to export the variable for the call to composer. | |
| \end{enumerate} | |
| \subsection{Need to override a package | |
| version}\label{need-to-override-a-package-version} | |
| Let say your project depends on package A which in turn depends on a | |
| specific version of package B (say 0.1) and you need a different version | |
| of that package - version 0.11. | |
| You can fix this by aliasing version 0.11 to 0.1: | |
| composer.json: | |
| \begin{verbatim} | |
| { | |
| "require": { | |
| "A": "0.2", | |
| "B": "0.11 as 0.1" | |
| } | |
| } | |
| \end{verbatim} | |
| See \href{aliases.md}{aliases} for more information. | |
| \subsection{Memory limit errors}\label{memory-limit-errors} | |
| If composer shows memory errors on some commands: | |
| \begin{verbatim} | |
| PHP Fatal error: Allowed memory size of XXXXXX bytes exhausted <...> | |
| \end{verbatim} | |
| The PHP \texttt{memory\_limit} should be increased. | |
| \begin{quote} | |
| \textbf{Note:} Composer internally increases the \texttt{memory\_limit} | |
| to \texttt{512M}. If you have memory issues when using composer, please | |
| consider \href{https://github.com/composer/composer/issues}{creating an | |
| issue ticket} so we can look into it. | |
| \end{quote} | |
| To get the current \texttt{memory\_limit} value, run: | |
| \begin{verbatim} | |
| php -r "echo ini_get('memory_limit').PHP_EOL;" | |
| \end{verbatim} | |
| Try increasing the limit in your \texttt{php.ini} file (ex. | |
| \texttt{/etc/php5/cli/php.ini} for Debian-like systems): | |
| \begin{verbatim} | |
| ; Use -1 for unlimited or define an explicit value like 512M | |
| memory_limit = -1 | |
| \end{verbatim} | |
| Or, you can increase the limit with a command-line argument: | |
| \begin{verbatim} | |
| php -d memory_limit=-1 composer.phar <...> | |
| \end{verbatim} | |
| \subsection{``The system cannot find the path specified'' | |
| (Windows)}\label{the-system-cannot-find-the-path-specified-windows} | |
| \begin{enumerate} | |
| \def\labelenumi{\arabic{enumi}.} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| Open regedit. | |
| \item | |
| Search for an \texttt{AutoRun} key inside | |
| \texttt{HKEY\_LOCAL\_MACHINE\textbackslash{}Software\textbackslash{}Microsoft\textbackslash{}Command Processor} | |
| or | |
| \texttt{HKEY\_CURRENT\_USER\textbackslash{}Software\textbackslash{}Microsoft\textbackslash{}Command Processor}. | |
| \item | |
| Check if it contains any path to non-existent file, if it's the case, | |
| just remove them. | |
| \end{enumerate} | |
| \section{Vendor binaries and the \texttt{vendor/bin} | |
| directory}\label{vendor-binaries-and-the-vendorbin-directory} | |
| \subsection{What is a vendor binary?}\label{what-is-a-vendor-binary} | |
| Any command line script that a Composer package would like to pass along | |
| to a user who installs the package should be listed as a vendor binary. | |
| If a package contains other scripts that are not needed by the package | |
| users (like build or compile scripts) that code should not be listed as | |
| a vendor binary. | |
| \subsection{How is it defined?}\label{how-is-it-defined} | |
| It is defined by adding the \texttt{bin} key to a project's | |
| \texttt{composer.json}. It is specified as an array of files so multiple | |
| binaries can be added for any given project. | |
| \begin{verbatim} | |
| { | |
| "bin": ["bin/my-script", "bin/my-other-script"] | |
| } | |
| \end{verbatim} | |
| \subsection{What does defining a vendor binary in composer.json | |
| do?}\label{what-does-defining-a-vendor-binary-in-composer.json-do} | |
| It instructs Composer to install the package's binaries to | |
| \texttt{vendor/bin} for any project that \textbf{depends} on that | |
| project. | |
| This is a convenient way to expose useful scripts that would otherwise | |
| be hidden deep in the \texttt{vendor/} directory. | |
| \subsection{What happens when Composer is run on a composer.json that | |
| defines vendor | |
| binaries?}\label{what-happens-when-composer-is-run-on-a-composer.json-that-defines-vendor-binaries} | |
| For the binaries that a package defines directly, nothing happens. | |
| \subsection{What happens when Composer is run on a composer.json that | |
| has dependencies with vendor binaries | |
| listed?}\label{what-happens-when-composer-is-run-on-a-composer.json-that-has-dependencies-with-vendor-binaries-listed} | |
| Composer looks for the binaries defined in all of the dependencies. A | |
| symlink is created from each dependency's binaries to | |
| \texttt{vendor/bin}. | |
| Say package \texttt{my-vendor/project-a} has binaries setup like this: | |
| \begin{verbatim} | |
| { | |
| "name": "my-vendor/project-a", | |
| "bin": ["bin/project-a-bin"] | |
| } | |
| \end{verbatim} | |
| Running \texttt{composer install} for this \texttt{composer.json} will | |
| not do anything with \texttt{bin/project-a-bin}. | |
| Say project \texttt{my-vendor/project-b} has requirements setup like | |
| this: | |
| \begin{verbatim} | |
| { | |
| "name": "my-vendor/project-b", | |
| "requires": { | |
| "my-vendor/project-a": "*" | |
| } | |
| } | |
| \end{verbatim} | |
| Running \texttt{composer install} for this \texttt{composer.json} will | |
| look at all of project-b's dependencies and install them to | |
| \texttt{vendor/bin}. | |
| In this case, Composer will make | |
| \texttt{vendor/my-vendor/project-a/bin/project-a-bin} available as | |
| \texttt{vendor/bin/project-a-bin}. On a Unix-like platform this is | |
| accomplished by creating a symlink. | |
| \subsection{What about Windows and .bat | |
| files?}\label{what-about-windows-and-.bat-files} | |
| Packages managed entirely by Composer do not \emph{need} to contain any | |
| \texttt{.bat} files for Windows compatibility. Composer handles | |
| installation of binaries in a special way when run in a Windows | |
| environment: | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| A \texttt{.bat} file is generated automatically to reference the | |
| binary | |
| \item | |
| A Unix-style proxy file with the same name as the binary is generated | |
| automatically (useful for Cygwin or Git Bash) | |
| \end{itemize} | |
| Packages that need to support workflows that may not include Composer | |
| are welcome to maintain custom \texttt{.bat} files. In this case, the | |
| package should \textbf{not} list the \texttt{.bat} file as a binary as | |
| it is not needed. | |
| \subsection{Can vendor binaries be installed somewhere other than | |
| vendor/bin?}\label{can-vendor-binaries-be-installed-somewhere-other-than-vendorbin} | |
| Yes, there are two ways an alternate vendor binary location can be | |
| specified: | |
| \begin{enumerate} | |
| \def\labelenumi{\arabic{enumi}.} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| Setting the \texttt{bin-dir} configuration setting in | |
| \texttt{composer.json} | |
| \item | |
| Setting the environment variable \texttt{COMPOSER\_BIN\_DIR} | |
| \end{enumerate} | |
| An example of the former looks like this: | |
| \begin{verbatim} | |
| { | |
| "config": { | |
| "bin-dir": "scripts" | |
| } | |
| } | |
| \end{verbatim} | |
| Running \texttt{composer install} for this \texttt{composer.json} will | |
| result in all of the vendor binaries being installed in | |
| \texttt{scripts/} instead of \texttt{vendor/bin/}. | |
| \chapter{FAQs} | |
| \section{How do I install a package to a custom path for my | |
| framework?}\label{how-do-i-install-a-package-to-a-custom-path-for-my-framework} | |
| Each framework may have one or many different required package | |
| installation paths. Composer can be configured to install packages to a | |
| folder other than the default \texttt{vendor} folder by using | |
| \href{https://github.com/composer/installers}{composer/installers}. | |
| If you are a \textbf{package author} and want your package installed to | |
| a custom directory, simply require \texttt{composer/installers} and set | |
| the appropriate \texttt{type}. This is common if your package is | |
| intended for a specific framework such as CakePHP, Drupal or WordPress. | |
| Here is an example composer.json file for a WordPress theme: | |
| \begin{verbatim} | |
| { | |
| "name": "you/themename", | |
| "type": "wordpress-theme", | |
| "require": { | |
| "composer/installers": "~1.0" | |
| } | |
| } | |
| \end{verbatim} | |
| Now when your theme is installed with Composer it will be placed into | |
| \texttt{wp-content/themes/themename/} folder. Check the | |
| \href{https://github.com/composer/installers\#current-supported-types}{current | |
| supported types} for your package. | |
| As a \textbf{package consumer} you can set or override the install path | |
| for a package that requires composer/installers by configuring the | |
| \texttt{installer-paths} extra. A useful example would be for a Drupal | |
| multisite setup where the package should be installed into your sites | |
| subdirectory. Here we are overriding the install path for a module that | |
| uses composer/installers: | |
| \begin{verbatim} | |
| { | |
| "extra": { | |
| "installer-paths": { | |
| "sites/example.com/modules/{$name}": ["vendor/package"] | |
| } | |
| } | |
| } | |
| \end{verbatim} | |
| Now the package would be installed to your folder location, rather than | |
| the default composer/installers determined location. | |
| \begin{quote} | |
| \textbf{Note:} You cannot use this to change the path of any package. | |
| This is only applicable to packages that require | |
| \texttt{composer/installers} and use a custom type that it handles. | |
| \end{quote} | |
| \section{Should I commit the dependencies in my vendor | |
| directory?}\label{should-i-commit-the-dependencies-in-my-vendor-directory} | |
| The general recommendation is \textbf{no}. The vendor directory (or | |
| wherever your dependencies are installed) should be added to | |
| \texttt{.gitignore}/\texttt{svn:ignore}/etc. | |
| The best practice is to then have all the developers use Composer to | |
| install the dependencies. Similarly, the build server, CI, deployment | |
| tools etc should be adapted to run Composer as part of their project | |
| bootstrapping. | |
| While it can be tempting to commit it in some environment, it leads to a | |
| few problems: | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| Large VCS repository size and diffs when you update code. | |
| \item | |
| Duplication of the history of all your dependencies in your own VCS. | |
| \item | |
| Adding dependencies installed via git to a git repo will show them as | |
| submodules. This is problematic because they are not real submodules, | |
| and you will run into issues. | |
| \end{itemize} | |
| If you really feel like you must do this, you have a few options: | |
| \begin{enumerate} | |
| \def\labelenumi{\arabic{enumi}.} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| Limit yourself to installing tagged releases (no dev versions), so | |
| that you only get zipped installs, and avoid problems with the git | |
| ``submodules''. | |
| \item | |
| Use --prefer-dist or set \texttt{preferred-install} to \texttt{dist} | |
| in your \href{../04-schema.md\#config}{config}. | |
| \item | |
| Remove the \texttt{.git} directory of every dependency after the | |
| installation, then you can add them to your git repo. You can do that | |
| with \texttt{rm -rf vendor/**/.git} but this means you will have to | |
| delete those dependencies from disk before running composer update. | |
| \item | |
| Add a .gitignore rule (\texttt{vendor/.git}) to ignore all the vendor | |
| \texttt{.git} folders. This approach does not require that you delete | |
| dependencies from disk prior to running a composer update. | |
| \end{enumerate} | |
| \section{Why are version constraints combining comparisons and wildcards | |
| a bad | |
| idea?}\label{why-are-version-constraints-combining-comparisons-and-wildcards-a-bad-idea} | |
| This is a fairly common mistake people make, defining version | |
| constraints in their package requires like \texttt{\textgreater{}=2.*} | |
| or \texttt{\textgreater{}=1.1.*}. | |
| If you think about it and what it really means though, you will quickly | |
| realize that it does not make much sense. If we decompose | |
| \texttt{\textgreater{}=2.*}, you have two parts: | |
| \begin{itemize} | |
| \itemsep1pt\parskip0pt\parsep0pt | |
| \item | |
| \texttt{\textgreater{}=2} which says the package should be in version | |
| 2.0.0 or above. | |
| \item | |
| \texttt{2.*} which says the package should be between version 2.0.0 | |
| (inclusive) and 3.0.0 (exclusive). | |
| \end{itemize} | |
| As you see, both rules agree on the fact that the package must be | |
| \textgreater{}=2.0.0, but it is not possible to determine if when you | |
| wrote that you were thinking of a package in version 3.0.0 or not. | |
| Should it match because you asked for \texttt{\textgreater{}=2} or | |
| should it not match because you asked for a \texttt{2.*}? | |
| For this reason, Composer just throws an error and says that this is | |
| invalid. The easy way to fix it is to think about what you really mean, | |
| and use only one of those rules. | |
| \section{Why can't Composer load repositories | |
| recursively?}\label{why-cant-composer-load-repositories-recursively} | |
| You may run into problems when using custom repositories because | |
| Composer does not load the repositories of your requirements, so you | |
| have to redefine those repositories in all your \texttt{composer.json} | |
| files. | |
| Before going into details as to why this is like that, you have to | |
| understand that the main use of custom VCS \& package repositories is to | |
| temporarily try some things, or use a fork of a project until your pull | |
| request is merged, etc. You should not use them to keep track of private | |
| packages. For that you should look into | |
| \href{../articles/handling-private-packages-with-satis.md}{setting up | |
| Satis} for your company or even for yourself. | |
| There are three ways the dependency solver could work with custom | |
| repositories: | |
| \begin{itemize} | |
| \item | |
| Fetch the repositories of root package, get all the packages from the | |
| defined repositories, resolve requirements. This is the current state | |
| and it works well except for the limitation of not loading | |
| repositories recursively. | |
| \item | |
| Fetch the repositories of root package, while initializing packages | |
| from the defined repos, initialize recursively all repos found in | |
| those packages, and their package's packages, etc, then resolve | |
| requirements. It could work, but it slows down the initialization a | |
| lot since VCS repos can each take a few seconds, and it could end up | |
| in a completely broken state since many versions of a package could | |
| define the same packages inside a package repository, but with | |
| different dist/source. There are many many ways this could go wrong. | |
| \item | |
| Fetch the repositories of root package, then fetch the repositories of | |
| the first level dependencies, then fetch the repositories of their | |
| dependencies, etc, then resolve requirements. This sounds more | |
| efficient, but it suffers from the same problems than the second | |
| solution, because loading the repositories of the dependencies is not | |
| as easy as it sounds. You need to load all the repos of all the | |
| potential matches for a requirement, which again might have | |
| conflicting package definitions. | |
| \end{itemize} | |
| \end{document} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment