Reorganize plugin/extension discovery; add plugin enable/disable (PWT-113, PWT-114)#76
Conversation
…ble commands findExtensions() previously only located plugins installed as symlinks (path repositories); real directories were silently missed. A naive recursive marker search instead surfaced vendored copies of other plugins (e.g. polymer_drupal inside polymer_pantheon_drupal/vendor). Replace it with a fixed-depth glob for the .poly_info.yml marker so symlinked and real-directory plugins are both discovered without descending into a plugin's own vendor/ tree. Also: - Harden enabled-extension resolution: drop entries enabled in config but not installed on disk, and guard against a missing .polymer/plugins directory. - Add plugin:list / plugin:enable / plugin:disable commands to toggle enabled_extensions, building the AC-1 toggle on top of existing gating. - Fix a stale PolymerConfig namespace import that left the unit suite red after the package reorganization. Refs PWT-114. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request restructures the Polymer framework by moving core classes into the DigitalPolygon\Polymer\Core namespace, introducing a new bootstrapping script (polymer-robo-run.php), and implementing a robust plugin/extension management system with associated CLI commands and unit tests. Feedback on these changes highlights several reliability improvements, including handling potential failures of getcwd() and file_put_contents(), removing the arbitrary 10-iteration limit on directory traversal, removing an unused import, ensuring classes exist before reflection to prevent crashes, safely stripping the .php extension during class discovery, and using array_merge instead of the + operator to combine hooks and commands safely.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
- ExtensionDiscovery: throw if writing enabled_extensions to config.yml fails (file_put_contents was unchecked, so a failed write still reported success). - ExtensionDiscovery: skip enabled extensions whose ExtensionInfo class is missing via class_exists() instead of crashing with a ReflectionException. - ExtensionDiscovery: drop an unused Drupal test-fixture import (stray IDE auto-import). - ClassDiscoveryTrait: strip only a trailing ".php" extension instead of str_replace, which corrupted any path containing ".php" mid-string. - Polymer: combine core + extension hooks/commands with array_merge() rather than the "+" union operator, which silently drops colliding numeric keys. - bin/polymer-robo-run.php: guard against getcwd() returning false, and remove the arbitrary 10-level cap on the upward .polymer search (filesystem-root termination already bounds the loop). Refs PWT-114. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fresh builds of the web image failed at the `pip install ... git+https://gitlab.com/blacs30/mkdocs-edit-url.git` step with "module 'setuptools' has no attribute 'setup'". The DDEV Python 3.13 base image ships an empty `setuptools` namespace package with no RECORD file, so `pip install -U setuptools` fails with uninstall-no-record-file and legacy setup.py builds cannot import a usable setuptools. Install a real setuptools + wheel into /usr/local (earlier on sys.path) with --ignore-installed before the mkdocs install so it shadows the stub. Verified with a full clean build. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Document the package for Claude Code / agents (architecture, commands, conventions) and add an Issue tracking section pointing at the PWT Jira board. CLAUDE.md is a one-line pointer to AGENTS.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Summary
Reorganization of Polymer's plugin/extension discovery, plus the PWT-114 plugin enable/disable work built on top of it. Part of the PWT-113 epic.
Refs PWT-113, PWT-114. De-risks PWT-115 (see discovery fix below).
What's in here
Discovery / plugin-system reorganization (
d34e271,dfb0491)ClassDiscoveryTrait, consumed byCoreClassDiscovery,ExtensionClassDiscovery, and the newPluginClassDiscovery.PluginManagerBase) and template plugin manager wiring.src/,bin/, andcomposer.json.Plugin enable/disable — PWT-114 (
fb46a09)plugin:list/plugin:enable/plugin:disablecommands that toggleenabled_extensionsin.polymer/config.yml. The runtime gating already existed (namespaces, commands, hooks, and service providers all derive fromenabled_extensions), so disabled plugins are excluded from the autoloader — this adds the missing toggle surface.array_flipinteger used as a path); guarded a missing.polymer/pluginsdirectory.findExtensions()discovery fix: it previously only found plugins installed as symlinks (path repositories) — real (dist/committed) directories were silently missed. Replaced the leaf-based recursive scan with a fixed-depth glob for the.poly_info.ymlmarker, so symlinked and real-directory plugins are both discovered, without descending into a plugin's ownvendor/tree (which otherwise surfaced vendored copies of other plugins, e.g.polymer_drupalinsidepolymer_pantheon_drupal/vendor). This is what de-risks PWT-115.PolymerConfignamespace import that left the unit suite fully red after the reorganization.Testing
ExtensionDiscoveryTestcovers symlink + real-directory discovery and enable/disable gating; previously the suite was 0/7 due to the stale import).polymer list; re-enabling restores them; discovery paths are correct for the symlinked production layout.Notes
--no-verify; the equivalent checks were run manually and pass.🤖 Generated with Claude Code