-- -- --- --- --- --- --- --- ------- ------- ------- |
"""
-- -- --- --- --- --- --- --- ------- ------- ------- |
Rank command.
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- -- --- --- --- --- --- --- ------- ------- ------- |
The report command gives a table of files sorted according their ranking scheme
-- -- --- --- --- --- --- --- ------- ------- ------- |
of a specified metric.
-- -- --- --- --- --- --- --- ------- ------- ------- |
Will compare the values between files and return a sorted table.
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- -- --- --- --- --- --- --- ------- ------- ------- |
TODO: Refactor individual file work into a separate function
-- -- --- --- --- --- --- --- ------- ------- ------- |
TODO: Layer on Click invocation in operators section, __main__.py file
-- -- --- --- --- --- --- --- ------- ------- ------- |
TODO: Is the a better way to retrieve the revision number than via index?
-- -- --- --- --- --- --- --- ------- ------- ------- |
"""
-- -- --- --- --- --- --- --- ------- ------- ------- |
import tabulate
-- -- --- --- --- --- --- --- ------- ------- ------- |
import operator as op
-- -- --- --- --- --- --- --- ------- ------- ------- |
from pathlib import Path
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- -- --- --- --- --- --- --- ------- ------- ------- |
from wily import logger, format_date, format_revision, MAX_MESSAGE_WIDTH
-- -- --- --- --- --- --- --- ------- ------- ------- |
from wily.config import DEFAULT_GRID_STYLE
-- -- --- --- --- --- --- --- ------- ------- ------- |
from wily.operators import resolve_metric, MetricType
-- -- --- --- --- --- --- --- ------- ------- ------- |
from wily.state import State
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- 02 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
def aggregate_metric(metric_table: list):
-- 02 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
"""
-- 02 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
Aggregate/total wily metrics in a tabular format.
-- 02 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
-- 02 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
Data is assumed to be in the tabular format of the rank function within the rank.py
-- 02 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
command.
-- 02 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
-- 02 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
:param metric_table: table with list of wily metrics across multiple files.
-- 02 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
:type metric_table: ''list''
-- 02 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
-- 02 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
:return: Sorted table of all files in path, sorted in order of metric.
-- 02 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
"""
-- 02 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
# value in first draft is assumed to be the fifth item in the list.
-- 02 000 000 000 000 000 000 0000.00 0000.00 0000.00 |
return ["Total", "---", "---", "---", sum(float(rev[4]) for rev in metric_table)]
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- -- --- --- --- --- --- --- ------- ------- ------- |
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
def rank(config, path, metric, revision_index):
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
"""
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
Rank command ordering files, methods or functions using metrics.
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
:param config: The configuration
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
:type config: :class:'wily.config.WilyConfig'
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
:param path: The path to the file
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
:type path ''str''
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
:param metric: Name of the metric to report on
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
:type metric: ''str''
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
:param revision_index: Version of git repository to revert to.
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
:type revision_index: ''int''
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
:return: Sorted table of all files in path, sorted in order of metric.
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
"""
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
logger.debug("Running rank command")
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
logger.info(f"-----------Rank for {metric}------------")
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
data = []
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
operator, key = metric.split(".")
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
metric = resolve_metric(metric)
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
metric_meta = {
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
"key": key,
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
"operator": operator,
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
"title": metric.description,
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
"type": metric.type,
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
"wily_metric_type": metric.measure.name, # AimHigh, AimLow, Informational
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
}
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
# Assumption is there is only one metric (e.g., therefore list of metrics commented out)
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
pth = Path(path)
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
if not str(pth).endswith(".py"):
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
items = pth.glob("**/*.py")
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
else:
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
items = [pth]
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
for item in items:
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
state = State(config)
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
for archiver in state.archivers:
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
# Last revision in the list is the first item (ordered Newest to Oldest => 0 to -1 index.
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
rev = state.index[archiver].revisions[revision_index]
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
try:
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
logger.debug(
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
f"Fetching metric {metric_meta['key']} for {metric_meta['operator']} in {str(item)}"
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
)
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
val = rev.get(
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
config,
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
archiver,
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
metric_meta["operator"],
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
str(item),
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
metric_meta["key"],
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
)
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
value = str(val)
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
except KeyError as e:
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
value = f"Not found {e}"
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
# Assumption is there is only one metric (e.g., value versus val* as in report.py command
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
data.append(
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
(
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
item,
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
format_revision(rev.revision.key),
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
rev.revision.author_name,
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
format_date(rev.revision.date),
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
value,
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
)
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
)
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
# before moving towards the print tabular data - the values are sorted according to the metric type
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
# The "value" is assumed to be the fourth item in an individual data row. An alternative that may
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
# be more readable is the op.attrgetter.
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
if metric_meta["wily_metric_type"] == "AimHigh":
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
# AimHigh is sorted lowest to highest
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
data.sort(key=op.itemgetter(4))
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
elif metric_meta["wily_metric_type"] == "AimLow":
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
# AimLow is sorted highest to lowest
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
data.sort(key=op.itemgetter(4), reverse=True)
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
# Tack on the total row at the end
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
data.append(aggregate_metric(data))
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
headers = ("File", "Revision", "Author", "Date", metric_meta["title"])
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
print(
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
tabulate.tabulate(
-- 07 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
headers=headers, tabular_data=data, tablefmt=DEFAULT_GRID_STYLE
-- -- 002 005 003 005 007 008 0022.46 0022.46 0001.00 |
)
-- -- --- --- --- --- --- --- ------- ------- ------- |
)