capistrano-s3 2.3.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bce49162959fade7c6c40e55edb80feaf9b370ef442dc155ec917407bbb9994c
4
- data.tar.gz: 54295d08772a2b0ef41807fe495b0252092b02f6fa2262121bbf4b745b1668b2
3
+ metadata.gz: 7d90b10eb5f19179837cae17bcf810dd296e249dd7cbb9ef589091eaefe5b668
4
+ data.tar.gz: 4d7e192fe0bcbd150a8d9b2d846db39db30d7cb4ec420f4dd9e626d7abcec407
5
5
  SHA512:
6
- metadata.gz: e27108ca9d10306686c878ff86e575da556db7542a6711503bac883dc9a20cd6478a24a8fef4835fbcf774f5728200eba22db27a82f89e3b3e2fb01b2084b210
7
- data.tar.gz: 45681c3546f4f7d0160654b0eeb8dca9b4c236e610c6c7264229bddddfb5aac4670b9e13be036f4558701103970d9ecce4079b80930f2e0bc89d8cc6270b4f17
6
+ metadata.gz: bb1ec55f60aee74e0673a0f9e9219bab41ec107dd0b928326bf43b9694afc001dc3d82ff8a1d4776380082d51823039b6ce8550bbf306beb0581e213fc6632d6
7
+ data.tar.gz: ff237af6085eb21a2a7defe9c762d79491f0e58483f783cca60fe77701ab0935f2fe7be0efbbca22479df1d6c90d9d59c4b8cfa28af8b7685b62ce0f14d46f9e
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -1,5 +1,10 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## v2.4.0
4
+
5
+ Feature : Add option to prefer CloudFront compression supported MIME types (#54)
6
+ Feature : Add object_write_options to specify headers using patterns (#52)
7
+
3
8
  ## v2.3.0
4
9
 
5
10
  Change : Dotfiles are not ignored anymore (#48)
data/README.md CHANGED
@@ -104,6 +104,10 @@ set :target_path, 'app'
104
104
 
105
105
  ### Write options
106
106
 
107
+ See aws-sdk [S3Client.put_object doc](http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/S3/Client.html#put_object-instance_method) for all available options both for `bucket_write_options` and `object_write_options`.
108
+
109
+ #### Bucket-level options
110
+
107
111
  capistrano-s3 sets files `:content_type` and `:acl` to `public-read`, add or override with:
108
112
 
109
113
  ```ruby
@@ -112,7 +116,38 @@ set :bucket_write_options, {
112
116
  }
113
117
  ```
114
118
 
115
- See aws-sdk [S3Client.put_object doc](http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/S3/Client.html#put_object-instance_method) for all available options.
119
+ #### Object-level options
120
+
121
+ You can also set write options for files matching specific [patterns](https://ruby-doc.org/core-2.3.0/Dir.html#method-c-glob) using:
122
+
123
+ ```ruby
124
+ set :object_write_options, {
125
+ 'index.html' => { cache_control: 'no-cache' }
126
+ }
127
+ ```
128
+
129
+ or in a more advanced scenario
130
+
131
+ ```ruby
132
+ set :object_write_options, {
133
+ 'assets/**' => { cache_control: 'public, max-age=86400' },
134
+ 'index.html' => { cache_control: 'no-cache' }
135
+ }
136
+ ```
137
+
138
+ **NOTES:**
139
+
140
+ * `object_write_options` are evaulated **after** `bucket_write_options` and can override them
141
+ * Also the pattern matching for `object_write_options` is evaluated in the order of definition and overrides on match down the chain. For example defining
142
+
143
+ ```ruby
144
+ set :object_write_options, {
145
+ 'assets/my-script.js' => { cache_control: 'no-cache' },
146
+ 'assets/**' => { cache_control: 'public, max-age=86400' }
147
+ }
148
+ ```
149
+
150
+ will set `Cache-Control: public, max-age=86400` header on `assets/my-script.js` as well!
116
151
 
117
152
  ### Redirecting
118
153
 
@@ -174,6 +209,20 @@ You can set a list of files or directories to exclude from upload. The path must
174
209
  set :exclusions, [ "index.html", "resources/**/*" ]
175
210
  ```
176
211
 
212
+ ### MIME types
213
+
214
+ Under the hood capistrano-s3 is using the [mime-types](https://github.com/mime-types/ruby-mime-types) gem to determine the correct MIME type used for `:content_type` based on the filename extension. The possible list of MIME types are in a priority ordered list, and by default capistrano-s3 uses the first element - the "best" match.
215
+
216
+ However CloudFront has [a list](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html#compressed-content-cloudfront-file-types) of MIME types that are supported by the [Serving Compressed Files](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html) feature, and the two results are not necessarily overlap.
217
+
218
+ > *For example:* the "best" MIME type match for a `.js` file is `application/ecmascript`, but files with this type are not compressed by CloudFront, only the ones with `application/javascript`.
219
+
220
+ You can enable to prefer CloudFront-supported MIME types over the "best" ones by setting:
221
+
222
+ ```ruby
223
+ set :prefer_cf_mime_types, true
224
+ ```
225
+
177
226
  ## Example of usage
178
227
 
179
228
  Our Ruby stack for static websites:
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.name = 'capistrano-s3'
16
16
  s.require_paths = ['lib']
17
17
  s.version = Capistrano::S3::VERSION
18
- s.cert_chain = ['certs/aleksandrs-ledovskis--2018-11-04-2020-11-03.pem']
18
+ s.cert_chain = ['certs/j15e.pem']
19
19
  s.signing_key = File.expand_path("~/.ssh/gem-private_key.pem") if $0 =~ /gem\z/
20
20
 
21
21
  # Min rubies
@@ -1,22 +1,21 @@
1
1
  -----BEGIN CERTIFICATE-----
2
- MIIDmjCCAoKgAwIBAgIBATANBgkqhkiG9w0BAQUFADBJMRswGQYDVQQDDBJqZWFu
3
- cGhpbGlwcGUuZG95bGUxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT
4
- 8ixkARkWA2NvbTAeFw0xNjA5MjMxNjE1NDlaFw0xNzA5MjMxNjE1NDlaMEkxGzAZ
5
- BgNVBAMMEmplYW5waGlsaXBwZS5kb3lsZTEVMBMGCgmSJomT8ixkARkWBWdtYWls
6
- MRMwEQYKCZImiZPyLGQBGRYDY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
7
- CgKCAQEAzpnUIh2dzSBkAghI4ZzdefobWdGH8M9yjiyZl4DfO+LSLV5ovcqVYPYr
8
- fzHm4TJO4w0S7jnfdwq45mGO3ogEMbmQLz4B/bUZXVHX0K9//KRroseRCUH24BE0
9
- q46UCeaFMs5wGcniT7XhuDcqPQaqCIxDE1aBxcKlZg8i62yM3BO/yX5DwLPqhyEu
10
- XVViJ+PvHjUGa69iw1fqUs9PZaf9WdKHyPHhgbhwy7xqx7EavG+tmHQUxtIf7xhl
11
- OU80hUsHQrkj5PxPU2Qfs6q2jOxrfRcUSBJZxUDzjmbhP9eq0XN+b5/Cqz3OboSI
12
- nWF0Kj0971wJgZiNdzXsLMy+zmHdiQIDAQABo4GMMIGJMAkGA1UdEwQCMAAwCwYD
13
- VR0PBAQDAgSwMB0GA1UdDgQWBBRro81JisHXRBP5dZh5mzOEHsjLxTAnBgNVHREE
14
- IDAegRxqZWFucGhpbGlwcGUuZG95bGVAZ21haWwuY29tMCcGA1UdEgQgMB6BHGpl
15
- YW5waGlsaXBwZS5kb3lsZUBnbWFpbC5jb20wDQYJKoZIhvcNAQEFBQADggEBADsn
16
- 80BmZ9LcnXzKOvNFts/L230YyUuRvsSFhLpfTJqmvDmfjBWrtL6pXxnES79Ioshd
17
- zWSLZ1XYWwPFVDYODq+eupjVg2/DBSdOcMjwdrMP84nZeOS5AumogydbC8j22ETx
18
- Yal+NgwHw8x1+loPGm5ZLrRFgyMnDrhUnG0pFDEd4/rMpUlnG17eGeWq2Zr3Q5q+
19
- mj7phtPsRLGRWLV5ba9ROJYoASdZtQadvQMHvDOoYY9+vprJ8sYQJkBz6hRJrg30
20
- t/JsZnAlWYkJIees2SFV5X/t34oeMu04yY2u9y2YBqKovR97m5YF7zqgx0JODV0x
21
- ytwUJvEjznBnJV4OoDE=
2
+ MIIDYjCCAkqgAwIBAgIBATANBgkqhkiG9w0BAQsFADAtMSswKQYDVQQDDCJqZWFu
3
+ cGhpbGlwcGUuZG95bGUvREM9Z21haWwvREM9Y29tMB4XDTE5MDEwMzIzNDA1OFoX
4
+ DTI0MDEwMjIzNDA1OFowLTErMCkGA1UEAwwiamVhbnBoaWxpcHBlLmRveWxlL0RD
5
+ PWdtYWlsL0RDPWNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6Z
6
+ 1CIdnc0gZAIISOGc3Xn6G1nRh/DPco4smZeA3zvi0i1eaL3KlWD2K38x5uEyTuMN
7
+ Eu4533cKuOZhjt6IBDG5kC8+Af21GV1R19Cvf/yka6LHkQlB9uARNKuOlAnmhTLO
8
+ cBnJ4k+14bg3Kj0GqgiMQxNWgcXCpWYPIutsjNwTv8l+Q8Cz6ochLl1VYifj7x41
9
+ BmuvYsNX6lLPT2Wn/VnSh8jx4YG4cMu8asexGrxvrZh0FMbSH+8YZTlPNIVLB0K5
10
+ I+T8T1NkH7Oqtozsa30XFEgSWcVA845m4T/XqtFzfm+fwqs9zm6EiJ1hdCo9Pe9c
11
+ CYGYjXc17CzMvs5h3YkCAwEAAaOBjDCBiTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE
12
+ sDAdBgNVHQ4EFgQUa6PNSYrB10QT+XWYeZszhB7Iy8UwJwYDVR0RBCAwHoEcamVh
13
+ bnBoaWxpcHBlLmRveWxlQGdtYWlsLmNvbTAnBgNVHRIEIDAegRxqZWFucGhpbGlw
14
+ cGUuZG95bGVAZ21haWwuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAgO4ZWrs7jiVwB
15
+ rjuziOlVkE0pQYIL04DYqFHh+OUXehbla3ez6yXrJDYzmGssG9gWw2x7zLJDzMGS
16
+ Nuu5LJb6fLt7ngeNkT2VrX8BAi6SNOBkclDbaG2no8Of0/1Ckic0edeRhR2O2WiO
17
+ Ss4Bjfz1DIeMWXQ6XohtG2lW2hdHdkqZEz9CjOHtW9+oUZkEvE/x0zxW/xV1dy0E
18
+ wLg21KGfGL5oeHjZugRKz6VH9DchvEjlNdaagy3ew5+lxZqG5R26eCQv/SEI7UYw
19
+ O/dqEjT9PZ4B9DM6P859LG9xBvj/+cOBs8ViEUU/ExY0rPSZoZT1Ks37cCjj2mrC
20
+ ZBShvFcL
22
21
  -----END CERTIFICATE-----
@@ -2,6 +2,7 @@ require "capistrano"
2
2
  require "capistrano/s3/publisher"
3
3
  require "capistrano/s3/version"
4
4
  require "capistrano/s3/defaults"
5
+ require "capistrano/s3/mime_types"
5
6
 
6
7
  if Gem::Specification.find_by_name('capistrano').version >= Gem::Version.new('3.0.0')
7
8
  load File.expand_path('../tasks/capistrano_3.rb', __FILE__)
@@ -0,0 +1,53 @@
1
+ require 'mime/types'
2
+
3
+ module Capistrano
4
+ module S3
5
+ module MIMETypes
6
+ # List of supported MIME Types for CloudFront "Serving Compressed Files" feature
7
+ # - https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html#compressed-content-cloudfront-file-types
8
+ CF_MIME_TYPES = %w(
9
+ application/eot
10
+ application/font
11
+ application/font-sfnt
12
+ application/javascript
13
+ application/json
14
+ application/opentype
15
+ application/otf
16
+ application/pkcs7-mime
17
+ application/truetype
18
+ application/ttf
19
+ application/vnd.ms-fontobject
20
+ application/xhtml+xml
21
+ application/xml
22
+ application/xml+rss
23
+ application/x-font-opentype
24
+ application/x-font-truetype
25
+ application/x-font-ttf
26
+ application/x-httpd-cgi
27
+ application/x-javascript
28
+ application/x-mpegurl
29
+ application/x-opentype
30
+ application/x-otf
31
+ application/x-perl
32
+ application/x-ttf
33
+ font/eot
34
+ font/ttf
35
+ font/otf
36
+ font/opentype
37
+ image/svg+xml
38
+ text/css
39
+ text/csv
40
+ text/html
41
+ text/javascript
42
+ text/js
43
+ text/plain
44
+ text/richtext
45
+ text/tab-separated-values
46
+ text/xml
47
+ text/x-script
48
+ text/x-component
49
+ text/x-java-source
50
+ ).map { |name| MIME::Types[name].first }.compact
51
+ end
52
+ end
53
+ end
@@ -1,6 +1,7 @@
1
1
  require 'aws-sdk'
2
2
  require 'mime/types'
3
3
  require 'fileutils'
4
+ require 'capistrano/s3/mime_types'
4
5
 
5
6
  module Capistrano
6
7
  module S3
@@ -137,8 +138,10 @@ module Capistrano
137
138
  end
138
139
 
139
140
  def self.put_object(s3, bucket, target_path, path, file, only_gzip, extra_options)
141
+ prefer_cf_mime_types = extra_options[:prefer_cf_mime_types] || false
142
+
140
143
  base_name = File.basename(file)
141
- mime_type = mime_type_for_file(base_name)
144
+ mime_type = mime_type_for_file(base_name, prefer_cf_mime_types)
142
145
  options = {
143
146
  :bucket => bucket,
144
147
  :key => self.add_prefix(path, prefix: target_path),
@@ -149,12 +152,19 @@ module Capistrano
149
152
  options.merge!(build_redirect_hash(path, extra_options[:redirect]))
150
153
  options.merge!(extra_options[:write] || {})
151
154
 
155
+ object_write_options = extra_options[:object_write] || {}
156
+ object_write_options.each do |pattern, object_options|
157
+ if File.fnmatch(pattern, options[:key])
158
+ options.merge!(object_options)
159
+ end
160
+ end
161
+
152
162
  if mime_type
153
163
  options.merge!(build_content_type_hash(mime_type))
154
164
 
155
165
  if mime_type.sub_type == "gzip"
156
166
  options.merge!(build_gzip_content_encoding_hash)
157
- options.merge!(build_gzip_content_type_hash(file, mime_type))
167
+ options.merge!(build_gzip_content_type_hash(file, mime_type, prefer_cf_mime_types))
158
168
 
159
169
  # upload as original file name
160
170
  options.merge!(key: self.add_prefix(self.orig_name(path), prefix: target_path)) if only_gzip
@@ -182,18 +192,27 @@ module Capistrano
182
192
  File.exist?(self.gzip_name(file))
183
193
  end
184
194
 
185
- def self.build_gzip_content_type_hash(file, mime_type)
195
+ def self.build_gzip_content_type_hash(file, mime_type, prefer_cf_mime_types)
186
196
  orig_name = self.orig_name(file)
187
- orig_mime = mime_type_for_file(orig_name)
197
+ orig_mime = mime_type_for_file(orig_name, prefer_cf_mime_types)
188
198
 
189
199
  return {} unless orig_mime && File.exist?(orig_name)
190
200
 
191
201
  { :content_type => orig_mime.content_type }
192
202
  end
193
203
 
194
- def self.mime_type_for_file(file)
195
- type = MIME::Types.type_for(file)
196
- (type && !type.empty?) ? type[0] : nil
204
+ def self.mime_type_for_file(file, prefer_cf_mime_types)
205
+ types = MIME::Types.type_for(file)
206
+
207
+ if prefer_cf_mime_types
208
+ intersection = types & Capistrano::S3::MIMETypes::CF_MIME_TYPES
209
+
210
+ unless intersection.empty?
211
+ types = intersection
212
+ end
213
+ end
214
+
215
+ types.first
197
216
  end
198
217
 
199
218
  def self.gzip_name(file)
@@ -1,5 +1,5 @@
1
1
  module Capistrano
2
2
  module S3
3
- VERSION = "2.3.0"
3
+ VERSION = "2.4.0"
4
4
  end
5
5
  end
@@ -21,7 +21,7 @@ module Capistrano
21
21
 
22
22
  desc "Upload files to the bucket in the current state"
23
23
  task :upload_files do
24
- extra_options = { :write => bucket_write_options, :redirect => redirect_options }
24
+ extra_options = { :write => bucket_write_options, :redirect => redirect_options, :object_write => object_write_options, :prefer_cf_mime_types => prefer_cf_mime_types }
25
25
  S3::Publisher.publish!(region, access_key_id, secret_access_key,
26
26
  bucket, deployment_path, target_path, distribution_id, invalidations, exclusions, only_gzip, extra_options)
27
27
  end
@@ -18,7 +18,7 @@ namespace :deploy do
18
18
 
19
19
  desc "Upload files to the bucket in the current state"
20
20
  task :upload_files do
21
- extra_options = { :write => fetch(:bucket_write_options), :redirect => fetch(:redirect_options) }
21
+ extra_options = { :write => fetch(:bucket_write_options), :redirect => fetch(:redirect_options), :object_write => fetch(:object_write_options), :prefer_cf_mime_types => fetch(:prefer_cf_mime_types) }
22
22
  Capistrano::S3::Publisher.publish!(fetch(:region), fetch(:access_key_id), fetch(:secret_access_key),
23
23
  fetch(:bucket), fetch(:deployment_path), fetch(:target_path), fetch(:distribution_id), fetch(:invalidations), fetch(:exclusions), fetch(:only_gzip), extra_options, fetch(:stage))
24
24
  end
@@ -71,5 +71,83 @@ describe Capistrano::S3::Publisher do
71
71
  Capistrano::S3::Publisher.publish!('s3.amazonaws.com', 'abc', '123', 'mybucket.amazonaws.com', 'spec/sample', '', 'cf123', [], exclude_paths, false, {}, 'staging')
72
72
  end
73
73
  end
74
+
75
+ context "write options" do
76
+ it "sets bucket write options to all files" do
77
+ headers = { cache_control: 'no-cache' }
78
+ extra_options = { write: headers }
79
+
80
+ Aws::S3::Client.any_instance.expects(:put_object).with() { |options| contains(options, headers) }.times(3)
81
+ Capistrano::S3::Publisher.publish!('s3.amazonaws.com', 'abc', '123', 'mybucket.amazonaws.com', 'spec/sample-write', '', 'cf123', [], [], false, extra_options, 'staging')
82
+ end
83
+
84
+ it "sets object write options to a single file" do
85
+ headers = { cache_control: 'no-cache', acl: :private }
86
+ extra_options = {
87
+ object_write: {
88
+ 'index.html' => headers
89
+ }
90
+ }
91
+
92
+ Aws::S3::Client.any_instance.expects(:put_object).with { |options| options[:key] == 'index.html' && contains(options, headers) }.once
93
+ Aws::S3::Client.any_instance.expects(:put_object).with { |options| options[:key] != 'index.html' && !contains(options, headers) }.twice
94
+ Capistrano::S3::Publisher.publish!('s3.amazonaws.com', 'abc', '123', 'mybucket.amazonaws.com', 'spec/sample-write', '', 'cf123', [], [], false, extra_options, 'staging')
95
+ end
96
+
97
+ it "sets object write options to a directory" do
98
+ asset_headers = { cache_control: 'max-age=3600' }
99
+ index_headers = { cache_control: 'no-cache' }
100
+ extra_options = {
101
+ object_write: {
102
+ 'assets/**' => asset_headers,
103
+ 'index.html' => index_headers
104
+ }
105
+ }
106
+
107
+ Aws::S3::Client.any_instance.expects(:put_object).with { |options| options[:key] == 'index.html' && !contains(options, asset_headers) && contains(options, index_headers) }.once
108
+ Aws::S3::Client.any_instance.expects(:put_object).with { |options| options[:key] != 'index.html' && !contains(options, index_headers) && contains(options, asset_headers) }.twice
109
+ Capistrano::S3::Publisher.publish!('s3.amazonaws.com', 'abc', '123', 'mybucket.amazonaws.com', 'spec/sample-write', '', 'cf123', [], [], false, extra_options, 'staging')
110
+ end
111
+
112
+ it "sets object write permissions in the order of definition" do
113
+ asset_headers = { cache_control: 'max-age=3600' }
114
+ js_headers = { cache_control: 'no-cache' }
115
+ extra_options = { object_write: { 'assets/**' => asset_headers, 'assets/script.js' => js_headers } }
116
+
117
+ Aws::S3::Client.any_instance.expects(:put_object).with { |options| options[:key] == 'assets/script.js' && !contains(options, asset_headers) && contains(options, js_headers) }.once
118
+ Aws::S3::Client.any_instance.expects(:put_object).with { |options| options[:key] == 'assets/style.css' && !contains(options, js_headers) && contains(options, asset_headers) }.once
119
+ Aws::S3::Client.any_instance.expects(:put_object).with { |options| options[:key] == 'index.html' && !contains(options, js_headers) && !contains(options, asset_headers) }.once
120
+ Capistrano::S3::Publisher.publish!('s3.amazonaws.com', 'abc', '123', 'mybucket.amazonaws.com', 'spec/sample-write', '', 'cf123', [], [], false, extra_options, 'staging')
121
+ end
122
+
123
+ it "overwrites object write permissions with wrong ordering" do
124
+ js_headers = { cache_control: 'no-cache' }
125
+ asset_headers = { cache_control: 'max-age=3600' }
126
+ extra_options = {
127
+ object_write: {
128
+ 'assets/script.js' => js_headers,
129
+ 'assets/**' => asset_headers
130
+ }
131
+ }
132
+
133
+ Aws::S3::Client.any_instance.expects(:put_object).with { |options| options[:key] != 'index.html' && !contains(options, js_headers) && contains(options, asset_headers) }.twice
134
+ Aws::S3::Client.any_instance.expects(:put_object).with { |options| options[:key] == 'index.html' && !contains(options, js_headers) && !contains(options, asset_headers) }.once
135
+ Capistrano::S3::Publisher.publish!('s3.amazonaws.com', 'abc', '123', 'mybucket.amazonaws.com', 'spec/sample-write', '', 'cf123', [], [], false, extra_options, 'staging')
136
+ end
137
+ end
138
+
139
+ context "MIME types" do
140
+ it "sets best match MIME type by default" do
141
+ Aws::S3::Client.any_instance.expects(:put_object).with { |options| options[:content_type] == 'application/ecmascript' }.once
142
+ Capistrano::S3::Publisher.publish!('s3.amazonaws.com', 'abc', '123', 'mybucket.amazonaws.com', 'spec/sample-mime', '', 'cf123', [], [], false, {}, 'staging')
143
+ end
144
+
145
+ it "sets CloudFront preferred MIME type if needed" do
146
+ extra_options = { prefer_cf_mime_types: true }
147
+
148
+ Aws::S3::Client.any_instance.expects(:put_object).with { |options| options[:content_type] == 'application/javascript' }.once
149
+ Capistrano::S3::Publisher.publish!('s3.amazonaws.com', 'abc', '123', 'mybucket.amazonaws.com', 'spec/sample-mime', '', 'cf123', [], [], false, extra_options, 'staging')
150
+ end
151
+ end
74
152
  end
75
153
  end
@@ -0,0 +1 @@
1
+ const test = 'test';
@@ -0,0 +1 @@
1
+ const test = 'test';
@@ -0,0 +1,3 @@
1
+ body {
2
+ background: red;
3
+ }
@@ -0,0 +1,4 @@
1
+ <html>
2
+ <head>Test</head>
3
+ <body>Test</body>
4
+ </html>
@@ -6,3 +6,7 @@ Aws.config[:stub_responses] = true
6
6
  RSpec.configure do |config|
7
7
  config.mock_framework = :mocha
8
8
  end
9
+
10
+ def contains(options, extra_options)
11
+ options.merge(extra_options) == options
12
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano-s3
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean-Philippe Doyle
@@ -15,32 +15,27 @@ bindir: bin
15
15
  cert_chain:
16
16
  - |
17
17
  -----BEGIN CERTIFICATE-----
18
- MIIETTCCArWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAoMSYwJAYDVQQDDB1hbGVr
19
- c2FuZHJzL0RDPWxlZG92c2tpcy9EQz1sdjAeFw0xODExMDQxNTE2NDdaFw0yMDEx
20
- MDMxNTE2NDdaMCgxJjAkBgNVBAMMHWFsZWtzYW5kcnMvREM9bGVkb3Zza2lzL0RD
21
- PWx2MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAz38UsGlDYY67LDfs
22
- FP+iftIP/L04Hl4KrF2RvSHvhGn1qk5vIkeDeFBLJMEuzWaNReeszZndMGFWZ//0
23
- mbGeMSYdFBbEL7ImSRGcEx6cHHYNcDP7rP0pKHtAmkX1xpjZ6NBfwAaDODS+/fDE
24
- j8T5mzz1g9uWPnORFB6KZ717V6f4dCPSgeZYoPDZ3dKoBzMWtXOxRnj6ROrXrc8d
25
- 56/KQnoUhKRi+n8gPT6+L+xqRQts8nLDBusQ/a2R7bd9J7ymGAJJ8UzKYWrQ5c+A
26
- Re/se6XLi3xJsBnIxrCwx/8+qV3PvpRHruNRnxeXpe67Lc7CsdOlIhaUc6Bmx3y7
27
- Y0G9XSuOSjfXOOwtvEHkGKbDxG+RyPPG52WpXAxJQZS7GR4dpYPEQZzVicvLiHaP
28
- XuIT2i4UJrB/eMzdMk5KzeZP73cS6rpUBXANRVdjtQRL/bnEAli/szFY3OdirMfK
29
- 60u2mTsrxMzTI9cPjx9zCegnt5v82DWAYe5GaLHkFVrnhIqzAgMBAAGjgYEwfzAJ
30
- BgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUlBfRu+jvOXJUNVAgU1Qa
31
- YpSXueswIgYDVR0RBBswGYEXYWxla3NhbmRyc0BsZWRvdnNraXMubHYwIgYDVR0S
32
- BBswGYEXYWxla3NhbmRyc0BsZWRvdnNraXMubHYwDQYJKoZIhvcNAQELBQADggGB
33
- AGQV1MIzqELmXRiDzSo4LxylZmhlK4fP3v6TsexIBiWstqTO+jWknGA9z1Q47LWZ
34
- o6Zga143Ow/55HD7ihp6WL0czLMFWvVuaYs7VrHN7lKLgwaGshujI3zubwq4bND6
35
- 7m96uyF56IHPeUFHfUyRzxtJXILMT8k7b/uPptuWHFPofQ/prdcwvGLfmBjfl7Ws
36
- MppFUlKjMbCHiOUEct3fLgfZWDuKal2yLv2c28itEJmmlerbPHKVy4w70/Ez+5fH
37
- xZEuzpB16YCvQreL1v3+67m12C5FPA33mw18ZkUHjKuCKlsWG6zYyTc/6YkNR4FI
38
- jh7+6DnwQjHoyQfzwrFSN5vtdyY2tbJXHD8Kkxjj8VgUjhgTEJR7WTjSkUExEY5B
39
- RHL9HAJPC8rqojm6npCdZ950en9r8oUyPmdZlZY86US0T6CmC5sPJyYHEsERoiUx
40
- k20KJFF3jMIlNf6AWXy8t/1ot/hUUJKZIqzNow4oamKSpqiEA6NDH2lY2iY41mL6
41
- Mg==
18
+ MIIDYjCCAkqgAwIBAgIBATANBgkqhkiG9w0BAQsFADAtMSswKQYDVQQDDCJqZWFu
19
+ cGhpbGlwcGUuZG95bGUvREM9Z21haWwvREM9Y29tMB4XDTE5MDEwMzIzNDA1OFoX
20
+ DTI0MDEwMjIzNDA1OFowLTErMCkGA1UEAwwiamVhbnBoaWxpcHBlLmRveWxlL0RD
21
+ PWdtYWlsL0RDPWNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6Z
22
+ 1CIdnc0gZAIISOGc3Xn6G1nRh/DPco4smZeA3zvi0i1eaL3KlWD2K38x5uEyTuMN
23
+ Eu4533cKuOZhjt6IBDG5kC8+Af21GV1R19Cvf/yka6LHkQlB9uARNKuOlAnmhTLO
24
+ cBnJ4k+14bg3Kj0GqgiMQxNWgcXCpWYPIutsjNwTv8l+Q8Cz6ochLl1VYifj7x41
25
+ BmuvYsNX6lLPT2Wn/VnSh8jx4YG4cMu8asexGrxvrZh0FMbSH+8YZTlPNIVLB0K5
26
+ I+T8T1NkH7Oqtozsa30XFEgSWcVA845m4T/XqtFzfm+fwqs9zm6EiJ1hdCo9Pe9c
27
+ CYGYjXc17CzMvs5h3YkCAwEAAaOBjDCBiTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE
28
+ sDAdBgNVHQ4EFgQUa6PNSYrB10QT+XWYeZszhB7Iy8UwJwYDVR0RBCAwHoEcamVh
29
+ bnBoaWxpcHBlLmRveWxlQGdtYWlsLmNvbTAnBgNVHRIEIDAegRxqZWFucGhpbGlw
30
+ cGUuZG95bGVAZ21haWwuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAgO4ZWrs7jiVwB
31
+ rjuziOlVkE0pQYIL04DYqFHh+OUXehbla3ez6yXrJDYzmGssG9gWw2x7zLJDzMGS
32
+ Nuu5LJb6fLt7ngeNkT2VrX8BAi6SNOBkclDbaG2no8Of0/1Ckic0edeRhR2O2WiO
33
+ Ss4Bjfz1DIeMWXQ6XohtG2lW2hdHdkqZEz9CjOHtW9+oUZkEvE/x0zxW/xV1dy0E
34
+ wLg21KGfGL5oeHjZugRKz6VH9DchvEjlNdaagy3ew5+lxZqG5R26eCQv/SEI7UYw
35
+ O/dqEjT9PZ4B9DM6P859LG9xBvj/+cOBs8ViEUU/ExY0rPSZoZT1Ks37cCjj2mrC
36
+ ZBShvFcL
42
37
  -----END CERTIFICATE-----
43
- date: 2018-11-05 00:00:00.000000000 Z
38
+ date: 2019-01-07 00:00:00.000000000 Z
44
39
  dependencies:
45
40
  - !ruby/object:Gem::Dependency
46
41
  name: aws-sdk
@@ -176,6 +171,7 @@ files:
176
171
  - certs/j15e.pem
177
172
  - lib/capistrano/s3.rb
178
173
  - lib/capistrano/s3/defaults.rb
174
+ - lib/capistrano/s3/mime_types.rb
179
175
  - lib/capistrano/s3/publisher.rb
180
176
  - lib/capistrano/s3/version.rb
181
177
  - lib/capistrano/tasks/capistrano_2.rb
@@ -183,6 +179,10 @@ files:
183
179
  - spec/publisher_spec.rb
184
180
  - spec/sample-2/.well-known/test.txt
185
181
  - spec/sample-2/public/.htaccess
182
+ - spec/sample-mime/script.js
183
+ - spec/sample-write/assets/script.js
184
+ - spec/sample-write/assets/style.css
185
+ - spec/sample-write/index.html
186
186
  - spec/sample/fonts/cantarell-regular-webfont.eot
187
187
  - spec/sample/fonts/cantarell-regular-webfont.eot.gz
188
188
  - spec/sample/fonts/cantarell-regular-webfont.svg
@@ -211,8 +211,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
211
211
  - !ruby/object:Gem::Version
212
212
  version: '0'
213
213
  requirements: []
214
- rubyforge_project:
215
- rubygems_version: 2.7.8
214
+ rubygems_version: 3.0.2
216
215
  signing_key:
217
216
  specification_version: 4
218
217
  summary: Build and deploy a static website to Amazon S3
@@ -220,6 +219,10 @@ test_files:
220
219
  - spec/publisher_spec.rb
221
220
  - spec/sample-2/.well-known/test.txt
222
221
  - spec/sample-2/public/.htaccess
222
+ - spec/sample-mime/script.js
223
+ - spec/sample-write/assets/script.js
224
+ - spec/sample-write/assets/style.css
225
+ - spec/sample-write/index.html
223
226
  - spec/sample/fonts/cantarell-regular-webfont.eot
224
227
  - spec/sample/fonts/cantarell-regular-webfont.eot.gz
225
228
  - spec/sample/fonts/cantarell-regular-webfont.svg
metadata.gz.sig CHANGED
Binary file