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

Adds more projects description checks and refac to check everything per project #312

Merged
merged 5 commits into from
Jan 23, 2024
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/PRs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
python-version: "3.12"
- name: Install dependencies
run: |
python -m pip install pyyaml
python -m pip install pyyaml termcolor
- name: Run PR checker
run: |
python .github/workflows/pr_checker.py
94 changes: 76 additions & 18 deletions .github/workflows/pr_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import os
import itertools
import argparse
from typing import Dict, Set
from functools import cache
from termcolor import colored, cprint

here = os.path.dirname(__file__)
root = os.path.abspath(f'{here}/../../')
Expand All @@ -27,32 +30,87 @@ def ensure_all_yaml_files_are_valid(dry_run: bool = False):
raise e


@cache
def load_taxonomy():
with open(f"{root}/_data/taxonomy.yml", "r") as f:
t = yaml.safe_load(f)
return set(itertools.chain.from_iterable(map(lambda x: x["keywords"], t)))


def check_keywords_respect_taxonomy(projects_file: str, dry_run: bool = False):
def check_project_keywords_respect_taxonomy(project: Dict, dry_run: bool = False) -> bool:
allowed_keywords: set = load_taxonomy()
with open(projects_file, "r") as f:
projects = yaml.safe_load(f)
for project in projects:
if "keywords" in project:
project_keywords = set(project["keywords"])
unlisted_keywords = project_keywords.difference(allowed_keywords)
if len(unlisted_keywords) > 0:
if dry_run:
print(f"Unlisted keywords for project {project['name']}: {unlisted_keywords}")
else:
raise Exception(f"Unlisted keywords for project {project['name']}: {unlisted_keywords}")
else:
print(f"Project {project['name']} has no keywords")
if "keywords" in project:
project_keywords = set(project["keywords"])
unlisted_keywords = project_keywords.difference(allowed_keywords)
if len(project_keywords) == 0:
print(f"Project {project['name']} has no keywords")
return False
if len(unlisted_keywords) > 0:
print(f"Unlisted keywords for project {project['name']}: {unlisted_keywords}")
return False
else:
print(f"Project {project['name']} has no keywords")
return False
return True


if __name__ == "__main__":
@cache
def functionally_related_keywords() -> Set[str]:
with open(f"{root}/_data/taxonomy.yml", "r") as f:
t = yaml.safe_load(f)
return set(next(filter(lambda x: x["category"] == "Functionality", t))["keywords"])


def check_project_has_mandatory_fields(project: Dict, dry_run: bool = False) -> bool:
mandatory_fields = {
"name", "description", "code", "contact", "keywords", "community", "documentation", "testing",
"software_maturity",
"python3", "license"}

if len(mandatory_fields.difference(set(project.keys()))) > 0:
print(
f"Project {project['name']} misses mandatory fields: {mandatory_fields.difference(set(project.keys()))}")
return False
return True


def check_project_has_grades(project: Dict, dry_run: bool = False) -> bool:
grades = (["https://img.shields.io/badge/Requires%20improvement-red.svg", "Requires improvement"],
["https://img.shields.io/badge/Partially%20met-orange.svg", "Partially met"],
["https://img.shields.io/badge/Good-brightgreen.svg", "Good"])
fields_with_grades = {"community", "documentation", "testing", "software_maturity", "python3", "license"}
for field in fields_with_grades:
if field in project and project[field] not in grades:
print(f"Project {project['name']} deos not respect grades for field {field}, got {project[field]}")
return False
return True


def main():
dry_run = parser.parse_args().dry_run
ensure_all_yaml_files_are_valid(dry_run=dry_run)
check_keywords_respect_taxonomy(f"{root}/_data/projects_core.yml", dry_run=dry_run)
check_keywords_respect_taxonomy(f"{root}/_data/projects.yml", dry_run=dry_run)
check_keywords_respect_taxonomy(f"{root}/_data/projects_unevaluated.yml", dry_run=dry_run)
any_failed = False
for projects_file in (f"{root}/_data/projects.yml", f"{root}/_data/projects_core.yml"):
with open(projects_file, "r") as f:
projects = yaml.safe_load(f)
for project in projects:
print("-" * 80)
print(f"Checking project {project['name']} in file {projects_file}")
passes = all((
check_project_has_mandatory_fields(project),
check_project_keywords_respect_taxonomy(project),
check_project_has_grades(project)
))
if not passes:
print(colored(f"Project {project['name']} failed checks", "red"))
else:
print(colored(f"Project {project['name']} passed checks", "green"))
any_failed = any_failed or not passes
if any_failed:
exit(1)
else:
exit(0)


if __name__ == "__main__":
main()
2 changes: 1 addition & 1 deletion _data/projects.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
contact: "Lei Cai"
keywords: ["geospace","ionosphere_thermosphere_mesosphere","magnetosphere","data_retrieval","data_container","plotting","data_access", "data_analysis"]
community: ["https://img.shields.io/badge/Good-brightgreen.svg", "Good"]
documentation: ["https://img.shields.io/badge/Good-brightgreen.svg", "Partially met"]
documentation: ["https://img.shields.io/badge/Good-brightgreen.svg", "Good"]
testing: ["https://img.shields.io/badge/Good-brightgreen.svg", "Good"]
software_maturity: ["https://img.shields.io/badge/Good-brightgreen.svg", "Good"]
python3: ["https://img.shields.io/badge/Good-brightgreen.svg", "Good"]
Expand Down