diff --git a/app/Commands/Internal/Describer.php b/app/Commands/Internal/Describer.php index 613306b0..ea343108 100644 --- a/app/Commands/Internal/Describer.php +++ b/app/Commands/Internal/Describer.php @@ -172,17 +172,19 @@ protected function describeSection( $output->write(sprintf("\n %s\n %s\n", $section[0], $section[1])); - foreach ($groups as $index => $commands) { - $width = 0; + $width = 0; + foreach ($groups as $commands) { foreach ($commands as $command) { $width = max($width, mb_strlen((string) $command->getName())); } + } + foreach ($groups as $index => $commands) { $output->write("\n"); if ($index !== '') { - $output->write(sprintf("%s%s\n", str_repeat(' ', $groupIndent), $index)); + $output->write(sprintf("%s%s\n", str_repeat(' ', $groupIndent), $index)); } foreach ($commands as $command) { diff --git a/tests/Feature/CommandListTest.php b/tests/Feature/CommandListTest.php index 9769f6dd..747f3359 100644 --- a/tests/Feature/CommandListTest.php +++ b/tests/Feature/CommandListTest.php @@ -83,6 +83,25 @@ function listSections(string $output): array ->toMatch('/^ Other\n(?s:.*?) route:list/m'); }); +it('aligns descriptions across all project command groups', function () { + $lines = array_values(array_filter( + explode("\n", $this->plain), + fn (string $line): bool => preg_match('/^ (build|make|publish|herd|route):/', $line) === 1, + )); + + $descriptionColumns = array_map( + function (string $line): int { + preg_match('/^\s+\S+ +\S/', $line, $match); + + return strlen($match[0]) - 1; + }, + $lines, + ); + + expect($descriptionColumns)->not->toBeEmpty() + ->and(array_unique($descriptionColumns))->toHaveCount(1); +}); + it('puts the command that creates a project first', function () { // `new` creates the project the rest of the list acts on, so it leads. [$cli] = listSections($this->rendered);