s3cp 0.2.1 → 0.2.2

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.
@@ -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: