Composer is the industry-standard PHP dependency manager that is now in use in Drupal 8 core. This session will show the current best practices for using Composer, drupal-composer, drupal-scaffold, Drush, Drupal Console and Drush site-local aliases to streamline your Drupal 7 and Drupal 8 site repositories for optimal use on teams.
2. Pantheon.io 2
Session Description
Composer is the industry-standard PHP dependency manager that is now in use in Drupal 8 core. This session will show the current best practices for
using Composer, drupal-composer, drupal-scaffold, Drush, Drupal Console and Drush site-local aliases to streamline your Drupal 7 and Drupal 8 site
repositories for optimal use on teams.
We will answer such gripping questions as:
● How do I avoid placing a copy all of the Drupal core and contrib modules into my repository?
● How do I keep my core and contrib modules up-to-date?
● What if I need to customize .htaccess, or some other file?
● Can I work with a "lean" repository, and still seamlessly use a full repository to deploy?
● How do I share Drush aliases with team members, without using another repository, and without making my alias list too long?
● What is a Drush wrapper script, and how can it help me?
● How does Drupal Console fit in to all of this?
● Should I use test fixtures in my Behat tests, or make a copy of the production site database?
These techniques will also be helpful for solo site developers--you never know, the next person who needs to check out, build and test your Drupal site
from scratch might be you!
3. Pantheon.io
Then create a Git repository:
cd myproject
git init
git add .
git commit -m “My new project”
3
Getting Started with Drupal and Composer
One easy step in Composer:
composer create-project drupal-composer/drupal-project myproject --stability=dev
Install and run with Drush:
cd web
drush qd --db-url=mysql://root@localhost/myprojectdb
Answer “yes” when Composer
asks to remove VCS files, or run
with --no-interaction option
13. Pantheon.io 13
Checking for Security Updates
With Drush
With Composer
$ drush pm-updatestatus
Checking available update data ... [ok]
Checking available update data for Drupal. [ok]
Checking available update data for Token (token). [ok]
Name Installed Version Proposed version Message
Token (token) 7.x-1.2 7.x-1.6 SECURITY UPDATE available
$ composer require roave/security-advisories:dev-master
$ composer require drupal-composer/drupal-security-advisories:7.x-dev
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.
Problem 1
- drupal-composer/drupal-security-advisories 7.x-dev conflicts with drupal/token[7.1.2].
- Installation request for drupal-composer/drupal-security-advisories 7.x-dev ->
satisfiable by drupal-composer/drupal-security-advisories[7.x-dev].
- Installation request for drupal/token 7.1.2 -> satisfiable by drupal/token[7.1.2].
n.b. Requires git_deploy module if using Composer with
--prefer-source, or if dev modules are used.
18. Pantheon.io 18
Generate require Section from Existing Site
composer create-project drupal-composer/drupal-project myproject --stability=dev
cd myproject
drush composer-generate @remote
Look up the modules and themes
used on @remote and add them to
the require section of the
composer.json in the cwd.
20. Pantheon.io 20
Add a Project to Circle
A couple of clicks will get
Circle CI building your project.
There are a few credentials
that should also be set up:
● GitHub OAuth Token
● Terminus Machine Token
● SSH Key Pair
21. Pantheon.io 21
Generate OAuth Tokens for all Services
GitHub Personal Access Tokens Pantheon Machine Tokens
OAuth tokens are getting to be very common; many services provide them.
They work like passwords, but can have limited permissions, and may be revoked.
23. Pantheon.io
Prevents ‘composer install’
from failing due to hitting the
GitHub rate limit.
23
Use OAuth Environment Variables in CI
dependencies:
pre:
- composer config -g github-oauth.github.com $GITHUB_OAUTH
- terminus auth login --machine-token=$PANTHEON_MACHINE_TOKEN
circle.yml
Log in to Terminus via machine
token, e.g. to later deploy from
dev to test.
24. Pantheon.io 24
Create SSH Key Pair Specifically for CI
$ ssh-keygen -C me+mysite-ci@example.com -f my-ci-keyfile
Add Private Key to Circle SSH Permissions Add Public Key to Provider SSH Keys
For linux servers: ssh-copy-id user@isp.com
25. Pantheon.io 25
Dependency Hell
Bootstrapping Drupal 8 via a global Drush will ONLY WORK if the
dependencies of the two projects are in perfect alignment.
Upgrading one without upgrading the other is dangerous.
Drush Drupal 8
require autoload.php
Bootstrap require autoload.php
26. Pantheon.io 26
Simple Example of Dependency Hell
class Sub extends Base
{
public function foo()
{
return $this->bar();
}
}
class Base
{
private function bar()
{
…
}
}
class Sub extends Base
{
public function foo()
{
return $this->boz();
}
}
class Base
{
private function boz()
{
…
}
}
FancyLib v1.0.1 FancyLib v1.0.2
Sub.php Sub.php
Base.php Base.php
Semantic Versioning will not save
you!
Two autoloaders that contain multiple
copies of the same library can still fail,
even if both conform to the same
public API.
27. Pantheon.io 27
Dependency Hell Affects Drupal Console Too
Drupal Console, like Drush, keeps dependencies in sync with the Drupal 8 release with the
same version number. Problems can still occur if versions become mismatched.
Drupal Console Drupal 8
require autoload.php
Bootstrap require autoload.php
28. Pantheon.io
Place Drush and Drupal Console in Drupal’s composer.json file:
cd /path/to/drupal-8-root
composer require drush/drush:8.*
composer require drupal/console
28
Solution is to Use a Single Autoloader
CRITICAL
29. Pantheon.io 29
Gentoo’s “Composer Problem”
“ As long as the necessary
require statements are left in
the code (where they
belong), we can ignore
Composer entirely and install
the package with the system
package manager. We set
PHP's include directory for
our users, so require('Class.
php'); already looks in the
right place.https://wiki.gentoo.org/wiki/Project:PHP/The_Composer_problem
30. Pantheon.io 30
How Could We Fix Things for Gentoo?
One Class.php shared by every application is not going to work!
Make an autoload.php that loaded versioned Class.php files from
a global location?
How would all of the different versions of Class.php be managed?
How would you apply a security update for Class.php?
By the time we have solved all of
these issues, we have pretty much re-
invented Composer.
31. Pantheon.io
Drush startup now happens in four phases:
31
Drush Startup
Drush Finder Drush Wrapper Drush Launcher Drush Application
32. Pantheon.io 32
Drush Finder
Responsible for finding the correct Drush to run
- Checks to see if it can find a Drupal site
- If the Drupal site contains a Drush script, use it
- If no Site-Local Drush is found, use global Drush
Does not consider alias files.
PHP Script
named
“drush”
33. Pantheon.io 33
Drush Wrapper
Optional. Located at the Drupal Root if it exists.
User may customize this script to:
- Add site-specific options (e.g. commandfile locations)
- Turn off global search locations with --local option
- Select the location of the Drush launcher (if non-standard)
If there is no Drush Wrapper, then the Drush Finder will find and
execute the Drush Launcher.
Shell Script
named
“drush.wrapper”
34. Pantheon.io 34
Drush Launcher
Sets up the PHP operating environment.
- Select php.ini file to use
- Select php executable to use
- Passes info about environment to Drush
The launcher will always use the Drush application located in the
same directory.
Shell Script
named
“drush.launcher”
35. Pantheon.io 35
Drush Application
Contains all the code that is Drush.
- Load configuration and command file
- Parse site alias files
Might dispatch again, e.g. if site alias is remote.
PHP
Application
named
“drush.php”
36. Pantheon.io 36
Drush Phar
Bundles all of the code from the Drush application into a single file.
- Does not use Drush Launcher (no PHP executable selection).
- Will run a Drush Wrapper script if one is available.
If a Drush Wrapper or site-local Drush is found, they will be executed
via redispatch. The site-local Drush may be a Phar or a regular
Drush application.
Phar file
named
“drush.phar”
Phar
37. Pantheon.io 37
Sharing Drush Aliases
cd "`dirname $0`"
private/vendor/bin/drush.launcher
--local
--include=../drush/commands
--alias-path=../drush/aliases
--config=../drush/config "$@"
drush.wrapper
drush
web
drush.wrapper
aliases
commands
index.php
aliases.drushrc.php
$ cd web
$ drush sa @live
$aliases["live"] = array (
'remote-host' => 'server.isp.com',
'remote-user' => 'www-admin',
'root' => '/srv/www/live.example.com',
'uri' => 'http://example.com',
);
38. Pantheon.io 38
Behat Driver Enhancement
cd /path/to/drupal-project
composer require drush-ops/behat-drush-endpoint
YES!
Adds behat Drush command
to your site; used to remotely
create content.
39. Pantheon.io 39
Behat Fixtures
Background:
Given "places" terms:
| name |
| Kingdom of Imaginarium |
| Empire of Fabrication |
And "offices" terms:
| name |
| Grand Poohbah |
| Undersecretary of Things |
| Minister of Ministering |
$ drush behat import --file=fixtures.yml
create_term:
places:
- name: Kingdom of Imaginarium
- name: Empire of Fabrication
offices:
- name: Grand Poohbah
- name: Undersecretary of Things
- name: Minister of Ministering
Option 1:
Use Behat’s built-in “Background”
Option 2:
Create fixtures with behat-drush-endpoint
Deletes and re-creates fixtures for every test; useful
for testing operations that modify or delete terms.
Taxonomy IDs stay constant for every test run.
ALSO (for Drupal 8): drush site-install --config-dir=export-dir
40. Pantheon.io 40
That’s a Wrap!
Follow me on Twitter for slides and other Composer + Drush updates:
@greg_1_anderson