Skip to content

Instantly share code, notes, and snippets.

@paranoiq
Created April 5, 2026 12:54
Show Gist options
  • Select an option

  • Save paranoiq/af056f25d39981d30ef308d5842627db to your computer and use it in GitHub Desktop.

Select an option

Save paranoiq/af056f25d39981d30ef308d5842627db to your computer and use it in GitHub Desktop.
Simple Composer plugin to lists only user-defined scripts and their shortcuts
<?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

paranoiq commented Apr 5, 2026

Copy link
Copy Markdown
Author
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment