@@ -26,6 +26,7 @@ use std::{
2626 path:: { Path , PathBuf } ,
2727} ;
2828use tmc_langs:: {
29+ file_util:: { self , Lock , LockOptions } ,
2930 file_util,
3031 mooc:: MoocClient ,
3132 tmc:: { request:: FeedbackAnswer , TestMyCodeClient , TestMyCodeClientError } ,
@@ -180,14 +181,18 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
180181 locale : Locale ( locale) ,
181182 output_path,
182183 } => {
183- file_util:: lock!( exercise_path) ;
184+ let mut lock = Lock :: dir ( & exercise_path, LockOptions :: Read ) ?;
185+ let _guard = lock. lock ( ) ?;
186+
184187 let check_result =
185188 run_checkstyle_write_results ( & exercise_path, output_path. as_deref ( ) , locale) ?;
186189 CliOutput :: finished_with_data ( "ran checkstyle" , check_result. map ( DataKind :: Validation ) )
187190 }
188191
189192 Command :: Clean { exercise_path } => {
190- file_util:: lock!( exercise_path) ;
193+ let mut lock = Lock :: dir ( & exercise_path, LockOptions :: Write ) ?;
194+ let _guard = lock. lock ( ) ?;
195+
191196 tmc_langs:: clean ( & exercise_path) ?;
192197 CliOutput :: finished ( format ! ( "cleaned exercise at {}" , exercise_path. display( ) ) )
193198 }
@@ -199,7 +204,9 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
199204 deterministic,
200205 naive,
201206 } => {
202- file_util:: lock!( exercise_path) ;
207+ let mut lock = Lock :: dir ( & exercise_path, LockOptions :: Read ) ?;
208+ let _guard = lock. lock ( ) ?;
209+
203210 let hash = tmc_langs:: compress_project_to (
204211 & exercise_path,
205212 & output_path,
@@ -227,11 +234,11 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
227234 compression,
228235 naive,
229236 } => {
230- let mut archive = file_util :: open_file_locked ( & archive_path) ?;
231- let mut guard = archive . write ( ) ?;
237+ let mut archive_lock = Lock :: file ( & archive_path, LockOptions :: Read ) ?;
238+ let mut archive_guard = archive_lock . lock ( ) ?;
232239
233240 let mut data = vec ! [ ] ;
234- guard . read_to_end ( & mut data) ?;
241+ archive_guard . get_file_mut ( ) . read_to_end ( & mut data) ?;
235242
236243 tmc_langs:: extract_project ( Cursor :: new ( data) , & output_path, compression, true , naive) ?;
237244
@@ -243,7 +250,9 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
243250 }
244251
245252 Command :: FastAvailablePoints { exercise_path } => {
246- file_util:: lock!( exercise_path) ;
253+ let mut lock = Lock :: dir ( & exercise_path, LockOptions :: Read ) ?;
254+ let _guard = lock. lock ( ) ?;
255+
247256 let points = tmc_langs:: get_available_points ( & exercise_path) ?;
248257 CliOutput :: finished_with_data (
249258 format ! ( "found {} available points" , points. len( ) ) ,
@@ -255,7 +264,9 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
255264 search_path,
256265 output_path,
257266 } => {
258- file_util:: lock!( search_path) ;
267+ let mut lock = Lock :: dir ( & search_path, LockOptions :: Read ) ?;
268+ let _guard = lock. lock ( ) ?;
269+
259270 let exercises =
260271 tmc_langs:: find_exercise_directories ( & search_path) . with_context ( || {
261272 format ! (
@@ -276,7 +287,9 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
276287 exercise_path,
277288 output_path,
278289 } => {
279- file_util:: lock!( exercise_path) ;
290+ let mut lock = Lock :: dir ( & exercise_path, LockOptions :: Read ) ?;
291+ let _guard = lock. lock ( ) ?;
292+
280293 let config = tmc_langs:: get_exercise_packaging_configuration ( & exercise_path)
281294 . with_context ( || {
282295 format ! (
@@ -313,7 +326,9 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
313326 exercise_path,
314327 output_path,
315328 } => {
316- file_util:: lock!( exercise_path) ;
329+ let mut lock = Lock :: dir ( & exercise_path, LockOptions :: Read ) ?;
330+ let _guard = lock. lock ( ) ?;
331+
317332 tmc_langs:: prepare_solution ( & exercise_path, & output_path) . with_context ( || {
318333 format ! (
319334 "Failed to prepare solutions for exercise at {}" ,
@@ -331,7 +346,9 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
331346 exercise_path,
332347 output_path,
333348 } => {
334- file_util:: lock!( exercise_path) ;
349+ let mut lock = Lock :: dir ( & exercise_path, LockOptions :: Read ) ?;
350+ let _guard = lock. lock ( ) ?;
351+
335352 tmc_langs:: prepare_stub ( & exercise_path, & output_path) . with_context ( || {
336353 format ! (
337354 "Failed to prepare stubs for exercise at {}" ,
@@ -357,6 +374,9 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
357374 tmc_param,
358375 no_archive_prefix,
359376 } => {
377+ let mut clone_lock = Lock :: dir ( & clone_path, file_util:: LockOptions :: Read ) ?;
378+ let _clone_guard = clone_lock. lock ( ) ?;
379+
360380 // will contain for each key all the values with that key in a list
361381 let mut tmc_params_grouped = HashMap :: new ( ) ;
362382 for value in & tmc_param {
@@ -439,7 +459,8 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
439459 output_path,
440460 wait_for_secret,
441461 } => {
442- file_util:: lock!( exercise_path) ;
462+ let mut lock = Lock :: dir ( & exercise_path, LockOptions :: Read ) ?;
463+ let _guard = lock. lock ( ) ?;
443464
444465 let secret = if wait_for_secret {
445466 let mut s = String :: new ( ) ;
@@ -496,7 +517,8 @@ fn run_app(cli: Cli) -> Result<CliOutput> {
496517 exercise_path,
497518 output_path,
498519 } => {
499- file_util:: lock!( exercise_path) ;
520+ let mut lock = Lock :: dir ( & exercise_path, LockOptions :: Read ) ?;
521+ let _guard = lock. lock ( ) ?;
500522
501523 let exercise_name = exercise_path. file_name ( ) . with_context ( || {
502524 format ! (
@@ -584,6 +606,9 @@ fn run_tmc_inner(
584606 exercise_id,
585607 target,
586608 } => {
609+ let mut output_lock = Lock :: dir ( & target, file_util:: LockOptions :: WriteTruncate ) ?;
610+ let _output_guard = output_lock. lock ( ) ?;
611+
587612 client
588613 . download_model_solution ( exercise_id, & target)
589614 . context ( "Failed to download model solution" ) ?;
@@ -596,6 +621,9 @@ fn run_tmc_inner(
596621 exercise_id,
597622 output_path,
598623 } => {
624+ let mut output_lock = Lock :: dir ( & output_path, file_util:: LockOptions :: Write ) ?;
625+ let _output_guard = output_lock. lock ( ) ?;
626+
599627 tmc_langs:: download_old_submission (
600628 client,
601629 exercise_id,
@@ -837,7 +865,9 @@ fn run_tmc_inner(
837865 paste_message,
838866 submission_path,
839867 } => {
840- file_util:: lock!( submission_path) ;
868+ let mut lock = Lock :: dir ( & submission_path, LockOptions :: Read ) ?;
869+ let _guard = lock. lock ( ) ?;
870+
841871 let locale = locale. map ( |l| l. 0 ) ;
842872 let new_submission = client
843873 . paste ( exercise_id, & submission_path, paste_message, locale)
@@ -851,7 +881,9 @@ fn run_tmc_inner(
851881 message_for_reviewer,
852882 submission_path,
853883 } => {
854- file_util:: lock!( submission_path) ;
884+ let mut lock = Lock :: dir ( & submission_path, LockOptions :: Read ) ?;
885+ let _guard = lock. lock ( ) ?;
886+
855887 let new_submission = client
856888 . request_code_review (
857889 exercise_id,
@@ -871,7 +903,9 @@ fn run_tmc_inner(
871903 save_old_state,
872904 exercise_path,
873905 } => {
874- file_util:: lock!( exercise_path) ;
906+ let mut lock = Lock :: dir ( & exercise_path, LockOptions :: Write ) ?;
907+ let _guard = lock. lock ( ) ?;
908+
875909 if save_old_state {
876910 // submit current state
877911 client. submit ( exercise_id, & exercise_path, None ) ?;
@@ -923,7 +957,9 @@ fn run_tmc_inner(
923957 submission_path,
924958 exercise_id,
925959 } => {
926- file_util:: lock!( submission_path) ;
960+ let mut lock = Lock :: dir ( & submission_path, LockOptions :: Read ) ?;
961+ let _guard = lock. lock ( ) ?;
962+
927963 let locale = locale. map ( |l| l. 0 ) ;
928964 let new_submission = client
929965 . submit ( exercise_id, & submission_path, locale)
@@ -1040,7 +1076,9 @@ fn run_mooc_inner(mooc: Mooc, client: &mut MoocClient) -> Result<CliOutput> {
10401076 task_id,
10411077 submission_path,
10421078 } => {
1043- file_util:: lock!( submission_path) ;
1079+ let mut lock = Lock :: dir ( & submission_path, LockOptions :: Read ) ?;
1080+ let _guard = lock. lock ( ) ?;
1081+
10441082 let temp = file_util:: named_temp_file ( ) ?;
10451083 tmc_langs:: compress_project_to (
10461084 & submission_path,
@@ -1128,27 +1166,28 @@ fn write_result_to_file_as_json<T: Serialize>(
11281166 pretty : bool ,
11291167 secret : Option < String > ,
11301168) -> Result < ( ) > {
1131- let mut output_file = file_util:: create_file_locked ( output_path) . with_context ( || {
1132- format ! (
1133- "Failed to create results JSON file at {}" ,
1134- output_path. display( )
1135- )
1136- } ) ?;
1137- let guard = output_file. write ( ) ?;
1169+ let mut output_lock =
1170+ Lock :: file ( output_path, LockOptions :: WriteTruncate ) . with_context ( || {
1171+ format ! (
1172+ "Failed to create results JSON file at {}" ,
1173+ output_path. display( )
1174+ )
1175+ } ) ?;
1176+ let mut output_guard = output_lock. lock ( ) ?;
11381177
11391178 if let Some ( secret) = secret {
11401179 let token = tmc_langs:: sign_with_jwt ( result, secret. as_bytes ( ) ) ?;
1141- file_util:: write_to_writer ( token, guard . deref ( ) )
1180+ file_util:: write_to_writer ( token, output_guard . get_file_mut ( ) )
11421181 . with_context ( || format ! ( "Failed to write result to {}" , output_path. display( ) ) ) ?;
11431182 } else if pretty {
1144- serde_json:: to_writer_pretty ( guard . deref ( ) , result) . with_context ( || {
1183+ serde_json:: to_writer_pretty ( output_guard . get_file_mut ( ) , result) . with_context ( || {
11451184 format ! (
11461185 "Failed to write result as JSON to {}" ,
11471186 output_path. display( )
11481187 )
11491188 } ) ?;
11501189 } else {
1151- serde_json:: to_writer ( guard . deref ( ) , result) . with_context ( || {
1190+ serde_json:: to_writer ( output_guard . get_file_mut ( ) , result) . with_context ( || {
11521191 format ! (
11531192 "Failed to write result as JSON to {}" ,
11541193 output_path. display( )
@@ -1172,13 +1211,16 @@ fn run_checkstyle_write_results(
11721211 )
11731212 } ) ?;
11741213 if let Some ( output_path) = output_path {
1175- let output_file = File :: create ( output_path) . with_context ( || {
1176- format ! (
1177- "Failed to create code style check results file at {}" ,
1178- output_path. display( )
1179- )
1180- } ) ?;
1181- serde_json:: to_writer ( output_file, & check_result) . with_context ( || {
1214+ let mut output_lock =
1215+ Lock :: file ( output_path, LockOptions :: WriteTruncate ) . with_context ( || {
1216+ format ! (
1217+ "Failed to create code style check results file at {}" ,
1218+ output_path. display( )
1219+ )
1220+ } ) ?;
1221+ let mut output_guard = output_lock. lock ( ) ?;
1222+
1223+ serde_json:: to_writer ( output_guard. get_file_mut ( ) , & check_result) . with_context ( || {
11821224 format ! (
11831225 "Failed to write code style check results as JSON to {}" ,
11841226 output_path. display( )
0 commit comments