s3cp 1.1.8 → 1.1.9
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +5 -0
- data/bin/s3tree +4 -0
- data/lib/s3cp/s3cp.rb +10 -3
- data/lib/s3cp/s3tree.rb +162 -0
- data/lib/s3cp/version.rb +1 -1
- metadata +7 -4
data/History.txt
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
=== 1.1.9 (2012-11-27)
|
2
|
+
|
3
|
+
* Added: New `s3tree` command similar to Unix `tree` command.
|
4
|
+
* Changed: Correctly display 'Move' text instead of 'Copy' when moving files.
|
5
|
+
|
1
6
|
=== 1.1.8 (2012-10-29)
|
2
7
|
|
3
8
|
* Changed: Relaxed highline dependency requirement from ~> 1.5.1 to >= 1.5.1
|
data/bin/s3tree
ADDED
data/lib/s3cp/s3cp.rb
CHANGED
@@ -250,8 +250,15 @@ def md5(filename)
|
|
250
250
|
digest.hexdigest
|
251
251
|
end
|
252
252
|
|
253
|
+
def operation(options)
|
254
|
+
operation = "Copy"
|
255
|
+
operation = "Move" if options[:move]
|
256
|
+
operation = "Sync" if options[:sync]
|
257
|
+
operation
|
258
|
+
end
|
259
|
+
|
253
260
|
def s3_to_s3(bucket_from, key, bucket_to, dest, options = {})
|
254
|
-
log(with_headers("
|
261
|
+
log(with_headers("#{operation(options)} s3://#{bucket_from}/#{key} to s3://#{bucket_to}/#{dest}"))
|
255
262
|
s3_source = @s3.buckets[bucket_from].objects[key]
|
256
263
|
s3_dest = @s3.buckets[bucket_to].objects[dest]
|
257
264
|
s3_options = {}
|
@@ -265,7 +272,7 @@ def s3_to_s3(bucket_from, key, bucket_to, dest, options = {})
|
|
265
272
|
end
|
266
273
|
|
267
274
|
def local_to_s3(bucket_to, key, file, options = {})
|
268
|
-
log(with_headers("
|
275
|
+
log(with_headers("#{operation(options)} #{file} to s3://#{bucket_to}/#{key}"))
|
269
276
|
|
270
277
|
expected_md5 = if options[:checksum] || options[:sync]
|
271
278
|
md5(file)
|
@@ -342,7 +349,7 @@ def local_to_s3(bucket_to, key, file, options = {})
|
|
342
349
|
end
|
343
350
|
|
344
351
|
def s3_to_local(bucket_from, key_from, dest, options = {})
|
345
|
-
log("
|
352
|
+
log("#{operation(options)} s3://#{bucket_from}/#{key_from} to #{dest}")
|
346
353
|
|
347
354
|
retries = 0
|
348
355
|
begin
|
data/lib/s3cp/s3tree.rb
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
# Copyright (C) 2010-2012 Alex Boisvert and Bizo Inc. / All rights reserved.
|
2
|
+
#
|
3
|
+
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
|
4
|
+
# license agreements. See the NOTICE file distributed with this work for
|
5
|
+
# additional information regarding copyright ownership. The ASF licenses this
|
6
|
+
# file to you under the Apache License, Version 2.0 (the "License"); you may not
|
7
|
+
# use this file except in compliance with the License. You may obtain a copy of
|
8
|
+
# the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
14
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
15
|
+
# License for the specific language governing permissions and limitations under
|
16
|
+
# the License.
|
17
|
+
|
18
|
+
require 's3cp/utils'
|
19
|
+
|
20
|
+
# Parse arguments
|
21
|
+
options = {}
|
22
|
+
options[:rows_per_page] = ($terminal.output_rows - 1) if $stdout.isatty
|
23
|
+
options[:delimiter] = ENV["S3CP_DELIMITER"] || "/"
|
24
|
+
options[:max_depth] = 9999999
|
25
|
+
|
26
|
+
op = OptionParser.new do |opts|
|
27
|
+
opts.banner = "s3tree [path]"
|
28
|
+
opts.separator ''
|
29
|
+
|
30
|
+
opts.on("-d", "Show directories only") do
|
31
|
+
options[:directories_only] = true
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.on("--rows ROWS", "Rows per page") do |rows|
|
35
|
+
options[:rows_per_page] = rows.to_i
|
36
|
+
end
|
37
|
+
|
38
|
+
opts.on("--max-keys KEYS", "Maximum number of keys to display") do |keys|
|
39
|
+
options[:max_keys] = keys.to_i
|
40
|
+
end
|
41
|
+
|
42
|
+
opts.on("--max-depth DEPTH", "Maximum directory depth to display") do |depth|
|
43
|
+
options[:max_depth] = depth.to_i
|
44
|
+
end
|
45
|
+
|
46
|
+
opts.on("--delimiter CHAR", "Display keys starting with given path prefix and up to delimiter character") do |delimiter|
|
47
|
+
options[:delimiter] = delimiter
|
48
|
+
end
|
49
|
+
|
50
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
51
|
+
puts op
|
52
|
+
exit
|
53
|
+
end
|
54
|
+
end
|
55
|
+
op.parse!(ARGV)
|
56
|
+
|
57
|
+
unless ARGV.size > 0
|
58
|
+
puts op
|
59
|
+
exit
|
60
|
+
end
|
61
|
+
|
62
|
+
url = ARGV[0]
|
63
|
+
|
64
|
+
@bucket, @key = S3CP.bucket_and_key(url)
|
65
|
+
fail "Your URL looks funny, doesn't it?" unless @bucket
|
66
|
+
|
67
|
+
S3CP.load_config()
|
68
|
+
|
69
|
+
@s3 = S3CP.connect().buckets[@bucket]
|
70
|
+
|
71
|
+
keys = 0
|
72
|
+
rows = 0
|
73
|
+
|
74
|
+
begin
|
75
|
+
# find last index of character `ch` in `str`.
|
76
|
+
last_index_of = lambda do |str, ch|
|
77
|
+
case
|
78
|
+
when str[ch] then str.length-(str.reverse.index(ch)+1)
|
79
|
+
else -1
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# displays the next line, returns true if user interrupts or max keys shown
|
84
|
+
display_line = lambda do |line|
|
85
|
+
puts line
|
86
|
+
keys += 1
|
87
|
+
if options[:max_keys] && keys > options[:max_keys]
|
88
|
+
return true
|
89
|
+
end
|
90
|
+
rows += 1
|
91
|
+
response = ''
|
92
|
+
if options[:rows_per_page] && (rows % options[:rows_per_page] == 0)
|
93
|
+
begin
|
94
|
+
print "Continue? (Y/n) "
|
95
|
+
response = STDIN.gets.chomp.downcase
|
96
|
+
end until response == 'n' || response == 'y' || response == ''
|
97
|
+
end
|
98
|
+
(response == 'n')
|
99
|
+
end
|
100
|
+
|
101
|
+
# returns relative path against @key
|
102
|
+
#
|
103
|
+
# e.g. relative.call("foo/bar") => "bar" (assuming @key = "foo/")
|
104
|
+
#
|
105
|
+
relative = lambda do |key|
|
106
|
+
last_delimiter = last_index_of.call(@key, options[:delimiter])
|
107
|
+
(last_delimiter != -1) ? key[last_delimiter..-1] : key
|
108
|
+
end
|
109
|
+
|
110
|
+
# trim up to the last delimiter
|
111
|
+
#
|
112
|
+
# e.g. trim.call("foo/bar") => "foo/"
|
113
|
+
#
|
114
|
+
trim = lambda do |key|
|
115
|
+
last_delimiter = last_index_of.call(key, options[:delimiter])
|
116
|
+
(last_delimiter != -1) ? key[0..last_delimiter] : ""
|
117
|
+
end
|
118
|
+
|
119
|
+
# recursively display tree elements
|
120
|
+
#
|
121
|
+
# +prefix+: line prefix
|
122
|
+
# +children+: children of the current directory
|
123
|
+
# +depth+: current directory depth
|
124
|
+
display_tree = lambda do |prefix, children, depth|
|
125
|
+
stop = false
|
126
|
+
children = children.to_a # aws-sdk returns a sucky ChildCollection object
|
127
|
+
children.each_with_index do |node, index|
|
128
|
+
node = node
|
129
|
+
if options[:directories_only] && node.leaf?
|
130
|
+
next
|
131
|
+
end
|
132
|
+
|
133
|
+
last = (index == children.size - 1)
|
134
|
+
has_siblings = (children.size > 1)
|
135
|
+
key = node.branch? ? node.prefix : node.key
|
136
|
+
parts = relative.call(key).split(options[:delimiter])
|
137
|
+
postfix = last ? '└── ' : '├── '
|
138
|
+
|
139
|
+
stop = display_line.call(prefix + postfix + parts.last)
|
140
|
+
break if stop
|
141
|
+
|
142
|
+
if node.branch? && depth < options[:max_depth]
|
143
|
+
new_prefix = prefix + (has_siblings ? "│ " : " ")
|
144
|
+
stop = display_tree.call(new_prefix, node.children, depth + 1)
|
145
|
+
break if stop
|
146
|
+
end
|
147
|
+
|
148
|
+
break if stop
|
149
|
+
end
|
150
|
+
stop
|
151
|
+
end
|
152
|
+
|
153
|
+
display_line.call("s3://#{@bucket}/#{trim.call(@key)}")
|
154
|
+
|
155
|
+
prefix = ""
|
156
|
+
root = @s3.objects.with_prefix(@key).as_tree( :delimier => options[:delimiter], :append => false)
|
157
|
+
depth = 1
|
158
|
+
display_tree.call(prefix, root.children, depth)
|
159
|
+
rescue Errno::EPIPE
|
160
|
+
# ignore
|
161
|
+
end
|
162
|
+
|
data/lib/s3cp/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: s3cp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 1
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 1.1.
|
9
|
+
- 9
|
10
|
+
version: 1.1.9
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Alex Boisvert
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-
|
18
|
+
date: 2012-11-27 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
prerelease: false
|
@@ -127,6 +127,7 @@ executables:
|
|
127
127
|
- s3mv
|
128
128
|
- s3rm
|
129
129
|
- s3stat
|
130
|
+
- s3tree
|
130
131
|
- s3up
|
131
132
|
extensions: []
|
132
133
|
|
@@ -140,6 +141,7 @@ files:
|
|
140
141
|
- lib/s3cp/s3du.rb
|
141
142
|
- lib/s3cp/s3mod.rb
|
142
143
|
- lib/s3cp/utils.rb
|
144
|
+
- lib/s3cp/s3tree.rb
|
143
145
|
- lib/s3cp/s3cp.rb
|
144
146
|
- lib/s3cp/s3cat.rb
|
145
147
|
- lib/s3cp/s3buckets.rb
|
@@ -160,6 +162,7 @@ files:
|
|
160
162
|
- bin/s3cp
|
161
163
|
- bin/s3ls
|
162
164
|
- bin/s3stat
|
165
|
+
- bin/s3tree
|
163
166
|
homepage:
|
164
167
|
licenses: []
|
165
168
|
|