Fix trailing whitespace in 'composer show -N' (#11536)
The name column was always padded to maximum width, even if no other columns were printed. This makes it difficult to use the output e.g. in pipelines. Fixed for all possible columns, and with tests for two cases (regular show and show outdated).pull/11517/head^2
parent
07f706e57d
commit
3e9c148b63
|
@ -442,6 +442,10 @@ EOT
|
||||||
$exitCode = 0;
|
$exitCode = 0;
|
||||||
$viewData = [];
|
$viewData = [];
|
||||||
$viewMetaData = [];
|
$viewMetaData = [];
|
||||||
|
|
||||||
|
$writeVersion = false;
|
||||||
|
$writeDescription = false;
|
||||||
|
|
||||||
foreach (['platform' => true, 'locked' => true, 'available' => false, 'installed' => true] as $type => $showVersion) {
|
foreach (['platform' => true, 'locked' => true, 'available' => false, 'installed' => true] as $type => $showVersion) {
|
||||||
if (isset($packages[$type])) {
|
if (isset($packages[$type])) {
|
||||||
ksort($packages[$type]);
|
ksort($packages[$type]);
|
||||||
|
@ -616,14 +620,14 @@ EOT
|
||||||
$io->writeError('');
|
$io->writeError('');
|
||||||
$io->writeError('<info>Direct dependencies required in composer.json:</>');
|
$io->writeError('<info>Direct dependencies required in composer.json:</>');
|
||||||
if (\count($directDeps) > 0) {
|
if (\count($directDeps) > 0) {
|
||||||
$this->printPackages($io, $directDeps, $indent, $versionFits, $latestFits, $descriptionFits, $width, $versionLength, $nameLength, $latestLength);
|
$this->printPackages($io, $directDeps, $indent, $writeVersion && $versionFits, $latestFits, $writeDescription && $descriptionFits, $width, $versionLength, $nameLength, $latestLength);
|
||||||
} else {
|
} else {
|
||||||
$io->writeError('Everything up to date');
|
$io->writeError('Everything up to date');
|
||||||
}
|
}
|
||||||
$io->writeError('');
|
$io->writeError('');
|
||||||
$io->writeError('<info>Transitive dependencies not required in composer.json:</>');
|
$io->writeError('<info>Transitive dependencies not required in composer.json:</>');
|
||||||
if (\count($transitiveDeps) > 0) {
|
if (\count($transitiveDeps) > 0) {
|
||||||
$this->printPackages($io, $transitiveDeps, $indent, $versionFits, $latestFits, $descriptionFits, $width, $versionLength, $nameLength, $latestLength);
|
$this->printPackages($io, $transitiveDeps, $indent, $writeVersion && $versionFits, $latestFits, $writeDescription && $descriptionFits, $width, $versionLength, $nameLength, $latestLength);
|
||||||
} else {
|
} else {
|
||||||
$io->writeError('Everything up to date');
|
$io->writeError('Everything up to date');
|
||||||
}
|
}
|
||||||
|
@ -631,7 +635,7 @@ EOT
|
||||||
if ($writeLatest && \count($packages) === 0) {
|
if ($writeLatest && \count($packages) === 0) {
|
||||||
$io->writeError('All your direct dependencies are up to date');
|
$io->writeError('All your direct dependencies are up to date');
|
||||||
} else {
|
} else {
|
||||||
$this->printPackages($io, $packages, $indent, $versionFits, $latestFits, $descriptionFits, $width, $versionLength, $nameLength, $latestLength);
|
$this->printPackages($io, $packages, $indent, $writeVersion && $versionFits, $writeLatest && $latestFits, $writeDescription && $descriptionFits, $width, $versionLength, $nameLength, $latestLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -649,15 +653,18 @@ EOT
|
||||||
*/
|
*/
|
||||||
private function printPackages(IOInterface $io, array $packages, string $indent, bool $writeVersion, bool $writeLatest, bool $writeDescription, int $width, int $versionLength, int $nameLength, int $latestLength): void
|
private function printPackages(IOInterface $io, array $packages, string $indent, bool $writeVersion, bool $writeLatest, bool $writeDescription, int $width, int $versionLength, int $nameLength, int $latestLength): void
|
||||||
{
|
{
|
||||||
|
$padName = $writeVersion || $writeLatest || $writeDescription;
|
||||||
|
$padVersion = $writeLatest || $writeDescription;
|
||||||
|
$padLatest = $writeDescription;
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
$link = $package['source'] ?? $package['homepage'] ?? '';
|
$link = $package['source'] ?? $package['homepage'] ?? '';
|
||||||
if ($link !== '') {
|
if ($link !== '') {
|
||||||
$io->write($indent . '<href='.OutputFormatter::escape($link).'>'.$package['name'].'</>'. str_repeat(' ', $nameLength - strlen($package['name'])), false);
|
$io->write($indent . '<href='.OutputFormatter::escape($link).'>'.$package['name'].'</>'. str_repeat(' ', ($padName ? $nameLength - strlen($package['name']) : 0)), false);
|
||||||
} else {
|
} else {
|
||||||
$io->write($indent . str_pad($package['name'], $nameLength, ' '), false);
|
$io->write($indent . str_pad($package['name'], ($padName ? $nameLength : 0), ' '), false);
|
||||||
}
|
}
|
||||||
if (isset($package['version']) && $writeVersion) {
|
if (isset($package['version']) && $writeVersion) {
|
||||||
$io->write(' ' . str_pad($package['version'], $versionLength, ' '), false);
|
$io->write(' ' . str_pad($package['version'], ($padVersion ? $versionLength : 0), ' '), false);
|
||||||
}
|
}
|
||||||
if (isset($package['latest']) && isset($package['latest-status']) && $writeLatest) {
|
if (isset($package['latest']) && isset($package['latest-status']) && $writeLatest) {
|
||||||
$latestVersion = $package['latest'];
|
$latestVersion = $package['latest'];
|
||||||
|
@ -666,7 +673,7 @@ EOT
|
||||||
if (!$io->isDecorated()) {
|
if (!$io->isDecorated()) {
|
||||||
$latestVersion = str_replace(['up-to-date', 'semver-safe-update', 'update-possible'], ['=', '!', '~'], $updateStatus) . ' ' . $latestVersion;
|
$latestVersion = str_replace(['up-to-date', 'semver-safe-update', 'update-possible'], ['=', '!', '~'], $updateStatus) . ' ' . $latestVersion;
|
||||||
}
|
}
|
||||||
$io->write(' <' . $style . '>' . str_pad($latestVersion, $latestLength, ' ') . '</' . $style . '>', false);
|
$io->write(' <' . $style . '>' . str_pad($latestVersion, ($padLatest ? $latestLength : 0), ' ') . '</' . $style . '>', false);
|
||||||
}
|
}
|
||||||
if (isset($package['description']) && $writeDescription) {
|
if (isset($package['description']) && $writeDescription) {
|
||||||
$description = strtok($package['description'], "\r\n");
|
$description = strtok($package['description'], "\r\n");
|
||||||
|
|
|
@ -404,4 +404,45 @@ available:
|
||||||
installed:
|
installed:
|
||||||
vendor/installed 2.0.0 description of installed package', $output);
|
vendor/installed 2.0.0 description of installed package', $output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testNameOnlyPrintsNoTrailingWhitespace(): void
|
||||||
|
{
|
||||||
|
$this->initTempComposer([
|
||||||
|
'repositories' => [
|
||||||
|
'packages' => [
|
||||||
|
'type' => 'package',
|
||||||
|
'package' => [
|
||||||
|
// CAUTION: package names matter - output is sorted, and we want shorter before longer ones
|
||||||
|
['name' => 'vendor/apackage', 'description' => 'generic description', 'version' => '1.0.0'],
|
||||||
|
['name' => 'vendor/apackage', 'description' => 'generic description', 'version' => '1.1.0'],
|
||||||
|
['name' => 'vendor/longpackagename', 'description' => 'generic description', 'version' => '1.0.0'],
|
||||||
|
['name' => 'vendor/longpackagename', 'description' => 'generic description', 'version' => '1.1.0'],
|
||||||
|
['name' => 'vendor/somepackage', 'description' => 'generic description', 'version' => '1.0.0'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->createInstalledJson([
|
||||||
|
self::getPackage('vendor/apackage', '1.0.0'),
|
||||||
|
self::getPackage('vendor/longpackagename', '1.0.0'),
|
||||||
|
self::getPackage('vendor/somepackage', '1.0.0'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$appTester = $this->getApplicationTester();
|
||||||
|
$appTester->run(['command' => 'show', '-N' => true]);
|
||||||
|
self::assertSame(
|
||||||
|
'vendor/apackage
|
||||||
|
vendor/longpackagename
|
||||||
|
vendor/somepackage', trim($appTester->getDisplay(true))); // trim() is fine here, but see CAUTION above
|
||||||
|
|
||||||
|
$appTester = $this->getApplicationTester();
|
||||||
|
$appTester->run(['command' => 'show', '--outdated' => true, '-N' => true]);
|
||||||
|
self::assertSame(
|
||||||
|
'Legend:
|
||||||
|
! patch or minor release available - update recommended
|
||||||
|
~ major release available - update possible
|
||||||
|
vendor/apackage
|
||||||
|
vendor/longpackagename', trim($appTester->getDisplay(true))); // trim() is fine here, but see CAUTION above
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue