55
55
"""
56
56
57
57
58
- def resolve_optional_local_time (
59
- start : datetime .datetime | None ,
60
- ) -> datetime .datetime | globus_sdk .utils .MissingType :
61
- if start is None :
62
- return globus_sdk .MISSING
63
- # set the timezone to local system time if the timezone input is not aware
64
- start_with_tz = start .astimezone () if start .tzinfo is None else start
65
- return start_with_tz
66
-
67
-
68
58
@command ("transfer" , short_help = "Create a recurring transfer timer." )
69
59
@click .argument (
70
60
"source" , metavar = "SOURCE_ENDPOINT_ID[:SOURCE_PATH]" , type = ENDPOINT_PLUS_OPTPATH
@@ -108,6 +98,15 @@ def resolve_optional_local_time(
108
98
help = "Stop running the transfer after this number of runs have happened." ,
109
99
)
110
100
@mutex_option_group ("--stop-after-date" , "--stop-after-runs" )
101
+ @click .option (
102
+ "--delete" ,
103
+ is_flag = True ,
104
+ default = False ,
105
+ help = (
106
+ "Delete any files in the destination directory not contained in the source. "
107
+ 'This results in "directory mirroring." Only valid on recursive transfers.'
108
+ ),
109
+ )
111
110
@LoginManager .requires_login ("auth" , "timer" , "transfer" )
112
111
def transfer_command (
113
112
login_manager : LoginManager ,
@@ -122,6 +121,7 @@ def transfer_command(
122
121
label : str | None ,
123
122
stop_after_date : datetime .datetime | None ,
124
123
stop_after_runs : int | None ,
124
+ delete : bool ,
125
125
sync_level : t .Literal ["exists" , "size" , "mtime" , "checksum" ] | None ,
126
126
encrypt_data : bool ,
127
127
verify_checksum : bool ,
@@ -174,13 +174,18 @@ def transfer_command(
174
174
source_endpoint , cmd_source_path = source
175
175
dest_endpoint , cmd_dest_path = destination
176
176
177
- # avoid 'mutex_option_group', emit a custom error message
178
- if recursive is not None and batch :
179
- option_name = "--recursive" if recursive else "--no-recursive"
180
- raise click .UsageError (
181
- f"You cannot use { option_name } in addition to --batch. "
182
- f"Instead, use { option_name } on lines of --batch input which need it."
183
- )
177
+ if recursive is not None :
178
+ if batch :
179
+ # avoid 'mutex_option_group', emit a custom error message
180
+ option_name = "--recursive" if recursive else "--no-recursive"
181
+ raise click .UsageError (
182
+ f"You cannot use { option_name } in addition to --batch. "
183
+ f"Instead, use { option_name } on lines of --batch input which need it."
184
+ )
185
+
186
+ if delete and not recursive :
187
+ msg = "The --delete option cannot be specified with --no-recursion."
188
+ raise click .UsageError (msg )
184
189
if (cmd_source_path is None or cmd_dest_path is None ) and (not batch ):
185
190
raise click .UsageError (
186
191
"transfer requires either SOURCE_PATH and DEST_PATH or --batch"
@@ -273,6 +278,7 @@ def transfer_command(
273
278
encrypt_data = encrypt_data ,
274
279
skip_source_errors = skip_source_errors ,
275
280
fail_on_quota_errors = fail_on_quota_errors ,
281
+ delete_destination_extra = delete ,
276
282
# mypy can't understand kwargs expansion very well
277
283
** notify , # type: ignore[arg-type]
278
284
)
@@ -296,6 +302,16 @@ def transfer_command(
296
302
display (response ["timer" ], text_mode = display .RECORD , fields = FORMAT_FIELDS )
297
303
298
304
305
+ def resolve_optional_local_time (
306
+ start : datetime .datetime | None ,
307
+ ) -> datetime .datetime | globus_sdk .utils .MissingType :
308
+ if start is None :
309
+ return globus_sdk .MISSING
310
+ # set the timezone to local system time if the timezone input is not aware
311
+ start_with_tz = start .astimezone () if start .tzinfo is None else start
312
+ return start_with_tz
313
+
314
+
299
315
def _derive_needed_scopes (
300
316
needs_data_access : list [str ],
301
317
) -> dict [str , MutableScope ]:
0 commit comments