Composer

There's a Module (or Library) for that!

Composer

Presented by Rob Loach and Larry Garfield

Dependency management sucks

PHP sucks at sharing

  • How do I get a 3rd party library?
  • How do I load its code?
  • Does it depend on anything?
  • Where do I put the files?

Sharing is how Open Source works


Sucking at sharing is how
Open Source dies

But we're Drupal!

  • Drupal.org: Great for modules, nothing else
  • Duplicate work elsewhere
  • Code is not reusable

3rd party code

  • Manually download into your module and pray
  • Manually download into /libraries/ and pray
  • Manually setup extra hook

(... and pray)

"Do it manually and pray"
is for losers

We're better than that, right?

A little history

PEAR

PEAR
  • PHP Extension and Application Repository
  • Founded 2000 on the "new" PHP 4
  • Required root to use properly (WTF?)
  • Complex process for adding packages
  • Easy to get wrong

Symfony 2.0 & PHPBB

  • Initial alpha, Symfony Live Paris, February 2010
  • PHPBB: We're rebuilding on it!
  • Symfony2 uses 3rd party libs (Doctrine, Monolog)

Dependency Hell

Dependencies are hell

We need a dependency system!

It's dumb to make it Symfony specific

—Jordi Boggiano

April 2011

Nils Aderman (PHPBB): libzypp -> PHP

Jordi Boggiano (Monolog): Packagist, less sucky front-end for PEAR

With their powers combined...

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.

Uhh, what?

  • No more Copy/Paste of libraries
  • Resolves dependencies
  • Each project defines its own requirements
  • Performs build tasks
  • Like module .info files, but for any library

September 2011

Packagist.org

  1. Monolog
  2. Twig
  3. Pirum
  4. Swiftmailer
  5. Pimple
  6. Symfony
I'd say until early 2012 it was pretty unusable, yet people used it. I guess that's how badly it was needed.

— Jordi Boggiano

Package count

Number of packages on Packagist over time

April 2013: 10,000 packages

(Not just Symfony!)

Libraries

Some of the libraries available via Composer include...

Symfony

PHP framework for web applications

http://symfony.com

Zend Framework

Zend

PHP framework for web applications

http://framework.zend.com

PHPUnit PHPUnit

Unit testing software framework for PHP

http://phpunit.de

Guzzle

Guzzle

HTTP client & framework for building RESTful web service clients

http://guzzlephp.org

Solarium

Solarium

Solr client library for PHP

http://solarium-project.org

Elastica

Elasticsearch search engine/database for PHP

http://elastica.io

Monolog

Log to files, sockets, inboxes, databases and various web services

https://github.com/seldaek/monolog

Assetic

JavaScript, stylesheet, and image asset management

http://github.com/kriswallsmith/assetic

Drupal

Let's Do This

composer.json

Base manifest file for your project

{
    "name": "crell/mypackage",
    "description": "This package provides some awesomeness.",
    "require": {
        "guzzle/guzzle": "3.4.*"
    },
    "autoload": {
        "psr-0": {
            "MyName\\MyPackage": "src/"
        }
    }
}

composer install

Installs all dependencies for your project


$ curl -sS https://getcomposer.org/installer | php
All settings correct for using Composer
Downloading...

Composer successfully installed to: composer.phar
Use it: php composer.phar
$ php composer.phar install

File system


-rw-rw-r-- composer.json (your composer file)
-rw-rw-r-- composer.lock (generated)
drwxrwxr-x src/          (your code)
drwxrwxr-x vendor/       (everyone else's code)

index.php


require_once __DIR__ . '/vendor/autoload.php';

// Every class is now yours to command!

// Autoload on demand! Your work: zero.
$client = new Guzzle\Http\Client('https://api.github.com');
$request = $client->get('/user')->setAuth('user', 'pass');
$response = $request->send();
echo $response->getBody();

composer update

Updates all installed dependencies to the latest version


$ php composer.phar update
Loading composer repositories with package information
Updating dependencies

More Schema Options

Schema Documentation

{
    "license": "MIT",
    "require": {
        "php": ">=5.3.10",
        "guzzle/guzzle": "3.4.*"
    },
    "require-dev": {
        "phpunit/phpunit": "3.7.*"
    },
    "suggest": {
        "monolog/monolog": "Advanced logging package"
    }
}

Private Repositories

Satis allows you to host your own Composer repositories

{
  "repositories": [
    {
      "type": "composer",
      "url": "http://packages.example.org/"
    }
  ],
  "require": {
    "company/package": "1.2.0",
    "company/package2": "1.5.2",
    "company/package3": "dev-master"
  }
}

github.com/composer/satis

Composer for Drupal

Drush Composer

Allows running Composer commands through Drush


  $ drush dl composer-8.x
  $ drush composer
            
drupal.org/project/composer

Composer Autoload

Automatically loads any generated Composer files

Jimmy Berry - drupal.org/project/composer_autoload

Composer Manager

Builds Composer files from module composer.json files

Chris Pliakas - drupal.org/project/composer_manager

Drush Composer Manager

Downloads and installs dependencies for Drupal modules

 $ drush dl composer_manager monolog
 $ drush en composer_manager monolog
 $ drush composer-manager
 Loading composer repositories with package information
 Installing dependencies
   - Installing psr/log (1.0.0)
     Downloading: 100%

   - Installing monolog/monolog (1.5.0)
     Downloading: 100%
drupal.org/project/composer_manager

Composer Installers

Facilitates installation of Drupal modules/themes/profiles

github.com/composer/installers

Composer Installers

Add a composer.json file in your module/theme directory

{
  "name": "dries/mymodule",
  "type": "drupal-module",
  "require": {
    "composer/installers": "*"
  }
}
github.com/composer/installers

Adding these to each module is cumbersome though, so there is...

Drupal Packagist

Indexes Drupal themes/modules for installation using Satis

{
  "repositories": [
    {
      "type": "composer",
      "url": "http://drugist.espend.de"
    }
  ],
  "require": {
    "drupal/views": "*"
  }
}

Haehnchen - github.com/haehnchen/drupal-packagist

Still very early

Sprint: Friday

Sprint with the community on Friday. Tasks for every skill set. Mentors are available for new contributors.

Optional Friday morning workshop will help you set up community tools.

Drupal tag: #composer Follow @drupalmentoring

Thank you

Evaluate this session at:
portland2013.drupal.org/node/3468