@@ -14,10 +14,9 @@ extern crate serde;
14
14
extern crate serde_json;
15
15
16
16
use std:: error:: Error ;
17
- use std:: path:: Path ;
18
17
use std:: path:: PathBuf ;
19
18
20
- use chrono:: { DateTime , Datelike , TimeZone , Utc } ;
19
+ use chrono:: { DateTime , Utc } ;
21
20
use clap:: { Parser , Subcommand } ;
22
21
23
22
use aw_client_rust:: blocking:: AwClient ;
@@ -40,7 +39,7 @@ struct Opts {
40
39
41
40
/// Port of instance to connect to.
42
41
#[ clap( long) ]
43
- port : Option < String > ,
42
+ port : Option < u16 > ,
44
43
45
44
/// Convenience option for using the default testing host and port.
46
45
#[ clap( long) ]
@@ -58,8 +57,8 @@ enum Commands {
58
57
/// Pulls remote buckets then pushes local buckets.
59
58
Sync {
60
59
/// Host(s) to pull from, comma separated. Will pull from all hosts if not specified.
61
- #[ clap( long) ]
62
- host : Option < String > ,
60
+ #[ clap( long, value_parser=parse_list ) ]
61
+ host : Option < Vec < String > > ,
63
62
} ,
64
63
65
64
/// Sync subcommand (advanced)
@@ -73,57 +72,64 @@ enum Commands {
73
72
/// If not specified, start from beginning.
74
73
/// NOTE: might be unstable, as count cannot be used to verify integrity of sync.
75
74
/// Format: YYYY-MM-DD
76
- #[ clap( long) ]
77
- start_date : Option < String > ,
75
+ #[ clap( long, value_parser=parse_start_date ) ]
76
+ start_date : Option < DateTime < Utc > > ,
78
77
79
78
/// Specify buckets to sync using a comma-separated list.
80
79
/// If not specified, all buckets will be synced.
81
- #[ clap( long) ]
82
- buckets : Option < String > ,
80
+ #[ clap( long, value_parser=parse_list ) ]
81
+ buckets : Option < Vec < String > > ,
83
82
84
83
/// Mode to sync in. Can be "push", "pull", or "both".
85
84
/// Defaults to "both".
86
85
#[ clap( long, default_value = "both" ) ]
87
- mode : String ,
86
+ mode : sync :: SyncMode ,
88
87
89
88
/// Full path to sync directory.
90
89
/// If not specified, exit.
91
90
#[ clap( long) ]
92
- sync_dir : String ,
91
+ sync_dir : PathBuf ,
93
92
94
93
/// Full path to sync db file
95
94
/// Useful for syncing buckets from a specific db file in the sync directory.
96
95
/// Must be a valid absolute path to a file in the sync directory.
97
96
#[ clap( long) ]
98
- sync_db : Option < String > ,
97
+ sync_db : Option < PathBuf > ,
99
98
} ,
100
99
/// List buckets and their sync status.
101
100
List { } ,
102
101
}
103
102
103
+ fn parse_start_date ( arg : & str ) -> Result < DateTime < Utc > , chrono:: ParseError > {
104
+ chrono:: NaiveDate :: parse_from_str ( arg, "%Y-%m-%d" )
105
+ . map ( |nd| nd. and_time ( chrono:: NaiveTime :: MIN ) . and_utc ( ) )
106
+ }
107
+
108
+ fn parse_list ( arg : & str ) -> Result < Vec < String > , clap:: Error > {
109
+ Ok ( arg. split ( ',' ) . map ( |s| s. to_string ( ) ) . collect ( ) )
110
+ }
111
+
104
112
fn main ( ) -> Result < ( ) , Box < dyn Error > > {
105
113
let opts: Opts = Opts :: parse ( ) ;
106
114
let verbose = opts. verbose ;
107
115
108
116
info ! ( "Started aw-sync..." ) ;
109
117
110
- aw_server:: logging:: setup_logger ( "aw-sync" , opts. testing , verbose)
111
- . expect ( "Failed to setup logging" ) ;
118
+ aw_server:: logging:: setup_logger ( "aw-sync" , opts. testing , verbose) ?;
112
119
113
120
let port = opts
114
121
. port
115
- . or_else ( || Some ( crate :: util :: get_server_port ( opts . testing ) . ok ( ) ? . to_string ( ) ) )
116
- . unwrap ( ) ;
122
+ . map ( |a| Ok ( a ) )
123
+ . unwrap_or_else ( || util :: get_server_port ( opts . testing ) ) ? ;
117
124
118
- let client = AwClient :: new ( opts. host . as_str ( ) , port. as_str ( ) , "aw-sync" ) ;
125
+ let client = AwClient :: new ( & opts. host , port, "aw-sync" ) ? ;
119
126
120
- match & opts. command {
127
+ match opts. command {
121
128
// Perform basic sync
122
129
Commands :: Sync { host } => {
123
130
// Pull
124
131
match host {
125
- Some ( host) => {
126
- let hosts: Vec < & str > = host. split ( ',' ) . collect ( ) ;
132
+ Some ( hosts) => {
127
133
for host in hosts. iter ( ) {
128
134
info ! ( "Pulling from host: {}" , host) ;
129
135
sync_wrapper:: pull ( host, & client) ?;
@@ -137,8 +143,7 @@ fn main() -> Result<(), Box<dyn Error>> {
137
143
138
144
// Push
139
145
info ! ( "Pushing local data" ) ;
140
- sync_wrapper:: push ( & client) ?;
141
- Ok ( ( ) )
146
+ sync_wrapper:: push ( & client)
142
147
}
143
148
// Perform two-way sync
144
149
Commands :: SyncAdvanced {
@@ -148,60 +153,31 @@ fn main() -> Result<(), Box<dyn Error>> {
148
153
sync_dir,
149
154
sync_db,
150
155
} => {
151
- let sync_directory = if sync_dir. is_empty ( ) {
152
- error ! ( "No sync directory specified, exiting..." ) ;
153
- std:: process:: exit ( 1 ) ;
154
- } else {
155
- Path :: new ( & sync_dir)
156
- } ;
157
- info ! ( "Using sync dir: {}" , sync_directory. display( ) ) ;
158
-
159
- if let Some ( sync_db) = & sync_db {
160
- info ! ( "Using sync db: {}" , sync_db) ;
156
+ if !sync_dir. is_absolute ( ) {
157
+ Err ( "Sync dir must be absolute" ) ?
161
158
}
162
159
163
- let start: Option < DateTime < Utc > > = start_date. as_ref ( ) . map ( |date| {
164
- println ! ( "{}" , date. clone( ) ) ;
165
- chrono:: NaiveDate :: parse_from_str ( & date. clone ( ) , "%Y-%m-%d" )
166
- . map ( |nd| {
167
- Utc . with_ymd_and_hms ( nd. year ( ) , nd. month ( ) , nd. day ( ) , 0 , 0 , 0 )
168
- . single ( )
169
- . unwrap ( )
170
- } )
171
- . expect ( "Date was not on the format YYYY-MM-DD" )
172
- } ) ;
173
-
174
- // Parse comma-separated list
175
- let buckets_vec: Option < Vec < String > > = buckets
176
- . as_ref ( )
177
- . map ( |b| b. split ( ',' ) . map ( |s| s. to_string ( ) ) . collect ( ) ) ;
178
-
179
- let sync_db: Option < PathBuf > = sync_db. as_ref ( ) . map ( |db| {
180
- let db_path = Path :: new ( db) ;
160
+ info ! ( "Using sync dir: {}" , & sync_dir. display( ) ) ;
161
+
162
+ if let Some ( db_path) = & sync_db {
163
+ info ! ( "Using sync db: {}" , & db_path. display( ) ) ;
164
+
181
165
if !db_path. is_absolute ( ) {
182
- panic ! ( "Sync db path must be absolute" ) ;
166
+ Err ( "Sync db path must be absolute" ) ?
183
167
}
184
- if !db_path. starts_with ( sync_directory ) {
185
- panic ! ( "Sync db path must be in sync directory" ) ;
168
+ if !db_path. starts_with ( & sync_dir ) {
169
+ Err ( "Sync db path must be in sync directory" ) ?
186
170
}
187
- db_path. to_path_buf ( )
188
- } ) ;
171
+ }
189
172
190
173
let sync_spec = sync:: SyncSpec {
191
- path : sync_directory . to_path_buf ( ) ,
174
+ path : sync_dir ,
192
175
path_db : sync_db,
193
- buckets : buckets_vec,
194
- start,
195
- } ;
196
-
197
- let mode_enum = match mode. as_str ( ) {
198
- "push" => sync:: SyncMode :: Push ,
199
- "pull" => sync:: SyncMode :: Pull ,
200
- "both" => sync:: SyncMode :: Both ,
201
- _ => panic ! ( "Invalid mode" ) ,
176
+ buckets,
177
+ start : start_date,
202
178
} ;
203
179
204
- sync:: sync_run ( & client, & sync_spec, mode_enum )
180
+ sync:: sync_run ( & client, & sync_spec, mode )
205
181
}
206
182
207
183
// List all buckets
0 commit comments