OLD | NEW |
| (Empty) |
1 # -*- coding: utf-8 -*- | |
2 # Copyright 2011 Google Inc. All Rights Reserved. | |
3 # | |
4 # Licensed under the Apache License, Version 2.0 (the "License"); | |
5 # you may not use this file except in compliance with the License. | |
6 # You may obtain a copy of the License at | |
7 # | |
8 # http://www.apache.org/licenses/LICENSE-2.0 | |
9 # | |
10 # Unless required by applicable law or agreed to in writing, software | |
11 # distributed under the License is distributed on an "AS IS" BASIS, | |
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 # See the License for the specific language governing permissions and | |
14 # limitations under the License. | |
15 """Implementation of Unix-like mv command for cloud storage providers.""" | |
16 | |
17 from __future__ import absolute_import | |
18 | |
19 from gslib.command import Command | |
20 from gslib.command_argument import CommandArgument | |
21 from gslib.commands.cp import CP_SUB_ARGS | |
22 from gslib.cs_api_map import ApiSelector | |
23 from gslib.exception import CommandException | |
24 from gslib.storage_url import StorageUrlFromString | |
25 from gslib.util import NO_MAX | |
26 | |
27 | |
28 _SYNOPSIS = """ | |
29 gsutil mv [-p] src_url dst_url | |
30 gsutil mv [-p] src_url... dst_url | |
31 gsutil mv [-p] -I dst_url | |
32 """ | |
33 | |
34 _DETAILED_HELP_TEXT = (""" | |
35 <B>SYNOPSIS</B> | |
36 """ + _SYNOPSIS + """ | |
37 | |
38 | |
39 <B>DESCRIPTION</B> | |
40 The gsutil mv command allows you to move data between your local file | |
41 system and the cloud, move data within the cloud, and move data between | |
42 cloud storage providers. For example, to move all objects from a | |
43 bucket to a local directory you could use: | |
44 | |
45 gsutil mv gs://my_bucket dir | |
46 | |
47 Similarly, to move all objects from a local directory to a bucket you could | |
48 use: | |
49 | |
50 gsutil mv ./dir gs://my_bucket | |
51 | |
52 | |
53 <B>RENAMING BUCKET SUBDIRECTORIES</B> | |
54 You can use the gsutil mv command to rename subdirectories. For example, | |
55 the command: | |
56 | |
57 gsutil mv gs://my_bucket/olddir gs://my_bucket/newdir | |
58 | |
59 would rename all objects and subdirectories under gs://my_bucket/olddir to be | |
60 under gs://my_bucket/newdir, otherwise preserving the subdirectory structure. | |
61 | |
62 If you do a rename as specified above and you want to preserve ACLs, you | |
63 should use the -p option (see OPTIONS). | |
64 | |
65 Note that when using mv to rename bucket subdirectories you cannot specify | |
66 the source URL using wildcards. You need to spell out the complete name: | |
67 | |
68 gsutil mv gs://my_bucket/olddir gs://my_bucket/newdir | |
69 | |
70 If you have a large number of files to move you might want to use the | |
71 gsutil -m option, to perform a multi-threaded/multi-processing move: | |
72 | |
73 gsutil -m mv gs://my_bucket/olddir gs://my_bucket/newdir | |
74 | |
75 | |
76 <B>NON-ATOMIC OPERATION</B> | |
77 Unlike the case with many file systems, the gsutil mv command does not | |
78 perform a single atomic operation. Rather, it performs a copy from source | |
79 to destination followed by removing the source for each object. | |
80 | |
81 | |
82 <B>OPTIONS</B> | |
83 All options that are available for the gsutil cp command are also available | |
84 for the gsutil mv command (except for the -R flag, which is implied by the | |
85 gsutil mv command). Please see the OPTIONS sections of "gsutil help cp" | |
86 for more information. | |
87 | |
88 """) | |
89 | |
90 | |
91 class MvCommand(Command): | |
92 """Implementation of gsutil mv command. | |
93 | |
94 Note that there is no atomic rename operation - this command is simply | |
95 a shorthand for 'cp' followed by 'rm'. | |
96 """ | |
97 | |
98 # Command specification. See base class for documentation. | |
99 command_spec = Command.CreateCommandSpec( | |
100 'mv', | |
101 command_name_aliases=['move', 'ren', 'rename'], | |
102 usage_synopsis=_SYNOPSIS, | |
103 min_args=1, | |
104 max_args=NO_MAX, | |
105 # Flags for mv are passed through to cp. | |
106 supported_sub_args=CP_SUB_ARGS, | |
107 file_url_ok=True, | |
108 provider_url_ok=False, | |
109 urls_start_arg=0, | |
110 gs_api_support=[ApiSelector.XML, ApiSelector.JSON], | |
111 gs_default_api=ApiSelector.JSON, | |
112 argparse_arguments=[ | |
113 CommandArgument.MakeZeroOrMoreCloudOrFileURLsArgument() | |
114 ] | |
115 ) | |
116 # Help specification. See help_provider.py for documentation. | |
117 help_spec = Command.HelpSpec( | |
118 help_name='mv', | |
119 help_name_aliases=['move', 'rename'], | |
120 help_type='command_help', | |
121 help_one_line_summary='Move/rename objects and/or subdirectories', | |
122 help_text=_DETAILED_HELP_TEXT, | |
123 subcommand_help_text={}, | |
124 ) | |
125 | |
126 def RunCommand(self): | |
127 """Command entry point for the mv command.""" | |
128 # Check each source arg up, refusing to delete a bucket src URL (force users | |
129 # to explicitly do that as a separate operation). | |
130 for arg_to_check in self.args[0:-1]: | |
131 url = StorageUrlFromString(arg_to_check) | |
132 if url.IsCloudUrl() and (url.IsBucket() or url.IsProvider()): | |
133 raise CommandException('You cannot move a source bucket using the mv ' | |
134 'command. If you meant to move\nall objects in ' | |
135 'the bucket, you can use a command like:\n' | |
136 '\tgsutil mv %s/* %s' % | |
137 (arg_to_check, self.args[-1])) | |
138 | |
139 # Insert command-line opts in front of args so they'll be picked up by cp | |
140 # and rm commands (e.g., for -p option). Use undocumented (internal | |
141 # use-only) cp -M option, which causes each original object to be deleted | |
142 # after successfully copying to its destination, and also causes naming | |
143 # behavior consistent with Unix mv naming behavior (see comments in | |
144 # ConstructDstUrl). | |
145 unparsed_args = ['-M'] | |
146 if self.recursion_requested: | |
147 unparsed_args.append('-R') | |
148 unparsed_args.extend(self.unparsed_args) | |
149 self.command_runner.RunNamedCommand('cp', unparsed_args, self.headers, | |
150 self.debug, self.parallel_operations) | |
151 | |
152 return 0 | |
OLD | NEW |