git-svn-id: https://s3tools.svn.sourceforge.net/svnroot/s3tools/s3cmd/trunk@390 830e0280-6d2a-0410-9c65-932aecc39d9d
... | ... |
@@ -1,5 +1,10 @@ |
1 | 1 |
2009-05-28 Michal Ludvig <michal@logix.cz> |
2 | 2 |
|
3 |
+ * s3cmd, run-test.py, TODO, NEWS: Added --dry-run |
|
4 |
+ and --exclude/--include for [del]. |
|
5 |
+ |
|
6 |
+2009-05-28 Michal Ludvig <michal@logix.cz> |
|
7 |
+ |
|
3 | 8 |
* s3cmd: Support for recursive [cp] and [mv], including |
4 | 9 |
multiple-source arguments, --include/--exclude, |
5 | 10 |
--dry-run, etc. |
... | ... |
@@ -7,7 +7,7 @@ s3cmd 1.0.0 |
7 | 7 |
pre-processing. Good for fixing unreadable buckets. |
8 | 8 |
* Added --recursive support for [cp] and [mv], including |
9 | 9 |
multiple-source arguments, --include/--exclude, --dry-run, etc. |
10 |
- |
|
10 |
+* Added --exclude/--include and --dry-run for [del]. |
|
11 | 11 |
|
12 | 12 |
s3cmd 0.9.9 - 2009-02-17 |
13 | 13 |
=========== |
... | ... |
@@ -4,8 +4,8 @@ TODO list for s3cmd project |
4 | 4 |
- For 0.9.9.x |
5 | 5 |
- Make 'sync s3://bkt/some-filename local/other-filename' work |
6 | 6 |
(at the moment it'll always download). |
7 |
- - Enable --exclude for [del], [setacl], [ls]. |
|
8 |
- - Enable --dry-run for [del], [setacl], reject for all others. |
|
7 |
+ - Enable --exclude for [setacl], [ls]. |
|
8 |
+ - Enable --dry-run for [setacl], reject for all others. |
|
9 | 9 |
- Allow change /tmp to somewhere else |
10 | 10 |
- With --guess-mime use 'magic' module if available. |
11 | 11 |
- Support --preserve for [put] and [get]. Update manpage. |
... | ... |
@@ -388,9 +388,10 @@ test_s3cmd("Simple delete", ['del', 's3://s3cmd-autotest-1/xyz/etc2/Logo.PNG'], |
388 | 388 |
|
389 | 389 |
|
390 | 390 |
## ====== Recursive delete |
391 |
-test_s3cmd("Recursive delete", ['del', '--recursive', 's3://s3cmd-autotest-1/xyz/etc'], |
|
392 |
- must_find_re = [ "File .*\.svn/format deleted" ]) |
|
393 |
- |
|
391 |
+test_s3cmd("Recursive delete", ['del', '--recursive', '--exclude', 'Atomic*', 's3://s3cmd-autotest-1/xyz/etc'], |
|
392 |
+ must_find = [ "File s3://s3cmd-autotest-1/xyz/etc/TypeRa.ttf deleted" ], |
|
393 |
+ must_find_re = [ "File .*\.svn/format deleted" ], |
|
394 |
+ must_not_find = [ "AtomicClockRadio.ttf" ]) |
|
394 | 395 |
|
395 | 396 |
## ====== Recursive delete all |
396 | 397 |
test_s3cmd("Recursive delete all", ['del', '--recursive', '--force', 's3://s3cmd-autotest-1'], |
... | ... |
@@ -169,7 +169,7 @@ def cmd_bucket_delete(args): |
169 | 169 |
except S3Error, e: |
170 | 170 |
if e.info['Code'] == 'BucketNotEmpty' and (cfg.force or cfg.recursive): |
171 | 171 |
warning(u"Bucket is not empty. Removing all the objects from it first. This may take some time...") |
172 |
- subcmd_object_del_uri(uri, recursive = True) |
|
172 |
+ subcmd_object_del_uri(uri.uri(), recursive = True) |
|
173 | 173 |
return _bucket_delete_one(uri) |
174 | 174 |
elif S3.codes.has_key(e.info["Code"]): |
175 | 175 |
error(S3.codes[e.info["Code"]] % uri.bucket()) |
... | ... |
@@ -483,35 +483,43 @@ def cmd_object_get(args): |
483 | 483 |
(uri, destination, response["size"], response["elapsed"], speed_fmt[0], speed_fmt[1])) |
484 | 484 |
|
485 | 485 |
def cmd_object_del(args): |
486 |
- while (len(args)): |
|
487 |
- uri_arg = args.pop(0) |
|
488 |
- uri = S3Uri(uri_arg) |
|
486 |
+ for uri_str in args: |
|
487 |
+ uri = S3Uri(uri_str) |
|
489 | 488 |
if uri.type != "s3": |
490 |
- raise ParameterError("Expecting S3 URI instead of '%s'" % uri_arg) |
|
489 |
+ raise ParameterError("Expecting S3 URI instead of '%s'" % uri_str) |
|
491 | 490 |
if not uri.has_object(): |
492 | 491 |
if Config().recursive and not Config().force: |
493 |
- raise ParameterError("Please use --force to delete ALL contents of %s" % uri) |
|
492 |
+ raise ParameterError("Please use --force to delete ALL contents of %s" % uri_str) |
|
494 | 493 |
elif not Config().recursive: |
495 |
- raise ParameterError("File name required, not only the bucket name") |
|
496 |
- subcmd_object_del_uri(uri) |
|
494 |
+ raise ParameterError("File name required, not only the bucket name. Alternatively use --recursive") |
|
495 |
+ subcmd_object_del_uri(uri_str) |
|
496 |
+ |
|
497 |
+def subcmd_object_del_uri(uri_str, recursive = None): |
|
498 |
+ s3 = S3(cfg) |
|
497 | 499 |
|
498 |
-def subcmd_object_del_uri(uri, recursive = None): |
|
499 |
- s3 = S3(Config()) |
|
500 | 500 |
if recursive is None: |
501 | 501 |
recursive = cfg.recursive |
502 |
- uri_list = [] |
|
503 |
- if recursive: |
|
504 |
- filelist = _get_filelist_remote(uri) |
|
505 |
- uri_base = 's3://' + uri.bucket() + "/" |
|
506 |
- for idx in filelist: |
|
507 |
- object = filelist[idx] |
|
508 |
- debug(u"Adding URI " + uri_base + object['object_key']) |
|
509 |
- uri_list.append(S3Uri(uri_base + object['object_key'])) |
|
510 |
- else: |
|
511 |
- uri_list.append(uri) |
|
512 |
- for _uri in uri_list: |
|
513 |
- response = s3.object_delete(_uri) |
|
514 |
- output(u"File %s deleted" % _uri) |
|
502 |
+ |
|
503 |
+ remote_list = fetch_remote_list(uri_str, require_attribs = False, recursive = recursive) |
|
504 |
+ remote_list, exclude_list = _filelist_filter_exclude_include(remote_list) |
|
505 |
+ |
|
506 |
+ remote_count = len(remote_list) |
|
507 |
+ |
|
508 |
+ info(u"Summary: %d remote files to delete" % remote_count) |
|
509 |
+ |
|
510 |
+ if cfg.dry_run: |
|
511 |
+ for key in exclude_list: |
|
512 |
+ output(u"exclude: %s" % unicodise(key)) |
|
513 |
+ for key in remote_list: |
|
514 |
+ output(u"delete: %s" % remote_list[key]['object_uri_str']) |
|
515 |
+ |
|
516 |
+ warning(u"Exitting now because of --dry-run") |
|
517 |
+ return |
|
518 |
+ |
|
519 |
+ for key in remote_list: |
|
520 |
+ item = remote_list[key] |
|
521 |
+ response = s3.object_delete(S3Uri(item['object_uri_str'])) |
|
522 |
+ output(u"File %s deleted" % item['object_uri_str']) |
|
515 | 523 |
|
516 | 524 |
def subcmd_cp_mv(args, process_fce, action_str, message): |
517 | 525 |
if len(args) < 2: |