55import re
66import shutil
77
8+
89def check_author_file (project_path : str ):
910 """
1011 :param project_path: The path of the project where you want to check the author file
@@ -62,14 +63,17 @@ def check_norme(project_path: str):
6263 print ("No source file (.c) or header (.h) to check" )
6364 return 1
6465 with open (os .path .dirname (os .path .realpath (__file__ )) + "/.mynorme" , 'w+' ) as file :
65- result = subprocess .run (['norminette' ] + files .split (), stdout = subprocess .PIPE ).stdout .decode ('utf-8' )
66- file .write (result )
67- error_count = result .count ('Error' )
68- warning_count = result .count ('Warning' )
69- if error_count != 0 and warning_count != 0 :
70- print ("Found {} errors and {} warnings" .format (error_count , warning_count ))
71- return 2
72- print ("Normed passed" )
66+ try :
67+ result = subprocess .run (['norminette' ] + files .split (), stdout = subprocess .PIPE , stderr = subprocess .STDOUT ).stdout .decode ('utf-8' )
68+ except FileNotFoundError :
69+ file .write ("Error: Norminette not found.\n " )
70+ else :
71+ file .write (result )
72+ error_count = result .count ('Error' )
73+ warning_count = result .count ('Warning' )
74+ if error_count != 0 and warning_count != 0 :
75+ print ("Found {} errors and {} warnings" .format (error_count , warning_count ))
76+ return 2
7377 return 0
7478
7579
@@ -78,7 +82,7 @@ def check_makefile_clean_dir(project_path: str, binary_name: str):
7882 file .write ("Cleaning Directory\n " )
7983 file .write ("*------------------------------------------------------*\n " )
8084 file .write ("" )
81- result = subprocess .run ('make ' + '-C ' + project_path + ' fclean' , shell = True , stdout = subprocess .PIPE ).stdout .decode ('utf-8' )
85+ result = subprocess .run ('make ' + '-C ' + project_path + ' fclean' , shell = True , stdout = subprocess .PIPE , stderr = subprocess . STDOUT ).stdout .decode ('utf-8' )
8286 file .write (result + '\n ' )
8387 if os .path .exists (project_path + '/' + binary_name ):
8488 file .write ("-> Error when processing rule `fclean': It should have removed {}\n " .format (binary_name ))
@@ -89,14 +93,14 @@ def check_makefile_clean_dir(project_path: str, binary_name: str):
8993
9094def check_makefile_all (project_path : str , binary_name : str ):
9195 makefile_path = project_path + '/Makefile'
92- with open (os .path .dirname (os .path .realpath (__file__ )) + "/.mymakefile" , 'w+ ' ) as file :
96+ with open (os .path .dirname (os .path .realpath (__file__ )) + "/.mymakefile" , 'a ' ) as file :
9397 file .write ("*------------------------------------------------------*\n " )
9498 file .write ("Checking rule: `all'\n " )
9599 if 'all: ' not in open (makefile_path ).read ():
96100 file .write ("-> Error: rule `all' not found in the Makefile.\n " )
97101 if 'all: $(NAME)' not in open (makefile_path ).read ():
98102 file .write ("-> Error: rule `all' should call the rule `$(NAME)'\n " )
99- result = subprocess .run ('make ' + '-C ' + project_path + ' all' , shell = True , stdout = subprocess .PIPE ).stdout .decode ('utf-8' )
103+ result = subprocess .run ('make ' + '-C ' + project_path + ' all' , shell = True , stdout = subprocess .PIPE , stderr = subprocess . STDOUT ).stdout .decode ('utf-8' )
100104 file .write (result + '\n ' )
101105 if not os .path .exists (project_path + '/' + binary_name ):
102106 file .write ("-> Error when processing rule `fclean': It should have created {}\n " .format (binary_name ))
@@ -107,15 +111,15 @@ def check_makefile_all(project_path: str, binary_name: str):
107111
108112def check_makefile_clean (project_path : str , binary_name : str ):
109113 makefile_path = project_path + '/Makefile'
110- with open (os .path .dirname (os .path .realpath (__file__ )) + "/.mymakefile" , 'w+ ' ) as file :
114+ with open (os .path .dirname (os .path .realpath (__file__ )) + "/.mymakefile" , 'a ' ) as file :
111115 file .write ("*------------------------------------------------------*\n " )
112116 file .write ("Checking rule: `clean'\n " )
113117 if 'clean: ' not in open (makefile_path ).read ():
114118 file .write ("-> Error: rule `clean' not found in the Makefile.\n " )
115119 if not os .path .exists (project_path + '/' + binary_name ):
116120 file .write ("-> Error: Cannot test rule `clean' because rule `all' failed\n " )
117121 # Stop the makefile test here
118- result = subprocess .run ('make ' + '-C ' + project_path + ' clean' , shell = True , stdout = subprocess .PIPE ).stdout .decode ('utf-8' )
122+ result = subprocess .run ('make ' + '-C ' + project_path + ' clean' , shell = True , stdout = subprocess .PIPE , stderr = subprocess . STDOUT ).stdout .decode ('utf-8' )
119123 file .write (result + '\n ' )
120124 if not os .path .exists (project_path + '/' + binary_name ):
121125 file .write ("-> Error: Failing Rule: It should not have cleaned the binary named {}." .format (binary_name ))
@@ -125,7 +129,7 @@ def check_makefile_clean(project_path: str, binary_name: str):
125129
126130def check_makefile_re (project_path : str , binary_name : str ):
127131 makefile_path = project_path + '/Makefile'
128- with open (os .path .dirname (os .path .realpath (__file__ )) + "/.mymakefile" , 'w+ ' ) as file :
132+ with open (os .path .dirname (os .path .realpath (__file__ )) + "/.mymakefile" , 'a ' ) as file :
129133 file .write ("*------------------------------------------------------*\n " )
130134 file .write ("Checking rule: `re'\n " )
131135 if 're: ' not in open (makefile_path ).read ():
@@ -134,7 +138,7 @@ def check_makefile_re(project_path: str, binary_name: str):
134138 file .write ("-> Error: Cannot test rule `re' because rule `all' failed\n " )
135139 inode1 = os .stat (project_path + '/' + binary_name ).st_ino
136140 file .write ("-- Before running rule `re', the {} inode is {}\n " .format (binary_name , inode1 ))
137- result = subprocess .run ('make ' + '-C ' + project_path + ' re' , shell = True , stdout = subprocess .PIPE ).stdout .decode ('utf-8' )
141+ result = subprocess .run ('make ' + '-C ' + project_path + ' re' , shell = True , stdout = subprocess .PIPE , stderr = subprocess . STDOUT ).stdout .decode ('utf-8' )
138142 file .write (result + '\n ' )
139143 inode2 = os .stat (project_path + '/' + binary_name ).st_ino
140144 file .write ("-- After running rule `re', the {} inode is {}\n " .format (binary_name , inode2 ))
@@ -148,12 +152,12 @@ def check_makefile_re(project_path: str, binary_name: str):
148152
149153def check_makefile_fclean (project_path : str , binary_name : str ):
150154 makefile_path = project_path + '/Makefile'
151- with open (os .path .dirname (os .path .realpath (__file__ )) + "/.mymakefile" , 'w+ ' ) as file :
155+ with open (os .path .dirname (os .path .realpath (__file__ )) + "/.mymakefile" , 'a ' ) as file :
152156 file .write ("*------------------------------------------------------*\n " )
153157 file .write ("Checking rule: `fclean'\n " )
154158 if 'fclean: ' not in open (makefile_path ).read ():
155159 file .write ("-> Error: rule `fclean' not found in the Makefile.\n " )
156- result = subprocess .run ('make ' + '-C ' + project_path + ' fclean' , shell = True , stdout = subprocess .PIPE ).stdout .decode ('utf-8' )
160+ result = subprocess .run ('make ' + '-C ' + project_path + ' fclean' , shell = True , stdout = subprocess .PIPE , stderr = subprocess . STDOUT ).stdout .decode ('utf-8' )
157161 file .write (result + '\n ' )
158162 if os .path .exists (project_path + '/' + binary_name ):
159163 file .write ("--> Error when processing rule `re': It should have removed the binary named {}\n " .format (binary_name ))
@@ -165,12 +169,12 @@ def check_makefile_fclean(project_path: str, binary_name: str):
165169
166170def check_makefile_name (project_path : str , binary_name : str ):
167171 makefile_path = project_path + '/Makefile'
168- with open (os .path .dirname (os .path .realpath (__file__ )) + "/.mymakefile" , 'w+ ' ) as file :
172+ with open (os .path .dirname (os .path .realpath (__file__ )) + "/.mymakefile" , 'a ' ) as file :
169173 file .write ("*------------------------------------------------------*\n " )
170174 file .write ("Checking rule: `$(NAME)'\n " )
171175 if '$(NAME):' not in open (makefile_path ).read ():
172176 file .write ("-> Error: rule `$(NAME)' not found in the Makefile.\n " )
173- result = subprocess .run ('make ' + '-C ' + project_path + ' ' + binary_name , shell = True , stdout = subprocess .PIPE ).stdout .decode ('utf-8' )
177+ result = subprocess .run ('make ' + '-C ' + project_path + ' ' + binary_name , shell = True , stdout = subprocess .PIPE , stderr = subprocess . STDOUT ).stdout .decode ('utf-8' )
174178 file .write (result + '\n ' )
175179 if not os .path .exists (project_path + '/' + binary_name ):
176180 file .write ("--> Error when processing rule `re': It should have compiled a binary named {}\n " .format (binary_name ))
@@ -181,14 +185,14 @@ def check_makefile_name(project_path: str, binary_name: str):
181185
182186def check_makefile_phony (project_path : str , binary_name : str ):
183187 makefile_path = project_path + '/Makefile'
184- with open (os .path .dirname (os .path .realpath (__file__ )) + "/.mymakefile" , 'w+ ' ) as file :
188+ with open (os .path .dirname (os .path .realpath (__file__ )) + "/.mymakefile" , 'a ' ) as file :
185189 file .write ("*------------------------------------------------------*\n " )
186190 file .write ("Checking rule: `.PHONY'\n " )
187191 if '.PHONY:' not in open (makefile_path ).read ():
188192 file .write ("-> Error: rule `.PHONY' not found in the Makefile.\n " )
189193 if not os .path .exists (project_path + '/' + binary_name ):
190194 file .write ("-> Error: Cannot test rule `re' because rule `$(NAME)' failed\n " )
191- result = subprocess .run ('make ' + '-C ' + project_path + ' .PHONY' , shell = True , stdout = subprocess .PIPE ).stdout .decode ('utf-8' )
195+ result = subprocess .run ('make ' + '-C ' + project_path + ' .PHONY' , shell = True , stdout = subprocess .PIPE , stderr = subprocess . STDOUT ).stdout .decode ('utf-8' )
192196 file .write (result + '\n ' )
193197 if not os .path .exists (project_path + '/' + binary_name ):
194198 file .write ("--> Error when processing rule `.PHONY': It should not have cleaned the binary named {}\n " .format (binary_name ))
@@ -240,16 +244,17 @@ def check_42_commandements(project_path:str):
240244
241245def check_forbidden_functions (project_path : str , binary : str , authorized_functions ):
242246 functions_called = []
243- result = subprocess .run (['nm' , project_path + '/' + binary ], stdout = subprocess .PIPE ).stdout .decode ('utf-8' )
247+ result = subprocess .run (['nm' , project_path + '/' + binary ], stdout = subprocess .PIPE , stderr = subprocess . STDOUT ).stdout .decode ('utf-8' )
244248 for line in result .splitlines ():
245- if "U _ " in line :
249+ if "U " in line :
246250 functions_called .append (re .sub (' +' , ' ' , line ))
247- sys_calls = {function .replace (' U _ ' , '' ) for function in functions_called }
251+ sys_calls = {function .replace (' U ' , '' ) for function in functions_called }
248252 sys_calls = [item for item in sys_calls if not item .startswith ("ft_" )]
249253 extra_function_call = [item for item in sys_calls if item not in authorized_functions ]
250254 with open (os .path .dirname (os .path .realpath (__file__ )) + "/.myforbiddenfunctions" , 'w+' ) as file :
251255 for item in extra_function_call :
252- file .write ("You should justify the use of this function: `{}'\n " .format (item ))
256+ if not item .startswith ("__" ): #This is to ignore functions like `stack_chk_fail'
257+ file .write ("You should justify the use of this function: `{}'\n " .format (item ))
253258 return 0
254259
255260
@@ -265,8 +270,14 @@ def run_libftest(project_path: str):
265270 with open ('libftest/my_config.sh' , 'w' ) as file :
266271 file .write (filedata )
267272 # @todo Parse libftest output for UI and parse score for display and return values.
268- subprocess .run (['bash' , "libftest/grademe.sh" , "-s -f -n -u" ])
273+ result = subprocess .run (['bash' , "libftest/grademe.sh" , "-l - s -f -n -u" ], stdout = subprocess . PIPE , stderr = subprocess . STDOUT ). stdout . decode ( 'utf-8' )
269274 os .rename ("deepthought" , ".mylibftest" )
275+ with open (os .path .dirname (os .path .realpath (__file__ )) + "/.mylibftest" , 'a' ) as file :
276+ file .write ("\n \n \n \n \n \n \n \n \n *------------------------------------------------------*\n " )
277+ file .write ("LIBFTEST\n " )
278+ file .write ("Warning: This file contains escape sequences. Please use `cat' to view it properly.\n " )
279+ file .write ("*------------------------------------------------------*\n " )
280+ file .write (result )
270281 return 0
271282
272283
@@ -301,12 +312,13 @@ def exec_moulitest(test_name: str):
301312 file .write ("Warning: This file contains escape sequences. Please use `cat' to view it properly.\n " )
302313 file .write ("*------------------------------------------------------*\n " )
303314 # @todo Get the result line of moulitest and parse it.
304- result = subprocess .run ('make ' + test_name + ' -C ' + 'moulitest' + ' 2>&1' , shell = True , stdout = subprocess .PIPE ).stdout .decode ('utf-8' )
315+ result = subprocess .run ('make ' + test_name + ' -C ' + 'moulitest' , shell = True , stdout = subprocess .PIPE , stderr = subprocess . STDOUT ).stdout .decode ('utf-8' )
305316 file .write (result + '\n ' )
306317
307318
308319def run_moulitest (project_path : str , has_libft_bonuses : bool , project : str ):
309320 available_projects = ['ft_ls' , 'ft_printf' , 'gnl' , 'libft' , 'libftasm' ]
321+ # Available projects checks if the given project corresponds to one the moulitest tests.
310322 if project not in available_projects :
311323 raise ValueError ("given project not in moulitest available projects." )
312324 if project == "libft" :
@@ -316,10 +328,10 @@ def run_moulitest(project_path: str, has_libft_bonuses: bool, project: str):
316328 # @todo Fix moulitest makefile (it starts the bonus even when not asked.)
317329 if not has_libft_bonuses :
318330 moulitest_exclude_libft_bonuses ()
319- exec_moulitest ("libft_bonus " )
331+ exec_moulitest ("libft_part2 " )
320332 moulitest_include_libft_bonuses ()
321333 else :
322- exec_moulitest ("libft_bonus " )
334+ exec_moulitest ("libft_part2 " )
323335 return 0
324336
325337
@@ -356,9 +368,9 @@ def run_maintest(project_path: str):
356368 file .write ("MAINTEST\n " )
357369 file .write ("Warning: This file contains escape sequences. Please use `cat' to view it properly.\n " )
358370 file .write ("*------------------------------------------------------*\n " )
359- result = subprocess .run (['gcc' , 'libft_main.c' , '-L' + project_path , '-I' + project_path , "-I" + project_path + "/include" , "-I" + project_path + "/includes" , "-lft" , "-o" , "libft_main.out" ], stdout = subprocess .PIPE ).stdout .decode ('utf-8' )
371+ result = subprocess .run (['gcc' , 'libft_main.c' , '-L' + project_path , '-I' + project_path , "-I" + project_path + "/include" , "-I" + project_path + "/includes" , "-lft" , "-o" , "libft_main.out" ], stdout = subprocess .PIPE , stderr = subprocess . STDOUT ).stdout .decode ('utf-8' )
360372 file .write (result + '\n ' )
361- result = subprocess .run (['./libft_main.out' ], stdout = subprocess .PIPE ).stdout .decode ('utf-8' )
373+ result = subprocess .run (['./libft_main.out' ], stdout = subprocess .PIPE , stderr = subprocess . STDOUT ).stdout .decode ('utf-8' )
362374 # @todo: Count number of OK and FAILs and yellow tests to get score for maintest
363375 file .write (result + '\n ' )
364376
@@ -411,9 +423,11 @@ def check_libft(project_path: str):
411423 check_makefile (project_path , "libft.a" )
412424 check_forbidden_functions (project_path , "libft.a" , authorized_functions )
413425 run_libftest (project_path )
426+
414427 run_moulitest (project_path , has_libft_bonuses , "libft" )
415428 # @todo add libft-unit-test to the testing suite
416429 run_maintest (project_path )
417430 return 0
418431
419- sys .exit (run_maintest ("/tmp/libft" ))
432+
433+ sys .exit (check_libft ("/tmp/libft" ))
0 commit comments