@@ -352,7 +352,27 @@ fn execute_zip(
352352
353353 let mut writer = zip:: ZipWriter :: new ( file_util:: create_file ( zip_file_path) ?) ;
354354
355- for entry in WalkDir :: new ( & exercise_root) {
355+ // hidden files are filtered, so we handle .tmcproject.yml here
356+ let tmcproject_yml_path = exercise_root. join ( ".tmcproject.yml" ) ;
357+ if tmcproject_yml_path. exists ( ) {
358+ let tmcproject_yml = file_util:: read_file ( & tmcproject_yml_path) ?;
359+ let relative_path = tmcproject_yml_path. strip_prefix ( & root_path) . unwrap ( ) ; // safe
360+ writer. start_file (
361+ relative_path. to_string_lossy ( ) ,
362+ zip:: write:: FileOptions :: default ( ) ,
363+ ) ?;
364+ writer
365+ . write_all ( & tmcproject_yml)
366+ . map_err ( LangsError :: ZipWrite ) ?;
367+ }
368+ for entry in WalkDir :: new ( & exercise_root) . into_iter ( ) . filter_entry ( |e| {
369+ !e. file_name ( )
370+ . to_str ( )
371+ . map ( |e| e. starts_with ( '.' ) )
372+ . unwrap_or_default ( )
373+ } )
374+ // filter hidden
375+ {
356376 let entry = entry?;
357377 let relative_path = entry. path ( ) . strip_prefix ( & root_path) . unwrap ( ) ; // safe
358378
@@ -523,12 +543,14 @@ mod test {
523543 file_to ( & temp, "clone/part2/ex1/setup.py" , "" ) ;
524544 file_to ( & temp, "clone/part2/ex2/setup.py" , "" ) ;
525545 file_to ( & temp, "clone/part2/ex2/dir/subdir/file" , "" ) ;
546+ file_to ( & temp, "clone/part2/ex2/dir/subdir/.hidden" , "" ) ;
526547 file_to ( & temp, "clone/part2/ex2/.tmcproject.yml" , "some: 'yaml'" ) ;
527548 file_to ( & temp, "stub/part1/ex1/setup.py" , "" ) ;
528549 file_to ( & temp, "stub/part1/ex2/setup.py" , "" ) ;
529550 file_to ( & temp, "stub/part2/ex1/setup.py" , "" ) ;
530551 file_to ( & temp, "stub/part2/ex2/setup.py" , "" ) ;
531552 file_to ( & temp, "stub/part2/ex2/dir/subdir/file" , "some file" ) ;
553+ file_to ( & temp, "stub/part2/ex2/dir/subdir/.hidden" , "hidden file" ) ;
532554 file_to ( & temp, "stub/part2/ex2/.tmcproject.yml" , "some: 'yaml'" ) ;
533555
534556 let exercise_dirs = find_exercise_directories ( & temp. path ( ) . join ( "clone" ) )
@@ -565,6 +587,16 @@ mod test {
565587 for i in fz. file_names ( ) {
566588 log:: debug!( "{}" , i) ;
567589 }
590+ assert ! ( fz
591+ . by_name(
592+ & Path :: new( "part2" )
593+ . join( "ex2" )
594+ . join( "dir" )
595+ . join( "subdir" )
596+ . join( ".hidden" )
597+ . to_string_lossy( )
598+ )
599+ . is_err( ) ) ; // hidden files filtered
568600 assert ! ( fz
569601 . by_name(
570602 & Path :: new( "part2" )
0 commit comments