protonsystems / dev-tools
Reusable Drupal module providing a read-only developer inspection toolkit as Drush commands.
Package info
gitlab.com/Proton.Systems/drupal/dev-tools
Type:drupal-module
pkg:composer/protonsystems/dev-tools
Requires
- php: ^8.3
- drupal/core: ^10 || ^11
Requires (Dev)
- phpunit/phpunit: ^10.5
README
Reusable Drupal module providing a read-only developer inspection toolkit, plus a few targeted single-config export/import helpers, as Drush commands.
Purpose
The module is intended to be reused across Drupal 10 and Drupal 11 projects by installing it as a Composer package and enabling it in the target site. It stays deliberately narrow — fast, single-purpose "tell me about this one thing" commands for day-to-day development — rather than a full audit/report system.
Requirements
- PHP 8.3+
- Drupal 10 or 11
- Drush 12+
Architecture
Drush Command (thin presentation layer)
↓
Inspector / Doctor service (business logic)
↓
Drupal core APIs
src/Inspector/— read-only inspection services (ConfigDiffInspector,ConfigInspector,FieldInspector,EntityInspector,ProjectInspector), plusConfigSyncStorageResolver, a small shared helper that resolves the "effective" sync directory storage with Config Split's import transforms applied.src/Inspector/Model/— plain, immutable DTOs returned by the inspectors (ConfigDiffResult,ConfigDescription,FieldInfo,BundleDescription,ProjectSnapshot, etc.). Several of these (ConfigNamePattern,ConfigDiffResult) contain pure logic with no Drupal dependency, kept separate so they're straightforward to unit test.src/Doctor/—dev:doctor's health-check framework.ProjectDoctortakes its checks (seesrc/Doctor/Check/) as a variadic constructor argument, wired as a flat list of@servicereferences indrush.services.yml'sdev_tools.project_doctordefinition. That's deliberate: Drush's owndrush.services.ymlloader supports neither Symfony's!tagged_iteratorYAML tag nor@servicereferences nested inside an array argument, so checks can't be collected automatically — only flat, top-level@servicearguments work. Add a new check by implementingDoctorCheckInterface, registering it as a service, and adding it as one more argument there.src/Drush/Commands/— thin Drush 12+ attribute-based command classes. Each command builds its inspector's result and hands it to Drush's formatter system (RowsOfFieldsfor lists,PropertyListfor single records), rather than hand-rolling output.drush.services.yml— service registration for Drush command discovery.
Commands
Config inspection (read-only)
drush dev:config-diff <name> (aliases: cdo, cod, config:diff-one)
Compares one config object's active (database) copy against its sync
directory copy, including Config Split transformations. Default output is a
unified diff; --format=json returns structured status/diff data.
drush dev:config-diff core.extension
drush cod field.field.node.article.field_body
drush dev:config-find <pattern> (alias: dcf)
Finds config object names by substring or glob (*, ?) pattern, showing
whether each exists in active storage, sync, or both.
drush dev:config-find field.field.node
drush dev:config-find "views.view.*"
drush dev:config-show <name> (alias: dcs)
Shows developer-oriented metadata for a config object — entity type, label, provider, dependencies, sync status, and sync file — instead of raw YAML.
drush dev:config-show node.type.article
drush dev:config-uses <name> (alias: dcu)
Finds config objects that depend on or reference a given config object: declared dependents (via Drupal's own config dependency graph) and informal textual references.
drush dev:config-uses field.storage.node.field_tags
Field & entity inspection (read-only)
drush dev:fields <entity-type> <bundle> (alias: dfs)
Concise field list: name, label, type, cardinality, required, translatable.
drush dev:fields node article
drush dev:field-info <entity-type> <bundle> <field> (alias: dfi)
Detailed field/storage/reference information, including target entity type/bundles for entity reference fields and the config objects the field depends on.
drush dev:field-info node article field_tags
drush dev:describe <entity-type> <bundle> (alias: dde)
A concise developer overview of a bundle: field count, bundle config entity, config dependencies, configured view/form modes, and content count.
drush dev:describe node article
Project inspection (read-only)
drush dev:info (alias: di)
A concise project/environment snapshot: Drupal/PHP/Drush versions, database driver, install profile, themes, module count, config sync directory, multisite status.
drush dev:info
drush dev:doctor (alias: ddr)
Runs a set of safe, non-destructive health checks (config drift, module
dependency integrity, trusted_host_patterns, filesystem writability,
hash_salt, cron staleness) and reports pass/warning/fail per check.
drush dev:doctor
Single-config export/import (write)
These pre-date the read-only dev:* commands and remain for fast, targeted
iteration on one config object without a full drush cex/drush cim.
drush config:export-one <name> (alias: ceo)
drush config:export-one field.field.node.article.field_body
drush config:import-one <name> (alias: cio)
drush config:import-one field.field.node.article.field_body
Output formats
List commands (dev:config-find, dev:config-uses, dev:fields,
dev:doctor) return tables by default and support --format=json,
--format=yaml, --format=csv, etc. Single-record commands (dev:config-diff,
dev:config-show, dev:field-info, dev:describe, dev:info) return a
key/value table by default and the same --format options.
drush dev:fields node article --format=json
drush dev:doctor --format=json
Installation
composer require protonsystems/dev-tools
drush en dev_tools
Testing
composer install
vendor/bin/phpunit
tests/src/Unit/ contains Drupal-independent unit tests (pure logic: config
name pattern matching, diff status determination, doctor result
aggregation) and runs via the phpunit.xml.dist in this repo with no Drupal
bootstrap required.
tests/src/Kernel/ contains Drupal kernel tests covering the
entity/field/config-aware inspectors. These require a full Drupal test
environment and are meant to be run via a site's own
core/phpunit.xml.dist with this module installed, e.g.:
cd /path/to/drupal/root
vendor/bin/phpunit -c core --group dev_tools modules/contrib/dev-tools/tests/src/Kernel
Notes
- All
dev:*commands are read-only and safe to run against production. - Config diff/comparison respects Drupal's event dispatcher, so Config Split
transformations are applied the same way
drush config:importwould see them. dev:config-usesreuses Drupal core's own config dependency graph (ConfigManagerInterface::findConfigEntityDependencies()— despite the name, it returns entities that depend on the given config, not its own dependencies) rather than re-deriving it.