exel-s3 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8936d6a5957afc15092d755de27ebfdc8f8b5538
4
+ data.tar.gz: 73473d824eeb3851f0bc58700805abe63bb682d3
5
+ SHA512:
6
+ metadata.gz: 8e8fda44139bedd03056d12abbf883d96e9ca29812754983554699cf397dbd6b629fd51c18d255c30303dc3caa6198b09a28e4f0d9ca4007d10f63877c2c186a
7
+ data.tar.gz: 4e14a6f528fe780dc68be98ccaae651ad0ebf56e6da467784973d12a98e90b148fb0364d3f6da403f750ac86dbf3e7e38bef2fa8147f47142a7f9746094b4744
data/.gitignore ADDED
@@ -0,0 +1,25 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ .idea
24
+ *.iml
25
+ .ruby-*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,17 @@
1
+ require:
2
+ - rubocop-rspec
3
+ - rubocop/rspec/focused
4
+
5
+ inherit_from: .rubocop_todo.yml
6
+
7
+ AllCops:
8
+ DisplayStyleGuide: true
9
+
10
+ Metrics/LineLength:
11
+ Max: 120
12
+
13
+ Style/SpaceInsideHashLiteralBraces:
14
+ EnforcedStyle: no_space
15
+
16
+ RSpec/DescribedClass:
17
+ Enabled: false
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,17 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2015-12-14 10:00:47 -0500 using RuboCop version 0.35.1.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 3
10
+ # Configuration parameters: Exclude.
11
+ Style/Documentation:
12
+ Exclude:
13
+ - 'spec/**/*'
14
+ - 'test/**/*'
15
+ - 'lib/exel/s3.rb'
16
+ - 'lib/exel/s3/s3_provider.rb'
17
+ - 'lib/exel/s3/version.rb'
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in exel-s3.gemspec
4
+ gemspec
5
+
6
+ gem 'exel', git: 'https://github.com/47colborne/exel'
data/Guardfile ADDED
@@ -0,0 +1,21 @@
1
+ group :rspec_rubocop, halt_on_fail: true do
2
+ guard :rspec, cmd: 'bundle exec rspec' do
3
+ require 'guard/rspec/dsl'
4
+ dsl = Guard::RSpec::Dsl.new(self)
5
+
6
+ # RSpec files
7
+ rspec = dsl.rspec
8
+ watch(rspec.spec_helper) { rspec.spec_dir }
9
+ watch(rspec.spec_support) { rspec.spec_dir }
10
+ watch(rspec.spec_files)
11
+
12
+ # Ruby files
13
+ ruby = dsl.ruby
14
+ dsl.watch_spec_files_for(ruby.lib_files)
15
+ end
16
+
17
+ guard :rubocop do
18
+ watch(/.+\.rb$/)
19
+ watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
20
+ end
21
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 yroo
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # EXEL::S3
2
+
3
+ [![Build Status](https://snap-ci.com/47colborne/exel-s3/branch/master/build_image)](https://snap-ci.com/47colborne/exel-s3/branch/master)
4
+
5
+ This gem implements a "remote provider" for [EXEL](https://github.com/47colborne/exel) using Amazon S3. The remote provider is used when an async command is executed and a context shift occurs. Its job is to move the context to a remote storage location when the async call is initiated, and retrieve it before the async block is executed.
6
+
7
+ Typically, this gem would be used in conjunction with an EXEL async provider, such as [exel-sidekiq](https://github.com/47colborne/exel-sidekiq). In this case, the context is serialized and uploaded to S3 from the machine making the async call, then downloaded by the Sidekiq worker before it executes the async block.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'exel-s3'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install exel-s3
22
+
23
+ ## Usage
24
+
25
+ By requiring this gem, EXEL will automatically be configured to use S3 to upload and download the serialized context when an async command is executed.
26
+
27
+ The following configuration must be provided:
28
+
29
+ EXEL.configure do |config|
30
+ config.aws = OpenStruct.new(
31
+ access_key_id: 'your AWS access key ID',
32
+ secret_access_key: 'your AWS secret access key'
33
+ )
34
+
35
+ config.s3_bucket = 'the name of the bucket to use'
36
+ end
37
+
38
+ ## Contributing
39
+
40
+ 1. Fork it ( https://github.com/47colborne/exel-s3/fork )
41
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
42
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
43
+ 4. Push to the branch (`git push origin my-new-feature`)
44
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
data/exel-s3.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'exel/s3/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'exel-s3'
8
+ spec.version = EXEL::S3::VERSION
9
+ spec.authors = ['yroo']
10
+ spec.email = ['dev@yroo.com']
11
+ spec.summary = 'Makes EXEL use S3 to store files during context shifts.'
12
+ spec.description = 'Add-on to EXEL (https://github.com/47colborne/exel) that provides support for Amazon S3.'
13
+ spec.homepage = 'https://github.com/47colborne/exel-s3'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency 'exel', '~> 1'
22
+ spec.add_dependency 'aws-sdk', '~> 2'
23
+
24
+ spec.add_development_dependency 'bundler', '~> 1.6'
25
+ spec.add_development_dependency 'rake', '~> 10'
26
+ spec.add_development_dependency 'rspec', '~> 3'
27
+ spec.add_development_dependency 'guard', '~> 2'
28
+ spec.add_development_dependency 'guard-rspec', '~> 4'
29
+ spec.add_development_dependency 'guard-rubocop', '~> 1'
30
+ spec.add_development_dependency 'terminal-notifier', '~> 1'
31
+ spec.add_development_dependency 'terminal-notifier-guard', '~> 1'
32
+ spec.add_development_dependency 'rubocop', '~> 0'
33
+ spec.add_development_dependency 'rubocop-rspec', '~> 1'
34
+ spec.add_development_dependency 'rubocop-rspec-focused', '~> 0'
35
+ end
@@ -0,0 +1,46 @@
1
+ require 'aws-sdk-resources'
2
+
3
+ module EXEL
4
+ module S3
5
+ class S3Provider
6
+ def upload(file)
7
+ filename = get_filename(file)
8
+ obj = get_object(filename)
9
+ obj.upload_file(file)
10
+ file.close
11
+
12
+ "s3://#{filename}"
13
+ end
14
+
15
+ def download(uri)
16
+ filename = uri.partition('://').last
17
+ obj = get_object(filename)
18
+ file = Tempfile.new(filename, encoding: Encoding::ASCII_8BIT)
19
+ obj.get(response_target: file)
20
+ file.set_encoding(Encoding::UTF_8)
21
+ file
22
+ end
23
+
24
+ def get_object(filename)
25
+ s3 = Aws::S3::Resource.new(
26
+ credentials: Aws::Credentials.new(
27
+ EXEL.configuration.aws.access_key_id,
28
+ EXEL.configuration.aws.secret_access_key
29
+ ),
30
+ region: 'us-east-1'
31
+ )
32
+ s3.bucket(EXEL.configuration.s3_bucket).object(filename)
33
+ end
34
+
35
+ def self.remote?(uri)
36
+ uri =~ %r{s3://}
37
+ end
38
+
39
+ private
40
+
41
+ def get_filename(file)
42
+ file.path.split('/').last
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,5 @@
1
+ module EXEL
2
+ module S3
3
+ VERSION = '1.0.0'
4
+ end
5
+ end
data/lib/exel/s3.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'exel/s3/version'
2
+ require_relative 's3/s3_provider'
3
+
4
+ module EXEL
5
+ module S3
6
+ EXEL.configure do |config|
7
+ config.remote_provider = EXEL::S3::S3Provider
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,62 @@
1
+ module EXEL
2
+ module S3
3
+ describe S3Provider do
4
+ describe '#get_object' do
5
+ before do
6
+ EXEL.configure do |config|
7
+ config.aws = OpenStruct.new
8
+ config.s3_bucket = 'bucket'
9
+ end
10
+ end
11
+
12
+ it 'has the correct bucket and file names' do
13
+ file_name = 'abc.txt'
14
+ s3_obj = subject.get_object(file_name)
15
+ expect(s3_obj.bucket_name).to eq('bucket')
16
+ expect(s3_obj.key).to eq(file_name)
17
+ end
18
+ end
19
+
20
+ describe '#upload' do
21
+ let(:file) { double(path: '/path/to/abc.txt', close: nil) }
22
+
23
+ it 'uploads the file to s3' do
24
+ expect_any_instance_of(Aws::S3::Object).to receive(:upload_file).with(file)
25
+
26
+ subject.upload(file)
27
+ end
28
+
29
+ it 'returns the URI of the uploaded file' do
30
+ allow_any_instance_of(Aws::S3::Object).to receive(:upload_file).with(file)
31
+ expect(subject.upload(file)).to eq('s3://abc.txt')
32
+ end
33
+ end
34
+
35
+ describe '#download' do
36
+ it 'downloads the file from s3' do
37
+ file = double(:file)
38
+ s3_object = double(:s3_object)
39
+
40
+ expect(subject).to receive(:get_object).with('abc.txt').and_return(s3_object)
41
+ expect(Tempfile).to receive(:new).with('abc.txt', encoding: Encoding::ASCII_8BIT).and_return(file)
42
+ expect(s3_object).to receive(:get).with(hash_including(response_target: file)).and_return(file)
43
+ expect(file).to receive(:set_encoding).with(Encoding::UTF_8)
44
+
45
+ expect(subject.download('s3://abc.txt')).to eq(file)
46
+ end
47
+ end
48
+
49
+ describe '.remote?' do
50
+ it 'returns true for file:// URIs' do
51
+ expect(S3Provider.remote?('s3://file')).to be_truthy
52
+ end
53
+
54
+ it 'returns false for anything else' do
55
+ expect(S3Provider.remote?('file://path/to/file')).to be_falsey
56
+ expect(S3Provider.remote?(1)).to be_falsey
57
+ expect(S3Provider.remote?(nil)).to be_falsey
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,7 @@
1
+ module EXEL
2
+ describe S3 do
3
+ it 'sets itself as the remote provider' do
4
+ expect(EXEL.remote_provider).to eq(EXEL::S3::S3Provider)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ require 'exel'
2
+
3
+ Dir[File.expand_path('../../lib/**/*.rb', __FILE__)].each { |f| require f }
4
+
5
+ EXEL.logger = nil
metadata ADDED
@@ -0,0 +1,246 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: exel-s3
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - yroo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-12-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: exel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: aws-sdk
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.6'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: guard
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '2'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '2'
97
+ - !ruby/object:Gem::Dependency
98
+ name: guard-rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '4'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '4'
111
+ - !ruby/object:Gem::Dependency
112
+ name: guard-rubocop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1'
125
+ - !ruby/object:Gem::Dependency
126
+ name: terminal-notifier
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1'
139
+ - !ruby/object:Gem::Dependency
140
+ name: terminal-notifier-guard
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '1'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '1'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rubocop
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: rubocop-rspec
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '1'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '1'
181
+ - !ruby/object:Gem::Dependency
182
+ name: rubocop-rspec-focused
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ description: Add-on to EXEL (https://github.com/47colborne/exel) that provides support
196
+ for Amazon S3.
197
+ email:
198
+ - dev@yroo.com
199
+ executables: []
200
+ extensions: []
201
+ extra_rdoc_files: []
202
+ files:
203
+ - ".gitignore"
204
+ - ".rspec"
205
+ - ".rubocop.yml"
206
+ - ".rubocop_todo.yml"
207
+ - Gemfile
208
+ - Guardfile
209
+ - LICENSE.txt
210
+ - README.md
211
+ - Rakefile
212
+ - exel-s3.gemspec
213
+ - lib/exel/s3.rb
214
+ - lib/exel/s3/s3_provider.rb
215
+ - lib/exel/s3/version.rb
216
+ - spec/exel/s3/s3_provider_spec.rb
217
+ - spec/exel/s3_spec.rb
218
+ - spec/spec_helper.rb
219
+ homepage: https://github.com/47colborne/exel-s3
220
+ licenses:
221
+ - MIT
222
+ metadata: {}
223
+ post_install_message:
224
+ rdoc_options: []
225
+ require_paths:
226
+ - lib
227
+ required_ruby_version: !ruby/object:Gem::Requirement
228
+ requirements:
229
+ - - ">="
230
+ - !ruby/object:Gem::Version
231
+ version: '0'
232
+ required_rubygems_version: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
237
+ requirements: []
238
+ rubyforge_project:
239
+ rubygems_version: 2.4.5.1
240
+ signing_key:
241
+ specification_version: 4
242
+ summary: Makes EXEL use S3 to store files during context shifts.
243
+ test_files:
244
+ - spec/exel/s3/s3_provider_spec.rb
245
+ - spec/exel/s3_spec.rb
246
+ - spec/spec_helper.rb