def report(<EOL>config, path, metrics, n, output, include_message=False, format=ReportFormat.CONSOLE, console_format=None,<EOL>):
logger.debug("<STR_LIT>")<EOL>logger.info(f"<STR_LIT>")<EOL>data = []<EOL>metric_metas = []<EOL>for metric in metrics:<EOL><INDENT>operator, metric = resolve_metric_as_tuple(metric)<EOL>key = metric.name<EOL>operator = operator.name<EOL>if metric.measure == MetricType.AimHigh:<EOL><INDENT>good_color = <NUM_LIT:32><EOL>bad_color = <NUM_LIT><EOL><DEDENT>elif metric.measure == MetricType.AimLow:<EOL><INDENT>good_color = <NUM_LIT><EOL>bad_color = <NUM_LIT:32><EOL><DEDENT>elif metric.measure == MetricType.Informational:<EOL><INDENT>good_color = <NUM_LIT><EOL>bad_color = <NUM_LIT><EOL><DEDENT>metric_meta = {<EOL>"<STR_LIT:key>": key,<EOL>"<STR_LIT>": operator,<EOL>"<STR_LIT>": good_color,<EOL>"<STR_LIT>": bad_color,<EOL>"<STR_LIT:title>": metric.description,<EOL>"<STR_LIT:type>": metric.type,<EOL>}<EOL>metric_metas.append(metric_meta)<EOL><DEDENT>state = State(config)<EOL>for archiver in state.archivers:<EOL><INDENT>history = state.index[archiver].revisions[:n][::-<NUM_LIT:1>]<EOL>last = {}<EOL>for rev in history:<EOL><INDENT>vals = []<EOL>for meta in metric_metas:<EOL><INDENT>try:<EOL><INDENT>logger.debug(<EOL>f"<STR_LIT>"<EOL>)<EOL>val = rev.get(config, archiver, meta["<STR_LIT>"], path, meta["<STR_LIT:key>"])<EOL>last_val = last.get(meta["<STR_LIT:key>"], None)<EOL>if meta["<STR_LIT:type>"] in (int, float):<EOL><INDENT>if last_val:<EOL><INDENT>delta = val - last_val<EOL><DEDENT>else:<EOL><INDENT>delta = <NUM_LIT:0><EOL><DEDENT>last[meta["<STR_LIT:key>"]] = val<EOL><DEDENT>else:<EOL><INDENT>delta = <NUM_LIT:0><EOL><DEDENT>if delta == <NUM_LIT:0>:<EOL><INDENT>delta_col = delta<EOL><DEDENT>elif delta < <NUM_LIT:0>:<EOL><INDENT>delta_col = f"<STR_LIT>"<EOL><DEDENT>else:<EOL><INDENT>delta_col = f"<STR_LIT>"<EOL><DEDENT>if meta["<STR_LIT:type>"] in (int, float):<EOL><INDENT>k = f"<STR_LIT>"<EOL><DEDENT>else:<EOL><INDENT>k = f"<STR_LIT>"<EOL><DEDENT><DEDENT>except KeyError as e:<EOL><INDENT>k = f"<STR_LIT>"<EOL><DEDENT>vals.append(k)<EOL><DEDENT>if include_message:<EOL><INDENT>data.append(<EOL>(<EOL>format_revision(rev.revision.key),<EOL>rev.revision.message[:MAX_MESSAGE_WIDTH],<EOL>rev.revision.author_name,<EOL>format_date(rev.revision.date),<EOL>*vals,<EOL>)<EOL>)<EOL><DEDENT>else:<EOL><INDENT>data.append(<EOL>(<EOL>format_revision(rev.revision.key),<EOL>rev.revision.author_name,<EOL>format_date(rev.revision.date),<EOL>*vals,<EOL>)<EOL>)<EOL><DEDENT><DEDENT><DEDENT>descriptions = [meta["<STR_LIT:title>"] for meta in metric_metas]<EOL>if include_message:<EOL><INDENT>headers = ("<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>", *descriptions)<EOL><DEDENT>else:<EOL><INDENT>headers = ("<STR_LIT>", "<STR_LIT>", "<STR_LIT>", *descriptions)<EOL><DEDENT>if format == ReportFormat.HTML:<EOL><INDENT>if output.is_file and output.suffix == "<STR_LIT>":<EOL><INDENT>report_path = output.parents[<NUM_LIT:0>]<EOL>report_output = output<EOL><DEDENT>else:<EOL><INDENT>report_path = output<EOL>report_output = output.joinpath("<STR_LIT>")<EOL><DEDENT>report_path.mkdir(exist_ok=True, parents=True)<EOL>templates_dir = (Path(__file__).parents[<NUM_LIT:1>] / "<STR_LIT>").resolve()<EOL>report_template = Template((templates_dir / "<STR_LIT>").read_text())<EOL>table_headers = "<STR_LIT>".join([f"<STR_LIT>" for header in headers])<EOL>table_content = "<STR_LIT>"<EOL>for line in data[::-<NUM_LIT:1>]:<EOL><INDENT>table_content += "<STR_LIT>"<EOL>for element in line:<EOL><INDENT>element = element.replace("<STR_LIT>", "<STR_LIT>")<EOL>element = element.replace("<STR_LIT>", "<STR_LIT>")<EOL>element = element.replace("<STR_LIT>", "<STR_LIT>")<EOL>element = element.replace("<STR_LIT>", "<STR_LIT>")<EOL>table_content += f"<STR_LIT>"<EOL><DEDENT>table_content += "<STR_LIT>"<EOL><DEDENT>report_template = report_template.safe_substitute(<EOL>headers=table_headers, content=table_content<EOL>)<EOL>with report_output.open("<STR_LIT:w>") as output:<EOL><INDENT>output.write(report_template)<EOL><DEDENT>try:<EOL><INDENT>copytree(str(templates_dir / "<STR_LIT>"), str(report_path / "<STR_LIT>"))<EOL><DEDENT>except FileExistsError:<EOL><INDENT>pass<EOL><DEDENT>logger.info(f"<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>print(<EOL>tabulate.tabulate(<EOL>headers=headers, tabular_data=data[::-<NUM_LIT:1>], tablefmt=console_format<EOL>)<EOL>)<EOL><DEDENT>
Show information about the cache and runtime.

:param config: The configuration
:type  config: :class:`wily.config.WilyConfig`

:param path: The path to the file
:type  path: ``str``

:param metrics: Name of the metric to report on
:type  metrics: ``str``

:param n: Number of items to list
:type  n: ``int``

:param output: Output path
:type  output: ``Path``

:param include_message: Include revision messages
:type  include_message: ``bool``

:param format: Output format
:type  format: ``ReportFormat``

:param console_format: Grid format style for tabulate
:type  console_format: ``str``