1- import os
1+ import tempfile
2+ from pathlib import Path
23from typing import List
34
5+ from git import Repo
46from git_autograder import (
57 GitAutograderExercise ,
68 GitAutograderOutput ,
1921NOT_PATTERN_MATCHING_RUNAWAY = (
2022 "You should be using ** to match all subfolders to ignore runaway.txt."
2123)
24+ MISSING_GITIGNORE = "You are missing the .gitignore file! Try to reset the exercise using gitmastery progress reset"
2225
2326
2427def verify (exercise : GitAutograderExercise ) -> GitAutograderOutput :
@@ -27,36 +30,48 @@ def verify(exercise: GitAutograderExercise) -> GitAutograderOutput:
2730 if len (main_branch .user_commits ) == 0 :
2831 raise exercise .wrong_answer ([MISSING_COMMITS ])
2932
30- main_branch .latest_commit .checkout ()
33+ with main_branch .latest_commit .file (".gitignore" ) as gitignore_file :
34+ if gitignore_file is None :
35+ raise exercise .wrong_answer ([MISSING_GITIGNORE ])
36+ gitignore_file_contents = gitignore_file
3137
32- # Read the file and parse it
33- with open (
34- os .path .join (exercise .repo .repo_path , ".gitignore" ), "r"
35- ) as gitignore_file :
36- lines = [
37- line .strip () for line in gitignore_file .readlines () if line .strip () != ""
38+ # Verify the state of the ignore by recreating the necessary files and checking if
39+ # Git ignores them directly in a separate temporary Git repository
40+ with tempfile .TemporaryDirectory () as tmpdir :
41+ tmp_path = Path (tmpdir )
42+ (tmp_path / ".gitignore" ).write_text (gitignore_file_contents )
43+
44+ simulated_files = [
45+ "many/file22.txt" ,
46+ "why_am_i_hidden.txt" ,
47+ "ignore_me.txt" ,
48+ "this/is/very/nested/runaway.txt" ,
3849 ]
50+ for file in simulated_files :
51+ (tmp_path / file ).parent .mkdir (parents = True , exist_ok = True )
52+ (tmp_path / file ).touch ()
3953
40- comments : List [str ] = []
41- if "!many/file22.txt" not in lines :
42- comments .append (STILL_IGNORING_FILE_22 )
54+ test_repo : Repo = Repo .init (tmp_path )
55+ ignored = {f for f in simulated_files if test_repo .ignored (f )}
4356
44- if "why_am_i_hidden.txt" in lines :
45- comments .append (STILL_HIDING )
57+ comments : List [str ] = []
58+ if "many/file22.txt" in ignored :
59+ comments .append (STILL_IGNORING_FILE_22 )
4660
47- if "ignore_me .txt" not in lines :
48- comments .append (NOT_IGNORING_IGNORE_ME )
61+ if "why_am_i_hidden .txt" in ignored :
62+ comments .append (STILL_HIDING )
4963
50- if "this/is/very/nested/runaway.txt" in lines :
51- comments .append (NOT_PATTERN_MATCHING_RUNAWAY )
52- elif "this/**/runaway.txt" not in lines :
53- comments .append (NOT_IGNORING_RUNAWAY )
64+ if "ignore_me.txt" not in ignored :
65+ comments .append (NOT_IGNORING_IGNORE_ME )
5466
55- main_branch .checkout ()
67+ if "this/is/very/nested/runaway.txt" not in ignored :
68+ comments .append (NOT_IGNORING_RUNAWAY )
69+ elif "this/**/runaway.txt" not in gitignore_file_contents .splitlines ():
70+ comments .append (NOT_PATTERN_MATCHING_RUNAWAY )
5671
57- if comments :
58- raise exercise .wrong_answer (comments )
72+ if comments :
73+ raise exercise .wrong_answer (comments )
5974
60- return exercise .to_output (
61- ["Great work using .gitignore!" ], status = GitAutograderStatus .SUCCESSFUL
62- )
75+ return exercise .to_output (
76+ ["Great work using .gitignore!" ], status = GitAutograderStatus .SUCCESSFUL
77+ )
0 commit comments