better_s3 0.1.0

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