Updates to vendors etc

This commit is contained in:
Chris Hunt
2025-07-11 15:57:48 +01:00
parent d972cbcd0a
commit 8fb6438254
8043 changed files with 248005 additions and 189479 deletions

View File

@@ -45,7 +45,6 @@ class Table
private array $rows = [];
private array $effectiveColumnWidths = [];
private int $numberOfColumns;
private OutputInterface $output;
private TableStyle $style;
private array $columnStyles = [];
private array $columnWidths = [];
@@ -55,10 +54,9 @@ class Table
private static array $styles;
public function __construct(OutputInterface $output)
{
$this->output = $output;
public function __construct(
private OutputInterface $output,
) {
self::$styles ??= self::initStyles();
$this->setStyle('default');
@@ -66,10 +64,8 @@ class Table
/**
* Sets a style definition.
*
* @return void
*/
public static function setStyleDefinition(string $name, TableStyle $style)
public static function setStyleDefinition(string $name, TableStyle $style): void
{
self::$styles ??= self::initStyles();
@@ -83,7 +79,7 @@ class Table
{
self::$styles ??= self::initStyles();
return self::$styles[$name] ?? throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
return self::$styles[$name] ?? throw new InvalidArgumentException(\sprintf('Style "%s" is not defined.', $name));
}
/**
@@ -168,7 +164,7 @@ class Table
public function setColumnMaxWidth(int $columnIndex, int $width): static
{
if (!$this->output->getFormatter() instanceof WrappableOutputFormatterInterface) {
throw new \LogicException(sprintf('Setting a maximum column width is only supported when using a "%s" formatter, got "%s".', WrappableOutputFormatterInterface::class, get_debug_type($this->output->getFormatter())));
throw new \LogicException(\sprintf('Setting a maximum column width is only supported when using a "%s" formatter, got "%s".', WrappableOutputFormatterInterface::class, get_debug_type($this->output->getFormatter())));
}
$this->columnMaxWidths[$columnIndex] = $width;
@@ -194,7 +190,7 @@ class Table
/**
* @return $this
*/
public function setRows(array $rows)
public function setRows(array $rows): static
{
$this->rows = [];
@@ -237,7 +233,7 @@ class Table
public function appendRow(TableSeparator|array $row): static
{
if (!$this->output instanceof ConsoleSectionOutput) {
throw new RuntimeException(sprintf('Output should be an instance of "%s" when calling "%s".', ConsoleSectionOutput::class, __METHOD__));
throw new RuntimeException(\sprintf('Output should be an instance of "%s" when calling "%s".', ConsoleSectionOutput::class, __METHOD__));
}
if ($this->rendered) {
@@ -312,10 +308,8 @@ class Table
* | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
* | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
* +---------------+-----------------------+------------------+
*
* @return void
*/
public function render()
public function render(): void
{
$divider = new TableSeparator();
$isCellWithColspan = static fn ($cell) => $cell instanceof TableCell && $cell->getColspan() >= 2;
@@ -365,17 +359,19 @@ class Table
for ($i = 0; $i < $maxRows; ++$i) {
$cell = (string) ($row[$i] ?? '');
$parts = explode("\n", $cell);
$eol = str_contains($cell, "\r\n") ? "\r\n" : "\n";
$parts = explode($eol, $cell);
foreach ($parts as $idx => $part) {
if ($headers && !$containsColspan) {
if (0 === $idx) {
$rows[] = [sprintf(
'<comment>%s</>: %s',
str_pad($headers[$i] ?? '', $maxHeaderLength, ' ', \STR_PAD_LEFT),
$rows[] = [\sprintf(
'<comment>%s%s</>: %s',
str_repeat(' ', $maxHeaderLength - Helper::width(Helper::removeDecoration($formatter, $headers[$i] ?? ''))),
$headers[$i] ?? '',
$part
)];
} else {
$rows[] = [sprintf(
$rows[] = [\sprintf(
'%s %s',
str_pad('', $maxHeaderLength, ' ', \STR_PAD_LEFT),
$part
@@ -421,7 +417,7 @@ class Table
continue;
}
if ($isHeader && !$isHeaderSeparatorRendered) {
if ($isHeader && !$isHeaderSeparatorRendered && $this->style->displayOutsideBorder()) {
$this->renderRowSeparator(
self::SEPARATOR_TOP,
$hasTitle ? $this->headerTitle : null,
@@ -453,7 +449,10 @@ class Table
}
}
}
$this->renderRowSeparator(self::SEPARATOR_BOTTOM, $this->footerTitle, $this->style->getFooterTitleFormat());
if ($this->getStyle()->displayOutsideBorder()) {
$this->renderRowSeparator(self::SEPARATOR_BOTTOM, $this->footerTitle, $this->style->getFooterTitleFormat());
}
$this->cleanup();
$this->rendered = true;
@@ -495,12 +494,12 @@ class Table
}
if (null !== $title) {
$titleLength = Helper::width(Helper::removeDecoration($formatter = $this->output->getFormatter(), $formattedTitle = sprintf($titleFormat, $title)));
$titleLength = Helper::width(Helper::removeDecoration($formatter = $this->output->getFormatter(), $formattedTitle = \sprintf($titleFormat, $title)));
$markupLength = Helper::width($markup);
if ($titleLength > $limit = $markupLength - 4) {
$titleLength = $limit;
$formatLength = Helper::width(Helper::removeDecoration($formatter, sprintf($titleFormat, '')));
$formattedTitle = sprintf($titleFormat, Helper::substr($title, 0, $limit - $formatLength - 3).'...');
$formatLength = Helper::width(Helper::removeDecoration($formatter, \sprintf($titleFormat, '')));
$formattedTitle = \sprintf($titleFormat, Helper::substr($title, 0, $limit - $formatLength - 3).'...');
}
$titleStart = intdiv($markupLength - $titleLength, 2);
@@ -511,7 +510,7 @@ class Table
}
}
$this->output->writeln(sprintf($this->style->getBorderFormat(), $markup));
$this->output->writeln(\sprintf($this->style->getBorderFormat(), $markup));
}
/**
@@ -521,7 +520,7 @@ class Table
{
$borders = $this->style->getBorderChars();
return sprintf($this->style->getBorderFormat(), self::BORDER_OUTSIDE === $type ? $borders[1] : $borders[3]);
return \sprintf($this->style->getBorderFormat(), self::BORDER_OUTSIDE === $type ? $borders[1] : $borders[3]);
}
/**
@@ -562,18 +561,15 @@ class Table
}
// str_pad won't work properly with multi-byte strings, we need to fix the padding
if (false !== $encoding = mb_detect_encoding($cell, null, true)) {
$width += \strlen($cell) - mb_strwidth($cell, $encoding);
}
$width += \strlen($cell) - Helper::width($cell) - substr_count($cell, "\0");
$style = $this->getColumnStyle($column);
if ($cell instanceof TableSeparator) {
return sprintf($style->getBorderFormat(), str_repeat($style->getBorderChars()[2], $width));
return \sprintf($style->getBorderFormat(), str_repeat($style->getBorderChars()[2], $width));
}
$width += Helper::length($cell) - Helper::length(Helper::removeDecoration($this->output->getFormatter(), $cell));
$content = sprintf($style->getCellRowContentFormat(), $cell);
$content = \sprintf($style->getCellRowContentFormat(), $cell);
$padType = $style->getPadType();
if ($cell instanceof TableCell && $cell->getStyle() instanceof TableCellStyle) {
@@ -598,7 +594,7 @@ class Table
$padType = $cell->getStyle()->getPadByAlign();
}
return sprintf($cellFormat, str_pad($content, $width, $style->getPaddingChar(), $padType));
return \sprintf($cellFormat, str_pad($content, $width, $style->getPaddingChar(), $padType));
}
/**
@@ -630,15 +626,56 @@ class Table
foreach ($rows[$rowKey] as $column => $cell) {
$colspan = $cell instanceof TableCell ? $cell->getColspan() : 1;
if (isset($this->columnMaxWidths[$column]) && Helper::width(Helper::removeDecoration($formatter, $cell)) > $this->columnMaxWidths[$column]) {
$cell = $formatter->formatAndWrap($cell, $this->columnMaxWidths[$column] * $colspan);
$minWrappedWidth = 0;
$widthApplied = [];
$lengthColumnBorder = $this->getColumnSeparatorWidth() + Helper::width($this->style->getCellRowContentFormat()) - 2;
for ($i = $column; $i < ($column + $colspan); ++$i) {
if (isset($this->columnMaxWidths[$i])) {
$minWrappedWidth += $this->columnMaxWidths[$i];
$widthApplied[] = ['type' => 'max', 'column' => $i];
} elseif (($this->columnWidths[$i] ?? 0) > 0 && $colspan > 1) {
$minWrappedWidth += $this->columnWidths[$i];
$widthApplied[] = ['type' => 'min', 'column' => $i];
}
}
if (1 === \count($widthApplied)) {
if ($colspan > 1) {
$minWrappedWidth *= $colspan; // previous logic
}
} elseif (\count($widthApplied) > 1) {
$minWrappedWidth += (\count($widthApplied) - 1) * $lengthColumnBorder;
}
$cellWidth = Helper::width(Helper::removeDecoration($formatter, $cell));
if ($minWrappedWidth && $cellWidth > $minWrappedWidth) {
$cell = $formatter->formatAndWrap($cell, $minWrappedWidth);
}
// update minimal columnWidths for spanned columns
if ($colspan > 1 && $minWrappedWidth > 0) {
$columnsMinWidthProcessed = [];
$cellWidth = min($cellWidth, $minWrappedWidth);
foreach ($widthApplied as $item) {
if ('max' === $item['type'] && $cellWidth >= $this->columnMaxWidths[$item['column']]) {
$minWidthColumn = $this->columnMaxWidths[$item['column']];
$this->columnWidths[$item['column']] = $minWidthColumn;
$columnsMinWidthProcessed[$item['column']] = true;
$cellWidth -= $minWidthColumn + $lengthColumnBorder;
}
}
for ($i = $column; $i < ($column + $colspan); ++$i) {
if (isset($columnsMinWidthProcessed[$i])) {
continue;
}
$this->columnWidths[$i] = $cellWidth + $lengthColumnBorder;
}
}
if (!str_contains($cell ?? '', "\n")) {
continue;
}
$escaped = implode("\n", array_map(OutputFormatter::escapeTrailingBackslash(...), explode("\n", $cell)));
$eol = str_contains($cell ?? '', "\r\n") ? "\r\n" : "\n";
$escaped = implode($eol, array_map(OutputFormatter::escapeTrailingBackslash(...), explode($eol, $cell)));
$cell = $cell instanceof TableCell ? new TableCell($escaped, ['colspan' => $cell->getColspan()]) : $escaped;
$lines = explode("\n", str_replace("\n", "<fg=default;bg=default></>\n", $cell));
$lines = explode($eol, str_replace($eol, '<fg=default;bg=default></>'.$eol, $cell));
foreach ($lines as $lineKey => $line) {
if ($colspan > 1) {
$line = new TableCell($line, ['colspan' => $colspan]);
@@ -694,14 +731,15 @@ class Table
$unmergedRows = [];
foreach ($rows[$line] as $column => $cell) {
if (null !== $cell && !$cell instanceof TableCell && !\is_scalar($cell) && !$cell instanceof \Stringable) {
throw new InvalidArgumentException(sprintf('A cell must be a TableCell, a scalar or an object implementing "__toString()", "%s" given.', get_debug_type($cell)));
throw new InvalidArgumentException(\sprintf('A cell must be a TableCell, a scalar or an object implementing "__toString()", "%s" given.', get_debug_type($cell)));
}
if ($cell instanceof TableCell && $cell->getRowspan() > 1) {
$nbLines = $cell->getRowspan() - 1;
$lines = [$cell];
if (str_contains($cell, "\n")) {
$lines = explode("\n", str_replace("\n", "<fg=default;bg=default>\n</>", $cell));
$nbLines = \count($lines) > $nbLines ? substr_count($cell, "\n") : $nbLines;
$eol = str_contains($cell, "\r\n") ? "\r\n" : "\n";
$lines = explode($eol, str_replace($eol, '<fg=default;bg=default>'.$eol.'</>', $cell));
$nbLines = \count($lines) > $nbLines ? substr_count($cell, $eol) : $nbLines;
$rows[$line][$column] = new TableCell($lines[0], ['colspan' => $cell->getColspan(), 'style' => $cell->getStyle()]);
unset($lines[0]);
@@ -721,7 +759,7 @@ class Table
foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {
// we need to know if $unmergedRow will be merged or inserted into $rows
if (isset($rows[$unmergedRowKey]) && \is_array($rows[$unmergedRowKey]) && ($this->getNumberOfColumns($rows[$unmergedRowKey]) + $this->getNumberOfColumns($unmergedRows[$unmergedRowKey]) <= $this->numberOfColumns)) {
if (isset($rows[$unmergedRowKey]) && \is_array($rows[$unmergedRowKey]) && ($this->getNumberOfColumns($rows[$unmergedRowKey]) + $this->getNumberOfColumns($unmergedRow) <= $this->numberOfColumns)) {
foreach ($unmergedRow as $cellKey => $cell) {
// insert cell into row at cellKey position
array_splice($rows[$unmergedRowKey], $cellKey, 0, [$cell]);
@@ -729,8 +767,8 @@ class Table
} else {
$row = $this->copyRow($rows, $unmergedRowKey - 1);
foreach ($unmergedRow as $column => $cell) {
if (!empty($cell)) {
$row[$column] = $unmergedRow[$column];
if ($cell) {
$row[$column] = $cell;
}
}
array_splice($rows, $unmergedRowKey, 0, [$row]);
@@ -838,7 +876,7 @@ class Table
private function getColumnSeparatorWidth(): int
{
return Helper::width(sprintf($this->style->getBorderFormat(), $this->style->getBorderChars()[3]));
return Helper::width(\sprintf($this->style->getBorderFormat(), $this->style->getBorderChars()[3]));
}
private function getCellWidth(array $row, int $column): int
@@ -870,6 +908,12 @@ class Table
*/
private static function initStyles(): array
{
$markdown = new TableStyle();
$markdown
->setDefaultCrossingChar('|')
->setDisplayOutsideBorder(false)
;
$borderless = new TableStyle();
$borderless
->setHorizontalBorderChars('=')
@@ -907,6 +951,7 @@ class Table
return [
'default' => new TableStyle(),
'markdown' => $markdown,
'borderless' => $borderless,
'compact' => $compact,
'symfony-style-guide' => $styleGuide,
@@ -921,6 +966,6 @@ class Table
return $name;
}
return self::$styles[$name] ?? throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
return self::$styles[$name] ?? throw new InvalidArgumentException(\sprintf('Style "%s" is not defined.', $name));
}
}