git-svn-id: https://s3tools.svn.sourceforge.net/svnroot/s3tools/s3cmd/trunk@357 830e0280-6d2a-0410-9c65-932aecc39d9d
W. Tell authored on 2009/01/25 19:47:49... | ... |
@@ -1185,18 +1185,50 @@ def run_configure(config_file): |
1185 | 1185 |
error(u"Writing config file failed: %s: %s" % (config_file, e.strerror)) |
1186 | 1186 |
sys.exit(1) |
1187 | 1187 |
|
1188 |
-def process_exclude_from_file(exf, exclude_array): |
|
1188 |
+def process_patterns_from_file(fname, patterns_list): |
|
1189 | 1189 |
try: |
1190 |
- exfi = open(exf, "rt") |
|
1190 |
+ fn = open(fname, "rt") |
|
1191 | 1191 |
except IOError, e: |
1192 | 1192 |
error(e) |
1193 | 1193 |
sys.exit(1) |
1194 |
- for ex in exfi: |
|
1195 |
- ex = ex.strip() |
|
1196 |
- if re.match("^#", ex) or re.match("^\s*$", ex): |
|
1194 |
+ for pattern in fn: |
|
1195 |
+ pattern = pattern.strip() |
|
1196 |
+ if re.match("^#", pattern) or re.match("^\s*$", pattern): |
|
1197 | 1197 |
continue |
1198 |
- debug(u"adding rule: %s" % ex) |
|
1199 |
- exclude_array.append(ex) |
|
1198 |
+ debug(u"%s: adding rule: %s" % (fname, pattern)) |
|
1199 |
+ patterns_list.append(pattern) |
|
1200 |
+ |
|
1201 |
+ return patterns_list |
|
1202 |
+ |
|
1203 |
+def process_patterns(patterns_list, patterns_from, is_glob, option_txt = ""): |
|
1204 |
+ """ |
|
1205 |
+ process_patterns(patterns, patterns_from, is_glob, option_txt = "") |
|
1206 |
+ Process --exclude / --include GLOB and REGEXP patterns. |
|
1207 |
+ 'option_txt' is 'exclude' / 'include' / 'rexclude' / 'rinclude' |
|
1208 |
+ Returns: patterns_compiled, patterns_text |
|
1209 |
+ """ |
|
1210 |
+ |
|
1211 |
+ patterns_compiled = [] |
|
1212 |
+ patterns_textual = {} |
|
1213 |
+ |
|
1214 |
+ if patterns_list is None: |
|
1215 |
+ patterns_list = [] |
|
1216 |
+ |
|
1217 |
+ if patterns_from: |
|
1218 |
+ ## Append patterns from glob_from |
|
1219 |
+ for fname in patterns_from: |
|
1220 |
+ debug(u"processing --%s-from %s" % (option_txt, fname)) |
|
1221 |
+ patterns_list = process_patterns_from_file(fname, patterns_list) |
|
1222 |
+ |
|
1223 |
+ for pattern in patterns_list: |
|
1224 |
+ debug(u"processing %s rule: %s" % (option_txt, patterns_list)) |
|
1225 |
+ if is_glob: |
|
1226 |
+ pattern = glob.fnmatch.translate(pattern) |
|
1227 |
+ r = re.compile(pattern) |
|
1228 |
+ patterns_compiled.append(r) |
|
1229 |
+ patterns_textual[r] = pattern |
|
1230 |
+ |
|
1231 |
+ return patterns_compiled, patterns_textual |
|
1200 | 1232 |
|
1201 | 1233 |
commands = {} |
1202 | 1234 |
commands_list = [ |
... | ... |
@@ -1288,6 +1320,10 @@ def main(): |
1288 | 1288 |
optparser.add_option( "--exclude-from", dest="exclude_from", action="append", metavar="FILE", help="Read --exclude GLOBs from FILE") |
1289 | 1289 |
optparser.add_option( "--rexclude", dest="rexclude", action="append", metavar="REGEXP", help="Filenames and paths matching REGEXP (regular expression) will be excluded from sync") |
1290 | 1290 |
optparser.add_option( "--rexclude-from", dest="rexclude_from", action="append", metavar="FILE", help="Read --rexclude REGEXPs from FILE") |
1291 |
+ optparser.add_option( "--include", dest="include", action="append", metavar="GLOB", help="Filenames and paths matching GLOB will be included even if previously excluded by one of --(r)exclude(-from) patterns") |
|
1292 |
+ optparser.add_option( "--include-from", dest="include_from", action="append", metavar="FILE", help="Read --include GLOBs from FILE") |
|
1293 |
+ optparser.add_option( "--rinclude", dest="rinclude", action="append", metavar="REGEXP", help="Same as --include but uses REGEXP (regular expression) instead of GLOB") |
|
1294 |
+ optparser.add_option( "--rinclude-from", dest="rinclude_from", action="append", metavar="FILE", help="Read --rinclude REGEXPs from FILE") |
|
1291 | 1295 |
optparser.add_option( "--debug-syncmatch", "--debug-exclude", dest="debug_syncmatch", action="store_true", help="Output detailed information about remote vs. local filelist matching and --exclude processing and then exit") |
1292 | 1296 |
|
1293 | 1297 |
optparser.add_option( "--bucket-location", dest="bucket_location", help="Datacentre to create bucket in. Either EU or US (default)") |
... | ... |
@@ -1374,37 +1410,25 @@ def main(): |
1374 | 1374 |
sys.stdout = codecs.getwriter(cfg.encoding)(sys.stdout, "replace") |
1375 | 1375 |
sys.stderr = codecs.getwriter(cfg.encoding)(sys.stderr, "replace") |
1376 | 1376 |
|
1377 |
- ## Process GLOB (shell wildcard style) excludes |
|
1378 |
- if options.exclude is None: |
|
1379 |
- options.exclude = [] |
|
1380 |
- |
|
1381 |
- if options.exclude_from: |
|
1382 |
- for exf in options.exclude_from: |
|
1383 |
- debug(u"processing --exclude-from %s" % exf) |
|
1384 |
- process_exclude_from_file(exf, options.exclude) |
|
1385 |
- |
|
1386 |
- if options.exclude: |
|
1387 |
- for ex in options.exclude: |
|
1388 |
- debug(u"processing rule: %s" % ex) |
|
1389 |
- exc = re.compile(glob.fnmatch.translate(ex)) |
|
1390 |
- cfg.exclude.append(exc) |
|
1391 |
- cfg.debug_exclude[exc] = ex |
|
1392 |
- |
|
1393 |
- ## Process REGEXP style excludes |
|
1394 |
- if options.rexclude is None: |
|
1395 |
- options.rexclude = [] |
|
1396 |
- |
|
1397 |
- if options.rexclude_from: |
|
1398 |
- for exf in options.rexclude_from: |
|
1399 |
- debug(u"processing --rexclude-from %s" % exf) |
|
1400 |
- process_exclude_from_file(exf, options.rexclude) |
|
1401 |
- |
|
1402 |
- if options.rexclude: |
|
1403 |
- for ex in options.rexclude: |
|
1404 |
- debug(u"processing rule: %s" % ex) |
|
1405 |
- exc = re.compile(ex) |
|
1406 |
- cfg.exclude.append(exc) |
|
1407 |
- cfg.debug_exclude[exc] = ex |
|
1377 |
+ ## Process --exclude and --exclude-from |
|
1378 |
+ patterns_list, patterns_textual = process_patterns(options.exclude, options.exclude_from, is_glob = True, option_txt = "exclude") |
|
1379 |
+ cfg.exclude.extend(patterns_list) |
|
1380 |
+ cfg.debug_exclude.update(patterns_textual) |
|
1381 |
+ |
|
1382 |
+ ## Process --rexclude and --rexclude-from |
|
1383 |
+ patterns_list, patterns_textual = process_patterns(options.rexclude, options.rexclude_from, is_glob = False, option_txt = "rexclude") |
|
1384 |
+ cfg.exclude.extend(patterns_list) |
|
1385 |
+ cfg.debug_exclude.update(patterns_textual) |
|
1386 |
+ |
|
1387 |
+ ## Process --include and --include-from |
|
1388 |
+ patterns_list, patterns_textual = process_patterns(options.include, options.include_from, is_glob = True, option_txt = "include") |
|
1389 |
+ cfg.include.extend(patterns_list) |
|
1390 |
+ cfg.debug_include.update(patterns_textual) |
|
1391 |
+ |
|
1392 |
+ ## Process --rinclude and --rinclude-from |
|
1393 |
+ patterns_list, patterns_textual = process_patterns(options.rinclude, options.rinclude_from, is_glob = False, option_txt = "rinclude") |
|
1394 |
+ cfg.include.extend(patterns_list) |
|
1395 |
+ cfg.debug_include.update(patterns_textual) |
|
1408 | 1396 |
|
1409 | 1397 |
if cfg.encrypt and cfg.gpg_passphrase == "": |
1410 | 1398 |
error(u"Encryption requested but no passphrase set in config file.") |