@@ -16,7 +16,7 @@ const _SELF_CONFIG_: &str = "project-sync-self-config";
1616pub struct Sync {
1717 pub name : String ,
1818 pub source : String ,
19- pub destination : String ,
19+ pub destinations : Vec < String > ,
2020 pub synced : Instant ,
2121 //updated: Instant,
2222 pub sync_on_start : bool ,
@@ -51,46 +51,50 @@ impl Sync {
5151 }
5252
5353 fn sync ( & mut self ) {
54- //std::thread::sleep(Duration::from_secs_f32(0.25));
55- print ! ( "Syncing {} " , self . name. bright_green( ) ) ;
56-
57- let verbosity = "--itemize-changes" ; // -v
58- let extras = self . sync_extras ( ) ;
59- let command_line = format ! ( "rsync {verbosity} -az -e ssh {extras} {} '{}'" , self . source, self . destination) ;
60-
61- println ! ( "{}" , command_line. white( ) . dimmed( ) ) ;
62-
63- let mut attempts = 0 ;
64- let start = Instant :: now ( ) ;
65-
66- self . synced = Instant :: now ( ) ;
67- while !std:: process:: Command :: new ( "sh" )
68- . arg ( "-c" )
69- . arg ( & command_line)
70- . status ( )
71- . expect ( "could not run shell command..." )
72- . success ( )
73- {
74- println ! ( "{}... going to sleep and retry..." , "FAILED" . on_red( ) ) ;
75- std:: thread:: sleep ( Duration :: from_secs ( 4 ) ) ;
76- if attempts > 7 {
77- println ! ( "Too many failed attempts: {}, giving up..." , attempts. to_string( ) . bright_red( ) ) ;
78- break ;
54+ for destination in & self . destinations {
55+ //std::thread::sleep(Duration::from_secs_f32(0.25));
56+ print ! ( "Syncing {} " , self . name. bright_green( ) ) ;
57+
58+ let verbosity = "--itemize-changes" ; // -v
59+ let extras = self . sync_extras ( ) ;
60+ let command_line = format ! ( "rsync {verbosity} -az -e ssh {extras} {} '{}'" , self . source, destination) ;
61+
62+ println ! ( "{}" , command_line. white( ) . dimmed( ) ) ;
63+
64+ let mut attempts = 0 ;
65+ let start = Instant :: now ( ) ;
66+
67+ self . synced = Instant :: now ( ) ;
68+ while !std:: process:: Command :: new ( "sh" )
69+ . arg ( "-c" )
70+ . arg ( & command_line)
71+ . status ( )
72+ . expect ( "could not run shell command..." )
73+ . success ( )
74+ {
75+ println ! ( "{}... going to sleep and retry..." , "FAILED" . on_red( ) ) ;
76+ std:: thread:: sleep ( Duration :: from_secs ( 4 ) ) ;
77+ if attempts > 7 {
78+ println ! ( "Too many failed attempts: {}, giving up..." , attempts. to_string( ) . bright_red( ) ) ;
79+ break ;
80+ }
81+ attempts += 1 ;
7982 }
80- attempts += 1 ;
81- }
8283
83- let _duration = start. elapsed ( ) ;
84- //println!("Elapsed time: {:.2?}", _duration);
84+ let _duration = start. elapsed ( ) ;
85+ //println!("Elapsed time: {:.2?}", _duration);
86+ }
8587 }
8688 fn create_project_watcher ( & self , transmitter : std:: sync:: mpsc:: Sender < SyncUpdate > ) -> notify:: RecommendedWatcher {
8789 println ! (
88- "Adding {:<16} {:>24} → {:<32} sync-on-start: {}" ,
90+ "Adding {:<16} {:>24} → [" , // {:<32}
8991 self . name. bright_green( ) ,
9092 self . source,
91- self . destination,
92- self . sync_on_start
9393 ) ;
94+ for d in & self . destinations {
95+ println ! ( " {d}" ) ;
96+ }
97+ println ! ( "] sync-on-start: {}" , self . sync_on_start) ;
9498
9599 let path = PathBuf :: from ( shellexpand:: tilde ( & self . source ) . as_ref ( ) ) ;
96100
@@ -115,18 +119,10 @@ impl Sync {
115119struct ProjectConfig {
116120 projects : BTreeMap < String , Sync > ,
117121 debounce : f32 ,
118- filter : Option < String > ,
119122}
120123
121124impl ProjectConfig {
122125 fn sync_projects ( & mut self ) {
123- // Retain only those entries that match the filter string
124- if let Some ( filter) = & self . filter {
125- self . projects . retain ( |_name, project| {
126- project. destination . contains ( filter) || project. name == _SELF_CONFIG_ //|| project.path.contains(&filter)
127- } ) ;
128- }
129-
130126 let ( tx, rx) = std:: sync:: mpsc:: channel :: < SyncUpdate > ( ) ;
131127
132128 let mut watchers = Vec :: < _ > :: new ( ) ;
@@ -181,7 +177,7 @@ where
181177 Sync {
182178 name : _SELF_CONFIG_. into ( ) ,
183179 source : config_path. to_str ( ) . unwrap ( ) . to_string ( ) ,
184- destination : config_path. to_str ( ) . unwrap ( ) . to_string ( ) ,
180+ destinations : vec ! [ config_path. to_str( ) . unwrap( ) . to_string( ) ] ,
185181 synced : Instant :: now ( ) ,
186182 sync_on_start : false ,
187183 ignore : "" . into ( ) ,
@@ -198,6 +194,15 @@ pub fn run(config_path: &Path, filter: Option<String>) {
198194 println ! ( "Reading sync config from {}..." , config_path. display( ) . to_string( ) . bright_yellow( ) ) ;
199195 let config = config:: read_config ( config_path) ;
200196 // println!("Parsed config: {:#?}", config);
197+
198+ // Retain only those entries that match the filter string
199+ fn destination_filter ( mut destinations : Vec < String > , filter : & Option < String > ) -> Vec < String > {
200+ if let Some ( filter) = filter {
201+ destinations. retain ( |dest| dest. contains ( filter) ) ;
202+ }
203+ destinations
204+ }
205+
201206 let projects = config
202207 . sync
203208 . into_iter ( )
@@ -207,7 +212,7 @@ pub fn run(config_path: &Path, filter: Option<String>) {
207212 Sync {
208213 name : c. name ,
209214 source : c. source ,
210- destination : c . destination ,
215+ destinations : destination_filter ( c . destinations , & filter ) ,
211216 synced : Instant :: now ( ) ,
212217 sync_on_start : c. sync_on_start ,
213218 ignore : c. ignore ,
@@ -220,7 +225,6 @@ pub fn run(config_path: &Path, filter: Option<String>) {
220225 ProjectConfig {
221226 projects,
222227 debounce : config. debounce ,
223- filter : filter. clone ( ) ,
224228 }
225229 } ;
226230
0 commit comments