Module Dependencies
WissKI is a set of Drupal modules with a directed dependency graph.
Drupal enables declared dependencies before the dependent module.
A PHP use of another WissKI module without a matching .info.yml dependency can therefore fatal at enable time (especially on Drupal 10).
Cycles in the declared graph are also forbidden.
Core layering¶
wisski_core sits at the bottom of the WissKI stack: it declares no WissKI module dependencies.
Higher layers depend on it (and often on each other) in one direction only.
To inspect the full declared graph, run drush wisski-devel:dump-dot.
That prints a DOT description of the module dependency digraph.
Render it with Graphviz (for example dot to SVG or PNG):
drush wisski-devel:dump-dot | dot -Tsvg -o wisski-deps.svg
Typical edges (always check the module's own .info.yml for the authoritative list):
| Module | Depends on (WissKI) |
|---|---|
wisski_pathbuilder |
wisski_core |
wisski_salz |
wisski_pathbuilder |
wisski_core |
none |
| Adapter / feature modules | Usually wisski_pathbuilder, wisski_salz and wisski_core or a concrete adapter such as wisski_adapter_sparql11_pb |
legacy/ modules are excluded from the automated check and from normal maintenance.
Avoiding cycles with pathbuilder interfaces¶
Concrete engine and adapter implementations live in wisski_salz and the adapter modules.
If wisski_core imported those concrete classes, it would need to depend on them — and they already depend on wisski_core, which would create a cycle.
To keep the graph acyclic, capability contracts live in wisski_core:
- Base types under
wisski_pathbuilder/src/Entities/(notablyEngineInterfaceandAdapterInterface) - Capability interfaces under
wisski_core/src/Engines/(for exampleSparql11EngineInterface,Sparql11EngineWithPbInterface,PathbuilderEngineInterface,ImageEngineInterface, …)
Implementations in lower-to-higher modules implement those interfaces.
Call sites in pathbuilder (and other modules that must not hard-depend on a concrete adapter) type-hint the interfaces only, then use instanceof when a specific capability is required.
When you need a new cross-module engine API, add or extend an interface in wisski_core rather than importing a concrete class from wisski_salz or an adapter into a module that those packages already depend on.
Checking dependencies¶
The unit test ModuleDependencyTest in wisski_core/tests/src/Unit/ drives ModuleDependencyChecker in the same directory.
Together they:
- Build the declared WissKI-to-WissKI graph from every non-legacy
.info.yml - Fail on dependency cycles
- Scan production PHP for
Drupal\wisski_*classuseimports and require a matching declared dependency (direct; not transitive)
Outgoing import edges from modules listed in ModuleDependencyTest::SKIP_MODULES (currently wisski_test) are ignored.
Run:
phpunit wisski_core/tests/src/Unit/ModuleDependencyTest.php
If the test reports a missing edge, either add - wisski:… to the importing module's .info.yml, or redesign the import to go through a pathbuilder interface so the hard dependency is unnecessary.
Deptrac¶
Deptrac can additionally analyse PHP layer rules derived from the same module graph.
Generate a config with Drush, write it to deptrac.yaml at the project root, then run Deptrac:
drush wisski-devel:dump-deptrac-config > deptrac.yaml
deptrac analyse
Do not commit a generated deptrac.yaml unless the project deliberately tracks one; Deptrac's cache (.deptrac.cache) is gitignored.