Created
April 5, 2026 12:54
-
-
Save paranoiq/af056f25d39981d30ef308d5842627db to your computer and use it in GitHub Desktop.
Simple Composer plugin to lists only user-defined scripts and their shortcuts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Composer plugin to lists user-defined scripts from composer.json in the same format as `composer list`. | |
| */ | |
| $composerJson = dirname(__DIR__) . '/composer.json'; | |
| $data = json_decode(file_get_contents($composerJson), true, 100, JSON_THROW_ON_ERROR); | |
| $scripts = array_keys($data['scripts'] ?? []); | |
| $descriptions = $data['scripts-descriptions'] ?? []; | |
| // split into flat (no colon) and namespaced (with colon) | |
| $flat = []; | |
| $namespaced = []; // namespace => [name => description] | |
| foreach ($scripts as $name) { | |
| $desc = $descriptions[$name] ?? ''; | |
| if (str_contains($name, ':')) { | |
| [$ns] = explode(':', $name, 2); | |
| $namespaced[$ns][$name] = $desc; | |
| } else { | |
| $flat[$name] = $desc; | |
| } | |
| } | |
| // identify shortcuts: flat names ? 3 chars that alias exactly one other script via "@target" | |
| $shortcuts = []; // target => shortcut | |
| foreach ($flat as $name => $desc) { | |
| if (strlen($name) <= 3) { | |
| $value = $data['scripts'][$name]; | |
| if (is_string($value) && str_starts_with($value, '@')) { | |
| $shortcuts[ltrim($value, '@')] = $name; | |
| unset($flat[$name]); | |
| } | |
| } | |
| } | |
| ksort($flat); | |
| ksort($namespaced); | |
| foreach ($namespaced as &$group) { | |
| ksort($group); | |
| } | |
| unset($group); | |
| // display name appends shortcut alias in parentheses if one exists | |
| $displayName = static function (string $name) use ($shortcuts): string { | |
| return isset($shortcuts[$name]) ? "$name \e[0;34m({$shortcuts[$name]})" : $name; | |
| }; | |
| $visibleLen = static function (string $s): int { | |
| return strlen(preg_replace('/\e\[[0-9;]*m/', '', $s)); | |
| }; | |
| // determine column width from visible display name lengths (max + 2 gap, minimum 21) | |
| $allNames = array_merge(array_keys($flat), ...array_map('array_keys', array_values($namespaced))); | |
| $nameWidth = max(21, max(array_map(static fn($n) => $visibleLen($displayName($n)), $allNames)) + 2); | |
| $pad = static function (string $name) use ($nameWidth, $displayName, $visibleLen): string { | |
| $display = $displayName($name); | |
| return ' ' . $display . str_repeat(' ', $nameWidth - $visibleLen($display)); | |
| }; | |
| echo "Available commands:\n"; | |
| foreach ($flat as $name => $desc) { | |
| echo "\e[0;32m" . $pad($name) . $desc . "\e[0m\n"; | |
| } | |
| foreach ($namespaced as $ns => $group) { | |
| echo " \e[0;33m$ns\e[0m\n"; | |
| foreach ($group as $name => $desc) { | |
| echo "\e[0;32m" . $pad($name) . $desc . "\e[0m\n"; | |
| } | |
| } |
paranoiq
commented
Apr 5, 2026
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment