Note
Acquia will end support for BLT on December 31, 2024. For more information on how to replace your BLT implementation with updated functionality, see You don’t need BLT on Acquia Cloud.
BLT provides an extensive plugin and configuration system to support customization.
Adding a custom Robo hook or command
BLT uses Robo and the Annotated Command library to define commands. You can use annotated commands to define new custom commands or hook into existing commands, such as executing custom code before or after an existing BLT command.
You can generate a file containing an example custom command and hook by running the following command:
blt recipes:blt:command:init
You can place custom commands in a different directory in your project or even a separate Composer package, as long as you expose the command file using PSR4.
To create your own Robo PHP command or hook, complete the following steps:
- Create a new file named using the required pattern
*Commands.php
. For instance, the generated example uses the file nameExampleCommands.php
. - Use a namespace ending in
*\Blt\Plugin\Commands
exposed using PSR4 in yourcomposer.json
file. For instance, the generated example uses the namespaceExample\Blt\Plugin\Commands
. - Follow the Robo PHP Getting started guide to write a custom command. For a list of all available hook types, see Annotated Command’s hook types.
Replacing or overriding a Robo command
To replace a BLT command with your own custom version, use the replace command annotation for your custom command.
Note
If you replace a BLT command, you take responsibility for maintaining your custom command. Your command may break when changes are made to the upstream version of the command in BLT itself.
Disabling a command
You can disable any BLT command. This will cause the target to be skipped during the normal build process. To disable a target, add a disable-targets
key to your blt.yml
file, as follows:
disable-targets:
tests:
phpcs:
sniff:
all: true
files: true
This snippet causes BLT builds to skip the tests:phpcs:sniff:all
and tests:phpcs:sniff:files
targets.
Adding or overriding filesets
You can also define your own custom filesets or override existing filesets.
Note
To change the behavior of PHPCodeSniffer, see the documentation on the tests:phpcs:sniff:all
command in the following section.
You can generate a file with an example custom fileset by running the following command:
blt recipes:blt:filesystem:init
You can place custom commands in a different directory in your project or even a separate Composer package, as long as you expose the command file using PSR4.
To create your own fileset definition, complete the following steps:
- Create a new file named using the required pattern
*Filesets.php
. For instance, the generated example uses the file nameExampleFilesets.php
. - Use a namespace ending in
*\Blt\Plugin\Filesets
exposed using PSR4 in yourcomposer.json
file. For instance, the generated example uses the namespaceExample\Blt\Plugin\Filesets
. - Create a public method in the
Filesets
class in the generated file. Add a Fileset annotation to your public method, specifying its id:
@fileset(id="files.yaml.custom")
- Instantiate and return a
Symfony\Component\Finder\Finder
object. The files found by the finder form the fileset.
To change the filesets used in commands such as tests:twig:lint:all
, tests:yaml:lint:all
, and tests:php:lint
, add the following configuration key to blt/blt.yml
:
validate:
yaml:
filesets:
- files.yaml.custom
Overriding the environment detector
BLT includes a unified environment detector class providing information about the current hosting environment such as the stage (dev
, stage
, or prod
), provider (Acquia or Pantheon), and type (local or CI). The environment detector primarily examines environment variables and system configuration files to give details about the current environment.
You can extend the environment detector to support custom environments or override the detection behavior of built-in environments.
Note
Page requests (due to settings.php
includes) and BLT commands, can both invoke the environment detector, so performance is critical. The detector can’t depend on a UI, the Drupal container, or Robo configuration.
To override environment detector methods, create a new BLT plugin as follows:
- Create a new custom environment detector class implementing BLT’s environment detector.
- Override any supported method in your custom class.
- Expose your custom class using PSR4 and add your class to Composer’s
classmap
in your plugin’scomposer.json
file.
BLT’s Environment Detector will discover your overrides using PSR4 and re-dispatch any method calls to your custom implementation.
As a reference implementation, the BLT Tugboat plugin illustrates how to override the Environment Detector in practice.
For more discussion on the Environment Detector architecture, design choices, and performance considerations, see this issue.
Modifying your BLT configuration
You can customize your BLT configuration by overriding the value of default variable values. The build.yml file contains the default values of all BLT variables.
Overriding a variable value
BLT loads configuration values from the following list of YAML files, in the listed order:
vendor/acquia/blt/config/build.yml
blt/blt.yml
blt/[environment].blt.yml
docroot/sites/[site]/blt.yml
docroot/sites/[site]/[environment].blt.yml
Values loaded from the later files will overwrite values in earlier files.
Note
If you want to override a non-empty value with an empty value, the override value must be set to null
, and not ''
or []
.
Overriding variables project-wide
You can override any variable value by adding an entry for that variable to your blt/blt.yml
file. This change will be committed to your repository and shared by all developers for the project. For example:
behat.tags: @mytags
Overriding variables locally
You can override a variable value for your local computer in the same way that you can for specific environments.
For instructions about how to do this, see the following section, and use local
for the environment value.
Overriding variables in specific environments
You can override a variable value for specific environments (such as the local
or ci
environments) by adding an entry for the variable to a file named in the pattern of [environment].blt.yml
(for example, ci.blt.yml
).
BLT detects only the local
and ci
environments. You can pass --environment
as an argument to BLT to specify the correct environmental configuration to load.
Overriding variables at runtime
You may overwrite a variable value at runtime by specifying the variable value in your blt
command using the argument syntax -D [key]=[value]
. For example:
blt tests:behat:run -D behat.tags='@mytags'
For configuration values that are indexed arrays, you can override individual values using the numeric index, such as git.remotes.0
.
Modifying the build artifact
To modify the behavior of the artifact:build
target, you may override BLT’s deploy
configuration. For example, review the deploy
key in the build.yml file.
You can customize which files are committed to the build artifact using two general methods:
- An exclude file that prevents certain files from being copied into the build artifact
- A gitignore file that prevents files in the build directory from being committed to Git
Excluding files from the build artifact
This is the preferred method of modifying which files are included in the build artifact. It prevents files from being copied from the source directory to the build artifact.
To change which files are rsynced to the artifact, provide your own deploy.exclude_file
value in the blt.yml
file. For example, review the upstream deploy-exclude.txt file:
deploy:
exclude_file: ${repo.root}/blt/deploy/rsync-exclude.txt
If you want to add to the upstream deploy-exclude.txt file instead of overriding it, you don’t need to define your own deploy.exclude_file
. Instead, leverage the deploy-exclude-additions.txt
file found under the top-level BLT directory by adding each file or directory you want to exclude on its own line. For example:
/directorytoexclude
excludeme.txt
Ignoring build artifact files using gitignore
Files that are generated by Composer (such as contributed Drupal modules) should be excluded from the build artifact by using a custom gitignore file.
To change which files Git must ignore in the artifact, provide your own deploy.gitignore_file
value in the blt.yml
file. For example, review the upstream .gitignore file.
deploy:
gitignore_file: ${repo.root}/blt/deploy/.gitignore
Additional build artifact customization
If neither of the above methods work, you can modify any aspect of the artifact after it is built by using the post-deploy-build hook or postArtifactBuild command, as described below.
Pre and post command hooks
BLT provides two types of hooks for running custom tasks before, during, or after a built-in command.
BLT native command hooks
Some built-in commands that expect user modification explicitly call command hooks. Such values can be overridden using the command-hooks
key in the blt.yml
file.
The currently-available hooks are:
- post-setup-build
- post-deploy-build
- pre-config-import
- post-config-import
- frontend-assets
- frontend-reqs
- frontend-test
For example, once the artifact is built, you can execute a custom command by providing your own command-hooks.post-deploy-build.dir
and command-hooks.post-deploy-build.command
values in the blt.yml
file.
# Executed after deployment artifact is created.
post-deploy-build:
dir: ${deploy.dir}/docroot/profiles/contrib/acquia_cms
command: npm install
Robo annotated command hooks
BLT is built using Robo, which provides the Annotated Command system. Annotated commands allow you to hook into _any_ BLT command, but require the called code to be provided via a custom command rather than the blt.yml
file.
For example, you can accomplish the same task of modifying the build artifact as in the previous section using an annotated command hook.
/**
* This will be called after the artifact:build command.
*
* @hook post-command artifact:build
*/
public function postArtifactBuild() {
$this->doSomething();
}
For more information, see the main section on Robo annotated commands.
Modifying Git hooks
You may disable a Git hook by setting its value under git.hooks
to false:
git:
hooks:
pre-commit: false
You can use a custom Git hook in place of BLT’s default Git hooks by setting its value under git.hooks
to the directory path containing the hook. The directory must contain an executable file named after the Git hook:
git:
hooks:
pre-commit: ${repo.root}/my-custom-git-hooks
In the preceding example, an executable file named pre-commit
should exist in ${repo.root}/my-custom-git-hooks
.
Execute blt blt:init:git-hooks
after modifying these values for changes to take effect. As most projects will already have a git
key in their blt.yml
file, ensure that you append hooks to the existing key.
By default, BLT will execute the internal:git-hook:execute:commit-msg
command when new Git commits are made. This command validates that the commit message matches the regular expression defined in git.commit-msg.pattern
. You can override the default configuration.
Modifying tests
You can modify the following test targets:
- tests:behat:run: To modify the behavior of the
tests:behat:run
target, you may override BLT’s Behat configuration. For examples, review the build.yml file. - tests:phpcs:sniff:all: To change the behavior of the
tests:phpcs:sniff:all
target, you may copyphpcs.xml.dist
tophpcs.xml
in your repository’s root directory and modify the XML. For more information, see the official PHPCS documentation. tests:twig:lint:all: To prevent validation failures on any Twig filters or functions created in custom or contrib module
twig.extension
services, add filters and functions as follows:validate: twig: filters: - my_filter_1 - my_filter_2 functions: - my_function_1 - my_function_2