OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium 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 from __future__ import print_function | |
7 | |
6 import fnmatch | 8 import fnmatch |
7 import glob | 9 import glob |
8 import optparse | 10 import argparse |
9 import os | 11 import os |
10 import posixpath | 12 import posixpath |
11 import shutil | 13 import shutil |
12 import stat | 14 import stat |
13 import sys | 15 import sys |
14 import time | 16 import time |
15 import zipfile | 17 import zipfile |
16 | 18 |
17 if sys.version_info < (2, 6, 0): | 19 if sys.version_info < (2, 6, 0): |
18 sys.stderr.write("python 2.6 or later is required run this script\n") | 20 sys.stderr.write("python 2.6 or later is required run this script\n") |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
55 filter.""" | 57 filter.""" |
56 if options.includes: | 58 if options.includes: |
57 if not IncludeFiles(options.includes, [src]): | 59 if not IncludeFiles(options.includes, [src]): |
58 return | 60 return |
59 | 61 |
60 if options.excludes: | 62 if options.excludes: |
61 if not ExcludeFiles(options.excludes, [src]): | 63 if not ExcludeFiles(options.excludes, [src]): |
62 return | 64 return |
63 | 65 |
64 if options.verbose: | 66 if options.verbose: |
65 print 'cp %s %s' % (src, dst) | 67 print('cp %s %s' % (src, dst)) |
66 | 68 |
67 # If the source is a single file, copy it individually | 69 # If the source is a single file, copy it individually |
68 if os.path.isfile(src): | 70 if os.path.isfile(src): |
69 # We can not copy over a directory with a file. | 71 # We can not copy over a directory with a file. |
70 if os.path.exists(dst): | 72 if os.path.exists(dst): |
71 if not os.path.isfile(dst): | 73 if not os.path.isfile(dst): |
72 msg = "cp: cannot overwrite non-file '%s' with file." % dst | 74 msg = "cp: cannot overwrite non-file '%s' with file." % dst |
73 raise OSError(msg) | 75 raise OSError(msg) |
74 # If the destination exists as a file, remove it before copying to avoid | 76 # If the destination exists as a file, remove it before copying to avoid |
75 # 'readonly' issues. | 77 # 'readonly' issues. |
76 os.remove(dst) | 78 os.remove(dst) |
77 | 79 |
78 # Now copy to the non-existent fully qualified target | 80 # Now copy to the non-existent fully qualified target |
79 shutil.copy(src, dst) | 81 shutil.copy(src, dst) |
80 return | 82 return |
81 | 83 |
82 # Otherwise it's a directory, ignore it unless allowed | 84 # Otherwise it's a directory, ignore it unless allowed |
83 if os.path.isdir(src): | 85 if os.path.isdir(src): |
84 if not options.recursive: | 86 if not options.recursive: |
85 print "cp: omitting directory '%s'" % src | 87 print("cp: omitting directory '%s'" % src) |
86 return | 88 return |
87 | 89 |
88 # We can not copy over a file with a directory. | 90 # We can not copy over a file with a directory. |
89 if os.path.exists(dst): | 91 if os.path.exists(dst): |
90 if not os.path.isdir(dst): | 92 if not os.path.isdir(dst): |
91 msg = "cp: cannot overwrite non-directory '%s' with directory." % dst | 93 msg = "cp: cannot overwrite non-directory '%s' with directory." % dst |
92 raise OSError(msg) | 94 raise OSError(msg) |
93 else: | 95 else: |
94 # if it didn't exist, create the directory | 96 # if it didn't exist, create the directory |
95 os.makedirs(dst) | 97 os.makedirs(dst) |
96 | 98 |
97 # Now copy all members | 99 # Now copy all members |
98 for filename in os.listdir(src): | 100 for filename in os.listdir(src): |
99 srcfile = os.path.join(src, filename) | 101 srcfile = os.path.join(src, filename) |
100 dstfile = os.path.join(dst, filename) | 102 dstfile = os.path.join(dst, filename) |
101 CopyPath(options, srcfile, dstfile) | 103 CopyPath(options, srcfile, dstfile) |
102 return | 104 return |
103 | 105 |
104 | 106 |
105 def Copy(args): | 107 def Copy(args): |
106 """A Unix cp style copy. | 108 """A Unix cp style copy. |
107 | 109 |
108 Copies multiple sources to a single destination using the normal cp | 110 Copies multiple sources to a single destination using the normal cp |
109 semantics. In addition, it support inclusion and exclusion filters which | 111 semantics. In addition, it support inclusion and exclusion filters which |
110 allows the copy to skip certain types of files.""" | 112 allows the copy to skip certain types of files.""" |
111 parser = optparse.OptionParser(usage='usage: cp [Options] sources... dest') | 113 parser = argparse.ArgumentParser(usage='cp [Options] sources... dest') |
binji
2014/11/13 23:57:04
use doc?
Sam Clegg
2014/11/30 17:55:13
Done.
| |
112 parser.add_option( | 114 parser.add_argument( |
113 '-R', '-r', '--recursive', dest='recursive', action='store_true', | 115 '-R', '-r', '--recursive', dest='recursive', action='store_true', |
114 default=False, | 116 default=False, |
115 help='copy directories recursively.') | 117 help='copy directories recursively.') |
116 parser.add_option( | 118 parser.add_argument( |
117 '-v', '--verbose', dest='verbose', action='store_true', | 119 '-v', '--verbose', dest='verbose', action='store_true', |
118 default=False, | 120 default=False, |
119 help='verbose output.') | 121 help='verbose output.') |
120 parser.add_option( | 122 parser.add_argument( |
121 '--include', dest='includes', action='append', default=[], | 123 '--include', dest='includes', action='append', default=[], |
122 help='include files matching this expression.') | 124 help='include files matching this expression.') |
123 parser.add_option( | 125 parser.add_argument( |
124 '--exclude', dest='excludes', action='append', default=[], | 126 '--exclude', dest='excludes', action='append', default=[], |
125 help='exclude files matching this expression.') | 127 help='exclude files matching this expression.') |
126 options, files = parser.parse_args(args) | 128 parser.add_argument('src', nargs='+', help='files to copy') |
binji
2014/11/13 23:57:04
srcs
Sam Clegg
2014/11/30 17:55:13
Done.
| |
127 if len(files) < 2: | 129 parser.add_argument('dest', help='destination') |
128 parser.error('ERROR: expecting SOURCE(s) and DEST.') | |
129 | 130 |
130 srcs = files[:-1] | 131 options = parser.parse_args(args) |
131 dst = files[-1] | |
132 | 132 |
133 src_list = [] | 133 src_list = [] |
134 for src in srcs: | 134 for src in options.src: |
135 files = glob.glob(src) | 135 files = glob.glob(src) |
136 if not files: | 136 if not files: |
137 raise OSError('cp: no such file or directory: ' + src) | 137 raise OSError('cp: no such file or directory: ' + src) |
138 if files: | 138 if files: |
139 src_list.extend(files) | 139 src_list.extend(files) |
140 | 140 |
141 for src in src_list: | 141 for src in src_list: |
142 # If the destination is a directory, then append the basename of the src | 142 # If the destination is a directory, then append the basename of the src |
143 # to the destination. | 143 # to the destination. |
144 if os.path.isdir(dst): | 144 if os.path.isdir(options.dest): |
145 CopyPath(options, src, os.path.join(dst, os.path.basename(src))) | 145 CopyPath(options, src, os.path.join(options.dest, os.path.basename(src))) |
146 else: | 146 else: |
147 CopyPath(options, src, dst) | 147 CopyPath(options, src, options.dest) |
148 | 148 |
149 | 149 |
150 def Mkdir(args): | 150 def Mkdir(args): |
151 """A Unix style mkdir""" | 151 """A Unix style mkdir""" |
152 parser = optparse.OptionParser(usage='usage: mkdir [Options] DIRECTORY...') | 152 parser = argparse.ArgumentParser(usage='mkdir [Options] DIRECTORY...') |
binji
2014/11/13 23:57:04
use doc?
Sam Clegg
2014/11/30 17:55:13
Done.
| |
153 parser.add_option( | 153 parser.add_argument( |
154 '-p', '--parents', dest='parents', action='store_true', | 154 '-p', '--parents', dest='parents', action='store_true', |
155 default=False, | 155 default=False, |
156 help='ignore existing parents, create parents as needed.') | 156 help='ignore existing parents, create parents as needed.') |
157 parser.add_option( | 157 parser.add_argument( |
158 '-v', '--verbose', dest='verbose', action='store_true', | 158 '-v', '--verbose', dest='verbose', action='store_true', |
159 default=False, | 159 default=False, |
160 help='verbose output.') | 160 help='verbose output.') |
161 parser.add_argument('dirs', nargs='+', help='directoy to create') | |
binji
2014/11/13 23:57:04
sp: directories
Sam Clegg
2014/11/30 17:55:13
Done.
| |
161 | 162 |
162 options, dsts = parser.parse_args(args) | 163 options = parser.parse_args(args) |
163 if len(dsts) < 1: | |
164 parser.error('ERROR: expecting DIRECTORY...') | |
165 | 164 |
166 for dst in dsts: | 165 for dst in options.dirs: |
167 if options.verbose: | 166 if options.verbose: |
168 print 'mkdir ' + dst | 167 print('mkdir %s' % dst) |
169 try: | 168 try: |
170 os.makedirs(dst) | 169 os.makedirs(dst) |
171 except OSError: | 170 except OSError: |
172 if os.path.isdir(dst): | 171 if os.path.isdir(dst): |
173 if options.parents: | 172 if options.parents: |
174 continue | 173 continue |
175 raise OSError('mkdir: Already exists: ' + dst) | 174 raise OSError('mkdir: Already exists: ' + dst) |
176 else: | 175 else: |
177 raise OSError('mkdir: Failed to create: ' + dst) | 176 raise OSError('mkdir: Failed to create: ' + dst) |
178 return 0 | 177 return 0 |
(...skipping 14 matching lines...) Expand all Loading... | |
193 if os.path.exists(dst): | 192 if os.path.exists(dst): |
194 if options.force: | 193 if options.force: |
195 Remove(['-vfr', dst]) | 194 Remove(['-vfr', dst]) |
196 if os.path.exists(dst): | 195 if os.path.exists(dst): |
197 raise OSError('mv: FAILED TO REMOVE ' + dst) | 196 raise OSError('mv: FAILED TO REMOVE ' + dst) |
198 else: | 197 else: |
199 raise OSError('mv: already exists ' + dst) | 198 raise OSError('mv: already exists ' + dst) |
200 for _ in range(5): | 199 for _ in range(5): |
201 try: | 200 try: |
202 os.rename(src, dst) | 201 os.rename(src, dst) |
203 return | 202 break |
204 except OSError as error: | 203 except OSError as error: |
205 print 'Failed on %s with %s, retrying' % (src, error) | 204 print('Failed on %s with %s, retrying' % (src, error)) |
206 time.sleep(5) | 205 time.sleep(5) |
207 print 'Gave up.' | 206 else: |
binji
2014/11/13 23:57:04
I find for/else confusing, but OK
Sam Clegg
2014/11/30 17:55:13
I will re-write this as a function and/or context
| |
208 raise OSError('mv: ' + error) | 207 print('Gave up.') |
208 raise OSError('mv: ' + error) | |
209 | 209 |
210 | 210 |
211 def Move(args): | 211 def Move(args): |
212 parser = optparse.OptionParser(usage='usage: mv [Options] sources... dest') | 212 parser = argparse.ArgumentParser(usage='mv [Options] sources... dest') |
binji
2014/11/13 23:57:04
use doc?
Sam Clegg
2014/11/30 17:55:13
Done.
| |
213 parser.add_option( | 213 parser.add_argument( |
214 '-v', '--verbose', dest='verbose', action='store_true', | 214 '-v', '--verbose', dest='verbose', action='store_true', |
215 default=False, | 215 default=False, |
216 help='verbose output.') | 216 help='verbose output.') |
217 parser.add_option( | 217 parser.add_argument( |
218 '-f', '--force', dest='force', action='store_true', | 218 '-f', '--force', dest='force', action='store_true', |
219 default=False, | 219 default=False, |
220 help='force, do not error it files already exist.') | 220 help='force, do not error it files already exist.') |
221 options, files = parser.parse_args(args) | 221 parser.add_argument('source', nargs='+') |
binji
2014/11/13 23:57:04
srcs
| |
222 if len(files) < 2: | 222 parser.add_argument('dest') |
223 parser.error('ERROR: expecting SOURCE... and DEST.') | |
224 | 223 |
225 srcs = files[:-1] | 224 options = parser.parse_args(args) |
226 dst = files[-1] | |
227 | 225 |
228 if options.verbose: | 226 if options.verbose: |
229 print 'mv %s %s' % (' '.join(srcs), dst) | 227 print('mv %s %s' % (' '.join(options.srcs), options.dest)) |
230 | 228 |
231 for src in srcs: | 229 for src in options.srcs: |
232 MovePath(options, src, dst) | 230 MovePath(options, src, options.dest) |
233 return 0 | 231 return 0 |
234 | 232 |
235 | 233 |
236 def Remove(args): | 234 def Remove(args): |
237 """A Unix style rm. | 235 """A Unix style rm. |
238 | 236 |
239 Removes the list of paths. Because of possible temporary failures do to locks | 237 Removes the list of paths. Because of possible temporary failures do to locks |
240 (such as anti-virus software on Windows), the function will retry up to five | 238 (such as anti-virus software on Windows), the function will retry up to five |
241 times.""" | 239 times.""" |
242 parser = optparse.OptionParser(usage='usage: rm [Options] PATHS...') | 240 parser = argparse.ArgumentParser(usage='rm [Options] PATHS...') |
243 parser.add_option( | 241 parser.add_argument( |
244 '-R', '-r', '--recursive', dest='recursive', action='store_true', | 242 '-R', '-r', '--recursive', dest='recursive', action='store_true', |
245 default=False, | 243 default=False, |
246 help='remove directories recursively.') | 244 help='remove directories recursively.') |
247 parser.add_option( | 245 parser.add_argument( |
248 '-v', '--verbose', dest='verbose', action='store_true', | 246 '-v', '--verbose', dest='verbose', action='store_true', |
249 default=False, | 247 default=False, |
250 help='verbose output.') | 248 help='verbose output.') |
251 parser.add_option( | 249 parser.add_argument( |
252 '-f', '--force', dest='force', action='store_true', | 250 '-f', '--force', dest='force', action='store_true', |
253 default=False, | 251 default=False, |
254 help='force, do not error it files does not exist.') | 252 help='force, do not error it files does not exist.') |
255 options, files = parser.parse_args(args) | 253 parser.add_argument('files', nargs='+') |
256 if len(files) < 1: | 254 options = parser.parse_args(args) |
257 parser.error('ERROR: expecting FILE...') | |
258 | 255 |
259 try: | 256 try: |
260 for pattern in files: | 257 for pattern in options.files: |
261 dst_files = glob.glob(pattern) | 258 dst_files = glob.glob(pattern) |
262 if not dst_files: | 259 if not dst_files: |
263 # Ignore non existing files when using force | 260 # Ignore non existing files when using force |
264 if options.force: | 261 if options.force: |
265 continue | 262 continue |
266 raise OSError('rm: no such file or directory: ' + pattern) | 263 raise OSError('rm: no such file or directory: ' + pattern) |
267 | 264 |
268 for dst in dst_files: | 265 for dst in dst_files: |
269 if options.verbose: | 266 if options.verbose: |
270 print 'rm ' + dst | 267 print('rm ' + dst) |
271 | 268 |
272 if os.path.isfile(dst) or os.path.islink(dst): | 269 if os.path.isfile(dst) or os.path.islink(dst): |
273 for i in range(5): | 270 for _ in range(5): |
274 try: | 271 try: |
275 # Check every time, since it may have been deleted after the | 272 # Check every time, since it may have been deleted after the |
276 # previous failed attempt. | 273 # previous failed attempt. |
277 if os.path.isfile(dst) or os.path.islink(dst): | 274 if os.path.isfile(dst) or os.path.islink(dst): |
278 os.remove(dst) | 275 os.remove(dst) |
279 break | 276 break |
280 except OSError as error: | 277 except OSError as error: |
281 if i == 5: | 278 print('Failed remove with %s, retrying' % error) |
282 print 'Gave up.' | |
283 raise OSError('rm: ' + str(error)) | |
284 print 'Failed remove with %s, retrying' % error | |
285 time.sleep(5) | 279 time.sleep(5) |
280 else: | |
281 print('Gave up.') | |
282 raise OSError('rm: ' + str(error)) | |
286 | 283 |
287 if options.recursive: | 284 if options.recursive: |
288 for i in range(5): | 285 for _ in range(5): |
289 try: | 286 try: |
290 if os.path.isdir(dst): | 287 if os.path.isdir(dst): |
291 shutil.rmtree(dst) | 288 shutil.rmtree(dst) |
292 break | 289 break |
293 except OSError as error: | 290 except OSError as error: |
294 if i == 5: | 291 print('Failed rmtree with %s, retrying' % error) |
295 print 'Gave up.' | |
296 raise OSError('rm: ' + str(error)) | |
297 print 'Failed rmtree with %s, retrying' % error | |
298 time.sleep(5) | 292 time.sleep(5) |
293 else: | |
294 print('Gave up.') | |
295 raise OSError('rm: ' + str(error)) | |
299 | 296 |
300 except OSError as error: | 297 except OSError as error: |
301 print error | 298 print(error) |
299 | |
302 return 0 | 300 return 0 |
303 | 301 |
304 | 302 |
305 def MakeZipPath(os_path, isdir, iswindows): | 303 def MakeZipPath(os_path, isdir, iswindows): |
306 """Changes a path into zipfile format. | 304 """Changes a path into zipfile format. |
307 | 305 |
308 # doctest doesn't seem to honor r'' strings, so the backslashes need to be | 306 # doctest doesn't seem to honor r'' strings, so the backslashes need to be |
309 # escaped. | 307 # escaped. |
310 >>> MakeZipPath(r'C:\\users\\foobar\\blah', False, True) | 308 >>> MakeZipPath(r'C:\\users\\foobar\\blah', False, True) |
311 'users/foobar/blah' | 309 'users/foobar/blah' |
(...skipping 24 matching lines...) Expand all Loading... | |
336 | 334 |
337 | 335 |
338 def OSMakeZipPath(os_path): | 336 def OSMakeZipPath(os_path): |
339 return MakeZipPath(os_path, os.path.isdir(os_path), sys.platform == 'win32') | 337 return MakeZipPath(os_path, os.path.isdir(os_path), sys.platform == 'win32') |
340 | 338 |
341 | 339 |
342 def Zip(args): | 340 def Zip(args): |
343 """A Unix style zip. | 341 """A Unix style zip. |
344 | 342 |
345 Compresses the listed files.""" | 343 Compresses the listed files.""" |
346 parser = optparse.OptionParser(usage='usage: zip [Options] zipfile list') | 344 parser = argparse.ArgumentParser(description=Zip.__doc__) |
347 parser.add_option( | 345 parser.add_argument( |
348 '-r', dest='recursive', action='store_true', | 346 '-r', dest='recursive', action='store_true', |
349 default=False, | 347 default=False, |
350 help='recurse into directories') | 348 help='recurse into directories') |
351 parser.add_option( | 349 parser.add_argument( |
352 '-q', dest='quiet', action='store_true', | 350 '-q', dest='quiet', action='store_true', |
353 default=False, | 351 default=False, |
354 help='quiet operation') | 352 help='quiet operation') |
355 options, files = parser.parse_args(args) | 353 parser.add_argument('zipfile') |
356 if len(files) < 2: | 354 parser.add_argument('filenames', nargs='+') |
357 parser.error('ERROR: expecting ZIPFILE and LIST.') | 355 options = parser.parse_args(args) |
358 | |
359 dest_zip = files[0] | |
360 src_args = files[1:] | |
361 | 356 |
362 src_files = [] | 357 src_files = [] |
363 for src_arg in src_args: | 358 for filename in options.filenames: |
364 globbed_src_args = glob.glob(src_arg) | 359 globbed_src_args = glob.glob(filename) |
365 if not globbed_src_args: | 360 if not globbed_src_args: |
366 if not options.quiet: | 361 if not options.quiet: |
367 print 'zip warning: name not matched: %s' % (src_arg,) | 362 print('zip warning: name not matched: %s' % filename) |
368 | 363 |
369 for src_file in globbed_src_args: | 364 for src_file in globbed_src_args: |
370 src_file = os.path.normpath(src_file) | 365 src_file = os.path.normpath(src_file) |
371 src_files.append(src_file) | 366 src_files.append(src_file) |
372 if options.recursive and os.path.isdir(src_file): | 367 if options.recursive and os.path.isdir(src_file): |
373 for root, dirs, files in os.walk(src_file): | 368 for root, dirs, files in os.walk(src_file): |
374 for dirname in dirs: | 369 for dirname in dirs: |
375 src_files.append(os.path.join(root, dirname)) | 370 src_files.append(os.path.join(root, dirname)) |
376 for filename in files: | 371 for filename in files: |
377 src_files.append(os.path.join(root, filename)) | 372 src_files.append(os.path.join(root, filename)) |
378 | 373 |
379 zip_stream = None | |
380 # zip_data represents a list of the data to be written or appended to the | 374 # zip_data represents a list of the data to be written or appended to the |
381 # zip_stream. It is a list of tuples: | 375 # zip_stream. It is a list of tuples: |
382 # (OS file path, zip path/zip file info, and file data) | 376 # (OS file path, zip path/zip file info, and file data) |
383 # In all cases one of the |os path| or the |file data| will be None. | 377 # In all cases one of the |os path| or the |file data| will be None. |
384 # |os path| is None when there is no OS file to write to the archive (i.e. | 378 # |os path| is None when there is no OS file to write to the archive (i.e. |
385 # the file data already existed in the archive). |file data| is None when the | 379 # the file data already existed in the archive). |file data| is None when the |
386 # file is new (never existed in the archive) or being updated. | 380 # file is new (never existed in the archive) or being updated. |
387 zip_data = [] | 381 zip_data = [] |
388 new_files_to_add = [OSMakeZipPath(src_file) for src_file in src_files] | 382 new_files_to_add = [OSMakeZipPath(src_file) for src_file in src_files] |
389 zip_path_to_os_path_dict = dict((new_files_to_add[i], src_files[i]) | 383 zip_path_to_os_path_dict = dict((new_files_to_add[i], src_files[i]) |
390 for i in range(len(src_files))) | 384 for i in range(len(src_files))) |
391 write_mode = 'a' | 385 write_mode = 'a' |
392 try: | 386 if os.path.exists(options.zipfile): |
393 zip_stream = zipfile.ZipFile(dest_zip, 'r') | 387 with zipfile.ZipFile(options.zipfile, 'r') as zip_stream: |
394 files_to_update = set(new_files_to_add).intersection( | 388 try: |
395 set(zip_stream.namelist())) | 389 files_to_update = set(new_files_to_add).intersection( |
396 if files_to_update: | 390 set(zip_stream.namelist())) |
397 # As far as I can tell, there is no way to update a zip entry using | 391 if files_to_update: |
398 # zipfile; the best you can do is rewrite the archive. | 392 # As far as I can tell, there is no way to update a zip entry using |
399 # Iterate through the zipfile to maintain file order. | 393 # zipfile; the best you can do is rewrite the archive. |
400 write_mode = 'w' | 394 # Iterate through the zipfile to maintain file order. |
401 for zip_path in zip_stream.namelist(): | 395 write_mode = 'w' |
402 if zip_path in files_to_update: | 396 for zip_path in zip_stream.namelist(): |
403 os_path = zip_path_to_os_path_dict[zip_path] | 397 if zip_path in files_to_update: |
404 zip_data.append((os_path, zip_path, None)) | 398 os_path = zip_path_to_os_path_dict[zip_path] |
405 new_files_to_add.remove(zip_path) | 399 zip_data.append((os_path, zip_path, None)) |
406 else: | 400 new_files_to_add.remove(zip_path) |
407 file_bytes = zip_stream.read(zip_path) | 401 else: |
408 file_info = zip_stream.getinfo(zip_path) | 402 file_bytes = zip_stream.read(zip_path) |
409 zip_data.append((None, file_info, file_bytes)) | 403 file_info = zip_stream.getinfo(zip_path) |
410 except IOError: | 404 zip_data.append((None, file_info, file_bytes)) |
411 pass | 405 except IOError: |
412 finally: | 406 pass |
413 if zip_stream: | |
414 zip_stream.close() | |
415 | 407 |
416 for zip_path in new_files_to_add: | 408 for zip_path in new_files_to_add: |
417 zip_data.append((zip_path_to_os_path_dict[zip_path], zip_path, None)) | 409 zip_data.append((zip_path_to_os_path_dict[zip_path], zip_path, None)) |
418 | 410 |
419 if not zip_data: | 411 if not zip_data: |
420 print 'zip error: Nothing to do! (%s)' % (dest_zip,) | 412 print('zip error: Nothing to do! (%s)' % options.zipfile) |
421 return 1 | 413 return 1 |
422 | 414 |
423 try: | 415 with zipfile.ZipFile(options.zipfile, write_mode, |
424 zip_stream = zipfile.ZipFile(dest_zip, write_mode, zipfile.ZIP_DEFLATED) | 416 zipfile.ZIP_DEFLATED) as zip_stream: |
425 for os_path, file_info_or_zip_path, file_bytes in zip_data: | 417 for os_path, file_info_or_zip_path, file_bytes in zip_data: |
426 if isinstance(file_info_or_zip_path, zipfile.ZipInfo): | 418 if isinstance(file_info_or_zip_path, zipfile.ZipInfo): |
427 zip_path = file_info_or_zip_path.filename | 419 zip_path = file_info_or_zip_path.filename |
428 else: | 420 else: |
429 zip_path = file_info_or_zip_path | 421 zip_path = file_info_or_zip_path |
430 | 422 |
431 if os_path: | 423 if os_path: |
432 st = os.stat(os_path) | 424 st = os.stat(os_path) |
433 if stat.S_ISDIR(st.st_mode): | 425 if stat.S_ISDIR(st.st_mode): |
434 # Python 2.6 on the buildbots doesn't support writing directories to | 426 # Python 2.6 on the buildbots doesn't support writing directories to |
(...skipping 16 matching lines...) Expand all Loading... | |
451 zip_stream.writestr(file_info_or_zip_path, file_bytes) | 443 zip_stream.writestr(file_info_or_zip_path, file_bytes) |
452 | 444 |
453 if not options.quiet: | 445 if not options.quiet: |
454 if zip_path in new_files_to_add: | 446 if zip_path in new_files_to_add: |
455 operation = 'adding' | 447 operation = 'adding' |
456 else: | 448 else: |
457 operation = 'updating' | 449 operation = 'updating' |
458 zip_info = zip_stream.getinfo(zip_path) | 450 zip_info = zip_stream.getinfo(zip_path) |
459 if (zip_info.compress_type == zipfile.ZIP_STORED or | 451 if (zip_info.compress_type == zipfile.ZIP_STORED or |
460 zip_info.file_size == 0): | 452 zip_info.file_size == 0): |
461 print ' %s: %s (stored 0%%)' % (operation, zip_path) | 453 print(' %s: %s (stored 0%%)' % (operation, zip_path)) |
462 elif zip_info.compress_type == zipfile.ZIP_DEFLATED: | 454 elif zip_info.compress_type == zipfile.ZIP_DEFLATED: |
463 print ' %s: %s (deflated %d%%)' % (operation, zip_path, | 455 print(' %s: %s (deflated %d%%)' % (operation, zip_path, |
464 100 - zip_info.compress_size * 100 / zip_info.file_size) | 456 100 - zip_info.compress_size * 100 / zip_info.file_size)) |
465 finally: | |
466 zip_stream.close() | |
467 | 457 |
468 return 0 | 458 return 0 |
469 | 459 |
470 | 460 |
471 def FindExeInPath(filename): | 461 def FindExeInPath(filename): |
472 env_path = os.environ.get('PATH', '') | 462 env_path = os.environ.get('PATH', '') |
473 paths = env_path.split(os.pathsep) | 463 paths = env_path.split(os.pathsep) |
474 | 464 |
475 def IsExecutableFile(path): | 465 def IsExecutableFile(path): |
476 return os.path.isfile(path) and os.access(path, os.X_OK) | 466 return os.path.isfile(path) and os.access(path, os.X_OK) |
(...skipping 10 matching lines...) Expand all Loading... | |
487 | 477 |
488 def Which(args): | 478 def Which(args): |
489 """A Unix style which. | 479 """A Unix style which. |
490 | 480 |
491 Looks for all arguments in the PATH environment variable, and prints their | 481 Looks for all arguments in the PATH environment variable, and prints their |
492 path if they are executable files. | 482 path if they are executable files. |
493 | 483 |
494 Note: If you pass an argument with a path to which, it will just test if it | 484 Note: If you pass an argument with a path to which, it will just test if it |
495 is executable, not if it is in the path. | 485 is executable, not if it is in the path. |
496 """ | 486 """ |
497 parser = optparse.OptionParser(usage='usage: which args...') | 487 parser = argparse.ArgumentParser(description=Which.__doc__) |
498 _, files = parser.parse_args(args) | 488 parser.add_argument('files', nargs='+') |
499 if not files: | 489 options = parser.parse_args(args) |
500 return 0 | |
501 | 490 |
502 retval = 0 | 491 retval = 0 |
503 for filename in files: | 492 for filename in options.files: |
504 fullname = FindExeInPath(filename) | 493 fullname = FindExeInPath(filename) |
505 if fullname: | 494 if fullname: |
506 print fullname | 495 print(fullname) |
507 else: | 496 else: |
508 retval = 1 | 497 retval = 1 |
509 | 498 |
510 return retval | 499 return retval |
511 | 500 |
512 | 501 |
513 FuncMap = { | 502 FuncMap = { |
514 'cp': Copy, | 503 'cp': Copy, |
515 'mkdir': Mkdir, | 504 'mkdir': Mkdir, |
516 'mv': Move, | 505 'mv': Move, |
517 'rm': Remove, | 506 'rm': Remove, |
518 'zip': Zip, | 507 'zip': Zip, |
519 'which': Which, | 508 'which': Which, |
520 } | 509 } |
521 | 510 |
522 | 511 |
523 def main(args): | 512 def main(args): |
524 if not args: | 513 if not args: |
525 print 'No command specified' | 514 print('No command specified') |
526 print 'Available commands: %s' % ' '.join(FuncMap) | 515 print('Available commands: %s' % ' '.join(FuncMap)) |
527 return 1 | 516 return 1 |
528 func_name = args[0] | 517 func_name = args[0] |
529 func = FuncMap.get(func_name) | 518 func = FuncMap.get(func_name) |
530 if not func: | 519 if not func: |
531 print 'Do not recognize command: %s' % func_name | 520 print('Do not recognize command: %s' % func_name) |
532 print 'Available commands: %s' % ' '.join(FuncMap) | 521 print('Available commands: %s' % ' '.join(FuncMap)) |
533 return 1 | 522 return 1 |
534 try: | 523 try: |
535 return func(args[1:]) | 524 return func(args[1:]) |
536 except KeyboardInterrupt: | 525 except KeyboardInterrupt: |
537 print '%s: interrupted' % func_name | 526 print('%s: interrupted' % func_name) |
538 return 1 | 527 return 1 |
539 | 528 |
540 if __name__ == '__main__': | 529 if __name__ == '__main__': |
541 sys.exit(main(sys.argv[1:])) | 530 sys.exit(main(sys.argv[1:])) |
OLD | NEW |