
DDEV Drupal Contrib
DDEV integration for developing Drupal contrib projects. As a general philosophy, your contributed module is the center of the universe. The codebase layout (see image below) and commands in this project match the Gitlab CI approach from the Drupal Association.
Install
- If you haven’t already, install Docker and DDEV
git clone
your contrib module
- cd [contrib module directory]
- Configure DDEV for Drupal using
ddev config --project-type=drupal --docroot=web --php-version=8.3 --corepack-enable --project-name=[module]
or select these options when prompted using ddev config
- Remove underscores in the project name, or replace with hyphens. (DDEV will do this for you.)
- See Misc for help on using alternate versions of Drupal core.
- Run
ddev add-on get ddev/ddev-drupal-contrib
- Run
ddev start
- Run
ddev poser
- Run
ddev symlink-project
ddev config --update
to detect expected Drupal and PHP versions.
ddev restart
After installation, make sure to commit the .ddev
directory to version control.
Update
ddev add-on get ddev/ddev-drupal-contrib
ddev restart
Commands
This project provides the following DDEV container commands.
- ddev poser.
- Creates a temporary composer.contrib.json so that
drupal/core-recommended
becomes a dev dependency. This way the composer.json from the module is untouched.
- Runs
composer install
AND yarn install
so that dependencies are available. Additional arguments to ddev poser
like –prefer-source are passed along to composer install
- Note: it is perfectly acceptable to skip this command and edit the require-dev of composer.json by hand.
- ddev symlink-project. Symlinks the top level files of your project into web/modules/custom so that Drupal finds your module. This command runs automatically on every
ddev start
as long as Composer has generated vendor/autoload.php
which occurs during composer install/update
. See codebase image below.
Run tests on the web/modules/custom
directory:
Codebase layout

Misc
Changing defaults
Override any environment variable value from .ddev/config.contrib.yaml by creating a .ddev/config.local.yaml
(or any filename lexicographically following config.contrib.yaml) file which has the same structure as .ddev/config.contrib.yaml. Add your overrides under web_environment
.
Changing the Drupal core version
In .ddev/config.local.yaml
set the Drupal core version:
web_environment:
- DRUPAL_CORE=^11
Then run ddev restart
and then ddev poser
to update the Drupal core version.
If Drupal core cannot be changed because the project is using an unsupported version of PHP, ddev poser
will show a composer
error. In that case, open .ddev/config.yaml
and change the PHP_VERSION
to a supported version; then run ddev restart
and ddev poser
again. Note that the project PHP version is set in .ddev/config.yaml
, while the core version to use is set in .ddev/config.local.yaml
.
Changing the symlink location
In .ddev/config.local.yaml
set the location relative to webroot (which usually is web/
). Defaults to modules/custom
web_environment:
- ...
- DRUPAL_PROJECTS_PATH=modules
Then restart DDEV by running ddev restart
.
Example of successful test
This is what a successful test looks like, based on Config Enforce Devel.
user:~/config_enforce_devel$ ddev phpunit
PHPUnit 9.6.15 by Sebastian Bergmann and contributors.
Default Target Module (Drupal\Tests\config_enforce_devel\Functional\DefaultTargetModule)
✔ Default target module created
Form Alter Implementation Order (Drupal\Tests\config_enforce_devel\Functional\FormAlterImplementationOrder)
✔ Form alter implementation order
Theme Settings Form (Drupal\Tests\config_enforce_devel\Functional\ThemeSettingsForm)
✔ Theme settings form submit
Time: 00:13.453, Memory: 4.00 MB
OK (3 tests, 20 assertions)
Automatically correct coding standard violations
You can set up a pre-commit hook that runs phpcbf:
- Create a new file
touch .git/hooks/pre-commit
in your repository if it doesn’t already exist.
- Add the following lines to the
pre-commit
file:
#!/usr/bin/env bash
ddev phpcbf -q
- Mark the file as executable:
chmod +x pre-commit
.
Add-on tests
Tests are done with Bats. It is a testing framework that uses Bash.
To run tests locally you need to first install bats’ git submodules with:
git submodule update --init
Then you can run within the root of this project:
./tests/bats/bin/bats ./tests
Tests will be run using the default drupal core of the contrib. To test against a different Drupal core version, update the TEST_DRUPAL_CORE
environment
variable.
i.e. TEST_DRUPAL_CORE=11 ./tests/bats/bin/bats ./tests
.
Tests are triggered automatically on every push to the
repository, and periodically each night. The automated tests are agains all of
the supported Drupal core versions.
Please make sure to attend to test failures when they happen. Others will be
depending on you.
Also, consider adding tests to test for bugs or new features on your PR.
To learn more about Bats see the documentation.
Troubleshooting
“Error: unknown command”:
The commands from this addon are available when the project type is drupal
. Make sure the type
configuration is correctly set in .ddev/config.yaml
:
Don’t forget to run ddev restart
if .ddev/config.yaml
has been updated.
Credits
Contributed and maintained by @weitzman