@@ -19,7 +19,7 @@ use rust_i18n::t;
1919use serde:: Serialize ;
2020use std:: collections:: { HashMap , HashSet } ;
2121use std:: fs;
22- use std:: path:: PathBuf ;
22+ use std:: path:: { Path , PathBuf } ;
2323use std:: process:: ExitCode ;
2424use tabled:: { Table , Tabled } ;
2525
@@ -98,6 +98,34 @@ fn symlink_file(dry_run: bool, f: PathBuf) {
9898 }
9999}
100100
101+ fn remove_symlink ( dry_run : bool , file : & Path ) {
102+ let dotfile = Dotfile :: try_from ( file. to_path_buf ( ) ) . unwrap ( ) ;
103+ let target_dotfile = dotfile. to_target_path ( ) . unwrap ( ) ;
104+ let Ok ( linked) = fs:: read_link ( & target_dotfile) else {
105+ return ;
106+ } ;
107+
108+ if dotfile. path != linked {
109+ return ;
110+ }
111+
112+ if dry_run {
113+ eprintln ! (
114+ "{}" ,
115+ t!( "dry-run.removing_x" , x = target_dotfile. display( ) ) . red( )
116+ ) ;
117+ return ;
118+ }
119+
120+ if target_dotfile. is_dir ( ) {
121+ fs:: remove_dir_all ( & target_dotfile) . unwrap ( ) ;
122+ } else {
123+ fs:: remove_file ( & target_dotfile)
124+ . map_err ( |err| format ! ( "error with path `{}`: {err}" , target_dotfile. display( ) ) )
125+ . unwrap ( ) ;
126+ }
127+ }
128+
101129#[ enumflags2:: bitflags]
102130#[ repr( u8 ) ]
103131#[ derive( Copy , Clone , PartialEq , Debug ) ]
@@ -414,8 +442,9 @@ impl<'a> SymlinkHandler<'a> {
414442 for f in group. try_iter ( ) . unwrap ( ) {
415443 let f_target = f. to_target_path ( ) . unwrap ( ) ;
416444
417- // if there's a symlink in this path, we take its group and put it in the "to be removed" bucket
418- // it will later be readded so that the groups are all contained in the same parent directory
445+ // if there's a symlink in this path or its parents, we take it and put it in the "to be removed" bucket
446+ // it will later be readded after the parents dirs are created,
447+ // so that the groups are all contained in the same parent directory
419448 if let Some ( dotfile) = dotfiles:: get_dotfile_from_path ( & f_target) {
420449 removed_files. insert ( dotfile) ;
421450 }
@@ -433,26 +462,23 @@ impl<'a> SymlinkHandler<'a> {
433462
434463 let group_only_added_files = added_files. clone ( ) ;
435464
436- // NOTE/TODO?: this will only work if the dotfiles are in the same profile context
437- // maybe we should instead move the files into a temporary and then move them back
438465 for file in & removed_files {
439- self . remove ( dry_run, & file. group_name ) ;
466+ remove_symlink ( dry_run, & file. path ) ;
440467
441468 let target_path = file. to_target_path ( ) . unwrap ( ) ;
442469 fs:: create_dir_all ( if file. path . is_file ( ) {
443470 target_path. parent ( ) . unwrap ( )
444471 } else {
445472 & target_path
446473 } )
447- . unwrap ( ) ;
474+ . unwrap ( ) ;
448475
449- let group_iter = Dotfile :: try_from ( file. group_path . clone ( ) )
450- . unwrap ( )
451- . try_iter ( )
452- . unwrap ( ) ;
453-
454- for file in group_iter {
455- added_files. insert ( file) ;
476+ for file in fileops:: DirWalk :: new ( & file. group_path ) {
477+ let Ok ( dotfile) = Dotfile :: try_from ( file) else {
478+ continue ;
479+ } ;
480+ println ! ( "{:?}" , dotfile) ;
481+ added_files. insert ( dotfile) ;
456482 }
457483 }
458484
@@ -482,34 +508,6 @@ impl<'a> SymlinkHandler<'a> {
482508
483509 /// Deletes symlinks from $TUCKR_TARGET if they're owned by dotfiles dir
484510 fn remove ( & self , dry_run : bool , group : & str ) {
485- fn remove_symlink ( dry_run : bool , file : PathBuf ) {
486- let dotfile = Dotfile :: try_from ( file) . unwrap ( ) ;
487- let target_dotfile = dotfile. to_target_path ( ) . unwrap ( ) ;
488- let Ok ( linked) = fs:: read_link ( & target_dotfile) else {
489- return ;
490- } ;
491-
492- if dotfile. path != linked {
493- return ;
494- }
495-
496- if dry_run {
497- eprintln ! (
498- "{}" ,
499- t!( "dry-run.removing_x" , x = target_dotfile. display( ) ) . red( )
500- ) ;
501- return ;
502- }
503-
504- if target_dotfile. is_dir ( ) {
505- fs:: remove_dir_all ( & target_dotfile) . unwrap ( ) ;
506- } else {
507- fs:: remove_file ( & target_dotfile)
508- . map_err ( |err| format ! ( "error with path `{}`: {err}" , target_dotfile. display( ) ) )
509- . unwrap ( ) ;
510- }
511- }
512-
513511 let Some ( groups) =
514512 self . get_related_conditional_groups ( group, SymlinkType :: Symlinked . into ( ) , false )
515513 else {
@@ -527,7 +525,7 @@ impl<'a> SymlinkHandler<'a> {
527525 group
528526 . try_iter ( )
529527 . unwrap ( )
530- . for_each ( |f| remove_symlink ( dry_run, f. path ) ) ;
528+ . for_each ( |f| remove_symlink ( dry_run, & f. path ) ) ;
531529 }
532530 }
533531}
0 commit comments