"""
buildtest cli: include functions to build, get test configurations, and
interact with a global configuration for buildtest.
"""
import argparse
import datetime
from buildtest import BUILDTEST_COPYRIGHT, BUILDTEST_VERSION
from buildtest.defaults import console
from buildtest.schemas.defaults import schema_table
from pygments.styles import STYLE_MAP
from rich.color import Color, ColorParseError
[docs]def handle_kv_string(val):
"""This method is used as type field in --filter argument in ``buildtest buildspec find``.
This method returns a dict of key,value pair where input is in format
key1=val1,key2=val2,key3=val3
Args:
val (str): Input string in ``key1=value1,key2=value2`` format that is processed into a dictionary type
Returns:
dict: A dict mapping of key=value pairs
"""
kv_dict = {}
if "," in val:
args = val.split(",")
for kv in args:
if "=" not in kv:
raise argparse.ArgumentTypeError("Must specify k=v")
key, value = kv.split("=")[0], kv.split("=")[1]
kv_dict[key] = value
return kv_dict
if "=" not in val:
raise argparse.ArgumentTypeError("Must specify in key=value format")
key, value = val.split("=")[0], val.split("=")[1]
kv_dict[key] = value
return kv_dict
[docs]def positive_number(value):
"""Checks if input is positive number and returns value as an int type.
Args:
value (str or int): Specify an input number
Returns:
int: Return value as int type
Raises:
argparse.ArgumentTypeError will be raised if input is not positive number or input is not str or int type
>>> positive_number("1")
1
>>> positive_number(2)
2
"""
if not isinstance(value, (str, int)):
raise argparse.ArgumentTypeError(
f"Input must be an integer or string type, you have specified '{value}' which is of type {type(value)}"
)
try:
int_val = int(value)
except ValueError:
console.print(f"[red]Unable to convert {value} to int ")
console.print_exception()
raise ValueError
if int_val <= 0:
raise argparse.ArgumentTypeError(
f"Input: {value} converted to int: {int_val} must be a positive number"
)
return int_val
[docs]def supported_color(input_color):
"""Checks if input is a supported color and returns value as an Color type.
Args:
input_color (str): Specify an input color
Returns:
str: Return value as rich.color.Color type
Raises:
argparse.ArgumentTypeError will be raised if input is not a supported color input or is not str type
>>> supported_color("red")
red
"""
if not isinstance(input_color, (str)):
raise argparse.ArgumentTypeError(
f"Input must be a string type, you have specified '{input_color}' which is of type {type(input_color)}"
)
try:
color_val = Color.parse(input_color)
except ColorParseError:
console.print(f"[red]Unable to convert {input_color} to a Color ")
console.print_exception()
return
return color_val
[docs]def valid_time(value):
"""Checks if input is valid time and returns value as a str type.
Args:
value (str): Specify an input date in yyyy-mm-dd format
Returns:
int: Return value as str type in correct format
Raises:
argparse.ArgumentTypeError will be raised if input is not str or input is not in desired format
>>> valid_time("2022-01-01")
"2022-01-01"
>>> valid_time("2022-01-13")
"2022-01-13"
"""
if not isinstance(value, str):
raise argparse.ArgumentTypeError(
f"Input must be string type, you have specified '{value}' which is of type {type(value)}"
)
fmt = "%Y-%m-%d"
try:
dt_object = datetime.datetime.strptime(value, fmt)
except ValueError:
console.print(f"[red]Unable to convert {value} to correct date format")
console.print_exception()
raise ValueError
return dt_object
[docs]def get_parser():
epilog_str = f"""
References
GitHub: https://github.com/buildtesters/buildtest
Documentation: https://buildtest.readthedocs.io/en/latest/index.html
Schema Documentation: https://buildtesters.github.io/buildtest/
Slack: http://hpcbuildtest.slack.com/
Please report issues at https://github.com/buildtesters/buildtest/issues
{BUILDTEST_COPYRIGHT}
"""
parser = argparse.ArgumentParser(
prog="buildtest",
formatter_class=argparse.RawDescriptionHelpFormatter,
description="buildtest is a HPC testing framework for building and running tests.",
usage="%(prog)s [options] [COMMANDS]",
epilog=epilog_str,
)
parser.add_argument(
"-V",
"--version",
action="version",
version=f"%(prog)s version {BUILDTEST_VERSION}",
)
parser.add_argument(
"-c", "--config", dest="configfile", help="Specify Path to Configuration File"
)
parser.add_argument(
"-d", "--debug", action="store_true", help="Stream log messages to stdout"
)
parser.add_argument(
"-l",
"--loglevel",
help="Filter log messages based on logging level",
choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
default="DEBUG",
)
parser.add_argument(
"--editor",
help="Select your preferred editor when opening files.",
choices=["vi", "vim", "emacs", "nano"],
)
parser.add_argument(
"--view-log", action="store_true", help="Show content of last log"
)
parser.add_argument(
"--logpath", action="store_true", help="Print full path to last log file"
)
parser.add_argument(
"--print-log",
action="store_true",
help="Print content of last log without pagination",
)
parser.add_argument(
"--color",
type=supported_color,
metavar="COLOR",
help="Print output of table with the selected color.",
)
parser.add_argument(
"--no-color", help="Disable colored output", action="store_true"
)
parser.add_argument(
"--helpcolor",
action="store_true",
help="Print available color options in a table format.",
)
parser.add_argument("-r", "--report", help="Specify path to test report file")
parent_parser = argparse.ArgumentParser(add_help=False)
parent_parser.add_argument(
"--pager", action="store_true", help="Enable PAGING when viewing result"
)
subparsers = parser.add_subparsers(title="COMMANDS", dest="subcommands", metavar="")
build_menu(subparsers)
buildspec_menu(subparsers, parent_parser)
config_menu(subparsers, parent_parser)
report_menu(subparsers, parent_parser)
inspect_menu(subparsers, parent_parser)
path_menu(subparsers)
history_menu(subparsers, parent_parser)
schema_menu(subparsers)
cdash_menu(subparsers)
unittest_menu(subparsers)
stylecheck_menu(subparsers)
misc_menu(subparsers)
tutorial_examples_menu(subparsers)
return parser