@@ -5,21 +5,28 @@ use git2::{DiffOptions, IndexAddOption, Repository, StatusOptions, Time};
55use std:: path:: PathBuf ;
66use tokio:: fs;
77
8- const UPLOAD_DIR : & str = "uploads" ;
98const DEFAULT_DIRECTORIES : [ & str ; 3 ] = [ "solutions" , "tests" , "statements" ] ;
109
1110#[ derive( Debug ) ]
1211struct GitManager {
1312 problem_id : u32 ,
13+ base_path : PathBuf ,
1414}
1515
1616impl GitManager {
17- fn new ( problem_id : u32 ) -> Self {
18- Self { problem_id }
17+ fn new ( problem_id : u32 , base_path : PathBuf ) -> Self {
18+ Self {
19+ problem_id,
20+ base_path,
21+ }
22+ }
23+
24+ fn get_upload_path ( & self ) -> PathBuf {
25+ self . base_path . join ( self . problem_id . to_string ( ) )
1926 }
2027
2128 fn git_init ( & self ) -> Result < ( ) > {
22- let path = PathBuf :: from ( UPLOAD_DIR ) . join ( self . problem_id . to_string ( ) ) ;
29+ let path = self . get_upload_path ( ) ;
2330 Repository :: init ( & path)
2431 . and_then ( |repo| {
2532 let mut config = repo. config ( ) ?;
@@ -28,7 +35,7 @@ impl GitManager {
2835 Ok ( repo)
2936 } )
3037 . map ( |_| ( ) )
31- . with_context ( || format ! ( "Failed to init git repo at {:?}" , path ) )
38+ . with_context ( || format ! ( "Failed to init git repo at {path :?}" ) )
3239 }
3340
3441 async fn create_problem ( & self ) -> Result < ( ) > {
@@ -127,12 +134,12 @@ impl GitManager {
127134 }
128135
129136 async fn create_default_directories ( & self ) -> Result < ( ) > {
130- let base_path = PathBuf :: from ( UPLOAD_DIR ) . join ( self . problem_id . to_string ( ) ) ;
137+ let base_path = self . get_upload_path ( ) ;
131138 for dir in DEFAULT_DIRECTORIES {
132139 let path = base_path. join ( dir) ;
133140 fs:: create_dir_all ( path)
134141 . await
135- . with_context ( || format ! ( "Failed to create directory: {}" , dir ) ) ?;
142+ . with_context ( || format ! ( "Failed to create directory: {dir}" ) ) ?;
136143 }
137144 Ok ( ( ) )
138145 }
@@ -169,9 +176,9 @@ impl GitManager {
169176 }
170177
171178 fn get_repository ( & self ) -> Result < Repository > {
172- let path = PathBuf :: from ( UPLOAD_DIR ) . join ( self . problem_id . to_string ( ) ) ;
179+ let path = self . get_upload_path ( ) ;
173180 Repository :: open ( & path)
174- . with_context ( || format ! ( "Failed to open git repository at {:?}" , path ) )
181+ . with_context ( || format ! ( "Failed to open git repository at {path :?}" ) )
175182 }
176183}
177184
@@ -194,6 +201,7 @@ mod tests {
194201 use super :: * ;
195202 use rstest:: rstest;
196203 use std:: path:: Path ;
204+ use tempfile:: TempDir ;
197205 use tokio:: fs;
198206
199207 #[ rstest]
@@ -223,20 +231,24 @@ mod tests {
223231
224232 #[ tokio:: test]
225233 async fn can_init_git_repository ( ) -> Result < ( ) , std:: io:: Error > {
226- let problem_id = 10 ;
227- let git_manager = GitManager :: new ( problem_id) ;
234+ let temp_dir = TempDir :: new ( ) ?;
235+ let problem_id = 0 ;
236+ let git_manager = GitManager :: new ( problem_id, temp_dir. path ( ) . to_path_buf ( ) ) ;
228237 assert ! ( git_manager. git_init( ) . is_ok( ) ) ;
229- assert ! ( Path :: new( format!( "{UPLOAD_DIR}/{problem_id}" ) . as_str( ) ) . exists( ) ) ;
230- assert ! ( Path :: new( format!( "{UPLOAD_DIR}/{problem_id}/.git" ) . as_str( ) ) . exists( ) ) ;
238+ assert ! ( Path :: new( git_manager. get_upload_path( ) . to_str( ) . unwrap( ) ) . exists( ) ) ;
239+ assert ! ( Path :: new(
240+ format!( "{}/.git" , git_manager. get_upload_path( ) . to_str( ) . unwrap( ) ) . as_str( )
241+ )
242+ . exists( ) ) ;
231243
232- fs:: remove_dir_all ( format ! ( "{UPLOAD_DIR}/{problem_id}" ) ) . await ?;
233244 Ok ( ( ) )
234245 }
235246
236247 #[ tokio:: test]
237248 async fn can_set_config ( ) -> Result < ( ) , std:: io:: Error > {
238- let problem_id = 11 ;
239- let git_manager = GitManager :: new ( problem_id) ;
249+ let temp_dir = TempDir :: new ( ) ?;
250+ let problem_id = 0 ;
251+ let git_manager = GitManager :: new ( problem_id, temp_dir. path ( ) . to_path_buf ( ) ) ;
240252 assert ! ( git_manager. git_init( ) . is_ok( ) ) ;
241253 let repo = git_manager. get_repository ( ) . unwrap ( ) ;
242254 let config = repo. config ( ) . unwrap ( ) ;
@@ -246,48 +258,103 @@ mod tests {
246258 Ok ( "[email protected] " . to_string
( ) ) 247259 ) ;
248260
249- fs:: remove_dir_all ( format ! ( "{UPLOAD_DIR}/{problem_id}" ) ) . await ?;
250261 Ok ( ( ) )
251262 }
252263
253264 #[ tokio:: test]
254265 async fn can_create_default_file ( ) -> Result < ( ) , std:: io:: Error > {
255- let problem_id = 12 ;
256- let git_manager = GitManager :: new ( problem_id) ;
266+ let temp_dir = TempDir :: new ( ) ?;
267+ let problem_id = 0 ;
268+ let git_manager = GitManager :: new ( problem_id, temp_dir. path ( ) . to_path_buf ( ) ) ;
257269 assert ! ( git_manager. create_default_directories( ) . await . is_ok( ) ) ;
258- assert ! ( Path :: new( format!( "{UPLOAD_DIR}/{problem_id}/solutions" ) . as_str( ) ) . exists( ) ) ;
259- assert ! ( Path :: new( format!( "{UPLOAD_DIR}/{problem_id}/tests" ) . as_str( ) ) . exists( ) ) ;
260- assert ! ( Path :: new( format!( "{UPLOAD_DIR}/{problem_id}/statements" ) . as_str( ) ) . exists( ) ) ;
270+ assert ! ( Path :: new(
271+ format!(
272+ "{}/solutions" ,
273+ git_manager. get_upload_path( ) . to_str( ) . unwrap( )
274+ )
275+ . as_str( )
276+ )
277+ . exists( ) ) ;
278+ assert ! ( Path :: new(
279+ format!( "{}/tests" , git_manager. get_upload_path( ) . to_str( ) . unwrap( ) ) . as_str( )
280+ )
281+ . exists( ) ) ;
282+ assert ! ( Path :: new(
283+ format!(
284+ "{}/statements" ,
285+ git_manager. get_upload_path( ) . to_str( ) . unwrap( )
286+ )
287+ . as_str( )
288+ )
289+ . exists( ) ) ;
261290
262- fs:: remove_dir_all ( format ! ( "{UPLOAD_DIR}/{problem_id}" ) ) . await ?;
263291 Ok ( ( ) )
264292 }
265293
266294 #[ tokio:: test]
267295 async fn can_create_problem ( ) -> Result < ( ) , std:: io:: Error > {
268- let problem_id = 13 ;
269- let git_manager = GitManager :: new ( problem_id) ;
296+ let temp_dir = TempDir :: new ( ) ?;
297+ let problem_id = 0 ;
298+ let git_manager = GitManager :: new ( problem_id, temp_dir. path ( ) . to_path_buf ( ) ) ;
270299 assert ! ( git_manager. create_problem( ) . await . is_ok( ) ) ;
271- assert ! ( Path :: new( format!( "{UPLOAD_DIR}/{problem_id}" ) . as_str( ) ) . exists( ) ) ;
272- assert ! ( Path :: new( format!( "{UPLOAD_DIR}/{problem_id}/.git" ) . as_str( ) ) . exists( ) ) ;
273- assert ! ( Path :: new( format!( "{UPLOAD_DIR}/{problem_id}/solutions" ) . as_str( ) ) . exists( ) ) ;
274- assert ! ( Path :: new( format!( "{UPLOAD_DIR}/{problem_id}/tests" ) . as_str( ) ) . exists( ) ) ;
275- assert ! ( Path :: new( format!( "{UPLOAD_DIR}/{problem_id}/statements" ) . as_str( ) ) . exists( ) ) ;
300+ assert ! ( Path :: new( git_manager. get_upload_path( ) . to_str( ) . unwrap( ) ) . exists( ) ) ;
301+ assert ! ( Path :: new(
302+ format!( "{}/.git" , git_manager. get_upload_path( ) . to_str( ) . unwrap( ) ) . as_str( )
303+ )
304+ . exists( ) ) ;
305+ assert ! ( Path :: new(
306+ format!(
307+ "{}/solutions" ,
308+ git_manager. get_upload_path( ) . to_str( ) . unwrap( )
309+ )
310+ . as_str( )
311+ )
312+ . exists( ) ) ;
313+ assert ! ( Path :: new(
314+ format!( "{}/tests" , git_manager. get_upload_path( ) . to_str( ) . unwrap( ) ) . as_str( )
315+ )
316+ . exists( ) ) ;
317+ assert ! ( Path :: new(
318+ format!(
319+ "{}/statements" ,
320+ git_manager. get_upload_path( ) . to_str( ) . unwrap( )
321+ )
322+ . as_str( )
323+ )
324+ . exists( ) ) ;
276325
277- fs:: remove_dir_all ( format ! ( "{UPLOAD_DIR}/{problem_id}" ) ) . await ?;
278326 Ok ( ( ) )
279327 }
280328
281329 #[ tokio:: test]
282330 async fn can_get_git_status ( ) -> Result < ( ) , tokio:: io:: Error > {
283- let problem_id = 14 ;
284- let git_manager = GitManager :: new ( problem_id) ;
331+ let temp_dir = TempDir :: new ( ) ?;
332+ let problem_id = 0 ;
333+ let git_manager = GitManager :: new ( problem_id, temp_dir. path ( ) . to_path_buf ( ) ) ;
285334
286335 git_manager. git_init ( ) . unwrap ( ) ;
287336
288- fs:: create_dir_all ( format ! ( "{UPLOAD_DIR}/{problem_id}/tests" ) ) . await ?;
289- fs:: write ( format ! ( "{UPLOAD_DIR}/{problem_id}/tests/1.in" ) , "1 2" ) . await ?;
290- fs:: write ( format ! ( "{UPLOAD_DIR}/{problem_id}/tests/1.out" ) , "3" ) . await ?;
337+ fs:: create_dir_all ( format ! (
338+ "{}/tests" ,
339+ git_manager. get_upload_path( ) . to_str( ) . unwrap( )
340+ ) )
341+ . await ?;
342+ fs:: write (
343+ format ! (
344+ "{}/tests/1.in" ,
345+ git_manager. get_upload_path( ) . to_str( ) . unwrap( )
346+ ) ,
347+ "1 2" ,
348+ )
349+ . await ?;
350+ fs:: write (
351+ format ! (
352+ "{}/tests/1.out" ,
353+ git_manager. get_upload_path( ) . to_str( ) . unwrap( )
354+ ) ,
355+ "3" ,
356+ )
357+ . await ?;
291358
292359 let file_infos = git_manager. git_status ( ) . unwrap ( ) ;
293360 let expected = vec ! [
@@ -302,47 +369,83 @@ mod tests {
302369 ] ;
303370 assert_eq ! ( file_infos, expected) ;
304371
305- fs:: remove_dir_all ( format ! ( "{UPLOAD_DIR}/{problem_id}" ) ) . await ?;
306372 Ok ( ( ) )
307373 }
308374
309375 #[ tokio:: test]
310376 async fn can_git_add ( ) -> Result < ( ) , tokio:: io:: Error > {
311- let problem_id = 15 ;
312- let git_manager = GitManager :: new ( problem_id) ;
377+ let temp_dir = TempDir :: new ( ) ?;
378+ let problem_id = 0 ;
379+ let git_manager = GitManager :: new ( problem_id, temp_dir. path ( ) . to_path_buf ( ) ) ;
313380
314381 git_manager. git_init ( ) . unwrap ( ) ;
315382
316383 let repo = git_manager. get_repository ( ) . unwrap ( ) ;
317- fs:: create_dir_all ( format ! ( "{UPLOAD_DIR}/{problem_id}/tests" ) ) . await ?;
318- fs:: write ( format ! ( "{UPLOAD_DIR}/{problem_id}/tests/1.in" ) , "1 2" ) . await ?;
319- fs:: write ( format ! ( "{UPLOAD_DIR}/{problem_id}/tests/1.out" ) , "3" ) . await ?;
384+ fs:: create_dir_all ( format ! (
385+ "{}/tests" ,
386+ git_manager. get_upload_path( ) . to_str( ) . unwrap( )
387+ ) )
388+ . await ?;
389+ fs:: write (
390+ format ! (
391+ "{}/tests/1.in" ,
392+ git_manager. get_upload_path( ) . to_str( ) . unwrap( )
393+ ) ,
394+ "1 2" ,
395+ )
396+ . await ?;
397+ fs:: write (
398+ format ! (
399+ "{}/tests/1.out" ,
400+ git_manager. get_upload_path( ) . to_str( ) . unwrap( )
401+ ) ,
402+ "3" ,
403+ )
404+ . await ?;
320405
321406 assert ! ( git_manager. git_add_all( ) . is_ok( ) ) ;
322407
323408 let statuses = repo. statuses ( None ) . unwrap ( ) ;
324409
325- // 워킹 디렉토리에 존재하지 않아야 한다.
410+ // Should not exist in working directory
326411 assert ! ( !statuses. iter( ) . any( |e| e. status( ) . is_wt_new( ) ) ) ;
327412 assert ! ( !statuses. iter( ) . any( |e| e. status( ) . is_wt_modified( ) ) ) ;
328413 assert ! ( !statuses. iter( ) . any( |e| e. status( ) . is_wt_deleted( ) ) ) ;
329414
330- // 스테이징 영역에 올라와야 한다.
415+ // Should be in staging area
331416 assert ! ( statuses. iter( ) . all( |e| e. status( ) . is_index_new( ) ) ) ;
332417
333- fs:: remove_dir_all ( format ! ( "{UPLOAD_DIR}/{problem_id}" ) ) . await ?;
334418 Ok ( ( ) )
335419 }
336420
337421 #[ tokio:: test]
338422 async fn can_commit ( ) -> Result < ( ) , tokio:: io:: Error > {
339- let problem_id = 16 ;
340- let git_manager = GitManager :: new ( problem_id) ;
423+ let temp_dir = TempDir :: new ( ) ?;
424+ let problem_id = 0 ;
425+ let git_manager = GitManager :: new ( problem_id, temp_dir. path ( ) . to_path_buf ( ) ) ;
341426 git_manager. git_init ( ) . unwrap ( ) ;
342427
343- fs:: create_dir_all ( format ! ( "{UPLOAD_DIR}/{problem_id}/tests" ) ) . await ?;
344- fs:: write ( format ! ( "{UPLOAD_DIR}/{problem_id}/tests/1.in" ) , "1 2" ) . await ?;
345- fs:: write ( format ! ( "{UPLOAD_DIR}/{problem_id}/tests/1.out" ) , "3" ) . await ?;
428+ fs:: create_dir_all ( format ! (
429+ "{}/tests" ,
430+ git_manager. get_upload_path( ) . to_str( ) . unwrap( )
431+ ) )
432+ . await ?;
433+ fs:: write (
434+ format ! (
435+ "{}/tests/1.in" ,
436+ git_manager. get_upload_path( ) . to_str( ) . unwrap( )
437+ ) ,
438+ "1 2" ,
439+ )
440+ . await ?;
441+ fs:: write (
442+ format ! (
443+ "{}/tests/1.out" ,
444+ git_manager. get_upload_path( ) . to_str( ) . unwrap( )
445+ ) ,
446+ "3" ,
447+ )
448+ . await ?;
346449
347450 let commit_message = "add test 1" ;
348451
@@ -354,19 +457,33 @@ mod tests {
354457
355458 assert_eq ! ( commit. message( ) , Some ( commit_message) ) ;
356459
357- fs:: remove_dir_all ( format ! ( "{UPLOAD_DIR}/{problem_id}" ) ) . await ?;
358460 Ok ( ( ) )
359461 }
360462
361463 #[ tokio:: test]
362464 async fn can_get_log ( ) -> Result < ( ) , tokio:: io:: Error > {
363- let problem_id = 17 ;
364- let git_manager = GitManager :: new ( problem_id) ;
465+ let temp_dir = TempDir :: new ( ) ?;
466+ let problem_id = 0 ;
467+ let git_manager = GitManager :: new ( problem_id, temp_dir. path ( ) . to_path_buf ( ) ) ;
365468 git_manager. git_init ( ) . unwrap ( ) ;
366469 git_manager. create_default_directories ( ) . await . unwrap ( ) ;
367470
368- fs:: write ( format ! ( "{UPLOAD_DIR}/{problem_id}/tests/1.in" ) , "1 2" ) . await ?;
369- fs:: write ( format ! ( "{UPLOAD_DIR}/{problem_id}/tests/1.out" ) , "3" ) . await ?;
471+ fs:: write (
472+ format ! (
473+ "{}/tests/1.in" ,
474+ git_manager. get_upload_path( ) . to_str( ) . unwrap( )
475+ ) ,
476+ "1 2" ,
477+ )
478+ . await ?;
479+ fs:: write (
480+ format ! (
481+ "{}/tests/1.out" ,
482+ git_manager. get_upload_path( ) . to_str( ) . unwrap( )
483+ ) ,
484+ "3" ,
485+ )
486+ . await ?;
370487
371488 git_manager
372489 . git_commit ( "create default file" . to_string ( ) )
@@ -386,7 +503,6 @@ mod tests {
386503 ] ;
387504 assert_eq ! ( log[ 0 ] . paths, expected_path) ;
388505
389- fs:: remove_dir_all ( format ! ( "{UPLOAD_DIR}/{problem_id}" ) ) . await ?;
390506 Ok ( ( ) )
391507 }
392508}
0 commit comments