Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add: added --check-include --checl-exclude and --show-failures flag #146

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
50 changes: 47 additions & 3 deletions gatorgrade/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,24 +45,68 @@ 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",
),
output_limit: int = typer.Option(
None,
"--output-limit",
"-l",
help="The maximum number of lines to store in an environment variable. Example: '--output-limit 1000'",
),
check_include: str = typer.Option(
None,
"--check-include",
"-i",
help="Description of the checks to include. Example: '--check-include \"Complete all TODOs\"'",
),
check_exclude: str = typer.Option(
None,
"--check-exclude",
"-e",
help="Description of the checks to exclude. Example: '--check-exclude \"Complete all TODOs\"'",
),
check_status: str = typer.Option(
None,
"--check-status",
"-s",
help="Filter checks by their status (pass or fail). Example: '--check-status pass'",
),
show_failures: bool = typer.Option(
False,
"--show-failures",
"-f",
help="Only show the failed checks.",
),
):
"""Run the GatorGrader checks in the specified gatorgrade.yml file."""
# if ctx.subcommand is None then this means
# that, by default, gatorgrade should run in checking mode
if ctx.invoked_subcommand is None:
# parse the provided configuration file
checks = parse_config(filename)
checks, match = parse_config(filename)
# 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, output_limit, check_status, show_failures
)
# no checks were created and this means
# that, most likely, the file was not
# valid and thus the tool cannot run checks
else:
checks_status = False
console.print()
console.print(f"The file {filename} either does not exist or is not valid.")
if match is False:
if check_include:
console.print(
f"The check {check_include} does not exist in the file {filename}."
)
if check_exclude:
console.print(
f"The check {check_exclude} does not exist in the file {filename}."
)
else:
console.print(
f"The file {filename} either does not exist or is not valid."
)
console.print("Exiting now!")
console.print()
# at least one of the checks did not pass or
Expand Down
120 changes: 83 additions & 37 deletions gatorgrade/output/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,13 +284,23 @@ def write_json_or_md_file(file_name, content_type, content):
) from e


from pathlib import Path
from typing import List, Union, Tuple


def run_checks(
checks: List[Union[ShellCheck, GatorGraderCheck]], report: Tuple[str, str, str]
checks: List[Union[ShellCheck, GatorGraderCheck]],
report: Tuple[str, str, str],
output_limit: int = None,
check_status: str = None,
show_failures: bool = False, # Added this parameter
check_include: str = None, # Added this parameter
check_exclude: str = None, # Added this parameter
) -> bool:
"""Run shell and GatorGrader checks and display whether each has passed or failed.

Also, print a list of all failed checks with their diagnostics and a summary message that
shows the overall fraction of passed checks.
Also, print a list of all failed checks with their diagnostics and a summary message that
shows the overall fraction of passed checks.

Args:
checks: The list of shell and GatorGrader checks to run.
Expand Down Expand Up @@ -330,49 +340,85 @@ def run_checks(
# there were results from running checks
# and thus they must be displayed
if result is not None:
result.print()
results.append(result)
if check_status:
if check_status == "pass" and result.passed:
result.print()
results.append(result)
elif check_status == "fail" and not result.passed:
result.print()
results.append(result)
else:
results.append(result)

# 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
# and print what ShellCheck command that Gatorgrade ran
if len(failed_results) > 0:
print("\n-~- FAILURES -~-\n")
for result in failed_results:
# main.console.print("This is a result")
# main.console.print(result)
result.print(show_diagnostic=True)
# this result is an instance of CheckResult
# that has a run_command field that is some
# value that is not the default of an empty
# string and thus it should be displayed;
# the idea is that displaying this run_command
# will give the person using Gatorgrade a way
# to quickly run the command that failed
if result.run_command != "":
rich.print(
f"[blue] → Run this command: [green]{result.run_command}\n"
)
# determine how many of the checks passed and then
# compute the total percentage of checks passed
passed_count = len(results) - len(failed_results)
# prevent division by zero if no results
if len(results) == 0:
percent = 0
if show_failures:
failed_results = list(filter(lambda result: not result.passed, results))
if len(failed_results) > 0:
print("\n-~- FAILURES -~-\n")
for result in failed_results:
# main.console.print("This is a result")
# main.console.print(result)
result.print(show_diagnostic=True)
# this result is an instance of CheckResult
# that has a run_command field that is some
# value that is not the default of an empty
# string and thus it should be displayed;
# the idea is that displaying this run_command
# will give the person using Gatorgrade a way
# to quickly run the command that failed
if result.run_command != "":
rich.print(
f"[blue] → Run this command: [green]{result.run_command}\n"
)
else:
print("No failures detected!")
for result in results:
result.print()
else:
percent = round(passed_count / len(results) * 100)
# if the report is wanted, create output in line with their specifications
if all(report):
report_output_data = create_report_json(passed_count, results, percent)
configure_report(report, report_output_data)
for result in results: # Print all results if show_failures is False
result.print()

# Check for included and excluded checks
if check_include or check_exclude:
filtered_results = results

if check_include:
filtered_results = [r for r in results if check_include in r.description]

if check_exclude:
filtered_results = [
r for r in filtered_results if check_exclude not in r.description
]

if len(filtered_results) > 0:
print("\n-~- INCLUDED / EXCLUDED CHECKS -~-\n")
for result in filtered_results:
if not result.passed:
result.print(
show_diagnostic=True
) # Show diagnostics for failing included/excluded checks
else:
result.print() # Print normally for passing checks

# compute summary results and display them in the console
summary = f"Passed {passed_count}/{len(results)} ({percent}%) of checks for {Path.cwd().name}!"
summary_color = "green" if passed_count == len(results) else "bright white"
# determine how many of the checks passed and then
# compute the total percentage of checks passed
failed_count = len([result for result in results if not result.passed])
passed_count = len(results) - failed_count
total = len(results)
percent = round((passed_count / total) * 100) if total > 0 else 0
summary = (
f"Passed {passed_count}/{total} ({percent}%) of checks for {Path.cwd().name}!"
)
summary_color = "green" if passed_count == total else "bright white"
print_with_border(summary, summary_color)

# determine whether or not the run was a success or not:
# if all of the tests pass then the function returns True;
# otherwise the function must return False
summary_status = True if passed_count == len(results) else False
summary_status = passed_count == total
return summary_status


Expand Down
Loading