Better dependency management: leverage composer to the limit.

Can I use composer to do this?

A talk by Rodrigo Aguilera / @marinero

Hello There

Ymbra

Agenda

  • The PHP reinassance
  • The old days of drush make and the Drupal island
  • Composer is awesome
  • Your drupal project has dependencies too
  • Compose all the things!

The PHP reinassance

elephant

We have too much code

Takes less time to write (or copypaste) a solution yourself than to find a component you can reuse.

Reusability

Sharing must be easy or it won't happen.

Free software as a feature.

First attemps, aka: the way there

  • Pear (PHP 4, required root, lots of includes)
  • Class autoloading (PHP 5.0)
  • Github (As replacement of Sourceforge)
  • Namespaces (PHP 5.3)
  • PHP standards (PSR-x)

The drupal island

Drupal diver

Drush make (2010)

The shopping list

api = 2
core = 7.*
projects[views] = 3.1
projects[ctools] = 1.0-rc1
projects[media] = 2.x-dev

projects[nodequeue][subdir] = contrib
projects[nodequeue][version] = 2.0-alpha1
projects[nodequeue][patch][] = "http://drupal.org/files/issues/1023606-qid-to-name-6.patch"
projects[nodequeue][patch][] = "http://drupal.org/files/issues/nodequeue_d7_autocomplete-872444-6.patch"

libraries[jquery.cycle][download][type] = get
libraries[jquery.cycle][download][url] = http://malsup.com/jquery/cycle/release/jquery.cycle.zip?v2.99
libraries[jquery.cycle][destination] = libraries
            

Problems

  • Downloads all the code everytime
  • All dependencies listed
  • You have to be specific about the versions
  • Only remote patches
  • Different make files for different purposes

Some brave sailors

Drupal diver

Some brave sailors

Sailorwoman

Drupal makes some friends out there

Just by looking at the composer.json in drupal core

  • A lot of symfony components(dependency injection, events, routing, yaml, etc)
  • Twig
  • Guzzle
  • Composer
  • And much more

Introducing Composer - 2012

Director

Director

The need

  • 3rd party libraries.
  • Dependency hell.
  • Other PHP projects didn't had drush make.

Definition

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.

What it means

  • No more Copy/Paste of libraries
  • Resolves dependencies
  • Each project defines its own requirements
  • Performs build tasks
  • Autoloading: all code under the same roof:

Similar to composer in diferent programming languages

  • npm (javascript)
  • pip (python)
  • rubygems (with bundler)

Get Composer


# Quick-n-easy:
$ curl -sS https://getcomposer.org/installer | php

# Global
$ curl -sS https://getcomposer.org/installer | php -- --install-dir=bin
            

Structure of composer.json

Base manifest file for your project


{
    "name": "rodrigoaguilera/mydrupalsite",
    "description": "This site is awesome.",
    "require": {
        "drupal/honeypot": "1.*"
    },
    "require-dev": {
        "drupal/devel": "1.*"
    },
    "config": {},
    "extra": {}
}
            

Composer.json and composer.lock

Dependencies solved.
Is the key for everyone to have the same versions.
Always commit your lock file.

Basic Commands

composer install

Reads composer.lock and downloads all your dependencies in the /vendor directory.

composer update

Writes a new composer.lock based on what is on composer.json and downloads what is needed
You can update only one package to do more atomic updates.

Require

            
composer require <vendor>/<package>:"<version-constrain>"
            
            

Packagist.org

Main repository for packages.
There is also https://packages.drupal.org/8 as a mirror of the modules and themes on drupal.org

Execute binaries

            
vendor/bin/drush
            
            

            
composer exec drush
            
            

Global vs local

  • The power of composer comes from having per project dependencies.
  • But you can also install composer packages shared by everything and everyone.
  • Use "composer global" before commands. (neeeds $COMPOSER_HOME)

Simulating enviroments

            
"config": {
    "platform": {
       "php": "5.6.2",
       "ext-mongodb": "1.1"
    }
}
            
            

Semantic versioning

Versioning

Composer in production

            
composer install --prefer-dist --no-dev --optimize-autoloader
            
            
  • No git repository files
  • The require-dev section is ignored
  • Faster autoloader

Component vs. project

The composer.json for a project (the root package) has more capabalities like:

  • Use your own repos
  • Define hook scripts (post-install, pre-update, etc.)
  • Configuration

Patches

              
{
  "require": {
    "cweagans/composer-patches": "~1.0",
    "drupal/drupal": "8.4.*@dev"
  },
  "config": {
    "preferred-install": "source"
  },
  "extra": {
    "patches": {
      "drupal/drupal": {
        "Add startup configuration for PHP server": "https://www.drupal.org/files/issues/add_a_startup-1543858-30.patch"
      }
    }
  }
}
              
            

Dawg

Quiz: Install or update

  • Be sure you have the last updates from your team: composer install
  • Deploying a new release of your application to production. composer install
  • Checked out with git a new project and want to start coding. composer install
  • Fetch new versions for the dependencies of your project. composer update

But... How do I use composer in my drupal project?

Composer template for drupal projects comes to the rescue.
https://github.com/drupal-composer/drupal-project

What does the template do?

  • Drupal will be downloaded with correct permissions ready for install.
  • Declaring a new depencency and downloading is one semantic command.
  • Modules, themes, and profiles (packages of type drupal-[module|theme|profile]) will be placed in web/[module|theme|profile]/contrib/

What does the template do?

  • Creates default writable version of settings.php.
  • Latest version of drush is installed locally for use at vendor/bin/drush.
  • Latest version of DrupalConsole is installed locally for use at vendor/bin/drupal.

Profit :D

  • Now everyone can have not only the same modules but also drush and console
  • Updating all your modules to the stable versions is just a couple of words away
  • Your continous integration system can become much more simple

Compose all the things!

Frontend libraries are also dependencies

  • Not in packagist (npmjs.org or bower)
  • Different locations than modules

asset-packagist.org

  • Add one repository to your root composer.json
  • Collects both packages from npm and bower under 2 vendors
  • Enables the ability to do composer require npm-asset/bootstrap-sass:"^3"
  • Needs oomphinc/composer-installers-extender to define custom paths

Binary tools are also dependencies

  • Generally found in distribution's repositories (apt-get, yum, etc)
  • Usually compiled for a certain arquitecture and operating system
  • Specific packages for each binary
  • Available on vendor/bin/
  • Examples: mouf/nodejs-installer, jakoch/phantomjs-installer
Dawg

Recommendations

Global minimum-stability

For example:

              "minimum-stability": "dev"
            

You can be more semantic and declare it for each package like

               composer require "drupal/webform":"^5@beta",
            

Config options


"config": {
    "sort-packages": true,
    "discard-changes": true,
    "process-timeout": 600,
    "platform": {
      "php": "7.1.0"
    }
  }
            

Questions

THE END

Thank you.
- https://getcomposer.org/