mirror of
https://we.phorge.it/source/arcanist.git
synced 2025-02-16 16:58:38 +01:00
Make arc tasks
print output in a unicode-aware and console-width-aware way
Summary: Currently, we print `arc tasks` in a console-agnostic and unicode-unaware way, so: - Tasks with multibyte characters get aligned incorrectly (see T1831); and - narrow terminals plus long task names results in a broken display. Test Plan: Ran `arc tasks`. Will post screenshots. Reviewers: btrahan, vrana, Korvin Reviewed By: btrahan CC: aran Maniphest Tasks: T749, T1831 Differential Revision: https://secure.phabricator.com/D3568
This commit is contained in:
parent
777c119a0e
commit
dffaa17e41
1 changed files with 97 additions and 30 deletions
|
@ -87,14 +87,33 @@ EOTEXT
|
|||
$order = $this->getArgument('order');
|
||||
$limit = $this->getArgument('limit');
|
||||
$this->tasks = $this->loadManiphestTasks(
|
||||
($status == 'all'?'any':$status),
|
||||
($owner?$this->findOwnerPhid($owner):$this->getUserPHID()),
|
||||
($status == 'all' ? 'any' : $status),
|
||||
($owner ? $this->findOwnerPhid($owner) : $this->getUserPHID()),
|
||||
$order,
|
||||
$limit
|
||||
$limit);
|
||||
|
||||
$task_rows = array();
|
||||
foreach ($this->tasks as $task) {
|
||||
$output = array();
|
||||
|
||||
// Render the "T123" column.
|
||||
$task_id = "T".$task['id'];
|
||||
$formatted_task_id = phutil_console_format(
|
||||
'**%s**',
|
||||
$task_id);
|
||||
$output['id'] = array(
|
||||
'text' => $formatted_task_id,
|
||||
'len' => phutil_utf8_console_strlen($task_id),
|
||||
);
|
||||
|
||||
foreach ($this->tasks as $task) {
|
||||
$tid = "T{$task['id']}";
|
||||
// Render the "Title" column.
|
||||
$formatted_title = rtrim($task['title']);
|
||||
$output['title'] = array(
|
||||
'text' => $formatted_title,
|
||||
'len' => phutil_utf8_console_strlen($formatted_title),
|
||||
);
|
||||
|
||||
// Render the "Priority" column.
|
||||
switch ($task['priority']) {
|
||||
case 'Needs Triage':
|
||||
$color = 'magenta';
|
||||
|
@ -118,35 +137,83 @@ EOTEXT
|
|||
$color = 'white';
|
||||
break;
|
||||
}
|
||||
$task_priority = $task['priority'];
|
||||
$priority = phutil_console_format("<bg:{$color}> </bg>{$task_priority}");
|
||||
$output[] = array(phutil_console_format("**{$tid}**"),
|
||||
$task['title'],
|
||||
$priority,
|
||||
($task['status']?
|
||||
phutil_console_format("<bg:red> </bg>Closed"):
|
||||
phutil_console_format('<bg:green> </bg>Open'))
|
||||
);
|
||||
}
|
||||
$this->render($output);
|
||||
}
|
||||
$formatted_priority = phutil_console_format(
|
||||
"<bg:{$color}> </bg> %s",
|
||||
$task['priority']);
|
||||
$output['priority'] = array(
|
||||
'text' => $formatted_priority,
|
||||
'len' => phutil_utf8_console_strlen($task['priority']) + 2,
|
||||
);
|
||||
|
||||
private function render($table) {
|
||||
$column_length = array();
|
||||
foreach ($table as $row) {
|
||||
foreach ($row as $col => $cell) {
|
||||
if (!isset($column_length[$col]))
|
||||
$column_length[$col] = 0;
|
||||
if (strlen($cell) > $column_length[$col])
|
||||
$column_length[$col] = strlen($cell);
|
||||
// Render the "Status" column.
|
||||
if ($task['status']) {
|
||||
$status_text = 'Closed';
|
||||
$status_color = 'red';
|
||||
} else {
|
||||
$status_text = 'Open';
|
||||
$status_color = 'green';
|
||||
}
|
||||
$formatted_status = phutil_console_format(
|
||||
"<bg:{$status_color}> </bg> %s",
|
||||
$status_text);
|
||||
$output['status'] = array(
|
||||
'text' => $formatted_status,
|
||||
'len' => phutil_utf8_console_strlen('status') + 2,
|
||||
);
|
||||
|
||||
$task_rows[] = $output;
|
||||
}
|
||||
|
||||
// Find the longest string in each column.
|
||||
$col_size = array();
|
||||
foreach ($task_rows as $row) {
|
||||
foreach ($row as $key => $col) {
|
||||
if (empty($col_size[$key])) {
|
||||
$col_size[$key] = 0;
|
||||
}
|
||||
$col_size[$key] = max($col_size[$key], $col['len']);
|
||||
}
|
||||
}
|
||||
foreach ($table as $row) {
|
||||
foreach ($row as $col => $cell) {
|
||||
echo $cell.str_repeat(' ', $column_length[$col] - strlen($cell) + 4);
|
||||
}
|
||||
echo "\n";
|
||||
|
||||
// Determine the terminal width. If we can't figure it out, assume 80.
|
||||
$width = nonempty(phutil_console_get_terminal_width(), 80);
|
||||
|
||||
|
||||
// We're going to clip the titles so they'll all fit in one line on the
|
||||
// terminal. Figure out where to clip them.
|
||||
$padding_between_columns = 4;
|
||||
$clip_title_at = max(
|
||||
// Always show at least a little bit of text even if it will make the
|
||||
// UI wrap, since it's useless if we don't show anything.
|
||||
16,
|
||||
$width -
|
||||
($col_size['id'] + $col_size['priority'] + $col_size['status'] +
|
||||
($padding_between_columns * 3)));
|
||||
$col_size['title'] = min($col_size['title'], $clip_title_at);
|
||||
|
||||
foreach ($task_rows as $key => $cols) {
|
||||
$new_title = phutil_utf8_shorten($cols['title']['text'], $clip_title_at);
|
||||
|
||||
$task_rows[$key]['title']['len'] = phutil_utf8_console_strlen($new_title);
|
||||
$task_rows[$key]['title']['text'] = $new_title;
|
||||
}
|
||||
|
||||
$table = array();
|
||||
foreach ($task_rows as $row) {
|
||||
$trow = array();
|
||||
foreach ($row as $col => $cell) {
|
||||
$text = $cell['text'];
|
||||
$pad_len = $col_size[$col] - $cell['len'];
|
||||
if ($pad_len) {
|
||||
$text .= str_repeat(' ', $pad_len);
|
||||
}
|
||||
$trow[] = $text;
|
||||
}
|
||||
$table[] = implode(str_repeat(' ', $padding_between_columns), $trow);
|
||||
}
|
||||
$table = implode("\n", $table)."\n";
|
||||
|
||||
echo $table;
|
||||
}
|
||||
|
||||
private function findOwnerPhid($owner) {
|
||||
|
|
Loading…
Add table
Reference in a new issue