Skip to content

Commit

Permalink
Merge f1c3c94 into f5f8211
Browse files Browse the repository at this point in the history
  • Loading branch information
trehn committed Feb 3, 2017
2 parents f5f8211 + f1c3c94 commit ae3b991
Show file tree
Hide file tree
Showing 16 changed files with 334 additions and 277 deletions.
133 changes: 41 additions & 92 deletions bundlewrap/cmdline/apply.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from ..concurrency import WorkerPool
from ..utils.cmdline import get_target_nodes
from ..utils.table import ROW_SEPARATOR, render_table
from ..utils.text import (
blue,
bold,
Expand Down Expand Up @@ -116,103 +117,51 @@ def stats_summary(results, total_duration):
'skipped': 0,
'failed': 0,
}
headings = {
'node_name': _("node"),
'items': _("items"),
'correct': _("OK"),
'fixed': _("fixed"),
'skipped': _("skipped"),
'failed': _("failed"),
'duration': _("time"),
'totals_row': _("total ({} nodes)").format(len(results)),
}

max_duration_length = max(len(headings['duration']), len(format_duration(total_duration)))
max_node_name_length = max(len(headings['node_name']), len(headings['totals_row']))
rows = [[
bold(_("node")),
_("items"),
_("OK"),
green(_("fixed")),
yellow(_("skipped")),
red(_("failed")),
_("time"),
], ROW_SEPARATOR]

for result in results:
totals['items'] += len(result.profiling_info)
max_duration_length = max(len(format_duration(result.duration)), max_duration_length)
max_node_name_length = max(len(result.node_name), max_node_name_length)
for metric in ('correct', 'fixed', 'skipped', 'failed'):
totals[metric] += getattr(result, metric)
rows.append([
result.node_name,
str(len(result.profiling_info)),
str(result.correct),
green_unless_zero(result.fixed),
yellow_unless_zero(result.skipped),
red_unless_zero(result.failed),
format_duration(result.duration),
])

column_width = {
'duration': max_duration_length,
'node_name': max_node_name_length,
}
for column, total in totals.items():
column_width[column] = max(len(str(total)), len(headings[column]))

