@@ -303,29 +303,7 @@ fn get_exercises(
303303 let name = exercise_dir. to_string_lossy ( ) . replace ( "/" , "-" ) ;
304304
305305 // checksum
306- let mut digest = Context :: new ( ) ;
307- for entry in WalkDir :: new ( course_stub_path. join ( & exercise_dir) )
308- . sort_by ( |a, b| a. file_name ( ) . cmp ( b. file_name ( ) ) )
309- . into_iter ( )
310- . filter_entry ( |e| {
311- !e. file_name ( )
312- . to_str ( )
313- . map ( |e| e. starts_with ( '.' ) )
314- . unwrap_or_default ( )
315- } )
316- {
317- let entry = entry?;
318- if entry. path ( ) . is_file ( ) {
319- let relative = entry. path ( ) . strip_prefix ( course_stub_path) . unwrap ( ) ;
320- digest. consume ( relative. as_os_str ( ) . to_string_lossy ( ) . into_owned ( ) ) ;
321- let file = file_util:: read_file ( entry. path ( ) ) ?;
322- digest. consume ( file) ;
323- }
324- }
325-
326- // convert the digest into a hex string
327- let digest = digest. compute ( ) ;
328- let checksum = format ! ( "{:x}" , digest) ;
306+ let checksum = calculate_checksum ( & course_stub_path. join ( & exercise_dir) ) ?;
329307
330308 let exercise_path = course_clone_path. join ( & exercise_dir) ;
331309 let points = task_executor:: get_available_points ( & exercise_path) ?;
@@ -341,6 +319,37 @@ fn get_exercises(
341319 Ok ( exercises)
342320}
343321
322+ fn calculate_checksum ( exercise_dir : & Path ) -> Result < String , UtilError > {
323+ let mut digest = Context :: new ( ) ;
324+
325+ for entry in WalkDir :: new ( exercise_dir)
326+ . sort_by ( |a, b| a. file_name ( ) . cmp ( b. file_name ( ) ) ) // order filenames for a consistent hash
327+ . into_iter ( )
328+ . filter_entry ( |e| {
329+ // filter out files starting with '.'
330+ !e. file_name ( )
331+ . to_str ( )
332+ . map ( |e| e. starts_with ( '.' ) )
333+ . unwrap_or_default ( )
334+ } )
335+ {
336+ let entry = entry?;
337+ let relative = entry. path ( ) . strip_prefix ( exercise_dir) . unwrap ( ) ;
338+ let string = relative. as_os_str ( ) . to_string_lossy ( ) ;
339+ log:: debug!( "updating {}" , string) ;
340+ digest. consume ( string. as_ref ( ) ) ;
341+ if entry. path ( ) . is_file ( ) {
342+ log:: debug!( "updating with file" ) ;
343+ let file = file_util:: read_file ( entry. path ( ) ) ?;
344+ digest. consume ( file) ;
345+ }
346+ }
347+
348+ // convert the digest into a hex string
349+ let digest = digest. compute ( ) ;
350+ Ok ( format ! ( "{:x}" , digest) )
351+ }
352+
344353fn execute_zip (
345354 course_exercises : & [ RefreshExercise ] ,
346355 root_path : & Path ,
@@ -409,6 +418,7 @@ mod test {
409418
410419 use super :: * ;
411420 use serde_yaml:: Value ;
421+ use task_executor:: find_exercise_directories;
412422 use tempfile:: tempdir;
413423
414424 fn init ( ) {
@@ -544,8 +554,13 @@ courses:
544554 "course/part1/ex1/test/test.py" ,
545555 "@points('1') @points('2')" ,
546556 ) ;
547- let exercises =
548- get_exercises ( & temp. path ( ) . join ( "course" ) , & temp. path ( ) . join ( "course" ) ) . unwrap ( ) ;
557+ let exercise_dirs = find_exercise_directories ( & temp. path ( ) . join ( "course" ) ) . unwrap ( ) ;
558+ let exercises = get_exercises (
559+ exercise_dirs,
560+ & temp. path ( ) . join ( "course" ) ,
561+ & temp. path ( ) . join ( "course" ) ,
562+ )
563+ . unwrap ( ) ;
549564 assert_eq ! ( exercises. len( ) , 1 ) ;
550565 assert_eq ! ( exercises[ 0 ] . path, Path :: new( "part1/ex1" ) ) ;
551566 assert_eq ! ( exercises[ 0 ] . points. len( ) , 2 ) ;
@@ -572,8 +587,13 @@ courses:
572587 file_to ( & temp, "stub/part2/ex2/dir/subdir/file" , "some file" ) ;
573588 file_to ( & temp, "stub/part2/ex2/dir/subdir/.hidden" , "hidden file" ) ;
574589
575- let exercises =
576- get_exercises ( & temp. path ( ) . join ( "clone" ) , & temp. path ( ) . join ( "stub" ) ) . unwrap ( ) ;
590+ let exercise_dirs = find_exercise_directories ( & temp. path ( ) . join ( "clone" ) ) . unwrap ( ) ;
591+ let exercises = get_exercises (
592+ exercise_dirs,
593+ & temp. path ( ) . join ( "clone" ) ,
594+ & temp. path ( ) . join ( "stub" ) ,
595+ )
596+ . unwrap ( ) ;
577597
578598 execute_zip ( & exercises, & temp. path ( ) . join ( "stub" ) , temp. path ( ) ) . unwrap ( ) ;
579599
@@ -622,4 +642,14 @@ courses:
622642
623643 set_permissions ( temp. path ( ) ) . unwrap ( ) ;
624644 }
645+
646+ #[ test]
647+ fn checksum_matches_old_implementation ( ) {
648+ init ( ) ;
649+
650+ let checksum =
651+ calculate_checksum ( Path :: new ( "tests/data/course_refresher/valid_exercises/ex1" ) )
652+ . unwrap ( ) ;
653+ assert_eq ! ( checksum, "1830118f2570f3448c0e096a7369b127" ) ;
654+ }
625655}
0 commit comments