@@ -13,13 +13,18 @@ use crate::{error::ScpError, utils::with_retry};
13
13
pub struct Connect {
14
14
session : Session ,
15
15
ssh_opts : SshOpts ,
16
+ mode : Mode ,
16
17
}
17
18
18
19
impl Connect {
19
- pub fn new ( ssh_opts : SshOpts ) -> anyhow:: Result < Self , ScpError > {
20
+ pub fn new ( ssh_opts : SshOpts , mode : Mode ) -> anyhow:: Result < Self , ScpError > {
20
21
let session = create_session ( & ssh_opts) ?;
21
22
22
- Ok ( Self { session, ssh_opts } )
23
+ Ok ( Self {
24
+ session,
25
+ ssh_opts,
26
+ mode,
27
+ } )
23
28
}
24
29
25
30
pub async fn receive ( & self , from : & PathBuf , to : & PathBuf ) -> anyhow:: Result < ( ) , ScpError > {
@@ -34,8 +39,10 @@ impl Connect {
34
39
let item_clone = item. clone ( ) ;
35
40
let ssh_opts = self . ssh_opts . clone ( ) ;
36
41
let pb = pb. clone ( ) ;
42
+ let mode = self . mode . clone ( ) ;
37
43
let handle = tokio:: task:: spawn ( async move {
38
- let result = copy_file_from_remote ( & ssh_opts, item_clone. clone ( ) , to_path) . await ;
44
+ let result =
45
+ copy_file_from_remote ( & ssh_opts, item_clone. clone ( ) , to_path, & mode) . await ;
39
46
pb. inc ( 1 ) ;
40
47
result
41
48
} ) ;
@@ -110,10 +117,20 @@ pub struct SshOpts {
110
117
pub private_key : PathBuf ,
111
118
}
112
119
120
+ /// Mode to use when copying files
121
+ /// Replace will overwrite the file if it exists
122
+ /// Ignore will skip the file if it exists
123
+ #[ derive( Clone ) ]
124
+ pub enum Mode {
125
+ Replace ,
126
+ Ignore ,
127
+ }
128
+
113
129
async fn copy_file_from_remote (
114
130
ssh_opts : & SshOpts ,
115
131
remote_file_path : PathBuf ,
116
132
local_file_path : PathBuf ,
133
+ mode : & Mode ,
117
134
) -> anyhow:: Result < ( ) , ScpError > {
118
135
let create_session = || create_session ( ssh_opts) ;
119
136
let session = with_retry ( create_session, 10 ) ?;
@@ -126,9 +143,21 @@ async fn copy_file_from_remote(
126
143
// make the dir if not exists
127
144
fs:: create_dir_all ( local_file_path. parent ( ) . unwrap ( ) ) ?;
128
145
129
- // Create local file and write to it
130
- let mut local_file = File :: create ( local_file_path) ?;
131
- local_file. write_all ( & contents) ?;
146
+ match mode {
147
+ Mode :: Replace => {
148
+ let mut local_file = File :: create ( & local_file_path) ?;
149
+ local_file. write_all ( & contents) ?;
150
+ }
151
+ Mode :: Ignore => {
152
+ if local_file_path. exists ( ) {
153
+ return Ok ( ( ) ) ;
154
+ }
155
+
156
+ let mut local_file = File :: create ( local_file_path) ?;
157
+ local_file. write_all ( & contents) ?;
158
+ }
159
+ }
160
+
132
161
session. disconnect ( None , "Bye" , None ) ?;
133
162
134
163
Ok ( ( ) )
0 commit comments