Browse code

* s3cmd, s3cmd.1: Added GLOB (shell-style wildcard) exclude, renamed orig regexp-style --exclude to --rexclude

git-svn-id: https://s3tools.svn.sourceforge.net/svnroot/s3tools/s3cmd/trunk@192 830e0280-6d2a-0410-9c65-932aecc39d9d

Michal Ludvig authored on 2008/06/12 00:06:15
Showing 3 changed files
... ...
@@ -1,3 +1,8 @@
1
+2008-06-12  Michal Ludvig  <michal@logix.cz>
2
+
3
+	* s3cmd, s3cmd.1: Added GLOB (shell-style wildcard) exclude, renamed
4
+	  orig regexp-style --exclude to --rexclude
5
+
1 6
 2008-06-11  Michal Ludvig  <michal@logix.cz>
2 7
 
3 8
 	* S3/PkgInfo.py: Version 0.9.8-rc1
... ...
@@ -12,6 +12,7 @@ import os
12 12
 import re
13 13
 import errno
14 14
 import pwd, grp
15
+import glob
15 16
 
16 17
 from copy import copy
17 18
 from optparse import OptionParser, Option, OptionValueError, IndentedHelpFormatter
... ...
@@ -806,6 +807,15 @@ def run_configure(config_file):
806 806
 		error("Writing config file failed: %s: %s" % (config_file, e.strerror))
807 807
 		sys.exit(1)
808 808
 
809
+def process_exclude_from_file(exf, exclude_array):
810
+	exfi = open(exf, "rt")
811
+	for ex in exfi:
812
+		ex = ex.strip()
813
+		if re.match("^#", ex) or re.match("^\s*$", ex):
814
+			continue
815
+		debug("adding rule: %s" % ex)
816
+		exclude_array.append(ex)
817
+
809 818
 commands = {}
