diff --git a/gatorgrade/main.py b/gatorgrade/main.py index 42bbbd81..b9377b16 100644 --- a/gatorgrade/main.py +++ b/gatorgrade/main.py @@ -45,6 +45,14 @@ def gatorgrade( 3. the name of the file or environment variable\ 4. use 'env md GITHUB_STEP_SUMMARY' to create GitHub job summary in GitHub Action", ), + run_status_bar: bool = typer.Option( + False, + "--run_status_bar", + help="Enable a progress bar for checks running/not running.", + ), + no_status_bar: bool = typer.Option( + False, "--no_status_bar", help="Disable the progress bar entirely." + ), ): """Run the GatorGrader checks in the specified gatorgrade.yml file.""" # if ctx.subcommand is None then this means @@ -55,7 +63,7 @@ def gatorgrade( # there are valid checks and thus the # tool should run them with run_checks if len(checks) > 0: - checks_status = run_checks(checks, report) + checks_status = run_checks(checks, report, run_status_bar, no_status_bar) # no checks were created and this means # that, most likely, the file was not # valid and thus the tool cannot run checks diff --git a/gatorgrade/output/output.py b/gatorgrade/output/output.py index 8fc94c5b..2c356eb6 100644 --- a/gatorgrade/output/output.py +++ b/gatorgrade/output/output.py @@ -11,6 +11,9 @@ import gator import rich +from rich.progress import BarColumn +from rich.progress import Progress +from rich.progress import TextColumn from gatorgrade.input.checks import GatorGraderCheck from gatorgrade.input.checks import ShellCheck @@ -285,7 +288,10 @@ def write_json_or_md_file(file_name, content_type, content): def run_checks( - checks: List[Union[ShellCheck, GatorGraderCheck]], report: Tuple[str, str, str] + checks: List[Union[ShellCheck, GatorGraderCheck]], + report: Tuple[str, str, str], + running_mode=False, + no_status_bar=False, ) -> bool: """Run shell and GatorGrader checks and display whether each has passed or failed. @@ -294,44 +300,101 @@ def run_checks( Args: checks: The list of shell and GatorGrader checks to run. + running_mode: Convert the Progress Bar to update based on checks ran/not ran. + no_status_bar: Option to completely disable all Progress Bar options. """ results = [] # run each of the checks - for check in checks: - result = None - command_ran = None - # run a shell check; this means - # that it is going to run a command - # in the shell as a part of a check; - # store the command that ran in the - # field called run_command that is - # inside of a CheckResult object but - # not initialized in the constructor - if isinstance(check, ShellCheck): - result = _run_shell_check(check) - command_ran = check.command - result.run_command = command_ran - # run a check that GatorGrader implements - elif isinstance(check, GatorGraderCheck): - result = _run_gg_check(check) - # check to see if there was a command in the - # GatorGraderCheck. This code finds the index of the - # word "--command" in the check.gg_args list if it - # is available (it is not available for all of - # the various types of GatorGraderCheck instances), - # and then it adds 1 to that index to get the actual - # command run and then stores that command in the - # result.run_command field that is initialized to - # an empty string in the constructor for CheckResult - if "--command" in check.gg_args: - index_of_command = check.gg_args.index("--command") - index_of_new_command = int(index_of_command) + 1 - result.run_command = check.gg_args[index_of_new_command] - # there were results from running checks - # and thus they must be displayed - if result is not None: - result.print() - results.append(result) + # check how many tests are being ran + total_checks = len(checks) + # run checks with no progress bar + if no_status_bar: + for check in checks: + result = None + command_ran = None + # run a shell check; this means + # that it is going to run a command + # in the shell as a part of a check; + # store the command that ran in the + # field called run_command that is + # inside of a CheckResult object but + # not initialized in the constructor + if isinstance(check, ShellCheck): + result = _run_shell_check(check) + command_ran = check.command + result.run_command = command_ran + # run a check that GatorGrader implements + elif isinstance(check, GatorGraderCheck): + result = _run_gg_check(check) + # check to see if there was a command in the + # GatorGraderCheck. This code finds the index of the + # word "--command" in the check.gg_args list if it + # is available (it is not available for all of + # the various types of GatorGraderCheck instances), + # and then it adds 1 to that index to get the actual + # command run and then stores that command in the + # result.run_command field that is initialized to + # an empty string in the constructor for CheckResult + if "--command" in check.gg_args: + index_of_command = check.gg_args.index("--command") + index_of_new_command = int(index_of_command) + 1 + result.run_command = check.gg_args[index_of_new_command] + # there were results from running checks + # and thus they must be displayed + if result is not None: + result.print() + results.append(result) + else: + with Progress( + TextColumn("[progress.description]{task.description}"), + BarColumn( + bar_width=40, + style="red", + complete_style="green", + finished_style="green", + ), + TextColumn("[progress.percentage]{task.percentage:>3.0f}%"), + ) as progress: + # add a progress task for tracking + task = progress.add_task("[green]Running checks...", total=total_checks) + + # run each of the checks + for check in checks: + result = None + command_ran = None + + if isinstance(check, ShellCheck): + result = _run_shell_check(check) + command_ran = check.command + result.run_command = command_ran + # run a check that GatorGrader implements + elif isinstance(check, GatorGraderCheck): + result = _run_gg_check(check) + # check to see if there was a command in the + # GatorGraderCheck. This code finds the index of the + # word "--command" in the check.gg_args list if it + # is available (it is not available for all of + # the various types of GatorGraderCheck instances), + # and then it adds 1 to that index to get the actual + # command run and then stores that command in the + # result.run_command field that is initialized to + # an empty string in the constructor for CheckResult + if "--command" in check.gg_args: + index_of_command = check.gg_args.index("--command") + index_of_new_command = int(index_of_command) + 1 + result.run_command = check.gg_args[index_of_new_command] + # there were results from running checks + # and thus they must be displayed + if result is not None: + result.print() + results.append(result) + + # update progress based on running_mode + if running_mode: + progress.update(task, advance=1) + else: + if result and result.passed: + progress.update(task, advance=1) # determine if there are failures and then display them failed_results = list(filter(lambda result: not result.passed, results)) # print failures list if there are failures to print