@@ -4,17 +4,31 @@ use crate::settings::dots::{Dot, DotOverride};
44use crate :: templating:: Variables ;
55use anyhow:: Result ;
66use colored:: * ;
7+ use std:: error:: Error ;
78use std:: fs;
89use std:: fs:: { File , OpenOptions } ;
910use std:: io:: Write ;
1011use std:: path:: { Path , PathBuf } ;
12+ use tera:: ErrorKind ;
1113
1214#[ derive( PartialEq , Eq , Debug ) ]
1315pub enum LinkResult {
14- Updated ,
15- Created ,
16- Ignored ,
17- Unchanged ,
16+ Updated {
17+ source : PathBuf ,
18+ copy : PathBuf ,
19+ target : PathBuf ,
20+ } ,
21+ Created {
22+ source : PathBuf ,
23+ copy : PathBuf ,
24+ target : PathBuf ,
25+ } ,
26+ Ignored {
27+ source : PathBuf ,
28+ } ,
29+ Unchanged {
30+ target : PathBuf ,
31+ } ,
1832}
1933
2034impl Dot {
@@ -44,15 +58,12 @@ impl Dot {
4458 vars. extend ( local_vars) ;
4559 }
4660
47- // Resolve % reference
48- vars. resolve_ref ( ) ;
49-
5061 // Recursively copy dotfile to .dots directory
5162 self . traverse_and_copy ( source, target, ignored_paths. as_slice ( ) , & vars, profiles)
5263 }
5364
5465 fn load_local_vars ( source : & Path ) -> Variables {
55- Variables :: from_toml ( source) . unwrap_or_else ( |err| {
66+ Variables :: from_path ( source) . unwrap_or_else ( |err| {
5667 eprintln ! ( "{}" , err. to_string( ) . yellow( ) ) ;
5768 Variables :: default ( )
5869 } )
@@ -77,23 +88,38 @@ impl Dot {
7788 profiles : & [ String ] ,
7889 ) -> Result < LinkResult > {
7990 if ignored. contains ( source) {
80- return Ok ( LinkResult :: Ignored ) ;
91+ return Ok ( LinkResult :: Ignored {
92+ source : source. clone ( ) ,
93+ } ) ;
8194 }
8295
8396 // Single file : inject vars and write to .dots/
8497 if source. is_file ( ) {
8598 fs:: create_dir_all ( target. parent ( ) . unwrap ( ) ) ?;
99+
86100 match vars. to_dot ( source, profiles) {
87101 Ok ( content) if target. exists ( ) => self . update ( source, target, content) ,
88102 Ok ( content) => self . create ( source, target, content) ,
89- Err ( _) if target. exists ( ) => {
90- // Fixme: we probabbly want to remove anyhow here
91- // And handle specific error case (i.e: ignore utf8 error)
103+ Err ( e) if target. exists ( ) => {
104+ match e. kind {
105+ ErrorKind :: Utf8Conversion { .. } => { }
106+ ErrorKind :: Io ( _) => { }
107+ ErrorKind :: Msg ( message) => println ! ( "\t {}" , message. to_string( ) . red( ) ) ,
108+ _ => {
109+ if let Some ( source) = e. source ( ) {
110+ println ! ( "\t {}" , source) ;
111+ }
112+ }
113+ }
92114 self . update_raw ( source, target)
93115 }
94116 Err ( _) => {
95- fs:: copy ( source, target) ?;
96- Ok ( LinkResult :: Created )
117+ fs:: copy ( & source, & target) ?;
118+ Ok ( LinkResult :: Created {
119+ source : source. clone ( ) ,
120+ target : target. clone ( ) ,
121+ copy : self . copy_path ( ) ?,
122+ } )
97123 }
98124 }
99125 } else {
@@ -117,12 +143,28 @@ impl Dot {
117143 }
118144 }
119145
120- if link_results. contains ( & LinkResult :: Updated ) {
121- Ok ( LinkResult :: Updated )
122- } else if link_results. contains ( & LinkResult :: Created ) {
123- Ok ( LinkResult :: Created )
146+ if link_results
147+ . iter ( )
148+ . any ( |res| matches ! ( res, LinkResult :: Updated { .. } ) )
149+ {
150+ Ok ( LinkResult :: Updated {
151+ copy : self . copy_path ( ) ?,
152+ source : self . source ( ) ?,
153+ target : self . target ( ) ?,
154+ } )
155+ } else if link_results
156+ . iter ( )
157+ . any ( |res| matches ! ( res, LinkResult :: Created { .. } ) )
158+ {
159+ Ok ( LinkResult :: Created {
160+ copy : self . copy_path ( ) ?,
161+ source : self . source ( ) ?,
162+ target : self . target ( ) ?,
163+ } )
124164 } else {
125- Ok ( LinkResult :: Unchanged )
165+ Ok ( LinkResult :: Unchanged {
166+ target : self . target ( ) ?,
167+ } )
126168 }
127169 }
128170 }
@@ -132,20 +174,30 @@ impl Dot {
132174 let mut dot_copy = File :: create ( target) ?;
133175 dot_copy. write_all ( content. as_bytes ( ) ) ?;
134176 dot_copy. set_permissions ( permissions) ?;
135- Ok ( LinkResult :: Created )
177+ Ok ( LinkResult :: Created {
178+ target : self . target ( ) ?,
179+ source : self . source ( ) ?,
180+ copy : self . copy_path ( ) ?,
181+ } )
136182 }
137183
138184 fn update ( & self , source : & PathBuf , target : & PathBuf , content : String ) -> Result < LinkResult > {
139185 let target_content = fs:: read_to_string ( target) ?;
140186 if target_content == content {
141- Ok ( LinkResult :: Unchanged )
187+ Ok ( LinkResult :: Unchanged {
188+ target : self . target ( ) ?,
189+ } )
142190 } else {
143191 let permissions = fs:: metadata ( source) ?. permissions ( ) ;
144192 let mut dot_copy = OpenOptions :: new ( ) . write ( true ) . truncate ( true ) . open ( target) ?;
145193 dot_copy. write_all ( content. as_bytes ( ) ) ?;
146194 dot_copy. set_permissions ( permissions) ?;
147195 dot_copy. sync_data ( ) ?;
148- Ok ( LinkResult :: Updated )
196+ Ok ( LinkResult :: Updated {
197+ target : self . target ( ) ?,
198+ source : self . source ( ) ?,
199+ copy : self . copy_path ( ) ?,
200+ } )
149201 }
150202 }
151203
@@ -154,15 +206,21 @@ impl Dot {
154206 let content = fs:: read ( source) ?;
155207
156208 if target_content == content {
157- Ok ( LinkResult :: Unchanged )
209+ Ok ( LinkResult :: Unchanged {
210+ target : self . target ( ) ?,
211+ } )
158212 } else {
159213 let permissions = fs:: metadata ( source) ?. permissions ( ) ;
160214 let mut dot_copy = OpenOptions :: new ( ) . write ( true ) . truncate ( true ) . open ( target) ?;
161215
162216 dot_copy. write_all ( & content) ?;
163217 dot_copy. set_permissions ( permissions) ?;
164218 dot_copy. sync_data ( ) ?;
165- Ok ( LinkResult :: Updated )
219+ Ok ( LinkResult :: Updated {
220+ target : self . target ( ) ?,
221+ source : self . source ( ) ?,
222+ copy : self . copy_path ( ) ?,
223+ } )
166224 }
167225 }
168226}
@@ -515,8 +573,7 @@ mod tests {
515573 vars : Dot :: default_vars ( ) ,
516574 } ;
517575
518- let mut vars = Variables :: default ( ) ;
519- vars. insert ( "name" , "Tom Bombadil" ) ;
576+ let vars: Variables = toml:: from_str ( r#"name = "Tom Bombadil""# ) ?;
520577
521578 // Act
522579 dot. install ( & vars, vec ! [ ] , & [ ] ) ?;
0 commit comments