better_s3 0.1.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: e9070018615cde079bd13bdedecdf4f7e4eb0345
4
+ data.tar.gz: 5f56a68976186bda80105a0eccee454c3df78a33
5
+ SHA512:
6
+ metadata.gz: 67018e1f8ce3ab64b15ffcc27c7cee11ec4f67a4a8a5a10b195d08996c7144e3de89391f614e370b9e22ede2f862b6299d195ae4b41dd0d60411564c04757a92
7
+ data.tar.gz: 72ee474a7b6a221c27f7087db93293ba280c69d0abee324b2d6294d83b5eb0979edcc4a5f311dbc05241c347122cb39bfcf644e363053d0129cd935d815f47a5
data/.gitignore ADDED
@@ -0,0 +1,50 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ ## Specific to RubyMotion:
17
+ .dat*
18
+ .repl_history
19
+ build/
20
+ *.bridgesupport
21
+ build-iPhoneOS/
22
+ build-iPhoneSimulator/
23
+
24
+ ## Specific to RubyMotion (use of CocoaPods):
25
+ #
26
+ # We recommend against adding the Pods directory to your .gitignore. However
27
+ # you should judge for yourself, the pros and cons are mentioned at:
28
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
+ #
30
+ # vendor/Pods/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalization:
39
+ /.bundle/
40
+ /vendor/bundle
41
+ /lib/bundler/man/
42
+
43
+ # for a library or gem, you might want to ignore these files since the code is
44
+ # intended to run in multiple environments; otherwise, check them in:
45
+ # Gemfile.lock
46
+ # .ruby-version
47
+ # .ruby-gemset
48
+
49
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
+ .rvmrc
data/.rubocop.yml ADDED
@@ -0,0 +1,87 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ Style/MutableConstant:
4
+ Enabled: false
5
+
6
+ Lint/UselessAssignment:
7
+ Enabled: true
8
+
9
+ Lint/UnusedMethodArgument:
10
+ Enabled: true
11
+
12
+ Lint/UnusedBlockArgument:
13
+ Enabled: true
14
+
15
+ Metrics/AbcSize:
16
+ Exclude:
17
+ - spec/**/*
18
+
19
+ Style/DotPosition:
20
+ Enabled: true
21
+ EnforcedStyle: trailing
22
+
23
+ Style/PercentLiteralDelimiters:
24
+ PreferredDelimiters:
25
+ '%': () # interpolated String
26
+ '%i': '[]' # Array of symbols
27
+ '%q': () # Single quoted string
28
+ '%Q': () # Double quoted string
29
+ '%r': '{}' # Regex
30
+ '%s': () # Symbol
31
+ '%w': '[]' # Array of strings
32
+ '%W': '[]' # Array of strings, interpolated
33
+ '%x': () # shell command
34
+
35
+ Style/StringLiterals:
36
+ EnforcedStyle: double_quotes
37
+
38
+ Style/CollectionMethods:
39
+ Enabled: true
40
+ # Mapping from undesired method to desired_method
41
+ # e.g. use `detect` over `find`:
42
+ PreferredMethods:
43
+ find: 'detect'
44
+ find_all: 'select'
45
+
46
+ Style/AlignHash:
47
+ EnforcedHashRocketStyle: table
48
+ EnforcedColonStyle: table
49
+
50
+ Style/AndOr:
51
+ # Whether `and` and `or` are banned only in conditionals (conditionals)
52
+ # or completely (always).
53
+ EnforcedStyle: conditionals # and/or are sometimes used for flow control.
54
+
55
+ Style/BlockDelimiters:
56
+ EnforcedStyle: semantic
57
+
58
+ Style/HashSyntax:
59
+ EnforcedStyle: ruby19_no_mixed_keys
60
+
61
+ Style/NumericLiterals:
62
+ MinDigits: 5
63
+
64
+ Style/SpaceBeforeFirstArg:
65
+ Enabled: false
66
+
67
+ # Configuration parameters: EnforcedStyleForMultiline, SupportedStyles.
68
+ Style/TrailingCommaInLiteral:
69
+ EnforcedStyleForMultiline: comma
70
+
71
+ Style/SingleLineBlockParams:
72
+ Enabled: false
73
+
74
+ Style/EachWithObject:
75
+ Enabled: false
76
+
77
+ Style/Lambda:
78
+ Enabled: false
79
+
80
+ AllCops:
81
+ Exclude:
82
+ - spec/support/mocks.rb
83
+ - better_s3.gemspec
84
+ - db/**/*.rb
85
+ - rakefile.rb
86
+ - spec/spec_helper.rb
87
+ - vendor/**/* # NOT RESPONSIBLE FOR THIS CODE
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,20 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2016-10-11 20:58:39 +0000 using RuboCop version 0.42.0.
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: 13
10
+ # Configuration parameters: AllowHeredoc, AllowURI, URISchemes.
11
+ # URISchemes: http, https
12
+ Metrics/LineLength:
13
+ Max: 107
14
+
15
+ # Offense count: 1
16
+ Style/Documentation:
17
+ Exclude:
18
+ - 'spec/**/*'
19
+ - 'test/**/*'
20
+ - 'lib/better_s3.rb'
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2016 Referly
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # better_s3
2
+ An idiomatic pattern for working with s3 in Ruby
3
+
4
+ [![CircleCI](https://circleci.com/gh/Referly/better_s3.svg?style=svg)](https://circleci.com/gh/Referly/better_s3)
5
+
6
+ ## Get the contents of a remote file
7
+
8
+ ```ruby
9
+ require "better_s3"
10
+ s3 = BetterS3.new
11
+ s3.get "some-filename.txt"
12
+ => "filescontentshere"
13
+ ```
14
+
15
+ ## Delete local copy of remote file
16
+
17
+ When downloading files from s3 there are benefits associated with storing a copy locally (most notably it enables
18
+ retry during download). As such BetterS3 stores a copy of files you get locally. If you want to delete one ...
19
+
20
+ ```ruby
21
+ require "better_s3"
22
+ s3 = BetterS3.new
23
+ s3.delete_local_file_copy "some-filename.txt"
24
+ ```
25
+
26
+ ## Put an arbitrary String to a remote file
27
+
28
+ ```ruby
29
+ require "better_s3"
30
+ s3 = BetterS3.new
31
+ content = { foo: "bar" }.to_json
32
+ s3.put content, "filename.ext"
33
+ ```
34
+
35
+ ## Configuration
36
+
37
+ To configure BetterS3 use the configuration block pattern
38
+
39
+ ```ruby
40
+ require "better_s3"
41
+ BetterS3.configure do |config|
42
+ # The name of the S3 bucket you plan to interact with
43
+ config.bucket = "your-bucket-name"
44
+
45
+ # The local path you want to use for temporary file
46
+ # storage
47
+ config.tmp_dir_path = "../tmp"
48
+
49
+ # If you want to hardcode which region of SQS should be used then you can set this option. It is recommended
50
+ # to use the environment variable ENV["AWS_REGION"] instead
51
+ config.region = "us-west-2"
52
+
53
+ # for aws_access_key_id and aws_secret_access_key you can set them in this fashion, but it is strongly
54
+ # recommended that you just use the environment variables instead: ENV["AWS_ACCESS_KEY_ID"],
55
+ # ENV["AWS_SECRET_ACCESS_KEY"]
56
+ end
57
+ ```
data/better_s3.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $LOAD_PATH.push File.expand_path("../lib", __FILE__)
3
+ require "better_s3/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "better_s3"
7
+ s.version = BetterS3::VERSION
8
+ s.date = BetterS3::VERSION_DATE
9
+ s.license = "MIT"
10
+ s.summary = "Idiomatic S3"
11
+ s.description = "Interact with S3 buckets in an idiomatic fashion."
12
+ s.authors = ["Courtland Caldwell"]
13
+ s.email = "engineering@mattermark.com"
14
+ s.files = `git ls-files`.split("\n") - %w[Gemfile Gemfile.lock]
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.homepage =
17
+ "https://github.com/Referly/better_s3"
18
+ s.add_runtime_dependency "aws-sdk", "~> 2" # Apache https://github.com/aws/aws-sdk-ruby/blob/master/LICENSE.txt
19
+ s.add_development_dependency "rspec", "~> 3.2" # MIT https://github.com/rspec/rspec/blob/master/License.txt
20
+ s.add_development_dependency "rb-readline", "~> 0.5", ">= 0.5.3" # BSD (content is BSD) https://github.com/ConnorAtherton/rb-readline/blob/master/LICENSE
21
+ s.add_development_dependency "byebug", "~> 3.5" # BSD (content is BSD) https://github.com/deivid-rodriguez/byebug/blob/master/LICENSE
22
+ s.add_development_dependency "simplecov", "~> 0.10" # MIT https://github.com/colszowka/simplecov/blob/master/MIT-LICENSE
23
+ s.add_development_dependency "rubocop", "~> 0.31" # Create Commons Attribution-NonCommerical https://github.com/bbatsov/rubocop/blob/master/LICENSE.txt
24
+ s.add_development_dependency "rspec_junit_formatter", "~> 0.2" # MIT https://github.com/sj26/rspec_junit_formatter/blob/master/LICENSE
25
+ end
data/circle.yml ADDED
@@ -0,0 +1,15 @@
1
+ machine:
2
+
3
+ timezone:
4
+ America/Los_Angeles # Set the timezone
5
+
6
+ # Version of ruby to use
7
+ ruby:
8
+ version:
9
+ 2.1.5
10
+
11
+ test:
12
+ override:
13
+ - bundle exec rubocop
14
+ - mkdir -p $CIRCLE_TEST_REPORTS/rspec
15
+ - bundle exec rspec --format RspecJunitFormatter --out $CIRCLE_TEST_REPORTS/rspec/rspec.xml spec --format progress
@@ -0,0 +1,29 @@
1
+ class BetterS3
2
+ # Provides configuration management for the BetterS3 gem
3
+ class Configuration
4
+ attr_accessor :bucket,
5
+ :tmp_dir_path,
6
+ :aws_access_key_id,
7
+ :aws_secret_access_key
8
+
9
+ def initialize
10
+ @aws_access_key_id = ENV["AWS_ACCESS_KEY_ID"]
11
+ @aws_secret_access_key = ENV["AWS_SECRET_ACCESS_KEY"]
12
+ @region = ENV["AWS_REGION"] || "us-east-1"
13
+ end
14
+
15
+ def configure_aws
16
+ return configure_region_only unless aws_secret_access_key && aws_access_key_id
17
+ Aws.config.update(
18
+ region: region,
19
+ credentials: Aws::Credentials.new(aws_access_key_id, aws_secret_access_key)
20
+ )
21
+ end
22
+
23
+ private
24
+
25
+ def configure_region_only
26
+ Aws.config.update(region: region)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,4 @@
1
+ class BetterS3
2
+ VERSION = "0.1.0"
3
+ VERSION_DATE = "2016-10-11"
4
+ end
data/lib/better_s3.rb ADDED
@@ -0,0 +1,90 @@
1
+ require "aws-sdk"
2
+ require_relative "better_s3/configuration"
3
+ require_relative "better_s3/version"
4
+ class BetterS3
5
+ class << self
6
+ # Allows the user to set configuration options
7
+ # by yielding the configuration block
8
+ #
9
+ # @param opts [Hash] an optional hash of options, supported options are `reset: true`
10
+ # @param block [Block] an optional configuration block
11
+ # @return [Configuration] the current configuration object
12
+ def configure(opts = {}, &_block)
13
+ @configuration = nil if opts.key?(:reset) && opts[:reset]
14
+ yield(configuration) if block_given?
15
+
16
+ configuration.configure_aws
17
+ configuration
18
+ end
19
+
20
+ # Returns the singleton class's configuration object
21
+ #
22
+ # @return [Configuration] the current configuration object
23
+ def configuration
24
+ @configuration ||= Configuration.new
25
+ end
26
+
27
+ def configured?
28
+ !@configuration.nil?
29
+ end
30
+
31
+ def logger
32
+ LincolnLogger.logger
33
+ end
34
+ end
35
+
36
+ attr_accessor :s3, :_payload_body, :file_copied
37
+ def s3
38
+ @s3 ||= Aws::S3::Client.new
39
+ end
40
+
41
+ # Returns the body of the payload, retrieved from S3
42
+ #
43
+ # @param remote_file_name [String] the s3 bucket key
44
+ # @return [String] the payload body from S3
45
+ def get(remote_file_name)
46
+ copy_file_from_s3 remote_file_name unless file_copied
47
+ @_payload_body ||= File.read(full_file_path(remote_file_name))
48
+ end
49
+
50
+ # Puts a Ruby hash to s3 as a file
51
+ #
52
+ # @param str [String] the string to be pushed to s3
53
+ # @param remote_file_name [String] the s3 bucket object key where the file should be put
54
+ def put(str, remote_file_name)
55
+ push_object_to_s3 str, remote_file_name
56
+ end
57
+
58
+ # Attempts to delete the local copy of the file, if it exists
59
+ #
60
+ # @param remote_file_name [String] the name of the file in the s3 bucket (the s3 object key)
61
+ def delete_local_file_copy(remote_file_name)
62
+ File.delete(full_file_path(remote_file_name)) if File.exist?(full_file_path(remote_file_name))
63
+ end
64
+
65
+ private
66
+
67
+ # Puts a Ruby hash to s3 as a file
68
+ #
69
+ # @param hsh [String] the content to be put into s3 (it really should be JSON)
70
+ # @param remote_file_name [String] the s3 bucket object key where the file should be put
71
+ def push_object_to_s3(hsh, remote_file_name)
72
+ s3.put_object(bucket: BetterS3.configuration.bucket.to_s,
73
+ key: remote_file_name.to_s,
74
+ body: hsh)
75
+ end
76
+
77
+ def copy_file_from_s3(remote_file_name)
78
+ s3.get_object({ bucket: BetterS3.configuration.bucket.to_s, key: remote_file_name.to_s },
79
+ target: full_file_path(remote_file_name))
80
+ @file_copied = true
81
+ end
82
+
83
+ # Returns the path on the server where the s3 file is downloaded locally
84
+ #
85
+ # @param remote_file_name [String] the name of the file in the s3 bucket (the s3 object key)
86
+ # @return [String] the complete path to location of the temporary local copy of the file
87
+ def full_file_path(remote_file_name)
88
+ "#{BetterS3.configuration.tmp_dir_path}/#{remote_file_name}"
89
+ end
90
+ end
@@ -0,0 +1,69 @@
1
+ require "spec_helper"
2
+
3
+ describe BetterS3 do
4
+ subject { described_class.new }
5
+ let(:remote_file_name) { "somefile" }
6
+ let(:s3_client) { mock_s3_client }
7
+
8
+ before do
9
+ allow(Aws::S3::Client).to receive(:new).and_return s3_client
10
+ end
11
+
12
+ describe "#get" do
13
+ before do
14
+ allow(s3_client).to receive(:get_object)
15
+ allow(File).to receive(:read).and_return remote_file_contents
16
+ end
17
+
18
+ let(:remote_file_contents) {
19
+ { "foo" => "bar" }
20
+ }
21
+
22
+ it "downloads a copy of the remote file to the local file system" do
23
+ expect(s3_client).
24
+ to receive(:get_object).
25
+ with({
26
+ bucket: BetterS3.configuration.bucket.to_s,
27
+ key: remote_file_name,
28
+ },
29
+ target: "#{BetterS3.configuration.tmp_dir_path}/#{remote_file_name}")
30
+
31
+ subject.get remote_file_name
32
+ end
33
+
34
+ it "returns the contents of the file" do
35
+ expect(subject.get(remote_file_name)).to eq remote_file_contents
36
+ end
37
+ end
38
+
39
+ describe "#put" do
40
+ let(:obj) { { "hi" => "toyou" } }
41
+ it "uploads the object to s3" do
42
+ expect(s3_client).to receive(:put_object).with(bucket: BetterS3.configuration.bucket.to_s,
43
+ key: remote_file_name,
44
+ body: obj.to_json)
45
+
46
+ subject.put obj.to_json, remote_file_name
47
+ end
48
+ end
49
+
50
+ describe "#delete_local_file_copy" do
51
+ it "checks to see if the file exists locally" do
52
+ expect(File).
53
+ to receive(:exist?).
54
+ with("#{BetterS3.configuration.tmp_dir_path}/#{remote_file_name}").
55
+ and_return false
56
+
57
+ subject.delete_local_file_copy remote_file_name
58
+ end
59
+
60
+ context "when the file exists locally" do
61
+ it "deletes the file from the local file system" do
62
+ allow(File).to receive(:exist?).and_return true
63
+ expect(File).to receive(:delete).with("#{BetterS3.configuration.tmp_dir_path}/#{remote_file_name}")
64
+
65
+ subject.delete_local_file_copy remote_file_name
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,4 @@
1
+ require "simplecov"
2
+ SimpleCov.profiles.define "better_s3" do
3
+ add_filter "/spec"
4
+ end
@@ -0,0 +1,5 @@
1
+ require_relative "simplecov_custom_profile"
2
+ SimpleCov.start "better_s3"
3
+ require "better_s3"
4
+ require "byebug"
5
+ require_relative "support/mocks"
@@ -0,0 +1,3 @@
1
+ def mock_s3_client
2
+ double "s3Client"
3
+ end
metadata ADDED
@@ -0,0 +1,166 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: better_s3
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Courtland Caldwell
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-10-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '3.2'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '3.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rb-readline
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '0.5'
48
+ - - '>='
49
+ - !ruby/object:Gem::Version
50
+ version: 0.5.3
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ~>
56
+ - !ruby/object:Gem::Version
57
+ version: '0.5'
58
+ - - '>='
59
+ - !ruby/object:Gem::Version
60
+ version: 0.5.3
61
+ - !ruby/object:Gem::Dependency
62
+ name: byebug
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ~>
66
+ - !ruby/object:Gem::Version
67
+ version: '3.5'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ~>
73
+ - !ruby/object:Gem::Version
74
+ version: '3.5'
75
+ - !ruby/object:Gem::Dependency
76
+ name: simplecov
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ~>
80
+ - !ruby/object:Gem::Version
81
+ version: '0.10'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ~>
87
+ - !ruby/object:Gem::Version
88
+ version: '0.10'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rubocop
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ~>
94
+ - !ruby/object:Gem::Version
95
+ version: '0.31'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ~>
101
+ - !ruby/object:Gem::Version
102
+ version: '0.31'
103
+ - !ruby/object:Gem::Dependency
104
+ name: rspec_junit_formatter
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: '0.2'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ~>
115
+ - !ruby/object:Gem::Version
116
+ version: '0.2'
117
+ description: Interact with S3 buckets in an idiomatic fashion.
118
+ email: engineering@mattermark.com
119
+ executables: []
120
+ extensions: []
121
+ extra_rdoc_files: []
122
+ files:
123
+ - .gitignore
124
+ - .rubocop.yml
125
+ - .rubocop_todo.yml
126
+ - LICENSE
127
+ - README.md
128
+ - better_s3.gemspec
129
+ - circle.yml
130
+ - lib/better_s3.rb
131
+ - lib/better_s3/configuration.rb
132
+ - lib/better_s3/version.rb
133
+ - spec/better_s3_spec.rb
134
+ - spec/simplecov_custom_profile.rb
135
+ - spec/spec_helper.rb
136
+ - spec/support/mocks.rb
137
+ homepage: https://github.com/Referly/better_s3
138
+ licenses:
139
+ - MIT
140
+ metadata: {}
141
+ post_install_message:
142
+ rdoc_options: []
143
+ require_paths:
144
+ - lib
145
+ required_ruby_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ required_rubygems_version: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - '>='
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ requirements: []
156
+ rubyforge_project:
157
+ rubygems_version: 2.4.2
158
+ signing_key:
159
+ specification_version: 4
160
+ summary: Idiomatic S3
161
+ test_files:
162
+ - spec/better_s3_spec.rb
163
+ - spec/simplecov_custom_profile.rb
164
+ - spec/spec_helper.rb
165
+ - spec/support/mocks.rb
166
+ has_rdoc: