s3cp 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +4 -0
- data/README.md +41 -0
- data/bin/s3cat +3 -0
- data/bin/s3cp +3 -0
- data/bin/s3ls +3 -0
- data/bin/s3mod +4 -0
- data/lib/s3cp/s3cat.rb +68 -0
- data/lib/s3cp/s3cp.rb +171 -0
- data/lib/s3cp/s3ls.rb +84 -0
- data/lib/s3cp/s3mod.rb +35 -0
- data/lib/s3cp/utils.rb +28 -0
- data/lib/s3cp/version.rb +4 -0
- metadata +177 -0
data/History.txt
ADDED
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
S3CP: Commands-line tools for Amazon S3 file manipulation
|
2
|
+
=============================================================
|
3
|
+
|
4
|
+
Just a few simple command-line utilities to list, copy, view S3 files, e.g., `s3cp`, `s3ls`, `s3cat`.
|
5
|
+
|
6
|
+
### Building ###
|
7
|
+
|
8
|
+
# rake gem
|
9
|
+
# gem install s3cp-0.1.0.gem
|
10
|
+
|
11
|
+
### Examples ###
|
12
|
+
|
13
|
+
export AWS_ACCESS_KEY_ID=...
|
14
|
+
export AWS_SECRET_ACCESS_KEY=...
|
15
|
+
|
16
|
+
s3ls s3://mybucket/path/to/some/files
|
17
|
+
s3cat s3://mybucket/path/to/some/file.txt
|
18
|
+
s3cp local_file.bin s3://mybucket/some/path
|
19
|
+
s3mod s3://mybucket/path/to/some/file.txt public-read
|
20
|
+
|
21
|
+
Use the `-h` option to learn about command-line options.
|
22
|
+
|
23
|
+
All commands support both `s3://bucket/path/to/file` and the legacy `bucket:path/to/file` syntax.
|
24
|
+
|
25
|
+
Commands are also TTY-aware; when run in an interactive shell, their behavior will change. For example, `s3cat` will launch your favorite `PAGER` or `less` (the default pager) whereas `s3ls` will display N items at a time, where N is the number of display lines on your terminal and pause between pages.
|
26
|
+
|
27
|
+
### Dependencies ###
|
28
|
+
|
29
|
+
* highline `>=1.5.1` (console/terminal size guessing)
|
30
|
+
* right_aws `=2.1.0` (underlying Amazon S3 API)
|
31
|
+
* right_http_connection `=1.3.0` (required by `right_aws`)
|
32
|
+
|
33
|
+
### Target platform ###
|
34
|
+
|
35
|
+
* Ruby 1.8.7 / 1.9.2
|
36
|
+
|
37
|
+
### License ###
|
38
|
+
|
39
|
+
S3CP is is licensed under the terms of the Apache Software License v2.0.
|
40
|
+
<http://www.apache.org/licenses/LICENSE-2.0.html>
|
41
|
+
|
data/bin/s3cat
ADDED
data/bin/s3cp
ADDED
data/bin/s3ls
ADDED
data/bin/s3mod
ADDED
data/lib/s3cp/s3cat.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'right_aws'
|
3
|
+
require 'optparse'
|
4
|
+
require 'date'
|
5
|
+
require 'highline/import'
|
6
|
+
require 'tempfile'
|
7
|
+
|
8
|
+
require 's3cp/utils'
|
9
|
+
|
10
|
+
# Parse arguments
|
11
|
+
options = {}
|
12
|
+
options[:tty] = $stdout.isatty
|
13
|
+
|
14
|
+
op = OptionParser.new do |opts|
|
15
|
+
opts.banner = "s3cat [path]"
|
16
|
+
opts.separator ''
|
17
|
+
|
18
|
+
opts.on("--debug", "Debug mode") do
|
19
|
+
options[:debug] = true
|
20
|
+
end
|
21
|
+
|
22
|
+
opts.on("--tty", "TTY mode") do |tty|
|
23
|
+
options[:tty] = tty
|
24
|
+
end
|
25
|
+
|
26
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
27
|
+
puts op
|
28
|
+
exit
|
29
|
+
end
|
30
|
+
end
|
31
|
+
op.parse!(ARGV)
|
32
|
+
|
33
|
+
unless ARGV.size > 0
|
34
|
+
puts op
|
35
|
+
exit
|
36
|
+
end
|
37
|
+
|
38
|
+
url = ARGV[0]
|
39
|
+
|
40
|
+
if options[:debug]
|
41
|
+
puts "URL: #{url}"
|
42
|
+
puts "Options: \n#{options.inspect}"
|
43
|
+
end
|
44
|
+
|
45
|
+
@bucket, @prefix = S3CP.bucket_and_key(url)
|
46
|
+
fail "Your URL looks funny, doesn't it?" unless @bucket
|
47
|
+
|
48
|
+
@s3 = S3CP.connect().interface
|
49
|
+
|
50
|
+
if options[:tty]
|
51
|
+
# store contents to file to display with PAGER
|
52
|
+
file = Tempfile.new('s3cat')
|
53
|
+
out = File.new(file.path, File::CREAT|File::RDWR)
|
54
|
+
begin
|
55
|
+
@s3.get(@bucket, @prefix) do |chunk|
|
56
|
+
out.write(chunk)
|
57
|
+
end
|
58
|
+
ensure
|
59
|
+
out.close()
|
60
|
+
end
|
61
|
+
exec "#{ENV['PAGER'] || 'less'} #{file.path}"
|
62
|
+
file.delete()
|
63
|
+
else
|
64
|
+
@s3.get(@bucket, @prefix) do |chunk|
|
65
|
+
STDOUT.print(chunk)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
data/lib/s3cp/s3cp.rb
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'extensions/kernel' if RUBY_VERSION =~ /1.8/
|
3
|
+
require 'right_aws'
|
4
|
+
require 'optparse'
|
5
|
+
require 'date'
|
6
|
+
require 'highline/import'
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
require 's3cp/utils'
|
10
|
+
|
11
|
+
# Parse arguments
|
12
|
+
options = {}
|
13
|
+
options[:verbose] = true if $stdout.isatty
|
14
|
+
|
15
|
+
op = OptionParser.new do |opts|
|
16
|
+
opts.banner = "s3cp [path]"
|
17
|
+
opts.separator ''
|
18
|
+
|
19
|
+
opts.on("-r", "Recursive mode") do
|
20
|
+
options[:recursive] = true
|
21
|
+
end
|
22
|
+
|
23
|
+
opts.on("--verbose", "Verbose mode") do
|
24
|
+
options[:verbose] = true
|
25
|
+
end
|
26
|
+
|
27
|
+
opts.on("--debug", "Debug mode") do
|
28
|
+
options[:debug] = true
|
29
|
+
end
|
30
|
+
|
31
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
32
|
+
puts op
|
33
|
+
exit
|
34
|
+
end
|
35
|
+
end
|
36
|
+
op.parse!(ARGV)
|
37
|
+
|
38
|
+
if ARGV.size < 2
|
39
|
+
puts op
|
40
|
+
exit
|
41
|
+
end
|
42
|
+
|
43
|
+
destination = ARGV.last
|
44
|
+
sources = ARGV[0..-2]
|
45
|
+
|
46
|
+
def s3?(url)
|
47
|
+
S3CP.bucket_and_key(url)[0]
|
48
|
+
end
|
49
|
+
|
50
|
+
if options[:debug]
|
51
|
+
puts "URL: #{url}"
|
52
|
+
puts "Options: \n#{options.inspect}"
|
53
|
+
end
|
54
|
+
|
55
|
+
@bucket = $1
|
56
|
+
@prefix = $2
|
57
|
+
|
58
|
+
@s3 = S3CP.connect()
|
59
|
+
|
60
|
+
def direction(from, to)
|
61
|
+
if s3?(from) && s3?(to)
|
62
|
+
:s3_to_s3
|
63
|
+
elsif !s3?(from) && s3?(to)
|
64
|
+
:local_to_s3
|
65
|
+
elsif s3?(from) && !s3?(to)
|
66
|
+
:s3_to_local
|
67
|
+
else
|
68
|
+
:local_to_local
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def no_slash(path)
|
73
|
+
path = path.match(/\/$/) ? path[0..-2] : path
|
74
|
+
path.match(/^\//) ? path[1..-1] : path
|
75
|
+
end
|
76
|
+
|
77
|
+
def relative(base, path)
|
78
|
+
no_slash(path[base.length..-1])
|
79
|
+
end
|
80
|
+
|
81
|
+
def copy(from, to, options)
|
82
|
+
bucket_from, key_from = S3CP.bucket_and_key(from)
|
83
|
+
bucket_to, key_to = S3CP.bucket_and_key(to)
|
84
|
+
|
85
|
+
#puts "bucket_from #{bucket_from.inspect} key_from #{key_from.inspect}"
|
86
|
+
#puts "bucket_to #{bucket_to.inspect} key_from #{key_to.inspect}"
|
87
|
+
#puts "direction #{direction(from, to)}"
|
88
|
+
|
89
|
+
case direction(from, to)
|
90
|
+
when :s3_to_s3
|
91
|
+
if options[:recursive]
|
92
|
+
keys = []
|
93
|
+
@s3.interface.incrementally_list_bucket(bucket_from, :prefix => key_from) do |page|
|
94
|
+
page[:contents].each { |entry| keys << entry[:key] }
|
95
|
+
end
|
96
|
+
keys.each do |key|
|
97
|
+
dest = no_slash(key_to) + '/' + relative(key_from, key)
|
98
|
+
puts "Copy s3://#{bucket_from}/#{key} to s3://#{bucket_to}/#{dest}"
|
99
|
+
@s3.interface.copy(bucket_from, key, bucket_to, dest)
|
100
|
+
end
|
101
|
+
else
|
102
|
+
puts "Copy s3://#{bucket_from}/#{key_from} to s3://#{bucket_to}/#{key_to}"
|
103
|
+
@s3.interface.copy(bucket_from, key_from, bucket_to, key_to)
|
104
|
+
end
|
105
|
+
when :local_to_s3
|
106
|
+
if options[:recursive]
|
107
|
+
files = Dir[from + "/**/*"]
|
108
|
+
files.each do |f|
|
109
|
+
f = File.expand_path(f)
|
110
|
+
key = no_slash(key_to) + '/' + relative(from, f)
|
111
|
+
puts "Copy #{f} to s3://#{bucket_to}/#{key}"
|
112
|
+
@s3.interface.put(bucket_to, key, File.open(f))
|
113
|
+
end
|
114
|
+
else
|
115
|
+
f = File.expand_path(from)
|
116
|
+
puts "Copy #{f} to s3://#{bucket_to}/#{key_to}"
|
117
|
+
f = File.open(f)
|
118
|
+
begin
|
119
|
+
@s3.interface.put(bucket_to, key_to, f)
|
120
|
+
ensure
|
121
|
+
f.close()
|
122
|
+
end
|
123
|
+
end
|
124
|
+
when :s3_to_local
|
125
|
+
if options[:recursive]
|
126
|
+
keys = []
|
127
|
+
@s3.interface.incrementally_list_bucket(bucket_from, :prefix => key_from) do |page|
|
128
|
+
page[:contents].each { |entry| keys << entry[:key] }
|
129
|
+
end
|
130
|
+
keys.each do |key|
|
131
|
+
dest = File.expand_path(to) + '/' + relative(key_from, key)
|
132
|
+
dest = File.join(dest, File.basename(key)) if File.directory?(dest)
|
133
|
+
puts "Copy s3://#{bucket_from}/#{key} to #{dest}"
|
134
|
+
dir = File.dirname(dest)
|
135
|
+
FileUtils.mkdir_p dir unless File.exist? dir
|
136
|
+
fail "Destination path is not a directory: #{dir}" unless File.directory?(dir)
|
137
|
+
f = File.new(dest, File::CREAT|File::RDWR)
|
138
|
+
begin
|
139
|
+
@s3.interface.get(bucket_from, key) do |chunk|
|
140
|
+
f.write(chunk)
|
141
|
+
end
|
142
|
+
ensure
|
143
|
+
f.close()
|
144
|
+
end
|
145
|
+
end
|
146
|
+
else
|
147
|
+
dest = File.expand_path(to)
|
148
|
+
dest = File.join(dest, File.basename(key_from)) if File.directory?(dest)
|
149
|
+
puts "Copy s3://#{bucket_from}/#{key_from} to #{dest}"
|
150
|
+
f = File.new(dest, File::CREAT|File::RDWR)
|
151
|
+
begin
|
152
|
+
@s3.interface.get(bucket_from, key_from) do |chunk|
|
153
|
+
f.write(chunk)
|
154
|
+
end
|
155
|
+
ensure
|
156
|
+
f.close()
|
157
|
+
end
|
158
|
+
end
|
159
|
+
when :local_to_local
|
160
|
+
if options[:recursive]
|
161
|
+
FileUtils.cp_r from, to
|
162
|
+
else
|
163
|
+
FileUtils.cp from, to
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
sources.each do |source|
|
169
|
+
copy(source, destination, options)
|
170
|
+
end
|
171
|
+
|
data/lib/s3cp/s3ls.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'extensions/kernel' if RUBY_VERSION =~ /1.8/
|
3
|
+
require 'right_aws'
|
4
|
+
require 'optparse'
|
5
|
+
require 'date'
|
6
|
+
require 'highline/import'
|
7
|
+
|
8
|
+
require 's3cp/utils'
|
9
|
+
|
10
|
+
# Parse arguments
|
11
|
+
options = {}
|
12
|
+
options[:date_format] = '%x %X'
|
13
|
+
options[:rows_per_page] = $terminal.output_rows if $stdout.isatty
|
14
|
+
|
15
|
+
op = OptionParser.new do |opts|
|
16
|
+
opts.banner = "s3ls [path]"
|
17
|
+
opts.separator ''
|
18
|
+
|
19
|
+
opts.on("-l", "Long listing format") do
|
20
|
+
options[:long_format] = true
|
21
|
+
end
|
22
|
+
|
23
|
+
opts.on("--date-format FORMAT", "Date format (see http://strfti.me/)") do |custom|
|
24
|
+
options[:custom_params] = custom
|
25
|
+
end
|
26
|
+
|
27
|
+
opts.on("--verbose", "Verbose mode") do
|
28
|
+
options[:verbose] = true
|
29
|
+
end
|
30
|
+
|
31
|
+
opts.on("--rows ROWS", "Rows per page") do |rows|
|
32
|
+
options[:rows_per_page] = rows.to_i
|
33
|
+
end
|
34
|
+
|
35
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
36
|
+
puts op
|
37
|
+
exit
|
38
|
+
end
|
39
|
+
end
|
40
|
+
op.parse!(ARGV)
|
41
|
+
|
42
|
+
unless ARGV.size > 0
|
43
|
+
puts op
|
44
|
+
exit
|
45
|
+
end
|
46
|
+
|
47
|
+
url = ARGV[0]
|
48
|
+
|
49
|
+
if options[:verbose]
|
50
|
+
puts "URL: #{url}"
|
51
|
+
puts "Options: #{options.inspect}"
|
52
|
+
end
|
53
|
+
|
54
|
+
@bucket, @key = S3CP.bucket_and_key(url)
|
55
|
+
fail "Your URL looks funny, doesn't it?" unless @bucket
|
56
|
+
|
57
|
+
if options[:verbose]
|
58
|
+
puts "bucket #{@bucket}"
|
59
|
+
puts "key #{@key}"
|
60
|
+
end
|
61
|
+
|
62
|
+
@s3 = S3CP.connect()
|
63
|
+
|
64
|
+
rows = 0
|
65
|
+
@s3.interface.incrementally_list_bucket(@bucket, :prefix => @key) do |page|
|
66
|
+
page[:contents].each do |entry|
|
67
|
+
key = entry[:key]
|
68
|
+
last_modified = DateTime.parse(entry[:last_modified])
|
69
|
+
if options[:long_format]
|
70
|
+
puts "#{last_modified.strftime(options[:date_format])} #{key}"
|
71
|
+
else
|
72
|
+
puts key
|
73
|
+
end
|
74
|
+
rows += 1
|
75
|
+
if options[:rows_per_page] && (rows % options[:rows_per_page] == 0)
|
76
|
+
begin
|
77
|
+
print "Continue? (Y/n) "
|
78
|
+
response = STDIN.gets.chomp.downcase
|
79
|
+
end until response == 'n' || response == 'y' || response == ''
|
80
|
+
exit if response == 'n'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
data/lib/s3cp/s3mod.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'right_aws'
|
3
|
+
require 'optparse'
|
4
|
+
require 's3cp/utils'
|
5
|
+
|
6
|
+
op = OptionParser.new do |opts|
|
7
|
+
opts.banner = "s3mod [path] [permission]"
|
8
|
+
|
9
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
10
|
+
puts op
|
11
|
+
exit
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
op.parse!(ARGV)
|
16
|
+
|
17
|
+
if ARGV.size < 2
|
18
|
+
puts op
|
19
|
+
exit
|
20
|
+
end
|
21
|
+
|
22
|
+
def update_permissions(s3, bucket, key, permission)
|
23
|
+
puts "Setting #{permission} on s3://#{bucket}/#{key}"
|
24
|
+
s3.interface.copy(bucket, key, bucket, key, :replace, {"x-amz-acl" => permission })
|
25
|
+
end
|
26
|
+
|
27
|
+
source = ARGV[0]
|
28
|
+
permission = ARGV.last
|
29
|
+
|
30
|
+
LEGAL_MODS = %w{private authenticated-read public-read public-read-write}
|
31
|
+
raise "Permissions must be one of the following values: #{LEGAL_MODS}" unless LEGAL_MODS.include?(permission)
|
32
|
+
|
33
|
+
@s3 = S3CP.connect()
|
34
|
+
bucket,key = S3CP.bucket_and_key(source)
|
35
|
+
update_permissions(@s3, bucket, key, permission)
|
data/lib/s3cp/utils.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
module S3CP
|
2
|
+
extend self
|
3
|
+
|
4
|
+
# Connect to AWS S3
|
5
|
+
def connect()
|
6
|
+
access_key = ENV["AWS_ACCESS_KEY_ID"] || raise("Missing environment variable AWS_ACCESS_KEY_ID")
|
7
|
+
secret_key = ENV["AWS_SECRET_ACCESS_KEY"] || raise("Missing environment variable AWS_SECRET_ACCESS_KEY")
|
8
|
+
|
9
|
+
logger = Logger.new('/dev/null')
|
10
|
+
RightAws::S3.new(access_key, secret_key, :logger => logger)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Parse URL and return bucket and key.
|
14
|
+
#
|
15
|
+
# e.g. s3://bucket/path/to/key => ["bucket", "path/to/key"]
|
16
|
+
# bucket:path/to/key => ["bucket", "path/to/key"]
|
17
|
+
def bucket_and_key(url)
|
18
|
+
if url =~ /s3:\/\/([^\/]+)\/?(.*)/
|
19
|
+
bucket = $1
|
20
|
+
key = $2
|
21
|
+
elsif url =~ /([^:]+):(.*)/
|
22
|
+
bucket = $1
|
23
|
+
key = $2
|
24
|
+
end
|
25
|
+
[bucket, key]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
data/lib/s3cp/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: s3cp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 25
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Alex Boisvert
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-09-22 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
22
|
+
none: false
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
hash: 7
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
- 6
|
30
|
+
version: "0.6"
|
31
|
+
requirement: *id001
|
32
|
+
type: :runtime
|
33
|
+
name: extensions
|
34
|
+
prerelease: false
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
hash: 1
|
42
|
+
segments:
|
43
|
+
- 1
|
44
|
+
- 5
|
45
|
+
- 1
|
46
|
+
version: 1.5.1
|
47
|
+
requirement: *id002
|
48
|
+
type: :runtime
|
49
|
+
name: highline
|
50
|
+
prerelease: false
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ~>
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 11
|
58
|
+
segments:
|
59
|
+
- 2
|
60
|
+
- 1
|
61
|
+
- 0
|
62
|
+
version: 2.1.0
|
63
|
+
requirement: *id003
|
64
|
+
type: :runtime
|
65
|
+
name: right_aws
|
66
|
+
prerelease: false
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ~>
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
hash: 27
|
74
|
+
segments:
|
75
|
+
- 1
|
76
|
+
- 3
|
77
|
+
- 0
|
78
|
+
version: 1.3.0
|
79
|
+
requirement: *id004
|
80
|
+
type: :runtime
|
81
|
+
name: right_http_connection
|
82
|
+
prerelease: false
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
hash: 27
|
90
|
+
segments:
|
91
|
+
- 2
|
92
|
+
- 5
|
93
|
+
- 0
|
94
|
+
version: 2.5.0
|
95
|
+
requirement: *id005
|
96
|
+
type: :development
|
97
|
+
name: rspec
|
98
|
+
prerelease: false
|
99
|
+
- !ruby/object:Gem::Dependency
|
100
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
101
|
+
none: false
|
102
|
+
requirements:
|
103
|
+
- - ~>
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
hash: 49
|
106
|
+
segments:
|
107
|
+
- 0
|
108
|
+
- 8
|
109
|
+
- 7
|
110
|
+
version: 0.8.7
|
111
|
+
requirement: *id006
|
112
|
+
type: :development
|
113
|
+
name: rake
|
114
|
+
prerelease: false
|
115
|
+
description:
|
116
|
+
email:
|
117
|
+
- alex.boisvert@gmail.com
|
118
|
+
executables:
|
119
|
+
- s3ls
|
120
|
+
- s3cp
|
121
|
+
- s3cat
|
122
|
+
- s3mod
|
123
|
+
extensions: []
|
124
|
+
|
125
|
+
extra_rdoc_files:
|
126
|
+
- README.md
|
127
|
+
- History.txt
|
128
|
+
files:
|
129
|
+
- lib/s3cp/s3ls.rb
|
130
|
+
- lib/s3cp/s3mod.rb
|
131
|
+
- lib/s3cp/s3cp.rb
|
132
|
+
- lib/s3cp/version.rb
|
133
|
+
- lib/s3cp/utils.rb
|
134
|
+
- lib/s3cp/s3cat.rb
|
135
|
+
- History.txt
|
136
|
+
- README.md
|
137
|
+
- bin/s3cp
|
138
|
+
- bin/s3cat
|
139
|
+
- bin/s3ls
|
140
|
+
- bin/s3mod
|
141
|
+
homepage:
|
142
|
+
licenses: []
|
143
|
+
|
144
|
+
post_install_message:
|
145
|
+
rdoc_options: []
|
146
|
+
|
147
|
+
require_paths:
|
148
|
+
- lib
|
149
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
150
|
+
none: false
|
151
|
+
requirements:
|
152
|
+
- - ">="
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
hash: 3
|
155
|
+
segments:
|
156
|
+
- 0
|
157
|
+
version: "0"
|
158
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
159
|
+
none: false
|
160
|
+
requirements:
|
161
|
+
- - ">="
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
hash: 23
|
164
|
+
segments:
|
165
|
+
- 1
|
166
|
+
- 3
|
167
|
+
- 6
|
168
|
+
version: 1.3.6
|
169
|
+
requirements: []
|
170
|
+
|
171
|
+
rubyforge_project:
|
172
|
+
rubygems_version: 1.8.10
|
173
|
+
signing_key:
|
174
|
+
specification_version: 3
|
175
|
+
summary: Amazon S3 tools to, e.g., list, copy, delete S3 files
|
176
|
+
test_files: []
|
177
|
+
|