io.stdout("{x} ╭─{node}─┬─{items}─┬─{correct}─┬─{fixed}─┬─{skipped}─┬─{failed}─┬─{duration}─╮".format(
node="─" * column_width['node_name'],
items="─" * column_width['items'],
correct="─" * column_width['correct'],
fixed="─" * column_width['fixed'],
skipped="─" * column_width['skipped'],
failed="─" * column_width['failed'],
duration="─" * column_width['duration'],
x=blue("i"),
))
io.stdout("{x} │ {node} │ {items} │ {correct} │ {fixed} │ {skipped} │ {failed} │ {duration} │".format(
node=bold(headings['node_name'].ljust(column_width['node_name'])),
items=headings['items'].ljust(column_width['items']),
correct=headings['correct'].ljust(column_width['correct']),
fixed=green(headings['fixed'].ljust(column_width['fixed'])),
skipped=yellow(headings['skipped'].ljust(column_width['skipped'])),
failed=red(headings['failed'].ljust(column_width['failed'])),
duration=headings['duration'].ljust(column_width['duration']),
x=blue("i"),
))
io.stdout("{x} ├─{node}─┼─{items}─┼─{correct}─┼─{fixed}─┼─{skipped}─┼─{failed}─┼─{duration}─┤".format(
node="─" * column_width['node_name'],
items="─" * column_width['items'],
correct="─" * column_width['correct'],
fixed="─" * column_width['fixed'],
skipped="─" * column_width['skipped'],
failed="─" * column_width['failed'],
duration="─" * column_width['duration'],
x=blue("i"),
))
for result in results:
io.stdout("{x} │ {node} │ {items} │ {correct} │ {fixed} │ {skipped} │ {failed} │ {duration} │".format(
node=result.node_name.ljust(column_width['node_name']),
items=str(len(result.profiling_info)).rjust(column_width['items']),
correct=str(result.correct).rjust(column_width['correct']),
fixed=green_unless_zero(result.fixed, column_width['fixed']),
skipped=yellow_unless_zero(result.skipped, column_width['skipped']),
failed=red_unless_zero(result.failed, column_width['failed']),
duration=format_duration(result.duration).rjust(column_width['duration']),
x=blue("i"),
))
if len(results) > 1:
io.stdout("{x} ├─{node}─┼─{items}─┼─{correct}─┼─{fixed}─┼─{skipped}─┼─{failed}─┼─{duration}─┤".format(
node="─" * column_width['node_name'],
items="─" * column_width['items'],
correct="─" * column_width['correct'],
fixed="─" * column_width['fixed'],
skipped="─" * column_width['skipped'],
failed="─" * column_width['failed'],
duration="─" * column_width['duration'],
x=blue("i"),
))
io.stdout("{x} │ {node} │ {items} │ {correct} │ {fixed} │ {skipped} │ {failed} │ {duration} │".format(
node=bold(headings['totals_row'].ljust(column_width['node_name'])),
items=str(totals['items']).rjust(column_width['items']),
correct=str(totals['correct']).rjust(column_width['correct']),
fixed=green_unless_zero(totals['fixed'], column_width['fixed']),
skipped=yellow_unless_zero(totals['skipped'], column_width['skipped']),
failed=red_unless_zero(totals['failed'], column_width['failed']),
duration=format_duration(total_duration).rjust(column_width['duration']),
x=blue("i"),
))
io.stdout("{x} ╰─{node}─┴─{items}─┴─{correct}─┴─{fixed}─┴─{skipped}─┴─{failed}─┴─{duration}─╯".format(
node="─" * column_width['node_name'],
items="─" * column_width['items'],
correct="─" * column_width['correct'],
fixed="─" * column_width['fixed'],
skipped="─" * column_width['skipped'],
failed="─" * column_width['failed'],
duration="─" * column_width['duration'],
x=blue("i"),
))
rows.append(ROW_SEPARATOR)
rows.append([
bold(_("total ({} nodes)").format(len(results))),
str(totals['items']),
str(totals['correct']),
green_unless_zero(totals['fixed']),
yellow_unless_zero(totals['skipped']),
red_unless_zero(totals['failed']),
format_duration(total_duration),
])

alignments = {
1: 'right',
2: 'right',
3: 'right',
4: 'right',
5: 'right',
6: 'right',
}

for line in render_table(rows, alignments=alignments):
io.stdout("{x} {line}".format(x=blue("i"), line=line))
116 changes: 45 additions & 71 deletions bundlewrap/cmdline/lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
from ..concurrency import WorkerPool
from ..lock import softlock_add, softlock_list, softlock_remove
from ..utils.cmdline import get_target_nodes
from ..utils.text import blue, bold, cyan, error_summary, green, mark_for_translation as _, \
from ..utils.table import ROW_SEPARATOR, render_table
from ..utils.text import blue, bold, error_summary, green, mark_for_translation as _, \
randstr, red
from ..utils.time import format_timestamp
from ..utils.ui import io
from ..utils.ui import io, page_lines


def remove_lock_if_present(node, lock_id):
Expand Down Expand Up @@ -126,7 +127,6 @@ def bw_lock_show(repo, args):
errors = []
target_nodes = get_target_nodes(repo, args['target'], adhoc_nodes=args['adhoc_nodes'])
pending_nodes = target_nodes[:]
max_node_name_length = max([len(node.name) for node in target_nodes])
locks_on_node = {}

def tasks_available():
Expand Down Expand Up @@ -164,77 +164,51 @@ def handle_exception(task_id, exception, traceback):
error_summary(errors)
return

headers = (
('id', _("ID")),
('formatted_date', _("Created")),
('formatted_expiry', _("Expires")),
('user', _("User")),
('items', _("Items")),
('comment', _("Comment")),
)

locked_nodes = 0
for node_name, locks in locks_on_node.items():
if locks:
locked_nodes += 1

previous_node_was_unlocked = False
for node_name, locks in sorted(locks_on_node.items()):
if not locks:
io.stdout(_("{x} {node} no soft locks present").format(
x=green("✓"),
node=bold(node_name.ljust(max_node_name_length)),
))
previous_node_was_unlocked = True
rows = [[
bold(_("node")),
bold(_("ID")),
bold(_("created")),
bold(_("expires")),
bold(_("user")),
bold(_("items")),
bold(_("comment")),
], ROW_SEPARATOR]

