Composer in relation to Drush Make

Last updated on
6 January 2017

This documentation is out of date. Help make it current.

Background

A Drupal project usually consists of the following:

  • Drupal Core
  • A number of modules and maybe a base theme downloaded from Drupal.org
  • Perhaps even some PHP libraries found on GitHub
  • Custom code written by you and your team mates

Previously, the most popular way to assemble all these parts has been Drush Make. In recent years the PHP Community has gathered around Composer, which is now used to manage the Drupal 8 core dependencies.

Getting started

To start your first Drupal project with Composer you need to:

  1. Install Composer - make sure you install it "globally". Mac users: the instructions don't mention it, but composer is also available via Homebrew:

    brew install composer

    Verify the global install: 

    composer -V

    which returns the version, such as:

    Composer version <x.y.z> 
  2. Composer template for Drupal projects provides a ready-madecomposer.json file which will also install Drush, Drupal Console and various testing frameworks. (There's also a simpler alternative project - see this explanation.)

    You need to manually install Drupal Console Launcher if you haven't already.

  3. To install Drupal 8 in a directory called some-dir, you would use:

    composer create-project drupal-composer/drupal-project:8.x-dev some-dir --stability dev --no-interaction

    If you want Drupal 7, there's a 7.x branch too.

    Composer will now install everything (including a long list of Symfony packages) - there should be no need to run composer install. 

  4. Note that drupal-project installs Drupal itself insome-dir/web (so Acquia Dev Desktop using the Import local Drupal site option need to use that for Local codebase folder - likewise your Apache or Nginx document root).
     

  5. To install modules or themes from Drupal.org:

    composer require drupal/module-name 

    Detailed instructions

    (Note that you don't require composer_manager. The functionality of drupal-composer/drupal-project and composer_manager are mutually exclusive.)
     

  6. If you have already created a database some_db you can now install Drupal using drush:

cd some-dir/web ../vendor/drush/drush/drush site-install standard \ --db-url=mysql://DBUSERNAME:DBPASSWORD@localhost/some_db \ --account-mail="admin@example.com" \ --account-name=admin \ --account-pass=some_admin_password \ --site-mail="admin@example.com" \ --site-name=“Site-Install” 

You should now have a Drupal installation in your project directory and be ready to include other modules and themes from Drupal.org.

Usage

The following aims to explain Composer in relation to Drush Make based on the structure of the Drush Make documentation.

Composer has a great introduction and thorough documentation of the composer.json format.

Packagist

Composer retrieves information from packagist.org to download packages.

The Drupal community created a "Drupal Packagist" on http://packagist.drupal-composer.org that aims to provide package information of all Projects hosted on drupal.org. This way, modules, themes and other projects do not have to be registered on packagist.org to be easily used in composer.

For adding the additional packagist server, simply add it to repositories of your composer.json:


"repositories": [ { "type": "composer", "url": "http://packagist.drupal-composer.org" } ],

This packagist is generated using the drupal-parse-composer project.

Core version

In Composer, Drupal core is a package like any other. So it is added to your project by adding a dependency to your composer.json.

Adding the following information to the composer.json will download the latest Drupal 7 release and place it in the web/-folder of the Composer project.


{ "require": { "composer/installers": "~1.0", "drupal/drupal": "7.*" }, "extra": { "installer-paths": { "web/": ["type:drupal-core"] } } }

With Drupal 8 we can choose the same approach ("drupal/drupal": "8.*") or we can use the subtree-split of the core-directory ("drupal/core": "8.*").

Drupal 6 will not be supported by "Drupal Packagist".

Projects

All Drupal projects to be retrieved should be added as dependencies in the format drupal/[module-short_name] and their version in the format [drupal-version].[module-major-version].[module.minor-version].

The following will download the Chaos tool suite (ctools) module version 1.4 for Drupal 7.


{ "require": { "drupal/ctools": "7.1.4" } }

The module will be placed under sites/all/modules/contrib/.

You can also run php composer.phar require drupal/ctools from the command line in the root directory of the project. This is prompt for any additional information needed and update composer.json accordingly.

Here is an example showing syntax of the require command when your require specific versions. In the first case the require section of composer.json will be updated; in the second case the require-dev section will be updated by the require command. (Note the way dev module versions are spelt.)


composer require drupal/mailsystem:8.4.0-alpha1 composer require drupal/examples:8.x-1.x-dev drupal/link_css:8.x-1.x-dev --dev 

Drupal projects are normally not available from the default Composer package repository Packagist. In order for this to work you need to add the Drupal Packagist to your repositories (see Packagist).

Project options

Version

You specify the version of each project using Composer package version constraints.

In this example the following releases of Drupal 7 modules will be downloaded:

  • Latest stable minor release of Chaos tool suite 1.x
  • Latest stable release of Features
  • Latest development release of Views 3.x
  • A specific revision of a module (note the dev- prefix)

{ "require": { "drupal/ctools": "7.1.*", "drupal/features": "7.*", "drupal/views": "7.3-dev", "drupal/devel": "dev-7.x-1.x#75f228f8086f74778e4cc7245b011bfd912dae04" } }

Subdir

With using the Composer Installers plugin you can customize the path of individual projects or by type. Therefore you will need to specify the installer-paths section of composer.json.


{ "extra": { "installer-paths": { "sites/all/modules/contrib/{$name}/": ["type:drupal-module"], "sites/all/themes/{$name}/": ["drupal/zen"] } } }

Patch

Patching is not natively supported by Composer. For implementing patches in the composer workflow you can use a composer plugin; cweagans/composer-patches is the standard patch manager recommended for use with Drupal projects.

Example

The following example shows usage with composer-patches plugin.

To apply a patch to a project a patches section must be added to the extras section of composer.json.

The following will patch the domain_conf module with this patch:


{ "extra": { "patches": { "drupal/domain": { "Domain_conf permissions": "https://www.drupal.org/files/issues/domain-conf-450688-%2310.patch" } } } }

The plugin generates a PATCHES.txt file for each patched project as Drush Make does.

Location

Specifying alternate release information for the projects is possible by setting up a custom repository with help of Satis.

Type

The type has to be specified in the composer.json of the Project (Module, Theme,...). Drupal Packagist takes care of that for Drupal.org Projects. If you are maintaining a custom composer.json you have to specify the the package type on your own to one of the types supported by the Composer Installers plugin. This includes drupal-module and drupal-theme.

This is necessary to let the installer place the project in the correct directory, when it is required "composer/installers": "~1.0".

Directory name

Projects can be placed in specific directories when using the Composer installers. See Subdir.

l10n_path

Composer does not support specifying custom paths for translations.

l10n_url

Composer does not support specifying custom translation servers.

overwrite

Composer always does install or update packages in the given path, when necessary. So there is no need for an overwrite flag.

On the other hand, if you want to make sure certain files or folders should not be overwritten, you could use the Composer preserve paths plugin.

translations

Composer does not handle translations.

Project download options

To download a project which is not on Drupal.org or a Composer package then define it as a custom package repository and add it as a dependency.

This method supports version control checkouts from custom branches or tags as well as file downloads. Also, this is useful if a module from a sandbox is required.

Libraries

If libraries are not available at packagist.org, they can be retrieved by specifying custom packages in the repository section. See Project download options.

Example downloading jQuery UI 1.10.4:


{ "repositories": [ { "type": "package", "package": { "name": "jquery/jqueryui", "version": "1.10.4", "type": "drupal-library", "dist": { "url": "http://jqueryui.com/resources/download/jquery-ui-1.10.4.zip", "type": "zip" }, "require": { "composer/installers": "~1.0" } } } ], "require": { "jquery/jquery.ui": "1.10.4" } }

Note: A different package type is introduced here: drupal-library. This allows Composer Installer to handle library placement different compared to modules and themes.

Library options

Libraries are defined as Composer packages and thus support the same options as Drupal projects and Composer packages in general.

Destination

Libraries can be placed in specific directories using the installer-paths section. See Subdir.

Includes

Composer uses dependencies as includes. If a dependency has dependencies on its own and specifies these in its' composer.json file then these dependencies will be installed as well. Note that a Composer package does not have to contain any actual code. You can even specify packages of type metapackage to specify dependency-wrappers that do not even install and only hold additional dependencies in the require section.

Note: some schema properties are only used in the root composer.json. They are marked as root-only in the documentation.

Defaults

Composer does not have the concept of user-defined default values for packages. Nonetheless, Composer Installer does support setting a standard directory for all packages of a specific type (e.g. drupal-module). See Subdir.

Overriding properties

Composer does not support overriding individual properties for a package.

One approach to changing properties is to fork the package, update the composer.json for the package accordingly and add a new repository pointing to the fork in the root composer.json.

Packages overriding the Drupal projects repository should be placed before Drupal Packagist, due to the order in which Composer looks for packages.

Recursion

Composer resolves dependencies only in the context of the provided composer.json package information. It does not look for dependencies in other composer.json files, for example in subdirectories of the downloaded packages.

In addition a few properties are only defined by the root package - the composer.json for the project.

Generate

Using the "Composer Generate" drush extension you can now generate a basic composer.json file from an existing Drupal 7 project.

FAQ

How is this better than Drush Make?

Drush Make has its own problems which makes it difficult to work with e.g.:

Also Drush Make is a tool primarily built for Drupal. Using Composer means using the same tool that many others in the PHP community use and makes it easy to use other libraries with a Drupal project.

See also: Composer instead of drush make to build projects (Lullabot)

Should I commit the contrib modules I download

Composer recommends no. They provide argumentation against but also workarounds if a project decides to do it anyway.

Credit

The initial document was created by kasperg, revised by webflo, derhasi and albertvolkman. It was moved from https://github.com/drupal-composer/drupal-project after that.

Using Composer to manage a Drupal project would not be possible without the work of others. Some projects are mentioned above.