middleman-cdn 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/.travis.yml +6 -0
- data/Gemfile +2 -0
- data/Guardfile +9 -0
- data/LICENSE +24 -0
- data/README.md +90 -0
- data/Rakefile +14 -0
- data/features/support/env.rb +6 -0
- data/lib/middleman-cdn/cdns/cloudflare.rb +57 -0
- data/lib/middleman-cdn/cdns/cloudfront.rb +59 -0
- data/lib/middleman-cdn/commands.rb +98 -0
- data/lib/middleman-cdn/extension.rb +39 -0
- data/lib/middleman-cdn/version.rb +5 -0
- data/lib/middleman-cdn.rb +5 -0
- data/lib/middleman_extension.rb +1 -0
- data/middleman-cdn.gemspec +39 -0
- data/spec/lib/middleman-cdn/commands_spec.rb +59 -0
- data/spec/spec_helper.rb +9 -0
- metadata +201 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3c69df7b602f0dab070c27d9c0ad63b7b91a6c0b
|
4
|
+
data.tar.gz: 0bd77eba0b7256212615c526de25f04d8dc2d250
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7d713c1b93db2a90b5be5472ab9be51dbc381fce5c32e3546569e383edb34b92330d7db6a945a2daab393fbb5799a15bbb381915fa93dd3a26a7b8df896d860f
|
7
|
+
data.tar.gz: ad09374e358f9e36be4aa94555ca6254f4572a0616bcf3a8beffc2c0d21c532243c8a2add8bd8f132c65ae5f115350539136f778ab07c6b2380db30505f05311
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
guard 'rspec', cli: '--drb --profile', all_after_pass: false do
|
2
|
+
# Specs
|
3
|
+
watch(%r(^spec/.+_spec\.rb$))
|
4
|
+
watch('spec/spec_helper.rb') { 'spec' }
|
5
|
+
watch(%r(^spec/support/(.+)\.rb$)) { 'spec' }
|
6
|
+
|
7
|
+
# Files
|
8
|
+
watch(%r(^lib/(.+)\.rb$)) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
9
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Middleman CDN is:
|
2
|
+
Copyright (c) 2014 Leigh McCulloch and licensed with the license below.
|
3
|
+
|
4
|
+
Derived from Middleman CloudFront which is:
|
5
|
+
Copyright (c) 2013 Andrey Korzhuev and licensed with the license below.
|
6
|
+
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
8
|
+
a copy of this software and associated documentation files (the
|
9
|
+
"Software"), to deal in the Software without restriction, including
|
10
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
11
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
12
|
+
permit persons to whom the Software is furnished to do so, subject to
|
13
|
+
the following conditions:
|
14
|
+
|
15
|
+
The above copyright notice and this permission notice shall be included
|
16
|
+
in all copies or substantial portions of the Software.
|
17
|
+
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
20
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
21
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
22
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
23
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
24
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# Middleman CDN [![Build Status](https://travis-ci.org/leighmcculloch/middleman-cdn.svg)](https://travis-ci.org/leighmcculloch/middleman-cdn) [![Dependency Status](https://gemnasium.com/leighmcculloch/middleman-cdn.png)](https://gemnasium.com/leighmcculloch/middleman-cdn)
|
2
|
+
A deploying tool for middleman which allows you to invalidate resources cached
|
3
|
+
on the CloudFlare and Amazon CloudFront CDNs. Specifically useful if your
|
4
|
+
using multiple CDNs to cache the content of your middleman website.
|
5
|
+
|
6
|
+
* Cache invalidation of files on:
|
7
|
+
* CloudFlare
|
8
|
+
* Amazon CloudFront
|
9
|
+
* **Use another CDN? Open an issue and I'll do it.**
|
10
|
+
* Invalidate files on multiple CDNs.
|
11
|
+
* Call from the command line.
|
12
|
+
* Call automatically after middleman build.
|
13
|
+
* Ability to select/filter files to be invalidated by regex.
|
14
|
+
|
15
|
+
What's next?
|
16
|
+
|
17
|
+
* Expand the test base.
|
18
|
+
* Add support for Fastly.
|
19
|
+
* Add support for MaxCDN.
|
20
|
+
|
21
|
+
# Usage
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
Add this to your `Gemfile`:
|
25
|
+
```ruby
|
26
|
+
gem "middleman-cdn"
|
27
|
+
```
|
28
|
+
|
29
|
+
Then run:
|
30
|
+
```
|
31
|
+
bundle install
|
32
|
+
```
|
33
|
+
|
34
|
+
## Configuration
|
35
|
+
|
36
|
+
Edit `config.rb` and add the following. Specify either one CDN config or
|
37
|
+
multiple.
|
38
|
+
```ruby
|
39
|
+
activate :cdn do |cdn|
|
40
|
+
cdn.cloudflare = {
|
41
|
+
client_api_key: '...', # default ENV['CLOUDFLARE_CLIENT_API_KEY']
|
42
|
+
email: 'you@example.com', # default ENV['CLOUDFLARE_EMAIL']
|
43
|
+
zone: 'example.com',
|
44
|
+
base_urls: ['http://example.com', 'https://example.com']
|
45
|
+
}
|
46
|
+
cdn.cloudfront = {
|
47
|
+
access_key_id: '...', # default ENV['AWS_ACCESS_KEY_ID']
|
48
|
+
secret_access_key: '...', # default ENV['AWS_SECRET_ACCESS_KEY']
|
49
|
+
distribution_id: '...'
|
50
|
+
}
|
51
|
+
cdn.filter = /\.html/i # default /.*/
|
52
|
+
cdn.after_build = true # default is false
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
Instead of storing your CDN credentials in config.rb store them in the
|
57
|
+
environment variables specified above, or execute on the commandline as:
|
58
|
+
|
59
|
+
```bash
|
60
|
+
CLOUDFLARE_CLIENT_API_KEY= CLOUDFLARE_EMAIL= AWS_ACCESS_KEY= AWS_SECRET= bundle exec middleman invalidate
|
61
|
+
```
|
62
|
+
|
63
|
+
## Invalidating
|
64
|
+
|
65
|
+
Set `after_build` to `true` and the cache will be invalidated after build:
|
66
|
+
```bash
|
67
|
+
bundle exec middleman build
|
68
|
+
```
|
69
|
+
|
70
|
+
Otherwise, invalidate manually using:
|
71
|
+
```bash
|
72
|
+
bundle exec middleman invalidate
|
73
|
+
```
|
74
|
+
|
75
|
+
Or, shorthand:
|
76
|
+
```bash
|
77
|
+
bundle exec middleman inv
|
78
|
+
```
|
79
|
+
|
80
|
+
## In the wild
|
81
|
+
|
82
|
+
I'm using middleman-cdn on my personal website leighmcculloch.com on github.
|
83
|
+
|
84
|
+
## Thanks
|
85
|
+
|
86
|
+
Middleman CDN is a fork off [Middleman CloudFront](https://github.com/andrusha/middleman-cloudfront) and I used it as the base for building this extension. The code was well structured and easy to understand. It was easy to break out the CloudFront specific logic and to add support for CloudFlare. My gratitude goes to @andrusha and his work on Middleman CloudFront.
|
87
|
+
|
88
|
+
Thanks to @b4k3r for the [Cloudflare gem](https://github.com/b4k3r/cloudflare) that made invalidating CloudFlare files a breeze.
|
89
|
+
|
90
|
+
Thanks to @cloudflare for CloudFlare.
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rspec/core/rake_task'
|
2
|
+
|
3
|
+
require 'bundler'
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
require 'cucumber/rake/task'
|
7
|
+
|
8
|
+
Cucumber::Rake::Task.new(:cucumber, 'Run features that should pass') do |t|
|
9
|
+
t.cucumber_opts = "--color --tags ~@wip --strict --format #{ENV['CUCUMBER_FORMAT'] || 'Fivemat'}"
|
10
|
+
end
|
11
|
+
|
12
|
+
RSpec::Core::RakeTask.new(:spec)
|
13
|
+
|
14
|
+
task :default => :spec
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#Encoding: UTF-8
|
2
|
+
require "cloudflare"
|
3
|
+
require "active_support/core_ext/string"
|
4
|
+
|
5
|
+
module Middleman
|
6
|
+
module Cli
|
7
|
+
|
8
|
+
class CloudFlareCDN
|
9
|
+
def self.key
|
10
|
+
"cloudflare"
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.example_configuration
|
14
|
+
<<-TEXT
|
15
|
+
cdn.cloudflare = {
|
16
|
+
client_api_key: 'I', # default ENV['CLOUDFLARE_CLIENT_API_KEY']
|
17
|
+
email: 'love', # default ENV['CLOUDFLARE_EMAIL']
|
18
|
+
zone: 'cats',
|
19
|
+
base_urls: ['http://example.com', 'https://example.com']
|
20
|
+
}
|
21
|
+
TEXT
|
22
|
+
end
|
23
|
+
|
24
|
+
def invalidate(options, files)
|
25
|
+
puts "## Invalidating files on CloudFlare"
|
26
|
+
|
27
|
+
options[:client_api_key] ||= ENV['CLOUDFLARE_CLIENT_API_KEY']
|
28
|
+
options[:email] ||= ENV['CLOUDFLARE_EMAIL']
|
29
|
+
[:client_api_key, :email, :zone, :base_urls].each do |key|
|
30
|
+
raise StandardError, "Configuration key cloudflare[:#{key}] is missing." if options[key].blank?
|
31
|
+
end
|
32
|
+
if options[:base_urls].is_a?(String)
|
33
|
+
options[:base_urls] = [options[:base_urls]]
|
34
|
+
end
|
35
|
+
if !options[:base_urls].is_a?(Array) || options[:base_urls].length == 0
|
36
|
+
raise StandardError, "Configuration key cloudfront[:base_urls] is missing."
|
37
|
+
end
|
38
|
+
|
39
|
+
options[:base_urls].each do |base_url|
|
40
|
+
files.each do |file|
|
41
|
+
cloudflare = ::CloudFlare::connection(options[:client_api_key], options[:email])
|
42
|
+
begin
|
43
|
+
url = "#{base_url}#{file}"
|
44
|
+
print "Invalidating #{url}... "
|
45
|
+
cloudflare.zone_file_purge(options[:zone], "#{base_url}#{file}")
|
46
|
+
rescue => e
|
47
|
+
puts "Error: #{e.message}"
|
48
|
+
else
|
49
|
+
puts "✓"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require "fog"
|
2
|
+
require "active_support/core_ext/string"
|
3
|
+
|
4
|
+
module Middleman
|
5
|
+
module Cli
|
6
|
+
|
7
|
+
class CloudFrontCDN
|
8
|
+
INVALIDATION_LIMIT = 1000
|
9
|
+
|
10
|
+
def self.key
|
11
|
+
"cloudfront"
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.example_configuration
|
15
|
+
<<-TEXT
|
16
|
+
cdn.cloudfront = {
|
17
|
+
access_key_id: 'I', # default ENV['AWS_ACCESS_KEY_ID']
|
18
|
+
secret_access_key: 'love', # default ENV['AWS_SECRET_ACCESS_KEY']
|
19
|
+
distribution_id: 'cats'
|
20
|
+
}
|
21
|
+
TEXT
|
22
|
+
end
|
23
|
+
|
24
|
+
def invalidate(options, files)
|
25
|
+
puts "## Invalidating files on CloudFront"
|
26
|
+
|
27
|
+
options[:access_key_id] ||= ENV['AWS_ACCESS_KEY_ID']
|
28
|
+
options[:secret_access_key] ||= ENV['AWS_SECRET_ACCESS_KEY']
|
29
|
+
[:access_key_id, :secret_access_key, :distribution_id].each do |key|
|
30
|
+
raise StandardError, "Configuration key cloudfront[:#{key}] is missing." if options[key].blank?
|
31
|
+
end
|
32
|
+
|
33
|
+
cloudfront = Fog::CDN.new({
|
34
|
+
:provider => 'AWS',
|
35
|
+
:aws_access_key_id => options[:access_key_id],
|
36
|
+
:aws_secret_access_key => options[:secret_access_key]
|
37
|
+
})
|
38
|
+
|
39
|
+
distribution = cloudfront.distributions.get(options[:distribution_id])
|
40
|
+
|
41
|
+
if files.count <= INVALIDATION_LIMIT
|
42
|
+
puts "Invalidating #{files.count} files. It might take 10 to 15 minutes until all files are invalidated."
|
43
|
+
puts 'Please check the AWS Management Console to see the status of the invalidation.'
|
44
|
+
invalidation = distribution.invalidations.create(:paths => files)
|
45
|
+
raise StandardError, %(Invalidation status is #{invalidation.status}. Expected "InProgress") unless invalidation.status == 'InProgress'
|
46
|
+
else
|
47
|
+
slices = files.each_slice(INVALIDATION_LIMIT)
|
48
|
+
puts "Invalidating #{files.count} files in #{slices.count} batch(es). It might take 10 to 15 minutes per batch until all files are invalidated."
|
49
|
+
slices.each_with_index do |slice, i|
|
50
|
+
puts "Invalidating batch #{i + 1}..."
|
51
|
+
invalidation = distribution.invalidations.create(:paths => slice)
|
52
|
+
invalidation.wait_for { ready? } unless i == slices.count - 1
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require "middleman-core/cli"
|
2
|
+
require "middleman-cdn/extension"
|
3
|
+
require "middleman-cdn/cdns/cloudflare.rb"
|
4
|
+
require "middleman-cdn/cdns/cloudfront.rb"
|
5
|
+
|
6
|
+
module Middleman
|
7
|
+
module Cli
|
8
|
+
|
9
|
+
class CDN < Thor
|
10
|
+
include Thor::Actions
|
11
|
+
|
12
|
+
check_unknown_options!
|
13
|
+
|
14
|
+
namespace :invalidate
|
15
|
+
|
16
|
+
def self.exit_on_failure?
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "cdn:invalidate", "A way to deal with your CloudFlare or CloudFront distributions"
|
21
|
+
def invalidate(options = nil)
|
22
|
+
if options.nil?
|
23
|
+
app_instance = ::Middleman::Application.server.inst
|
24
|
+
unless app_instance.respond_to?(:cdn_options)
|
25
|
+
raise Error, "ERROR: You need to activate the cdn extension in config.rb.\n#{example_configuration}"
|
26
|
+
end
|
27
|
+
options = app_instance.cdn_options
|
28
|
+
end
|
29
|
+
options.filter ||= /.*/
|
30
|
+
|
31
|
+
if cdns.all? { |cdn| options.public_send(cdn.key.to_sym).nil? }
|
32
|
+
raise Error, "ERROR: You must specify a config for one of the supported CDNs.\n#{example_configuration}"
|
33
|
+
end
|
34
|
+
|
35
|
+
# CloudFront limits the amount of files which can be invalidated by one request to 1000.
|
36
|
+
# If there are more than 1000 files to invalidate, do so sequentially and wait until each validation is ready.
|
37
|
+
# If there are max 1000 files, create the invalidation and return immediately.
|
38
|
+
files = list_files(options.filter)
|
39
|
+
return if files.empty?
|
40
|
+
|
41
|
+
cdns_keyed.each do |cdn_key, cdn|
|
42
|
+
cdn_options = options.public_send(cdn_key.to_sym)
|
43
|
+
cdn.new.invalidate(cdn_options, files) unless cdn_options.nil?
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
|
49
|
+
def cdns
|
50
|
+
[
|
51
|
+
CloudFlareCDN,
|
52
|
+
CloudFrontCDN
|
53
|
+
]
|
54
|
+
end
|
55
|
+
|
56
|
+
def cdns_keyed
|
57
|
+
Hash[cdns.map { |cdn| [cdn.key, cdn] }]
|
58
|
+
end
|
59
|
+
|
60
|
+
def example_configuration
|
61
|
+
<<-TEXT
|
62
|
+
|
63
|
+
The example configuration is:
|
64
|
+
activate :cdn do |cdn|
|
65
|
+
#{cdns.map(&:example_configuration).join}
|
66
|
+
cdn.filter = /\.html/i # default /.*/
|
67
|
+
cdn.after_build = true # default is false
|
68
|
+
end
|
69
|
+
TEXT
|
70
|
+
end
|
71
|
+
|
72
|
+
def list_files(filter)
|
73
|
+
Dir.chdir('build/') do
|
74
|
+
Dir.glob('**/*', File::FNM_DOTMATCH).tap do |files|
|
75
|
+
# Remove directories
|
76
|
+
files.reject! { |f| File.directory?(f) }
|
77
|
+
|
78
|
+
# Remove files that do not match filter
|
79
|
+
files.reject! { |f| f !~ filter }
|
80
|
+
|
81
|
+
# Add directories of index.html files since they have to be
|
82
|
+
# invalidated as well if :directory_indexes is active
|
83
|
+
files.each do |file|
|
84
|
+
file_dir = file.sub(/\bindex\.html\z/, '')
|
85
|
+
files << file_dir if file_dir != file
|
86
|
+
end
|
87
|
+
|
88
|
+
# Add leading slash
|
89
|
+
files.map! { |f| f.start_with?('/') ? f : "/#{f}" }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
Base.map({"inv" => "invalidate"})
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'middleman-core'
|
2
|
+
|
3
|
+
module Middleman
|
4
|
+
module CDN
|
5
|
+
module Helpers
|
6
|
+
def cdn_options
|
7
|
+
::Middleman::CDN::CDNExtension.options
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class CDNExtension < Middleman::Extension
|
12
|
+
option :cloudflare, nil, 'CloudFlare options'
|
13
|
+
option :cloudfront, nil, 'CloudFront options'
|
14
|
+
option :filter, nil, 'Cloudflare options'
|
15
|
+
option :after_build, false, 'Cloudflare options'
|
16
|
+
|
17
|
+
def initialize(app, options_hash = {}, &block)
|
18
|
+
super
|
19
|
+
|
20
|
+
app.after_build do
|
21
|
+
::Middleman::Cli::CDN.new.invalidate(options) if options.after_build
|
22
|
+
end
|
23
|
+
|
24
|
+
app.send :include, Helpers
|
25
|
+
|
26
|
+
@@cdn_options = options
|
27
|
+
end
|
28
|
+
|
29
|
+
def registered
|
30
|
+
included
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.options
|
34
|
+
@@cdn_options
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'middleman-cdn'
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require 'middleman-cdn/version'
|
7
|
+
|
8
|
+
Gem::Specification.new do |s|
|
9
|
+
s.name = 'middleman-cdn'
|
10
|
+
s.version = Middleman::CDN::VERSION
|
11
|
+
s.platform = Gem::Platform::RUBY
|
12
|
+
s.authors = ["Leigh McCulloch"]
|
13
|
+
s.homepage = "https://github.com/leighmcculloch/middleman-cdn"
|
14
|
+
s.summary = %q{Invalidate CloudFlare or CloudFront cache after deployment}
|
15
|
+
s.description = %q{Invalidate a specific set of files in your CloudFlare or CloudFront cache}
|
16
|
+
|
17
|
+
s.files = `git ls-files -z`.split("\0")
|
18
|
+
s.test_files = `git ls-files -z -- {fixtures,features}/*`.split("\0")
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_dependency 'fog', '~> 1.9'
|
22
|
+
s.add_dependency 'cloudflare', '~> 2.0'
|
23
|
+
|
24
|
+
s.add_development_dependency 'cucumber', '~> 1.3'
|
25
|
+
s.add_development_dependency 'aruba', '~> 0.5'
|
26
|
+
s.add_development_dependency 'fivemat', '~> 1.3'
|
27
|
+
s.add_development_dependency 'simplecov', '~> 0.8'
|
28
|
+
s.add_development_dependency 'rake', '~> 0.9'
|
29
|
+
|
30
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
31
|
+
|
32
|
+
if RUBY_VERSION <= '1.9.2'
|
33
|
+
s.add_dependency 'middleman-core', '~> 3.0', '<= 3.2.0'
|
34
|
+
s.add_development_dependency 'activesupport', '< 4.0.0'
|
35
|
+
else
|
36
|
+
s.add_dependency 'middleman-core', '~> 3.0'
|
37
|
+
s.add_development_dependency 'activesupport', '~> 4.1'
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'fog/aws/models/cdn/distributions'
|
4
|
+
|
5
|
+
describe Middleman::Cli::CDN do
|
6
|
+
let(:cdn) { described_class.new }
|
7
|
+
let(:options) do
|
8
|
+
OpenStruct.new({
|
9
|
+
cloudflare: nil,
|
10
|
+
cloudfront: {
|
11
|
+
access_key_id: 'access_key_id_123',
|
12
|
+
secret_access_key: 'secret_access_key_123',
|
13
|
+
distribution_id: 'distribution_id_123',
|
14
|
+
},
|
15
|
+
filter: 'filter_123',
|
16
|
+
after_build: 'after_build_123'
|
17
|
+
})
|
18
|
+
end
|
19
|
+
let(:distribution) { double('distribution', invalidations: double('invalidations')) }
|
20
|
+
|
21
|
+
describe '#invalidate' do
|
22
|
+
before do
|
23
|
+
allow_any_instance_of(Fog::CDN::AWS::Distributions).to receive(:get).and_return(distribution)
|
24
|
+
allow(distribution.invalidations).to receive(:create) do
|
25
|
+
double('invalidation', status: 'InProgress', wait_for: ->{} )
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'gets the correct distribution' do
|
30
|
+
allow(cdn).to receive(:list_files).and_return ['index.html']
|
31
|
+
expect_any_instance_of(Fog::CDN::AWS::Distributions).to receive(:get).with('distribution_id_123')
|
32
|
+
cdn.invalidate(options)
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when the amount of files to invalidate is under the limit' do
|
36
|
+
it 'divides them up in packages and creates one invalidation per package' do
|
37
|
+
files = (1..Middleman::Cli::CloudFrontCDN::INVALIDATION_LIMIT).map do |i|
|
38
|
+
"file_#{i}"
|
39
|
+
end
|
40
|
+
allow(cdn).to receive(:list_files).and_return files
|
41
|
+
expect(distribution.invalidations).to receive(:create).once.with(paths: files)
|
42
|
+
cdn.invalidate(options)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when the amount of files to invalidate is over the limit' do
|
47
|
+
it 'creates only one invalidation with all of them' do
|
48
|
+
files = (1..(Middleman::Cli::CloudFrontCDN::INVALIDATION_LIMIT * 3)).map do |i|
|
49
|
+
"file_#{i}"
|
50
|
+
end
|
51
|
+
allow(cdn).to receive(:list_files).and_return files
|
52
|
+
expect(distribution.invalidations).to receive(:create).once.with(paths: files[0, Middleman::Cli::CloudFrontCDN::INVALIDATION_LIMIT])
|
53
|
+
expect(distribution.invalidations).to receive(:create).once.with(paths: files[Middleman::Cli::CloudFrontCDN::INVALIDATION_LIMIT, Middleman::Cli::CloudFrontCDN::INVALIDATION_LIMIT])
|
54
|
+
expect(distribution.invalidations).to receive(:create).once.with(paths: files[Middleman::Cli::CloudFrontCDN::INVALIDATION_LIMIT * 2, Middleman::Cli::CloudFrontCDN::INVALIDATION_LIMIT])
|
55
|
+
cdn.invalidate(options)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,201 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: middleman-cdn
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Leigh McCulloch
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-07-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: fog
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.9'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.9'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: cloudflare
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: cucumber
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: aruba
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.5'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.5'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: fivemat
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.3'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.3'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.8'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.8'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.9'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.9'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '3.0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '3.0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: middleman-core
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '3.0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '3.0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: activesupport
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '4.1'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '4.1'
|
153
|
+
description: Invalidate a specific set of files in your CloudFlare or CloudFront cache
|
154
|
+
email:
|
155
|
+
executables: []
|
156
|
+
extensions: []
|
157
|
+
extra_rdoc_files: []
|
158
|
+
files:
|
159
|
+
- ".gitignore"
|
160
|
+
- ".travis.yml"
|
161
|
+
- Gemfile
|
162
|
+
- Guardfile
|
163
|
+
- LICENSE
|
164
|
+
- README.md
|
165
|
+
- Rakefile
|
166
|
+
- features/support/env.rb
|
167
|
+
- lib/middleman-cdn.rb
|
168
|
+
- lib/middleman-cdn/cdns/cloudflare.rb
|
169
|
+
- lib/middleman-cdn/cdns/cloudfront.rb
|
170
|
+
- lib/middleman-cdn/commands.rb
|
171
|
+
- lib/middleman-cdn/extension.rb
|
172
|
+
- lib/middleman-cdn/version.rb
|
173
|
+
- lib/middleman_extension.rb
|
174
|
+
- middleman-cdn.gemspec
|
175
|
+
- spec/lib/middleman-cdn/commands_spec.rb
|
176
|
+
- spec/spec_helper.rb
|
177
|
+
homepage: https://github.com/leighmcculloch/middleman-cdn
|
178
|
+
licenses: []
|
179
|
+
metadata: {}
|
180
|
+
post_install_message:
|
181
|
+
rdoc_options: []
|
182
|
+
require_paths:
|
183
|
+
- lib
|
184
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
185
|
+
requirements:
|
186
|
+
- - ">="
|
187
|
+
- !ruby/object:Gem::Version
|
188
|
+
version: '0'
|
189
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
190
|
+
requirements:
|
191
|
+
- - ">="
|
192
|
+
- !ruby/object:Gem::Version
|
193
|
+
version: '0'
|
194
|
+
requirements: []
|
195
|
+
rubyforge_project:
|
196
|
+
rubygems_version: 2.2.2
|
197
|
+
signing_key:
|
198
|
+
specification_version: 4
|
199
|
+
summary: Invalidate CloudFlare or CloudFront cache after deployment
|
200
|
+
test_files:
|
201
|
+
- features/support/env.rb
|