Source code for buildtest.cli.history

import logging
import os
import re
import sys

from rich.pretty import pprint

from buildtest.defaults import BUILD_HISTORY_DIR, console
from buildtest.utils.file import is_dir, load_json, read_file, walk_tree
from buildtest.utils.table import create_table, print_table, print_terse_format
from buildtest.utils.tools import checkColor

logger = logging.getLogger(__name__)


[docs] def build_history(args): """This is the entry point for command ``buildtest history`` command which reports Args: args (dict): Parsed arguments from `ArgumentParser.parse_args <https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.parse_args>`_ """ if args.history == "list": list_build_history( no_header=args.no_header, terse=args.terse, pager=args.pager, color=args.color, row_count=args.row_count, ) if args.history == "query": query_builds( build_id=args.id, log_option=args.log, output=args.output, pager=args.pager )
[docs] def sorted_alphanumeric(data): """This method is used for alphanumeric sorting of files. Args: data: A list of history files to sort alpha numerically Returns: list: sorted list of history files alphanumerically """ convert = lambda text: int(text) if text.isdigit() else text.lower() alphanum_key = lambda key: [convert(c) for c in re.split("([0-9]+)", key)] return sorted(data, key=alphanum_key)
[docs] def query_builds(build_id, log_option=None, output=None, pager=None): """This method is called when user runs `buildtest history query` which will report the build.json and logfile. Args: build_id (int): Build Identifier which is used for querying history file. The indentifier is an integer starting from 0 log_option (bool, optional): Option to control whether log file is opened in editor. This is specified via ``buildtest history query -l <id>`` output (bool, optional): Display output.txt file which contains output of ``buildtest build`` command. This is passed via ``buildtest history query -o`` pager (bool, optional): Print output in paging format """ if not is_dir(BUILD_HISTORY_DIR): sys.exit( f"Unable to find history directory: {BUILD_HISTORY_DIR}, seems like you have not run any builds using 'buildtest build' command." ) num_ids = list(range(len(os.listdir(BUILD_HISTORY_DIR)))) if not is_dir(os.path.join(BUILD_HISTORY_DIR, str(build_id))): sys.exit( f"Invalid build id: {build_id}. Please select one of the following build ids: {num_ids}" ) content = load_json(os.path.join(BUILD_HISTORY_DIR, str(build_id), "build.json")) # if --log option specified open file in vim if log_option: os.system(f"vim {content['logpath']}") return if output: output_content = read_file( os.path.join(BUILD_HISTORY_DIR, str(build_id), "output.txt") ) print(output_content) return if pager: with console.pager(): console.print(content) return pprint(content)
[docs] def list_build_history( no_header=None, terse=None, pager=None, color=None, row_count=None ): """This method is entry point for ``buildtest history list`` which prints all previous builds stored in **BUILD_HISTORY_DIR**. Each directory has a ``build.json`` file that stores content of each build that was run by ``buildtest build``. Args: no_header (bool, optional): Control whether header columns are displayed with terse format terse (bool, optional): Print output in terse format pager (bool, optional): Print output in paging format color (bool, optional): Select desired color when displaying results row_count (bool, optional): Print row count of all previous builds """ consoleColor = checkColor(color) history_files = walk_tree(BUILD_HISTORY_DIR, ".json") # only filter filters that are 'build.json' history_files = [f for f in history_files if os.path.basename(f) == "build.json"] history_files = sorted_alphanumeric(history_files) tdata = process_history_data(history_files) headers = [ "id", "user", "hostname", "system", "date", "command", "pass tests", "fail tests", "total tests", "pass rate", "fail rate", ] table = create_table( data=tdata, columns=headers, title="Build History", header_style="blue", column_style=consoleColor, show_lines=True, ) if terse: print_terse_format( tdata=tdata, headers=headers, display_header=no_header, color=consoleColor, pager=pager, ) return print_table(table, pager=pager, row_count=row_count)
[docs] def process_history_data(history_files): """This method processes history files and extracts data from each build.json file and returns a list of data for each build. Args: history_files (list): A list of history files to process Returns: list: A list containing build history data """ tdata = [] for fname in history_files: row = [] content = load_json(fname) row.append(os.path.basename(os.path.dirname(fname))) for field in ["user", "hostname", "system", "date", "command"]: row.append(content[field]) row.append(str(content["test_summary"]["pass"])) row.append(str(content["test_summary"]["fail"])) row.append(str(content["test_summary"]["total"])) row.append(str(content["test_summary"]["pass_rate"])) row.append(str(content["test_summary"]["fail_rate"])) tdata.append(row) return tdata