33
33
34
34
@command (
35
35
"transfer" ,
36
+ # the order of filter_rules determines behavior, so we need to combine
37
+ # include and exclude options during argument parsing to preserve their ordering
38
+ opts_to_combine = {
39
+ "include" : "filter_rules" ,
40
+ "exclude" : "filter_rules" ,
41
+ },
36
42
short_help = "Submit a transfer task (asynchronous)" ,
37
43
adoc_examples = """Transfer a single file:
38
44
160
166
show_default = True ,
161
167
help = ("Specify an algorithm for --external-checksum or --verify-checksum" ),
162
168
)
169
+ @click .option (
170
+ "--include" ,
171
+ multiple = True ,
172
+ show_default = True ,
173
+ expose_value = False , # this is combined into the filter_rules parameter
174
+ help = (
175
+ "Include files found with names that match the given pattern in "
176
+ 'recursive transfers. Pattern may include "*", "?", or "[]" for Unix-style '
177
+ "globbing. This option can be given multiple times along with "
178
+ "--exclude to control which files are transferred, with earlier "
179
+ "options having priority."
180
+ ),
181
+ )
163
182
@click .option (
164
183
"--exclude" ,
165
184
multiple = True ,
166
185
show_default = True ,
186
+ expose_value = False , # this is combined into the filter_rules parameter
167
187
help = (
168
- "Exclude files and directories found with names that match the given "
169
- "pattern in recursive transfers. Pattern may include * ? or [] for "
170
- "unix style globbing. Give this option multiple times to exclude "
171
- "multiple patterns."
188
+ "Exclude files found with names that match the given pattern in "
189
+ 'recursive transfers. Pattern may include "*", "?", or "[]" for Unix-style '
190
+ "globbing. This option can be given multiple times along with "
191
+ "--include to control which files are transferred, with earlier "
192
+ "options having priority."
172
193
),
173
194
)
174
195
@click .option ("--perf-cc" , type = int , hidden = True )
@@ -189,7 +210,7 @@ def transfer_command(
189
210
external_checksum : str | None ,
190
211
skip_source_errors : bool ,
191
212
fail_on_quota_errors : bool ,
192
- exclude : tuple [str , ... ],
213
+ filter_rules : list [ tuple [Literal [ "include" , "exclude" ], str ] ],
193
214
label : str | None ,
194
215
preserve_timestamp : bool ,
195
216
verify_checksum : bool ,
@@ -269,6 +290,20 @@ def transfer_command(
269
290
If a transfer fails, CHECKSUM must be used to restart the transfer.
270
291
All other levels can lead to data corruption.
271
292
293
+ \b
294
+ === Include and Exclude
295
+
296
+ The `--include` and `--exclude` options are evaluated in order together
297
+ to determine which files are transferred during recursive transfers.
298
+ Earlier `--include` and `exclude` options have priority over later such
299
+ options, with the first option that matches the name of a file being
300
+ applied. A file that does not match any `--include` or `exclude` options
301
+ is included by default, making the `--include` option only useful for
302
+ overriding later `--exclude` options.
303
+
304
+ For example, `globus transfer --include *.txt --exclude * ...` will
305
+ only transfer files ending in .txt found within the directory structure.
306
+
272
307
{AUTOMATIC_ACTIVATION}
273
308
"""
274
309
from globus_cli .services .transfer import add_batch_to_transfer_data , autoactivate
@@ -321,8 +356,9 @@ def transfer_command(
321
356
additional_fields = {** perf_opts , ** notify },
322
357
)
323
358
324
- for exclude_name in exclude :
325
- transfer_data .add_filter_rule (exclude_name )
359
+ for rule in filter_rules :
360
+ method , name = rule
361
+ transfer_data .add_filter_rule (method = method , name = name , type = "file" )
326
362
327
363
if batch :
328
364
add_batch_to_transfer_data (
@@ -348,8 +384,10 @@ def transfer_command(
348
384
else :
349
385
has_recursive_items = False
350
386
351
- if exclude and not has_recursive_items :
352
- raise click .UsageError ("--exclude can only be used with --recursive transfers" )
387
+ if filter_rules and not has_recursive_items :
388
+ raise click .UsageError (
389
+ "--include and --exclude can only be used with --recursive transfers"
390
+ )
353
391
354
392
if dry_run :
355
393
display (
0 commit comments