output_counter = 0
for node_name, locks in sorted(locks_on_node.items()):
if locks:
# Unlocked nodes are printed without empty lines in
# between them. Locked nodes can produce lengthy output,
# though, so we add empty lines.
if (
previous_node_was_unlocked or (
output_counter > 0 and output_counter < locked_nodes
)
):
previous_node_was_unlocked = False
io.stdout('')

first_lock = True
for lock in locks:
lock['formatted_date'] = format_timestamp(lock['date'])
lock['formatted_expiry'] = format_timestamp(lock['expiry'])

lengths = {}
headline = "{x} {node} ".format(
x=blue("i"),
node=bold(node_name.ljust(max_node_name_length)),
)

for column, title in headers:
lengths[column] = len(title)
for lock in locks:
if column == 'items':
length = max([len(selector) for selector in lock[column]])
else:
length = len(lock[column])
lengths[column] = max(lengths[column], length)
headline += bold(title.ljust(lengths[column] + 2))

io.stdout(headline.rstrip())
for lock in locks:
for lineno, item_selectors in enumerate(lock['items']):
line = "{x} {node} ".format(
x=cyan("›"),
node=bold(node_name.ljust(max_node_name_length)),
)
for column, title in headers:
if column == 'items':
line += lock[column][lineno].ljust(lengths[column] + 2)
elif lineno == 0:
line += lock[column].ljust(lengths[column] + 2)
else:
line += " " * (lengths[column] + 2)
io.stdout(line.rstrip())

output_counter += 1
first_item = True
for item in lock['items']:
rows.append([
node_name if first_item and first_lock else "",
lock['id'] if first_item else "",
lock['formatted_date'] if first_item else "",
lock['formatted_expiry'] if first_item else "",
lock['user'] if first_item else "",
item,
lock['comment'] if first_item else "",
])
first_item = False
first_lock = False
else:
rows.append([
node_name,
_("(none)"),
"",
"",
"",
"",
"",
])
rows.append(ROW_SEPARATOR)

page_lines([
"{x} {line}".format(x=blue("i"), line=line)
for line in render_table(
rows[:-1],
alignments={1: 'center'},
)
])
27 changes: 19 additions & 8 deletions bundlewrap/cmdline/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@

from operator import itemgetter

from ..utils.text import mark_for_translation as _
from ..utils.table import ROW_SEPARATOR, render_table
from ..utils.text import blue, bold, mark_for_translation as _
from ..utils.ui import io


def bw_stats(repo, args):
io.stdout(_("{} nodes").format(len(repo.nodes)))
io.stdout(_("{} groups").format(len(repo.groups)))
io.stdout(_("{} bundles").format(len(repo.bundle_names)))

items = {}
metaprocs = set()
for node in repo.nodes:
Expand All @@ -21,8 +18,22 @@ def bw_stats(repo, args):
items.setdefault(item.ITEM_TYPE_NAME, 0)
items[item.ITEM_TYPE_NAME] += 1

io.stdout(_("{} metadata processors").format(len(metaprocs)))
io.stdout(_("{} items").format(sum([len(list(node.items)) for node in repo.nodes])))
rows = [
[
bold(_("count")),
bold(_("type")),
],
ROW_SEPARATOR,
[str(len(repo.nodes)), _("nodes")],
[str(len(repo.groups)), _("groups")],
[str(len(repo.bundle_names)), _("bundles")],
[str(len(metaprocs)), _("metadata processors")],
[str(sum([len(list(node.items)) for node in repo.nodes])), _("items")],
ROW_SEPARATOR,
]

for item_type, count in sorted(items.items(), key=itemgetter(1), reverse=True):
io.stdout(" {} {}".format(count, item_type))
rows.append([str(count), item_type])

for line in render_table(rows, alignments={0: 'right'}):
io.stdout("{x} {line}".format(x=blue("i"), line=line))

0 comments on commit ae3b991

Please sign in to comment.