|
| 1 | +import subprocess |
| 2 | +import sys |
| 3 | +from pathlib import Path |
| 4 | + |
| 5 | +INSTALL_PYTEST_INSTRUCTIONS = """ |
| 6 | +python -m venv .venv |
| 7 | +source .venv/bin/activate |
| 8 | +pip install pytest |
| 9 | +""" |
| 10 | + |
| 11 | + |
| 12 | +def check_for_pytest(): |
| 13 | + try: |
| 14 | + import pytest # pyright: ignore[reportMissingImports] # noqa: F401 |
| 15 | + except ImportError: |
| 16 | + print( |
| 17 | + "❌ No `pytest` installed.\nPlease install `pytest` first.\nRun the following commands, one by one:" |
| 18 | + ) |
| 19 | + |
| 20 | + |
| 21 | +def resolve_exercise_path(query: str) -> Path: |
| 22 | + target = Path(query) |
| 23 | + if target.exists(): |
| 24 | + return target |
| 25 | + |
| 26 | + # Exclude non-exercise folders |
| 27 | + IGNORED_DIRS = {"__pycache__"} |
| 28 | + |
| 29 | + matches = [] |
| 30 | + root = Path("./exercises") |
| 31 | + |
| 32 | + for sub_dir in root.iterdir(): |
| 33 | + if ( |
| 34 | + sub_dir.is_dir() |
| 35 | + and sub_dir.name not in IGNORED_DIRS |
| 36 | + and not sub_dir.name.startswith(".") |
| 37 | + ): |
| 38 | + matches.extend(sub_dir.glob(f"*{query}*")) |
| 39 | + |
| 40 | + dirs_only = [m for m in matches if m.is_dir()] |
| 41 | + |
| 42 | + if len(dirs_only) == 1: |
| 43 | + return dirs_only[0] |
| 44 | + elif len(dirs_only) > 1: |
| 45 | + print(f"⚠️ Ambiguous query '{query}'. Did you mean one of these?") |
| 46 | + for match in dirs_only: |
| 47 | + print(f" - {match}") |
| 48 | + sys.exit(1) |
| 49 | + |
| 50 | + print(f"❌ No exercise folder found for: '{query}'") |
| 51 | + sys.exit(1) |
| 52 | + |
| 53 | + |
| 54 | +def filter_for_excercises_only(exercise_path: Path): |
| 55 | + for path in exercise_path.iterdir(): |
| 56 | + if ( |
| 57 | + not path.is_dir() |
| 58 | + and not path.name.endswith("solution.py") |
| 59 | + and path.name.endswith(".py") |
| 60 | + and path.name.startswith("test_") |
| 61 | + ): |
| 62 | + print(f"Found: {path}") |
| 63 | + return path |
| 64 | + |
| 65 | + |
| 66 | +def main(): |
| 67 | + if len(sys.argv) < 2: |
| 68 | + print("Usage: python check.py <exercise-folder-or-number>") |
| 69 | + sys.exit(1) |
| 70 | + |
| 71 | + exercise_path = resolve_exercise_path(sys.argv[1]) |
| 72 | + excercise_only_tests = filter_for_excercises_only(exercise_path) |
| 73 | + |
| 74 | + # pytest test_<exercise_name>.py -v |
| 75 | + cmd = ["pytest", str(excercise_only_tests)] |
| 76 | + result = subprocess.run(cmd) |
| 77 | + |
| 78 | + if result.returncode == 0: |
| 79 | + print("\n✨ All tests passed! Great job!") |
| 80 | + |
| 81 | + |
| 82 | +if __name__ == "__main__": |
| 83 | + main() |
0 commit comments