| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 # Copyright (c) 2012 The Native Client Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 import fnmatch | 6 import fnmatch |
| 7 import glob | 7 import glob |
| 8 import optparse | 8 import optparse |
| 9 import os | 9 import os |
| 10 import posixpath | 10 import posixpath |
| 11 import shutil | 11 import shutil |
| 12 import sys | 12 import sys |
| 13 import time | 13 import time |
| 14 import zipfile | 14 import zipfile |
| 15 | 15 |
| 16 | 16 |
| 17 def IncludeFiles(filters, files): | 17 def IncludeFiles(filters, files): |
| 18 """Filter files based on inclusion lists | 18 """Filter files based on inclusion lists |
| 19 | 19 |
| 20 Return a list of files which match and of the Unix shell-style wildcards | 20 Return a list of files which match and of the Unix shell-style wildcards |
| 21 provided, or return all the files if no filter is provided.""" | 21 provided, or return all the files if no filter is provided.""" |
| 22 if not filters: | 22 if not filters: |
| 23 return files | 23 return files |
| 24 match = set() | 24 match = set() |
| 25 for filter in filters: | 25 for file_filter in filters: |
| 26 match |= set(fnmatch.filter(files, filter)) | 26 match |= set(fnmatch.filter(files, file_filter)) |
| 27 return [name for name in files if name in match] | 27 return [name for name in files if name in match] |
| 28 | 28 |
| 29 | 29 |
| 30 def ExcludeFiles(filters, files): | 30 def ExcludeFiles(filters, files): |
| 31 """Filter files based on exclusions lists | 31 """Filter files based on exclusions lists |
| 32 | 32 |
| 33 Return a list of files which do not match any of the Unix shell-style | 33 Return a list of files which do not match any of the Unix shell-style |
| 34 wildcards provided, or return all the files if no filter is provided.""" | 34 wildcards provided, or return all the files if no filter is provided.""" |
| 35 if not filters: | 35 if not filters: |
| 36 return files | 36 return files |
| 37 match = set() | 37 match = set() |
| 38 for filter in filters: | 38 for file_filter in filters: |
| 39 excludes = set(fnmatch.filter(files, filter)) | 39 excludes = set(fnmatch.filter(files, file_filter)) |
| 40 match |= excludes | 40 match |= excludes |
| 41 return [name for name in files if name not in match] | 41 return [name for name in files if name not in match] |
| 42 | 42 |
| 43 | 43 |
| 44 def CopyPath(options, src, dst): | 44 def CopyPath(options, src, dst): |
| 45 """CopyPath from src to dst | 45 """CopyPath from src to dst |
| 46 | 46 |
| 47 Copy a fully specified src to a fully specified dst. If src and dst are | 47 Copy a fully specified src to a fully specified dst. If src and dst are |
| 48 both files, the dst file is removed first to prevent error. If and include | 48 both files, the dst file is removed first to prevent error. If and include |
| 49 or exclude list are provided, the destination is first matched against that | 49 or exclude list are provided, the destination is first matched against that |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 | 156 |
| 157 options, dsts = parser.parse_args(args) | 157 options, dsts = parser.parse_args(args) |
| 158 if len(dsts) < 1: | 158 if len(dsts) < 1: |
| 159 parser.error('ERROR: expecting DIRECTORY...') | 159 parser.error('ERROR: expecting DIRECTORY...') |
| 160 | 160 |
| 161 for dst in dsts: | 161 for dst in dsts: |
| 162 if options.verbose: | 162 if options.verbose: |
| 163 print 'mkdir ' + dst | 163 print 'mkdir ' + dst |
| 164 try: | 164 try: |
| 165 os.makedirs(dst) | 165 os.makedirs(dst) |
| 166 except OSError as error: | 166 except OSError: |
| 167 if os.path.isdir(dst): | 167 if os.path.isdir(dst): |
| 168 if options.parents: | 168 if options.parents: |
| 169 continue | 169 continue |
| 170 raise OSError('mkdir: Already exsists: ' + dst) | 170 raise OSError('mkdir: Already exsists: ' + dst) |
| 171 else: | 171 else: |
| 172 raise OSError('mkdir: Failed to create: ' + dst) | 172 raise OSError('mkdir: Failed to create: ' + dst) |
| 173 return 0 | 173 return 0 |
| 174 | 174 |
| 175 | 175 |
| 176 def MovePath(options, src, dst): | 176 def MovePath(options, src, dst): |
| 177 """MovePath from src to dst | 177 """MovePath from src to dst |
| 178 | 178 |
| 179 Moves the src to the dst much like the Unix style mv command, except it | 179 Moves the src to the dst much like the Unix style mv command, except it |
| 180 only handles one source at a time. Because of possible temporary failures | 180 only handles one source at a time. Because of possible temporary failures |
| 181 do to locks (such as anti-virus software on Windows), the function will retry | 181 do to locks (such as anti-virus software on Windows), the function will retry |
| 182 up to five times.""" | 182 up to five times.""" |
| 183 # if the destination is not an existing directory, then overwrite it | 183 # if the destination is not an existing directory, then overwrite it |
| 184 if os.path.isdir(dst): | 184 if os.path.isdir(dst): |
| 185 dst = os.path.join(dst, os.path.basename(src)) | 185 dst = os.path.join(dst, os.path.basename(src)) |
| 186 | 186 |
| 187 # If the destination exists, the remove it | 187 # If the destination exists, the remove it |
| 188 if os.path.exists(dst): | 188 if os.path.exists(dst): |
| 189 if options.force: | 189 if options.force: |
| 190 Remove(['-vfr', dst]) | 190 Remove(['-vfr', dst]) |
| 191 if os.path.exists(dst): | 191 if os.path.exists(dst): |
| 192 raise OSError('mv: FAILED TO REMOVE ' + dst) | 192 raise OSError('mv: FAILED TO REMOVE ' + dst) |
| 193 else: | 193 else: |
| 194 raise OSError('mv: already exists ' + dst) | 194 raise OSError('mv: already exists ' + dst) |
| 195 for i in range(5): | 195 for _ in range(5): |
| 196 try: | 196 try: |
| 197 os.rename(src, dst) | 197 os.rename(src, dst) |
| 198 return | 198 return |
| 199 except OSError as error: | 199 except OSError as error: |
| 200 print 'Failed on %s with %s, retrying' % (src, error) | 200 print 'Failed on %s with %s, retrying' % (src, error) |
| 201 time.sleep(5) | 201 time.sleep(5) |
| 202 print 'Gave up.' | 202 print 'Gave up.' |
| 203 raise OSError('mv: ' + error) | 203 raise OSError('mv: ' + error) |
| 204 | 204 |
| 205 | 205 |
| 206 def Move(args): | 206 def Move(args): |
| 207 parser = optparse.OptionParser(usage='usage: mv [Options] souces... dest') | 207 parser = optparse.OptionParser(usage='usage: mv [Options] souces... dest') |
| 208 parser.add_option( | 208 parser.add_option( |
| 209 '-v', '--verbose', dest='verbose', action='store_true', | 209 '-v', '--verbose', dest='verbose', action='store_true', |
| 210 default=False, | 210 default=False, |
| 211 help='verbose output.') | 211 help='verbose output.') |
| 212 parser.add_option( | 212 parser.add_option( |
| 213 '-f', '--force', dest='force', action='store_true', | 213 '-f', '--force', dest='force', action='store_true', |
| 214 default=False, | 214 default=False, |
| 215 help='force, do not error it files already exist.') | 215 help='force, do not error it files already exist.') |
| 216 options, files = parser.parse_args(args) | 216 options, files = parser.parse_args(args) |
| 217 if len(files) < 2: | 217 if len(files) < 2: |
| 218 parser.error('ERROR: expecting SOURCE... and DEST.') | 218 parser.error('ERROR: expecting SOURCE... and DEST.') |
| 219 if options.verbose: | |
| 220 print 'mv %s %s' % (src, dst) | |
| 221 | 219 |
| 222 srcs = files[:-1] | 220 srcs = files[:-1] |
| 223 dst = files[-1] | 221 dst = files[-1] |
| 224 | 222 |
| 223 if options.verbose: |
| 224 print 'mv %s %s' % (' '.join(srcs), dst) |
| 225 |
| 225 for src in srcs: | 226 for src in srcs: |
| 226 MovePath(options, src, dst) | 227 MovePath(options, src, dst) |
| 227 return 0 | 228 return 0 |
| 228 | 229 |
| 229 | 230 |
| 230 def Remove(args): | 231 def Remove(args): |
| 231 """A Unix style rm. | 232 """A Unix style rm. |
| 232 | 233 |
| 233 Removes the list of paths. Because of possible temporary failures do to locks | 234 Removes the list of paths. Because of possible temporary failures do to locks |
| 234 (such as anti-virus software on Windows), the function will retry up to five | 235 (such as anti-virus software on Windows), the function will retry up to five |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 globbed_src_args = glob.glob(src_arg) | 360 globbed_src_args = glob.glob(src_arg) |
| 360 if len(globbed_src_args) == 0: | 361 if len(globbed_src_args) == 0: |
| 361 if not options.quiet: | 362 if not options.quiet: |
| 362 print 'zip warning: name not matched: %s' % (src_arg,) | 363 print 'zip warning: name not matched: %s' % (src_arg,) |
| 363 | 364 |
| 364 for src_file in globbed_src_args: | 365 for src_file in globbed_src_args: |
| 365 src_file = os.path.normpath(src_file) | 366 src_file = os.path.normpath(src_file) |
| 366 src_files.append(src_file) | 367 src_files.append(src_file) |
| 367 if options.recursive and os.path.isdir(src_file): | 368 if options.recursive and os.path.isdir(src_file): |
| 368 for root, dirs, files in os.walk(src_file): | 369 for root, dirs, files in os.walk(src_file): |
| 369 for dir in dirs: | 370 for dirname in dirs: |
| 370 src_files.append(os.path.join(root, dir)) | 371 src_files.append(os.path.join(root, dirname)) |
| 371 for file in files: | 372 for filename in files: |
| 372 src_files.append(os.path.join(root, file)) | 373 src_files.append(os.path.join(root, filename)) |
| 373 | 374 |
| 374 zip_stream = None | 375 zip_stream = None |
| 375 # zip_data represents a list of the data to be written or appended to the | 376 # zip_data represents a list of the data to be written or appended to the |
| 376 # zip_stream. It is a list of tuples: | 377 # zip_stream. It is a list of tuples: |
| 377 # (OS file path, zip path/zip file info, and file data) | 378 # (OS file path, zip path/zip file info, and file data) |
| 378 # In all cases one of the |os path| or the |file data| will be None. | 379 # In all cases one of the |os path| or the |file data| will be None. |
| 379 # |os path| is None when there is no OS file to write to the archive (i.e. | 380 # |os path| is None when there is no OS file to write to the archive (i.e. |
| 380 # the file data already existed in the archive). |file data| is None when the | 381 # the file data already existed in the archive). |file data| is None when the |
| 381 # file is new (never existed in the archive) or being updated. | 382 # file is new (never existed in the archive) or being updated. |
| 382 zip_data = [] | 383 zip_data = [] |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 'zip': Zip, | 455 'zip': Zip, |
| 455 } | 456 } |
| 456 | 457 |
| 457 | 458 |
| 458 if __name__ == '__main__': | 459 if __name__ == '__main__': |
| 459 func = FuncMap.get(sys.argv[1]) | 460 func = FuncMap.get(sys.argv[1]) |
| 460 if not func: | 461 if not func: |
| 461 print 'Do not recognize: ' + sys.argv[1] | 462 print 'Do not recognize: ' + sys.argv[1] |
| 462 sys.exit(1) | 463 sys.exit(1) |
| 463 sys.exit(func(sys.argv[2:])) | 464 sys.exit(func(sys.argv[2:])) |
| OLD | NEW |