Scaffolding with drush generate
When to Use
Use this to start a new Tool API plugin. The generator writes the plugin and two tests, and its access check fails closed until you define one.
Version: applies to
drupal/tool1.0.0-beta11 (beta; no security advisory coverage). Paths are undermodules/contrib/tool/.
Steps
- Run the generator. Name
plugin:tool, aliastool(tool 1.0.0-beta11src/Drush/Generators/ToolGenerator.php).
drush generate plugin:tool
-
Answer the prompts. Module machine name, tool label, plugin ID, class (suffix
Tool), description (required, no default), operation (defaultRead), and "Is the tool destructive (irreversible write/trigger)?" (default no). -
Review the three files it writes.
| File | Content |
|---|---|
src/Plugin/tool/Tool/{class}.php |
#[Tool] with one example string input and one result MapOutputDefinition |
tests/src/Unit/Tool/{class}AccessTest.php |
Unit access test |
tests/src/Kernel/Tool/{class}Test.php |
Kernel test |
-
Define access. The generated
checkAccess()throws\LogicException("Access control for %s has not been defined.") until you declare apermissionand delete the override, or implement it. See Access Control for what that exception does to callers. -
Replace the example input and output. The template comment says keys not in
output_definitions"are dropped"; they are not typed outputs, but they still reach callers raw. See Output Definitions. -
Fix the generated
catch (\Exception $e), which returns$e->getMessage()to callers. See doExecute and ExecutableResult. -
Rebuild and inspect.
drush cr
drush tool:info my_module_my_tool --format=json
Decision Points
| At this step... | If... | Then... |
|---|---|---|
| Access | The rule depends only on the account | Add permission: and delete the checkAccess() override |
| Access | The rule depends on input values | Implement checkAccess() |
| Operation | The tool stores data | Pick Write, not the default Read |
Common Mistakes
- Keeping the generic description → it is what agents read; the generator refuses a default for that reason
- Deleting the generated tests → they are the cheapest place to pin the access rule
- Leaving the default
Readoperation on a tool that writes → see Operation and Destructive
See Also
- Defining a Tool → the attribute in full
- Access Control → choosing
permissionvscheckAccess() - Reference:
modules/contrib/tool/src/Drush/Generators/