Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(227)

Side by Side Diff: third_party/gsutil/gslib/commands/mv.py

Issue 10199002: Upgrade gsutil to 3.4 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed comments Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/gsutil/gslib/commands/mb.py ('k') | third_party/gsutil/gslib/commands/rb.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright 2011 Google Inc.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 from gslib.command import Command
16 from gslib.command import COMMAND_NAME
17 from gslib.command import COMMAND_NAME_ALIASES
18 from gslib.command import CONFIG_REQUIRED
19 from gslib.command import FILE_URIS_OK
20 from gslib.command import MAX_ARGS
21 from gslib.command import MIN_ARGS
22 from gslib.command import PROVIDER_URIS_OK
23 from gslib.command import SUPPORTED_SUB_ARGS
24 from gslib.command import URIS_START_ARG
25 from gslib.exception import CommandException
26 from gslib.help_provider import HELP_NAME
27 from gslib.help_provider import HELP_NAME_ALIASES
28 from gslib.help_provider import HELP_ONE_LINE_SUMMARY
29 from gslib.help_provider import HELP_TEXT
30 from gslib.help_provider import HelpType
31 from gslib.help_provider import HELP_TYPE
32 from gslib.util import NO_MAX
33 from gslib.wildcard_iterator import ContainsWildcard
34
35 _detailed_help_text = ("""
36 <B>SYNOPSIS</B>
37 gsutil mv [-p] src_uri dst_uri
38 - or -
39 gsutil mv [-p] uri... dst_uri
40
41
42 <B>DESCRIPTION</B>
43 The gsutil mv command allows you to move data between your local file
44 system and the cloud, move data within the cloud, and move data between
45 cloud storage providers. For example, to move all objects from a
46 bucket to a local directory you could use:
47
48 gsutil mv gs://my_bucket dir
49
50 The mv command, like the rm command, will refuse to remove data from
51 the local disk. Thus, for example, this command will not be allowed:
52
53 gsutil mv *.txt gs://my_bucket
54
55
56 <B>RENAMING BUCKET SUBDIRECTORIES</B>
57 You can use the gsutil mv command to rename subdirectories. For example,
58 the command:
59
60 gsutil mv gs://my_bucket/olddir gs://my_bucket/newdir
61
62 would rename all objects and subdirectories under gs://my_bucket/olddir to be
63 under gs://my_bucket/newdir, otherwise preserving the subdirectory structure.
64
65 If you do a rename as specified above and you want to preserve ACLs, you
66 should use the -p option (see OPTIONS).
67
68 Note that when using mv to rename bucket subdirectories you cannot specify
69 the source URI using wildcards. You need to spell out the complete name:
70
71 gsutil mv gs://my_bucket/olddir gs://my_bucket/newdir
72
73 If you have a large number of files to move you might want to use the
74 gsutil -m option, to perform a multi-threaded/multi-processing move:
75
76 gsutil -m mv gs://my_bucket/olddir gs://my_bucket/newdir
77
78
79 <B>OPTIONS</B>
80 -p Causes ACL to be preserved when moving in the cloud. Note that
81 this option has performance and cost implications, because it
82 is essentially performing three requests (getacl, cp, setacl).
83 (The performance issue can be mitigated to some degree by
84 using gsutil -m cp to cause multi-threaded/multi-processing
85 copying.)
86 """)
87
88
89 class MvCommand(Command):
90 """Implementation of gsutil mv command.
91 Note that there is no atomic rename operation - this command is simply
92 a shorthand for 'cp' followed by 'rm'.
93 """
94
95 # Command specification (processed by parent class).
96 command_spec = {
97 # Name of command.
98 COMMAND_NAME : 'mv',
99 # List of command name aliases.
100 COMMAND_NAME_ALIASES : ['move', 'ren', 'rename'],
101 # Min number of args required by this command.
102 MIN_ARGS : 2,
103 # Max number of args required by this command, or NO_MAX.
104 MAX_ARGS : NO_MAX,
105 # Getopt-style string specifying acceptable sub args.
106 SUPPORTED_SUB_ARGS : 'p',
107 # True if file URIs acceptable for this command.
108 FILE_URIS_OK : True,
109 # True if provider-only URIs acceptable for this command.
110 PROVIDER_URIS_OK : False,
111 # Index in args of first URI arg.
112 URIS_START_ARG : 0,
113 # True if must configure gsutil before running command.
114 CONFIG_REQUIRED : True,
115 }
116 help_spec = {
117 # Name of command or auxiliary help info for which this help applies.
118 HELP_NAME : 'mv',
119 # List of help name aliases.
120 HELP_NAME_ALIASES : ['move', 'rename'],
121 # Type of help:
122 HELP_TYPE : HelpType.COMMAND_HELP,
123 # One line summary of this help.
124 HELP_ONE_LINE_SUMMARY : 'Move/rename objects and/or subdirectories',
125 # The full help text.
126 HELP_TEXT : _detailed_help_text,
127 }
128
129 # Command entry point.
130 def RunCommand(self):
131 # Check each source arg up, refusing to delete a bucket or directory src
132 # URI (force users to explicitly do that as a separate operation).
133 for arg_to_check in self.args[0:-1]:
134 if self.suri_builder.StorageUri(arg_to_check).names_container():
135 raise CommandException('Will not remove source buckets or directories '
136 '(%s).\nYou must separately copy and remove for '
137 'that purpose.' % arg_to_check)
138
139 # Expand wildcards, dirs, buckets, and bucket subdirs in StorageUris
140 # before running cp and rm commands, to prevent the
141 # following problem: starting with a bucket containing only the object
142 # gs://bucket/obj, say the user does:
143 # gsutil mv gs://bucket/* gs://bucket/d.txt
144 # If we didn't expand the wildcard first, the cp command would
145 # first copy gs://bucket/obj to gs://bucket/d.txt, and the
146 # rm command would then remove that object.
147 # Note 1: This is somewhat inefficient, since we request a bucket listing
148 # here and then again in the generated cp command. TODO: Consider adding
149 # an internal interface to cp command to allow this expansion to be passed
150 # in.
151 # Note 2: We use recursion_requested when expanding wildcards and containers
152 # so we can determine if any of the source URIs are directories (and then
153 # use cp -R and rm -R to perform the move, to match the behavior of UNIX mv
154 # (where moving a directory moves all the contained files).
155 src_uri_expansion = self.exp_handler.ExpandWildcardsAndContainers(
156 self.args[0:len(self.args)-1], True)
157 exp_arg_list = list(src_uri_expansion.IterExpandedUriStrings())
158
159 # Check whether exp_arg_list has any file:// URIs, and disallow it. Note
160 # that we can't simply set FILE_URIS_OK to False in command_spec because
161 # we *do* allow a file URI for the dest URI. (We allow users to move data
162 # out of the cloud to the local disk, but we disallow commands that would
163 # delete data off the local disk, and instead require the user to delete
164 # data separately, using local commands/tools.)
165 if self.HaveFileUris(exp_arg_list):
166 raise CommandException('"mv" command does not support "file://" URIs for '
167 'source arguments.\nDid you mean to use a '
168 'gs:// URI?')
169
170 if src_uri_expansion.IsEmpty():
171 raise CommandException('No URIs matched')
172
173 # If any of the src URIs are directories add -R to options to be passed to
174 # cp and rm commands.
175 self.recursion_requested = False
176 for src_uri in src_uri_expansion.GetSrcUris():
177 if src_uri_expansion.NamesContainer(src_uri):
178 self.recursion_requested = True
179 # Disallow wildcard src URIs when moving directories, as supporting it
180 # would make the name transformation too complex and would also be
181 # dangerous (e.g., someone could accidentally move many objects to the
182 # wrong name, or accidentally overwrite many objects).
183 if ContainsWildcard(src_uri):
184 raise CommandException(
185 'mv command disallows naming source directories using wildcards')
186
187 # Add command-line opts back in front of args so they'll be picked up by cp
188 # and rm commands (e.g., for -p option). Use undocumented (internal
189 # use-only) cp -M option to request move naming semantics (see
190 # _ConstructDstUri in cp.py).
191 unparsed_args = ['-M']
192 if self.recursion_requested:
193 unparsed_args.append('-R')
194 exp_arg_list.insert(0, '-R')
195 unparsed_args.extend(self.unparsed_args)
196 self.command_runner.RunNamedCommand('cp', unparsed_args, self.headers,
197 self.debug, self.parallel_operations)
198 # See comment above about why we're passing exp_arg_list instead of
199 # unparsed_args here.
200 self.command_runner.RunNamedCommand('rm', exp_arg_list,
201 self.headers, self.debug,
202 self.parallel_operations)
203
204 # test specification, see definition of test_steps in base class for
205 # details on how to populate these fields
206 test_steps = [
207 # (test name, cmd line, ret code, (result_file, expect_file))
208 ('gen expect files', 'echo 0 >$F0; echo 1 >$F1; echo 2 >$F2', 0, None),
209 ('verify 2 src objs', 'gsutil ls gs://$B2 | wc -l >$F9', 0, ('$F9', '$F2')),
210 ('verify 0 dst objs', 'gsutil ls gs://$B0 | wc -l >$F9', 0, ('$F9', '$F0')),
211 ('mv 2 objects',
212 'gsutil -m mv gs://$B2/$O0 gs://$B2/$O1 gs://$B0 2>&1 | grep Removing',
213 0, None),
214 ('verify 0 src objs', 'gsutil ls gs://$B2 | wc -l >$F9', 0, ('$F9', '$F0')),
215 ('verify 2 dst objs', 'gsutil ls gs://$B0 | wc -l >$F9', 0, ('$F9', '$F2')),
216 ('rm 1 src object', 'gsutil rm gs://$B0/$O0', 0, None),
217 ('verify 1 src obj', 'gsutil ls gs://$B0 | wc -l >$F9', 0, ('$F9', '$F1')),
218 ('verify 0 dst objs', 'gsutil ls gs://$B2 | wc -l >$F9', 0, ('$F9', '$F0')),
219 ('mv 2 objects',
220 'gsutil -m mv gs://$B0/$O0 gs://$B0/$O1 gs://$B2 2>&1 | grep Removing',
221 1, None),
222 ]
223
OLDNEW
« no previous file with comments | « third_party/gsutil/gslib/commands/mb.py ('k') | third_party/gsutil/gslib/commands/rb.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698