810 819
 commands_list = [
811 820
 	{"cmd":"mb", "label":"Make bucket", "param":"s3://BUCKET", "func":cmd_bucket_create, "argc":1},
... ...
@@ -877,8 +887,10 @@ if __name__ == '__main__':
877 877
 	optparser.add_option(      "--no-delete-removed", dest="delete_removed", action="store_false", help="Don't delete remote objects.")
878 878
 	optparser.add_option("-p", "--preserve", dest="preserve_attrs", action="store_true", help="Preserve filesystem attributes (mode, ownership, timestamps). Default for [sync] command.")
879 879
 	optparser.add_option(      "--no-preserve", dest="preserve_attrs", action="store_false", help="Don't store FS attributes")
880
-	optparser.add_option(      "--exclude", dest="exclude", action="append", metavar="REGEXP", help="Filenames and paths matching REGEXP will be excluded from sync")
881
-	optparser.add_option(      "--exclude-from", dest="exclude_from", action="append", metavar="FILE", help="Read --exclude REGEXPs from FILE")
880
+	optparser.add_option(      "--exclude", dest="exclude", action="append", metavar="GLOB", help="Filenames and paths matching GLOB will be excluded from sync")
881
+	optparser.add_option(      "--exclude-from", dest="exclude_from", action="append", metavar="FILE", help="Read --exclude GLOBs from FILE")
882
+	optparser.add_option(      "--rexclude", dest="rexclude", action="append", metavar="REGEXP", help="Filenames and paths matching REGEXP (regular expression) will be excluded from sync")
883
+	optparser.add_option(      "--rexclude-from", dest="rexclude_from", action="append", metavar="FILE", help="Read --rexclude REGEXPs from FILE")
882 884
 	optparser.add_option(      "--debug-syncmatch", dest="debug_syncmatch", action="store_true", help="Output detailed information about remote vs. local filelist matching and then exit")
883 885
 
884 886
 	optparser.add_option(      "--bucket-location", dest="bucket_location", help="Datacentre to create bucket in. Either EU or US (default)")
... ...
@@ -938,23 +950,35 @@ if __name__ == '__main__':
938 938
 			## Some Config() options are not settable from command line
939 939
 			pass
940 940
 
941
+	## Process GLOB (shell wildcard style) excludes
941 942
 	if options.exclude is None:
942 943
 		options.exclude = []
943 944
 
944 945
 	if options.exclude_from:
945 946
 		for exf in options.exclude_from:
946 947
 			debug("processing --exclude-from %s" % exf)
947
-			exfi = open(exf, "rt")
948
-			for ex in exfi:
949
-				ex = ex.strip()
950
-				if re.match("^#", ex) or re.match("^\s*$", ex):
951
-					continue
952
-				debug("adding rule: %s" % ex)
953
-				options.exclude.append(ex)
948
+			process_exclude_from_file(exf, options.exclude)
954 949
 
955 950
 	if options.exclude:
956 951
 		for ex in options.exclude:
957 952
 			debug("processing rule: %s" % ex)
953
+			exc = re.compile(glob.fnmatch.translate(ex))
954
+			cfg.exclude.append(exc)
955
+			if options.debug_syncmatch:
956
+				cfg.debug_exclude[exc] = ex
957
+
958
+	## Process REGEXP style excludes
959
+	if options.rexclude is None:
960
+		options.rexclude = []
961
+
962
+	if options.rexclude_from:
963
+		for exf in options.rexclude_from:
964
+			debug("processing --rexclude-from %s" % exf)
965
+			process_exclude_from_file(exf, options.rexclude)
966
+
967
+	if options.rexclude:
968
+		for ex in options.rexclude:
969
+			debug("processing rule: %s" % ex)
958 970
 			exc = re.compile(ex)
959 971
 			cfg.exclude.append(exc)
960 972
 			if options.debug_syncmatch:
... ...
@@ -86,11 +86,17 @@ Preserve filesystem attributes (mode, ownership, timestamps). Default for 'sync'
86 86
 \fB\-\-no\-preserve\fR
87 87
 Don't store filesystem attributes with uploaded files.
88 88
 .TP
89
-\fB\-\-exclude REGEXP\fR
90
-Exclude files matching REGEXP from \fIsync\fI. See SYNC COMMAND section for more information.
89
+\fB\-\-exclude GLOB\fR
90
+Exclude files matching GLOB (a.k.a. shell-style wildcard) from \fIsync\fI. See SYNC COMMAND section for more information.
91 91
 .TP
92 92
 \fB\-\-exclude\-from FILE\fR
93
-Same as \-\-exclude but reads REGEXPs from the given FILE instead of expecting them on the command line.
93
+Same as \-\-exclude but reads GLOBs from the given FILE instead of expecting them on the command line.
94
+.TP
95
+\fB\-\-rexclude REGEXP\fR
96
+Same as \-\-exclude but works with REGEXPs (Regular expressions).
97
+.TP
98
+\fB\-\-rexclude\-from FILE\fR
99
+Same as \-\-exclude\-from but works with REGEXPs.
94 100
 .TP
95 101
 \fB\-\-debug\-syncmatch\fR
96 102
 Display detailed information about matching file names against exclude\-rules as well as information about remote vs local filelists matching. S3cmd exits after performing the match and no actual transfer takes place.
... ...
@@ -177,21 +183,26 @@ will be \fB/\fRfile1.ext and \fB/\fRdir123/file2.bin, that is both with the lead
177 177
 slash regardless whether you specified s3://test-bucket/backup or 
178 178
 s3://test-bucket/backup/ (note the trailing slash) on the command line.
179 179
 
180
-Both \fB\-\-exclude\fR and \fB\-\-exclude\-from\fR options expect regular expressions, not 
181
-shell-style wildcards! Run s3cmd with \fB\-\-debug\-syncmatch\fR to get detailed information
180
+Both \fB\-\-exclude\fR and \fB\-\-exclude\-from\fR work with shell-style wildcards (a.k.a. GLOB).
181
+For a greater flexibility s3cmd provides Regular-expression versions of the two exclude options 
182
+named \fB\-\-rexclude\fR and \fB\-\-rexclude\-from\fR. 
183
+
184
+Run s3cmd with \fB\-\-debug\-syncmatch\fR to get detailed information
182 185
 about matching file names against exclude rules.
183 186
 
184
-For example to exclude all files with ".bin" extension use:
187
+For example to exclude all files with ".bin" extension with a REGEXP use:
188
+.PP
189
+	\-\-rexclude '\.bin$'
185 190
 .PP
186
-	\-\-exclude '\.bin$'
191
+to exclude all hidden files and subdirectories (i.e. those whose name begins with dot ".") use GLOB:
187 192
 .PP
188
-to exclude all hidden files and subdirectories (i.e. those whose name begins with dot ".") use:
193
+	\-\-exclude '/.*'
189 194
 .PP
190
-	\-\-exclude '/\.'
195
+on the other hand to exclude only hidden files but not hidden subdirectories use REGEXP:
191 196
 .PP
192
-on the other hand to exclude only hidden files but not hidden subdirectories use:
197
+	\-\-rexclude '/\.[^/]*$'
193 198
 .PP
194
-	\-\-exclude '/\.[^/]*$'
199
+etc...
195 200
 
196 201
 .SH AUTHOR
197 202
 Written by Michal Ludvig <michal@logix.cz>