s3cp 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,11 @@
1
- === 0.2.2 / (Pending)
1
+ === 0.2.3 / (Pending)
2
+
3
+ === 0.2.2 / (2012-02-23)
4
+
5
+ * Added: Progress bars during upload/download if $stdout.isatty
6
+
7
+ * Fixed: s3cat now handles broken pipes properly
8
+ e.g. "s3cat bucket:some/file | head" will now terminate early.
2
9
 
3
10
  === 0.2.1 / (2012-02-20)
4
11
 
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  S3CP: Commands-line tools for Amazon S3 file manipulation
2
2
  =============================================================
3
3
 
4
- Just a few simple command-line utilities to list, copy, view S3 files, e.g., `s3cp`, `s3ls`, `s3cat`.
4
+ Just a few simple command-line utilities to list, copy, view S3 files, e.g., `s3cp`, `s3ls`, `s3cat`, `s3rm`, etc.
5
5
 
6
6
  ### Installing ###
7
7
 
@@ -26,9 +26,11 @@ If you want to hack on s3cp and build the gem yourself, you will need Bundler (h
26
26
  export AWS_SECRET_ACCESS_KEY=...
27
27
 
28
28
  s3ls s3://mybucket/path/to/some/files
29
+ s3dir s3://mybucket/path/to/some/files
29
30
  s3cat s3://mybucket/path/to/some/file.txt
30
31
  s3cp local_file.bin s3://mybucket/some/path
31
32
  s3mod s3://mybucket/path/to/some/file.txt public-read
33
+ s3stat s3://mybucket/path/to/some/file.txt
32
34
 
33
35
  Use the `-h` option to learn about command-line options.
34
36
 
@@ -36,6 +38,14 @@ All commands support both `s3://bucket/path/to/file` and the legacy `bucket:path
36
38
 
37
39
  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.
38
40
 
41
+ ### Bash completion for S3 URLs ###
42
+
43
+ To install Bash completion for S3 URLs, add the following to ~/.bashrc:
44
+
45
+ for cmd in [ s3cat s3cp s3dir s3ls s3mod s3rm s3stat ]; do
46
+ complete -C s3cp_complete $cmd
47
+ done
48
+
39
49
  ### Usage ###
40
50
 
41
51
  $ s3cp
@@ -1,3 +1,20 @@
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
+
1
18
  require 'rubygems'
2
19
  require 'extensions/kernel' if RUBY_VERSION =~ /1.8/
3
20
  require 'right_aws'
@@ -14,7 +31,7 @@ position = ENV['COMP_POINT'].to_i
14
31
  url = begin
15
32
  start = position
16
33
  start -= 1 while start >= 1 && cmd_line[start-1].chr != ' '
17
- cmd_line[start..position-1]
34
+ cmd_line[start..position-1].gsub("\"", "")
18
35
  end
19
36
 
20
37
  cmd = ARGV[0]
@@ -35,6 +52,9 @@ end
35
52
 
36
53
  debug "url #{url}"
37
54
 
55
+ debug "arg1 #{arg1.inspect}"
56
+ debug "arg2 #{arg2.inspect}"
57
+
38
58
  delimiter = ENV["S3CP_DELIMITER"] || "/"
39
59
  debug "delimiter #{delimiter}"
40
60
 
@@ -1,3 +1,20 @@
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
+
1
18
  require 'rubygems'
2
19
  require 'extensions/kernel' if RUBY_VERSION =~ /1.8/
3
20
  require 'right_aws'
@@ -5,6 +22,7 @@ require 'optparse'
5
22
  require 'date'
6
23
  require 'highline/import'
7
24
  require 'tempfile'
25
+ require 'progressbar'
8
26
 
9
27
  require 's3cp/utils'
10
28
 
@@ -50,12 +68,21 @@ fail "Your URL looks funny, doesn't it?" unless @bucket
50
68
 
51
69
  if options[:tty]
52
70
  # store contents to file to display with PAGER
71
+ metadata = @s3.head(@bucket, @prefix)
72
+ size = metadata["content-length"].to_i
73
+
74
+ progress_bar = ProgressBar.new(File.basename(@prefix), size).tap do |p|
75
+ p.file_transfer_mode
76
+ end
77
+
53
78
  file = Tempfile.new('s3cat')
54
79
  out = File.new(file.path, "wb")
55
80
  begin
56
81
  @s3.get(@bucket, @prefix) do |chunk|
57
82
  out.write(chunk)
83
+ progress_bar.inc chunk.size
58
84
  end
85
+ progress_bar.finish
59
86
  ensure
60
87
  out.close()
61
88
  end
@@ -63,7 +90,11 @@ if options[:tty]
63
90
  file.delete()
64
91
  else
65
92
  @s3.get(@bucket, @prefix) do |chunk|
66
- STDOUT.print(chunk)
93
+ begin
94
+ STDOUT.print(chunk)
95
+ rescue Errno::EPIPE
96
+ break
97
+ end
67
98
  end
68
99
  end
69
100
 
@@ -1,3 +1,20 @@
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
+
1
18
  require 'rubygems'
2
19
  require 'extensions/kernel' if RUBY_VERSION =~ /1.8/
3
20
  require 'right_aws'
@@ -6,6 +23,7 @@ require 'date'
6
23
  require 'highline/import'
7
24
  require 'fileutils'
8
25
  require 'digest'
26
+ require 'progressbar'
9
27
 
10
28
  require 's3cp/utils'
11
29
 
@@ -95,6 +113,21 @@ end
95
113
  destination = ARGV.last
96
114
  sources = ARGV[0..-2]
97
115
 
116
+ class Proxy
117
+ instance_methods.each { |m| undef_method m unless m =~ /(^__|^send$|^object_id$)/ }
118
+
119
+ def initialize(target)
120
+ @target = target
121
+ end
122
+
123
+ protected
124
+
125
+ def method_missing(name, *args, &block)
126
+ #puts "method_missing! #{name} #{args.inspect}"
127
+ @target.send(name, *args, &block)
128
+ end
129
+ end
130
+
98
131
  def s3?(url)
99
132
  S3CP.bucket_and_key(url)[0]
100
133
  end
@@ -199,7 +232,31 @@ def local_to_s3(bucket_to, key, file, options = {})
199
232
 
200
233
  f = File.open(file)
201
234
  begin
235
+ if $stdout.isatty
236
+ f = Proxy.new(f)
237
+ progress_bar = ProgressBar.new(File.basename(file), File.size(file)).tap do |p|
238
+ p.file_transfer_mode
239
+ end
240
+ class << f
241
+ attr_accessor :progress_bar
242
+ def read(length, buffer=nil)
243
+ begin
244
+ result = @target.read(length, buffer)
245
+ @progress_bar.inc result.length if result
246
+ result
247
+ rescue => e
248
+ puts e
249
+ raise e
250
+ end
251
+ end
252
+ end
253
+ f.progress_bar = progress_bar
254
+ else
255
+ progress_bar = nil
256
+ end
257
+
202
258
  meta = @s3.interface.put(bucket_to, key, f, @headers)
259
+ progress_bar.finish if progress_bar
203
260
 
204
261
  if options[:checksum]
205
262
  metadata = @s3.interface.head(bucket_to, key)
@@ -235,6 +292,7 @@ def s3_to_local(bucket_from, key_from, dest, options = {})
235
292
 
236
293
  f = File.new(dest, "wb")
237
294
  begin
295
+ size = nil
238
296
  if options[:checksum]
239
297
  metadata = @s3.interface.head(bucket_from, key_from)
240
298
  expected_md5 = metadata["etag"] or fail "Unable to get etag/md5 for #{bucket_from}:#{key_from}"
@@ -243,9 +301,25 @@ def s3_to_local(bucket_from, key_from, dest, options = {})
243
301
  STDERR.puts "Warning: invalid MD5 checksum in metadata; skipped checksum verification."
244
302
  expected_md5 = nil
245
303
  end
304
+ size = metadata["content-length"].to_i
305
+ elsif $stdout.isatty
306
+ metadata = @s3.interface.head(bucket_from, key_from)
307
+ size = metadata["content-length"].to_i
246
308
  end
247
- @s3.interface.get(bucket_from, key_from) do |chunk|
248
- f.write(chunk)
309
+ begin
310
+ progress_bar = if size
311
+ ProgressBar.new(File.basename(key_from), size).tap do |p|
312
+ p.file_transfer_mode
313
+ end
314
+ end
315
+ @s3.interface.get(bucket_from, key_from) do |chunk|
316
+ f.write(chunk)
317
+ progress_bar.inc chunk.size if progress_bar
318
+ end
319
+ progress_bar.finish
320
+ rescue => e
321
+ progress_bar.halt if progress_bar
322
+ raise e
249
323
  end
250
324
  rescue => e
251
325
  raise e unless options[:checksum]
@@ -1,3 +1,20 @@
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
+
1
18
  require 'rubygems'
2
19
  require 'extensions/kernel' if RUBY_VERSION =~ /1.8/
3
20
  require 'right_aws'
@@ -1,3 +1,20 @@
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
+
1
18
  require 'rubygems'
2
19
  require 'extensions/kernel' if RUBY_VERSION =~ /1.8/
3
20
  require 'right_aws'
@@ -1,3 +1,20 @@
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
+
1
18
  require 'rubygems'
2
19
  require 'extensions/kernel' if RUBY_VERSION =~ /1.8/
3
20
  require 'right_aws'
@@ -1,3 +1,20 @@
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
+
1
18
  require 'rubygems'
2
19
  require 'extensions/kernel' if RUBY_VERSION =~ /1.8/
3
20
  require 'right_aws'
@@ -1,3 +1,20 @@
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
+
1
18
  module S3CP
2
19
  extend self
3
20
 
@@ -1,4 +1,20 @@
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.
1
17
 
2
18
  module S3CP
3
- VERSION = "0.2.1"
19
+ VERSION = "0.2.2"
4
20
  end
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: 21
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 1
10
- version: 0.2.1
9
+ - 2
10
+ version: 0.2.2
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-02-21 00:00:00 Z
18
+ date: 2012-02-23 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  prerelease: false
@@ -82,8 +82,24 @@ dependencies:
82
82
  name: right_http_connection
83
83
  - !ruby/object:Gem::Dependency
84
84
  prerelease: false
85
- type: :development
85
+ type: :runtime
86
86
  requirement: &id005 !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ~>
90
+ - !ruby/object:Gem::Version
91
+ hash: 55
92
+ segments:
93
+ - 0
94
+ - 10
95
+ - 0
96
+ version: 0.10.0
97
+ version_requirements: *id005
98
+ name: progressbar
99
+ - !ruby/object:Gem::Dependency
100
+ prerelease: false
101
+ type: :development
102
+ requirement: &id006 !ruby/object:Gem::Requirement
87
103
  none: false
88
104
  requirements:
89
105
  - - ~>
@@ -94,12 +110,12 @@ dependencies:
94
110
  - 5
95
111
  - 0
96
112
  version: 2.5.0
97
- version_requirements: *id005
113
+ version_requirements: *id006
98
114
  name: rspec
99
115
  - !ruby/object:Gem::Dependency
100
116
  prerelease: false
101
117
  type: :development
102
- requirement: &id006 !ruby/object:Gem::Requirement
118
+ requirement: &id007 !ruby/object:Gem::Requirement
103
119
  none: false
104
120
  requirements:
105
121
  - - ~>
@@ -110,7 +126,7 @@ dependencies:
110
126
  - 8
111
127
  - 7
112
128
  version: 0.8.7
113
- version_requirements: *id006
129
+ version_requirements: *id007
114
130
  name: rake
115
131
  description:
116
132
  email: