middleman-cdn 0.1.1

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: 3c69df7b602f0dab070c27d9c0ad63b7b91a6c0b
4
+ data.tar.gz: 0bd77eba0b7256212615c526de25f04d8dc2d250
5
+ SHA512:
6
+ metadata.gz: 7d713c1b93db2a90b5be5472ab9be51dbc381fce5c32e3546569e383edb34b92330d7db6a945a2daab393fbb5799a15bbb381915fa93dd3a26a7b8df896d860f
7
+ data.tar.gz: ad09374e358f9e36be4aa94555ca6254f4572a0616bcf3a8beffc2c0d21c532243c8a2add8bd8f132c65ae5f115350539136f778ab07c6b2380db30505f05311
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ Gemfile.lock
2
+ coverage
3
+ .ruby-version
4
+ *.sublime-*
5
+ *.gem
6
+ pkg
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - 2.1.0
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
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,6 @@
1
+ require "simplecov"
2
+ SimpleCov.start
3
+ PROJECT_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__)))
4
+ require "middleman-core"
5
+ require "middleman-core/step_definitions"
6
+ require File.join(PROJECT_ROOT_PATH, 'lib', 'middleman-cdn')
@@ -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,5 @@
1
+ module Middleman
2
+ module CDN
3
+ VERSION = '0.1.1'
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ require 'middleman-core'
2
+ require 'middleman-cdn/commands'
3
+ require "middleman-cdn/extension"
4
+
5
+ ::Middleman::Extensions.register(:cdn, ::Middleman::CDN::CDNExtension)
@@ -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
@@ -0,0 +1,9 @@
1
+ require 'middleman-cdn'
2
+
3
+ RSpec.configure do |config|
4
+ config.run_all_when_everything_filtered = true
5
+ config.filter_run :focus
6
+ config.order = 'random'
7
+ end
8
+
9
+ Fog.mock!
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