11#!/usr/bin/env python3
22import importlib .util
33import json
4+ import os
45import pathlib
56from types import ModuleType
67from typing import Dict , List
78
89import pytest
10+ import requests
911
1012PROJECT_EULER_DIR_PATH = pathlib .Path .cwd ().joinpath ("project_euler" )
1113PROJECT_EULER_ANSWERS_PATH = pathlib .Path .cwd ().joinpath (
@@ -24,7 +26,7 @@ def convert_path_to_module(file_path: pathlib.Path) -> ModuleType:
2426 return module
2527
2628
27- def collect_solution_file_paths () -> List [pathlib .Path ]:
29+ def all_solution_file_paths () -> List [pathlib .Path ]:
2830 """Collects all the solution file path in the Project Euler directory"""
2931 solution_file_paths = []
3032 for problem_dir_path in PROJECT_EULER_DIR_PATH .iterdir ():
@@ -37,12 +39,51 @@ def collect_solution_file_paths() -> List[pathlib.Path]:
3739 return solution_file_paths
3840
3941
42+ def get_files_url () -> str :
43+ """Return the pull request number which triggered this action."""
44+ with open (os .environ ["GITHUB_EVENT_PATH" ]) as file :
45+ event = json .load (file )
46+ return event ["pull_request" ]["url" ] + "/files"
47+
48+
49+ def added_solution_file_path () -> List [pathlib .Path ]:
50+ """Collects only the solution file path which got added in the current
51+ pull request.
52+
53+ This will only be triggered if the script is ran from GitHub Actions.
54+ """
55+ solution_file_paths = []
56+ headers = {
57+ "Accept" : "application/vnd.github.v3+json" ,
58+ "Authorization" : "token " + os .environ ["GITHUB_TOKEN" ],
59+ }
60+ files = requests .get (get_files_url (), headers = headers ).json ()
61+ for file in files :
62+ filepath = pathlib .Path .cwd ().joinpath (file ["filename" ])
63+ if (
64+ filepath .suffix != ".py"
65+ or filepath .name .startswith (("_" , "test" ))
66+ or not filepath .name .startswith ("sol" )
67+ ):
68+ continue
69+ solution_file_paths .append (filepath )
70+ return solution_file_paths
71+
72+
73+ def collect_solution_file_paths () -> List [pathlib .Path ]:
74+ if os .environ .get ("CI" ) and os .environ .get ("GITHUB_EVENT_NAME" ) == "pull_request" :
75+ # Return only if there are any, otherwise default to all solutions
76+ if filepaths := added_solution_file_path ():
77+ return filepaths
78+ return all_solution_file_paths ()
79+
80+
4081@pytest .mark .parametrize (
4182 "solution_path" ,
4283 collect_solution_file_paths (),
4384 ids = lambda path : f"{ path .parent .name } /{ path .name } " ,
4485)
45- def test_project_euler (solution_path : pathlib .Path ):
86+ def test_project_euler (solution_path : pathlib .Path ) -> None :
4687 """Testing for all Project Euler solutions"""
4788 # problem_[extract this part] and pad it with zeroes for width 3
4889 problem_number : str = solution_path .parent .name [8 :].zfill (3 )
0 commit comments