Composer is the new Drush - Drupal Developer Training (internal)
Transcript of Composer is the new Drush - Drupal Developer Training (internal)
Composer is the new Drush
Perttu Ehn // Exove Ltd // 2106-12-20
Scope
Drush Recap
Composer
Workflow with the Composer
Recipes
Semantic versioning
More recipes
Drupal Console
Perttu Ehnhttps://www.drupal.org/u/rpsu @ropsue
Competence manager @ Exove Ltd www.exove.com
10 years of Drupal, three (small) contrib modules
Motto:Q: Can this be done?A: Yes. Most certainly. It’s just a matter of the size of your budget.
blah blah blah.. about me
Drush recapdrush.org
Drush recap“Drush is a command line shell and Unix scripting interface for Drupal.“- www.drush.org
Build codebase based on the recipe (.make-file)$drushmakemy-makefile.make
Download and enable modules, themes
Set variables, reset passwords, rebuild or revert features…
Write your own custom commands to do practically anything with Drupal
Drush is not a dependency manager, but a fixed recipe for the codebase
Composergetcomposer.org
"Composer is a tool for dependency management in PHP"
Dependency manager, per project, within a project
Node: npm
Ruby: bundler
Composer
Composer does everything with the codebase Drush does, but better
Composer Does not touch Drupal
.. however, Drupal console does
Composer
Workflow with the Composer
Set up a project repository (localdev…!)
You add project requirements$composerrequiredrupal/drupal
Composer will solve requirement's dependencies
Commit composer.json and composer.lock -files to Git
Don’t commit code hosted elsewhere - Drupal core, modules, libraries
Workflow with the Composer
Use Composer template for Drupal, it comes with steroids! $composercreate-projectdrupal-composer/drupal-project:8.x-devcoolio--stabilitydev—no-interaction--prefer-dist
Workflow
Image: http://www.e-steroid.com/steroid-articles/negative-effects-of-steroids.html
Use Composer template for Drupal$composercreate-projectdrupal-composer/drupal-project:8.x-devcoolio--stabilitydev--no-interaction --prefer-dist
Composer may be installed globally or per project 1)
Composer == composer.phar -file, “Php ARchive”
Workflow
1) https://getcomposer.org/doc/00-intro.md#installation-linux-unix-osx
Use Composer template for Drupal $composercreate-projectdrupal-composer/drupal-project:8.x-devcoolio--stabilitydev--no-interaction --prefer-dist
create-project creates a new project from an existing project (think gitclone)
Workflow
Use Composer template for Drupal $composercreate-projectdrupal-composer/drupal-project:8.x-devcoolio--stabilitydev--no-interaction --prefer-dist
Use Composer template for Drupal as the base
8.xproject version (relates to the Drupal core version)
-devuse dev -version, ie. a git commit (latest one in this case)
Workflow
Use Composer template for Drupal $composercreate-projectdrupal-composer/drupal-project:8.x-devcoolio--stabilitydev--no-interaction --prefer-dist
cooliois the directory where the project will be created
also where composer.json and composer.lock files will be created
Workflow
$composercreate-projectdrupal-composer/drupal-project:8.x-devcoolio--stabilitydev--no-interaction --prefer-dist
--stabilitydevMinimum stability of package
--no-interaction Do not ask any interactive question
Workflow
$composercreate-projectdrupal-composer/drupal-project:8.x-devcoolio--stabilitydev--no-interaction --prefer-dist
--prefer-dist Prefer distributions over source, ie. use vendor zip/gzip/tar/whatever if found. Faster.
Workflow
$composercreate-projectdrupal-composer/drupal-project:8.x-devcoolio-d8--stabilitydev--no-interaction --prefer-dist……(wait)……(stillworkingonit)……Createasites/default/settings.phpfilewithchmod0666 Createasites/default/services.ymlfilewithchmod0666 Createasites/default/filesdirectorywithchmod0777
$cdcoolio-d8
Ladies and gentleman, start your engines!
coolio-d8$ls-A.gitignore.travis.ymlLICENSEREADME.mdcomposer.json#declarerequirementscomposer.lock#calculatedrequirement#treewithversionsphpunit.xml.distdrush/#drushperproject(!)scripts/vendor/#PHPlibrariesweb/#Drupalrootfolder
Codebase (D8)coolio-d8$ls-Aweb.csslintrc.editorconfig.eslintignore.eslintrc.htaccess.gitattributesautoload.phpindex.phprobots.txtupdate.phpweb.configcore/modules/profiles/sites/themes/
$composercreate-projectdrupal-composer/drupal-project:7.x-devcoolio-d7--stabilitydev--no-interaction —prefer-dist……(wait)……(stillworkingonit)……WritinglockfileGeneratingautoloadfiles>rmREADME.mdLICENSE.travis.ymlphpunit.xml.dist
$cdcoolio-d7
Ladies and gentleman, start your engines!
coolio-d7$ls-A1.gitignorecomposer.json#declarerequirementscomposer.lock#calculatedrequirement#treewithversionsvendor/#PHPlibrariesweb/#Drupalrootfolder
Codebase (D7)coolio-d7$ls-A1web.editorconfig.gitignore.htaccessCHANGELOG.txtCOPYRIGHT.txtINSTALL.mysql.txtINSTALL.pgsql.txtINSTALL.sqlite.txtINSTALL.txtLICENSE.txtMAINTAINERS.txtREADME.txtUPGRADE.txtauthorize.phpcron.phpincludesindex.phpinstall.phpmiscmodulesprofilesrobots.txtscriptssitesthemesupdate.phpweb.configxmlrpc.php
Web root is in coolio/web
All libraries are protected from direct accesscoolio/vendor/*
vendor code rarely needs to be accessible directly from the world
index.php
core/update.php (well...)
Folder structure
Recipes
;DrushINI
core=8.xapi=2
projects[drupal][version]="8.2.3"
projects[]="ctools"
projects[commerce][version]="2.0-beta3"projects[commerce][subdir]="commerce"
defaults[projects][subdir]="contrib"
RecipesGet some modules (.make)
List the modules you have with Drupal:$drushpmlRemove module code manually
#YAMLformat
core:8.xapi:'2'
projects:drupal:version:8.2.3
ctools:version:''
#projects:
commerce:subdir:commerceversion:2.0-beta3
defaults:projects:subdir:'contrib'
RecipesGet some modules (.make.yml)
List the modules you have with Drupal:$drushpmlRemove module code manually
$composerrequiredrupal/core:8.2.2
Changes core version 8.2.3 -> 8.2.2 (with template project)
$composerrequiredrupal/ctools$composerrequiredrupal/commerce:2.0-beta3
List the modules you have with Drupal:$composershowdrupal/*
Remove a module - affects composer.json and the codebase, too$composerremovedrupal/ctools
Add Drush and Registry Rebuild module (Drupal 7 only)$composeradddrush/drush:7.*drupal/registry_rebuild
RecipesGet some modules (composer)
zsh requires quoted parameter when it contains an asterisk: $ composershow"drupal/*"
You request a (Drupal) package$composerrequiredrupal/ctools
Composer finds it (https://packages.drupal.org/8)
Composer updates composer.json -file
Composer downloads the package
Composer checks if this new package has other requirements (composer.json file)
Composer searches for the requirement… => this is a dependency tree!
Composer dependency resolving 1/2
zsh requires quoted parameter when it contains an asterisk: $ composershow"drupal/*"
All good! && Write composer.lock file
OR
Exception!!! Exception!!! && Revert the changes in composer.json file
Composer dependency resolving 2/2
zsh requires quoted parameter when it contains an asterisk: $ composershow"drupal/*"
1. Clone project repository.
2. Run composerinstall
Composer reads composer.lock -file
Composer retrieves all the required dependencies
Composer generates autoloader
3. That’s it! (+ some vagrantup and Drupal site installs)
zsh requires quoted parameter when it contains an asterisk: $ composershow"drupal/*"
Fellow developer’s local
Run composerupdate to get the latest available (version constraints!)
Update code
Write updates to composer.lock -file
Change version (ie change version constraints)$composerrequiredrupal/commerce:2.*
zsh requires quoted parameter when it contains an asterisk: $ composershow"drupal/*"
How to do code updates?
Semantic versioning
Three digits; 1.2.3
1st changes might be backwards incompatible (major)
API removals, API changes
2nd changes with API additions, new features (minor)
3rd changes with bug fixes (patch)
Semantic versioning
Range
Comparison operators, specified range of allowed versions>=1.0>=1.0<2.0>=1.0<1.1||>=1.21.0-2.0
Wildcard
* is a wildcard: 1.0.* is the equivalent of >=1.0<1.1
https://getcomposer.org/doc/articles/versions.md
Constraints
Tilde
~ specifies a minimum version, but allows the last digit specified to go up: ~1.2 is the equivalent of >=1.2<2.*
Caret
^ sticks closer to semantic versioning; sub-major version updates should not break anything: ^1.2.3 is equivalent to >=1.2.3<2.0.0
https://getcomposer.org/doc/articles/versions.md
Constraints
Specify allowed versions, not a specific version
composer.lock -file will contain the specific version which composerinstall will use
drupal/core:8.2.2=> drupal/core:~8.2 or drupal/core:^8.2
drupal/commerce:2.0-beta3 => drupal/commerce:~2
drupal/ctools:~3
Git HEAD (not recommended): drupal/console:dev-1.xdrupal/console:dev-master-forGitHub
https://getcomposer.org/doc/articles/versions.md
Constraints
More recipes
Problem: Feature or fix you must have may be in Git, but not in the latest release
Solution:Use a specified Git commit
More recipes
Use a specified Git commit
;OptionallyprovidegitbranchsoDrush;canwritethatto.infofileprojects[ctools][download][branch]="8.x-3.x";Gitcommithashprojects[ctools][download][revision]=1fe3649
More recipes
Use a specified Git commit
projects:ctools:download:#Optionallyprovidegitbranchso#Drushcanwritethatto.infofilebranch:8.x-3.x#Gitcommithashrevision:1fe3649
More recipes
Use a specified Git commit
$composerrequiredrupal/ctools:dev-3.x#1fe3649
More recipes
Use a specified Git commit
READ: never use HEAD (“latest whatever code”)
More recipes
Problem:-> Found and fixed a bug in a contrib module, and now you need to use your fixes (a patch file) from drupal.org? No prob.-> Perhaps you were lazy and never uploaded the patch? No prob either.
Solution: Drush and Composer can apply remote and local patches
Patching modules
projects[field_group][version]="1.0-rc4";Explainbrieflywhythispatchisneeded.projects[field_group][patch][2761159]=https://www.drupal.org/files/issues/field_group-empty_group_nonnumeric_index-2761159-2-D8.patch ;Localpatch(pathrelativeto.make-file)projects[field_group][patch][other_fix]=patches/field_group-fix_it.patch
Apply the patch either by re-running$drushmakemy_project.make
…or manually$patch-p0<path/to/important.patch
Patching modules
projects:field_group:version:'1.0-rc4'patch:#Explainbrieflywhythispatchisneeded. 2761159:'https://www.drupal.org/files/issues/field_group-empty_group_nonnumeric_index-2761159-2-D8.patch'#Localpatch(pathrelativeto.make.yml-file)other_fix:‘patches/field_group-fix_it.patch'
Apply the patch the same way with old style .make file
Patching modules
Install module field_group$composerrequiredrupal/field_group:1.0-rc4
Edit composer.json and edit (or add) "extra": "extra":{"patches":{"drupal/field_group":{"ApatchwithURL”:“https://www.drupal.org/files/issues/field_group-empty_group_nonnumeric_index-2761159-2-D8.patch",“Localpatch(pathrelativetocomposer.json)”:"patches/field_group-fix_it.patch"}}}
Apply the patches and update composer.lock -file$composerinstall#appliesthepatch$composerupdate--lock#writespatchinfoto.lockfile
Patching modules
There is a module for that… but it requires an external library!
As an example:
Chosen -module is a wrapper for chosen-library
Chosen library must be downloaded separately
Other libraries
Image: https://opensource.com/life/16/1/indiahacks-2016
projects[chosen]=“2.0-beta4"
libraries[chosen][directory_name]="chosen" libraries[chosen][type]="library"libraries[chosen][download][type]="get"libraries[chosen][download][url]="https://github.com/harvesthq/chosen/releases/download/1.4.2/chosen_v1.4.2.zip"
Apply the patch either by re-running drushmakemy_project.make
…or downloading the library manually
Other libraries
Image: https://opensource.com/life/16/1/indiahacks-2016
libraries:chosen:directory_name:chosentype:librarydownload:type:geturl:'https://github.com/harvesthq/chosen/releases/download/1.4.2/chosen_v1.4.2.zip'
Apply the patch the same way with old style .make file
Other libraries
Image: https://opensource.com/life/16/1/indiahacks-2016
Manually add new item to your repository -section in composer.json:"repositories":[{"type":“package","package":{"name":"customlibs/chosen","version":"master","dist":{"type":"zip","url":"https://github.com/harvesthq/chosen/releases/download/1.4.2/chosen_v1.4.2.zip","reference":“1.4.2"},"autoload":{"classmap":["."]}}],
Request the library $composerrequirecustomlibs/chosen:1.4.2
Then update your packages as per what you've just done: $composerupdate
NOTE: Chosen modules declares this dependency in Drupal 8 version via composer.json
Other libraries
Image: https://opensource.com/life/16/1/indiahacks-2016
Drupal Console
Briefly about Drupal Console
Composer manages (Drupal) codebase
Drupal Console does tricks with Drupal itself (Drupal 8)
Help your self by aliasing drupal if it is not in your $PATH
#localdev VM bash alias isaliasdrupal="/vagrant/drupal_root/vendor/drupal/console/bin/drupal"
Site installation
Install Drupal site (default -folder) $drupalsite:installminimal--langcode="en"--db-type="mysql"--db-host="127.0.0.01"--db-port="3306"--db-name="local_1"--db-user="root"--db-pass="root"--site-name="Drupal8"--site-mail="[email protected]"--account-mail="[email protected]"--account-name="admin"--account-pass="admin"--no-interaction--learning-vvv
Site installation
Install Drupal site (default -folder)$drupalsite:installminimal--no-interaction
Command aliases ❤ $drupalsi
Multisite installation
1. Create multisite folder and directory aliasing file sites/sites.php$drupalmultisite:newexample.com--site-uri=“local-2.example.com”> creates sites/example.com -folder> creates site-alias local-2.example.com => sites/example.com
2. Install the site$drupalsiminimal--uri="local-2.example.com"--no-interaction
Multisite tools
Check multisite structure$drupalmultisite:debug
Clone (!) existing default site to a multisite folder $drupalmultisite:new--copy-install--site-uri="local2.example.com"example.com
Module commands
Install a module$drupalmodule:install|mou
Uninstall a module$drupalmodule:uninstall|mou
Generate module$drupalgenerate:module|gm
Rebuild D8 cache$drupalcache:rebuild|cr
Some random commands
Go nuts!$drupal[-l=local-1.example.com]list$drupal[--uri=local-1.example.com]list
Get help!$drupalhelp[topic]
Documentation https://drupalconsole.com/docs , also in Vietnamese and Hindi among some other languages
NOTE: Drupal Console v1.0.0-rc12 (not yet released) is needed for properly working (automated) multisite installation process
Questions?
Questions?
Drush Recap
Composer
Workflow with the Composer
Recipes
Semantic versioning
More recipes
Drupal Console
Take also look at these
Composer template for Drupal projectshttps://github.com/drupal-composer/drupal-project
Improving your Drupal 8 development workflow by Jesus Manuel Olivas http://weknowinc.com/talks/2016/drupalgov-workflow
Drupal Console Docshttps://drupalconsole.com/docs