rack-scriptstacker 0.0.1

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: ee8de66daca3fb8a4b83d4733f8ad8857910dd71
4
+ data.tar.gz: d38e64e90eff4b45bb3717275bfce9e996a393ef
5
+ SHA512:
6
+ metadata.gz: 949a8db63c8925981f1202a706e92c9a72394499402a2b8fefe444f3047739085a3120d8dd51ecf0d048e4e1ec6ae45889206d2cfd2e8a57760e02beb4cfee93
7
+ data.tar.gz: c2a77c84f5a5a0087a0bb30bdcb822ef9331f0c3770f8c9371d43f6568a7cbcda1e4e99f1ccc879fde3167a4ee24e89a1988bacbaf290b324a298b1c0cd4b1c2
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Max Cantor
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # Rack::ScriptStacker
2
+
3
+ Painless static file handling for Rack apps.
4
+
5
+ - Automatically configures `Rack::Static` by default.
6
+ - Glob and inject JavaScript/CSS files into served HTML.
7
+
8
+ # Usage
9
+
10
+ ```html
11
+ <!-- index.html //-->
12
+
13
+ <!doctype html>
14
+ <html lang="en">
15
+ <head>
16
+ <!-- ScriptStacker: CSS //-->
17
+ </head>
18
+ <body>
19
+ <!-- ScriptStacker: JAVASCRIPT //-->
20
+ </body>
21
+ </html>
22
+ ```
23
+
24
+ and
25
+
26
+ ```ruby
27
+ # config.ru
28
+
29
+ require 'rack/scriptstacker'
30
+
31
+ class App
32
+ def call env
33
+ [
34
+ 200,
35
+ { 'Content-Type' => 'text/html' },
36
+ [File.read('index.html')]
37
+ ]
38
+ end
39
+ end
40
+
41
+ use Rack::ScriptStacker do
42
+ css 'static/css'
43
+ javascript 'static/javascript'
44
+ end
45
+
46
+ run app
47
+ ```
48
+
49
+ Results in...
50
+
51
+ ```html
52
+ <!doctype html>
53
+ <html lang="en">
54
+ <head>
55
+ <link rel="stylesheet" type="text/css" href="/static/css/main.css" />
56
+ </head>
57
+ <body>
58
+ <script type="text/javascript" src="/static/javascript/main.js"></script>
59
+ <script type="text/javascript" src="/static/javascript/util.js"></script>
60
+ </body>
61
+ </html>
62
+ ```
63
+
64
+ ## Configure static serving yourself
65
+
66
+ ```ruby
67
+ use Rack::ScriptStacker, configure_static: false do
68
+ css 'static/css'
69
+ javascript 'static/javascript'
70
+ end
71
+
72
+ use Rack::Static, url: ['static']
73
+ ```
74
+
75
+ ## Serve multiple sets of files in order
76
+
77
+ ```ruby
78
+ use Rack::ScriptStacker do
79
+ css 'static/css'
80
+ javascript 'vendor/javascript'
81
+ javascript 'static/javascript'
82
+ end
83
+ ```
84
+
85
+ ## Serve files at a different path
86
+
87
+ ```ruby
88
+ use Rack::ScriptStacker, configure_static: false do
89
+ css 'css' => 'stylesheets'
90
+ javascript 'js' => 'scripts'
91
+ end
92
+ ```
93
+
94
+ ## Change the template for a stacker
95
+
96
+ ```ruby
97
+ use Rack::ScriptStacker,
98
+ stackers: {
99
+ javascript: { template: '<script src="%s"></script>' }
100
+ } do
101
+ javascript 'static/javascript'
102
+ end
103
+ ```
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,5 @@
1
+ module Rack
2
+ class ScriptStacker
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,183 @@
1
+ require 'rack/scriptstacker/version'
2
+ require 'rack'
3
+
4
+ class ::Hash
5
+ def recursive_merge other
6
+ merger = proc do |key, v1, v2|
7
+ Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2
8
+ end
9
+ self.merge(other, &merger)
10
+ end
11
+ end
12
+
13
+ module Rack
14
+ class ScriptStacker
15
+ DEFAULT_CONFIG = {
16
+ configure_static: true,
17
+ stackers: {
18
+ css: {
19
+ template: '<link rel="stylesheet" type="text/css" href="%s" />',
20
+ glob: '*.css',
21
+ slot: 'CSS'
22
+ },
23
+ javascript: {
24
+ template: '<script type="text/javascript" src="%s"></script>',
25
+ glob: '*.js',
26
+ slot: 'JAVASCRIPT'
27
+ }
28
+ }
29
+ }
30
+
31
+ def initialize app, config={}, &stack_spec
32
+ @config = DEFAULT_CONFIG.recursive_merge config
33
+ @path_specs = ScriptStackerUtils::SpecSolidifier.new.call stack_spec
34
+ @runner = ScriptStackerUtils::Runner.new @config[:stackers]
35
+ @app = @config[:configure_static] ? configure_static(app) : app
36
+ end
37
+
38
+ def call env
39
+ response = @app.call env
40
+
41
+ if response[1]['Content-Type'] != 'text/html'
42
+ response
43
+ else
44
+ [
45
+ response[0],
46
+ response[1],
47
+ @runner.replace_in_body(response[2], @path_specs)
48
+ ]
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ def configure_static app
55
+ Rack::Static.new app, {
56
+ urls: @path_specs
57
+ .values
58
+ .reduce([]) { |memo, specs| memo + specs }
59
+ .select { |spec| spec.paths_identical? }
60
+ .map { |spec| spec.serve_path }
61
+ }
62
+ end
63
+ end
64
+
65
+ module ScriptStackerUtils
66
+ class SpecSolidifier < BasicObject
67
+ def initialize
68
+ @specs = ::Hash.new { |hash, key| hash[key] = [] }
69
+ end
70
+
71
+ def call stack_spec
72
+ instance_eval &stack_spec
73
+ @specs
74
+ end
75
+
76
+ def method_missing name, *args
77
+ if args.size != 1
78
+ raise ::ArgumentError.new(
79
+ "Expected a path spec like 'static/css' => 'stylesheets', " +
80
+ "but got #{args.inspect} instead."
81
+ )
82
+ end
83
+ @specs[name].push ::Rack::ScriptStackerUtils::PathSpec.new(args[0])
84
+ end
85
+ end
86
+
87
+ class PathSpec
88
+ def initialize paths
89
+ if paths.respond_to? :key
90
+ # this is just for pretty method calls, eg.
91
+ # css 'stylesheets' => 'static/css'
92
+ @source_path, @serve_path = paths.to_a.flatten
93
+ else
94
+ # if only one path is given, use the same for both;
95
+ # this is just like how Rack::Static works
96
+ @source_path = @serve_path = paths
97
+ end
98
+ end
99
+
100
+ def source_path
101
+ normalize_end_slash @source_path
102
+ end
103
+
104
+ def serve_path
105
+ normalize_end_slash normalize_begin_slash(@serve_path)
106
+ end
107
+
108
+ def paths_identical?
109
+ # Paths are normalized differently, so this check isn't doable from
110
+ # outside the instance; but we still want to know if they're basically
111
+ # the same so we can easily configure Rack::Static to match.
112
+ @source_path == @serve_path
113
+ end
114
+
115
+ private
116
+
117
+ def normalize_end_slash path
118
+ path.end_with?('/') ? path : path + '/'
119
+ end
120
+
121
+ def normalize_begin_slash path
122
+ path.start_with?('/') ? path : '/' + path
123
+ end
124
+ end
125
+
126
+ class Runner
127
+ def initialize stacker_configs
128
+ @stackers = stacker_configs.map do |name, config|
129
+ [name, Stacker.new(config)]
130
+ end.to_h
131
+ end
132
+
133
+ def replace_in_body body, path_specs
134
+ path_specs.each do |name, specs|
135
+ specs.each do |spec|
136
+ @stackers[name].find_files spec.source_path, spec.serve_path
137
+ end
138
+ end
139
+
140
+ body.map do |chunk|
141
+ @stackers.values.reduce chunk do |memo, stacker|
142
+ stacker.replace_slot memo
143
+ end
144
+ end
145
+ end
146
+ end
147
+
148
+ class Stacker
149
+ def initialize config
150
+ @template = config[:template]
151
+ @glob = config[:glob]
152
+ @slot = config[:slot]
153
+ @files = []
154
+ end
155
+
156
+ def find_files source_path, serve_path
157
+ @files = @files + files_for(source_path).map do |filename|
158
+ sprintf @template, serve_path + filename
159
+ end
160
+ end
161
+
162
+ def replace_slot chunk
163
+ chunk.gsub /^(\s*)#{slot}/ do
164
+ indent = $1
165
+ @files.map do |line|
166
+ indent + line
167
+ end.join "\n"
168
+ end
169
+ end
170
+
171
+ private
172
+
173
+ def slot
174
+ "<!-- ScriptStacker: #{@slot} //-->"
175
+ end
176
+
177
+ def files_for source_path
178
+ Dir[source_path + @glob]
179
+ .map { |file| ::File.basename(file) }
180
+ end
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rack/scriptstacker/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rack-scriptstacker"
8
+ spec.version = Rack::ScriptStacker::VERSION
9
+ spec.authors = ["Max Cantor"]
10
+ spec.email = ["max@maxcantor.net"]
11
+ spec.summary = %q{Quickly inject static file lists into served HTML.}
12
+ spec.homepage = "http://github.com/mcantor/rack-scriptstacker"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency "rack", "~> 1.6"
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.7"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "rspec", "~> 3.3"
25
+ end
@@ -0,0 +1,151 @@
1
+ require 'rack/scriptstacker'
2
+
3
+ def smart_deindent str
4
+ first_line_indent = str.match(/^\s*/).to_s.size
5
+ str.gsub(/^\s{#{first_line_indent}}/, '')
6
+ end
7
+
8
+ def app_with_body body
9
+ lambda { |env| [200, {'Content-Type' => 'text/html'}, [body]] }
10
+ end
11
+
12
+ describe Rack::ScriptStacker do
13
+ let(:js_files) { ['main.js', 'util.js'] }
14
+ let(:vendor_js_files) { ['jquery.js', 'buttscript.js'] }
15
+ let(:css_files) { ['main.css', '_whatever.css'] }
16
+ let(:middleware) do
17
+ Rack::ScriptStacker.new app_with_body(body), configure_static: false do
18
+ css 'static/css'
19
+ javascript 'static/javascripts'
20
+ end
21
+ end
22
+
23
+ before :each do
24
+ allow_any_instance_of(Rack::ScriptStackerUtils::Stacker).to receive(:files_for).with('static/css/').and_return(css_files)
25
+ allow_any_instance_of(Rack::ScriptStackerUtils::Stacker).to receive(:files_for).with('static/javascripts/').and_return(js_files)
26
+ allow_any_instance_of(Rack::ScriptStackerUtils::Stacker).to receive(:files_for).with('vendor/javascripts/').and_return(vendor_js_files)
27
+ if middleware
28
+ @response = middleware.call nil
29
+ @response_body = @response[2][0]
30
+ end
31
+ end
32
+
33
+ context 'inactive' do
34
+ let(:body) { '<div>whatever</div>' }
35
+
36
+ it 'does not change without replacement slots' do
37
+ expect(@response_body).to eq('<div>whatever</div>')
38
+ end
39
+ end
40
+
41
+ context 'javascript' do
42
+ let(:body) do
43
+ smart_deindent(<<-HTML)
44
+ <body>
45
+ <div>lmao</div>
46
+ <!-- ScriptStacker: JAVASCRIPT //-->
47
+ </body>
48
+ HTML
49
+ end
50
+
51
+ it 'injects tags' do
52
+ expect(@response_body).to eq(smart_deindent(<<-HTML))
53
+ <body>
54
+ <div>lmao</div>
55
+ <script type="text/javascript" src="/static/javascripts/main.js"></script>
56
+ <script type="text/javascript" src="/static/javascripts/util.js"></script>
57
+ </body>
58
+ HTML
59
+ end
60
+ end
61
+
62
+ context 'css' do
63
+ let(:body) do
64
+ smart_deindent(<<-HTML)
65
+ <head>
66
+ <!-- ScriptStacker: CSS //-->
67
+ </head>
68
+ HTML
69
+ end
70
+
71
+ it 'injects tags' do
72
+ expect(@response_body).to eq(smart_deindent(<<-HTML))
73
+ <head>
74
+ <link rel="stylesheet" type="text/css" href="/static/css/main.css" />
75
+ <link rel="stylesheet" type="text/css" href="/static/css/_whatever.css" />
76
+ </head>
77
+ HTML
78
+ end
79
+ end
80
+
81
+ context 'path normalization' do
82
+ let(:middleware) do
83
+ Rack::ScriptStacker.new app_with_body(body), configure_static: false do
84
+ css 'static/css/' => '/stylesheets'
85
+ javascript 'static/javascripts' => 'static/js'
86
+ end
87
+ end
88
+ let(:body) do
89
+ smart_deindent(<<-HTML)
90
+ <!-- ScriptStacker: CSS //-->
91
+ <!-- ScriptStacker: JAVASCRIPT //-->
92
+ HTML
93
+ end
94
+
95
+ it 'does not mess up the paths' do
96
+ expect(@response_body).to eq(smart_deindent(<<-HTML))
97
+ <link rel="stylesheet" type="text/css" href="/stylesheets/main.css" />
98
+ <link rel="stylesheet" type="text/css" href="/stylesheets/_whatever.css" />
99
+ <script type="text/javascript" src="/static/js/main.js"></script>
100
+ <script type="text/javascript" src="/static/js/util.js"></script>
101
+ HTML
102
+ end
103
+ end
104
+
105
+ context 'multiple specs for one stacker' do
106
+ let(:middleware) do
107
+ Rack::ScriptStacker.new app_with_body(body), configure_static: false do
108
+ javascript 'vendor/javascripts'
109
+ javascript 'static/javascripts'
110
+ end
111
+ end
112
+ let(:body) do
113
+ smart_deindent(<<-HTML)
114
+ <body>
115
+ <div>lmao</div>
116
+ <!-- ScriptStacker: JAVASCRIPT //-->
117
+ </body>
118
+ HTML
119
+ end
120
+
121
+ it 'injects tags in order' do
122
+ expect(@response_body).to eq(smart_deindent(<<-HTML))
123
+ <body>
124
+ <div>lmao</div>
125
+ <script type="text/javascript" src="/vendor/javascripts/jquery.js"></script>
126
+ <script type="text/javascript" src="/vendor/javascripts/buttscript.js"></script>
127
+ <script type="text/javascript" src="/static/javascripts/main.js"></script>
128
+ <script type="text/javascript" src="/static/javascripts/util.js"></script>
129
+ </body>
130
+ HTML
131
+ end
132
+ end
133
+
134
+ context 'Rack::Static' do
135
+ let(:body) { '<div>whatever</div>' }
136
+
137
+ it 'configures static automatically' do
138
+ expect(Rack::Static).to receive(:new).with(
139
+ duck_type(:call), {
140
+ urls: ['/static/css/', '/static/javascripts/']
141
+ }
142
+ )
143
+
144
+ Rack::ScriptStacker.new app_with_body(body), configure_static: true do
145
+ css 'static/css'
146
+ javascript 'static/javascripts'
147
+ end
148
+ end
149
+ end
150
+ end
151
+
@@ -0,0 +1,96 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
4
+ # this file to always be loaded, without a need to explicitly require it in any
5
+ # files.
6
+ #
7
+ # Given that it is always loaded, you are encouraged to keep this file as
8
+ # light-weight as possible. Requiring heavyweight dependencies from this file
9
+ # will add to the boot time of your test suite on EVERY test run, even for an
10
+ # individual file that may not need all of that loaded. Instead, consider making
11
+ # a separate helper file that requires the additional dependencies and performs
12
+ # the additional setup, and require it from the spec files that actually need
13
+ # it.
14
+ #
15
+ # The `.rspec` file also contains a few flags that are not defaults but that
16
+ # users commonly want.
17
+ #
18
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
19
+ RSpec.configure do |config|
20
+ # rspec-expectations config goes here. You can use an alternate
21
+ # assertion/expectation library such as wrong or the stdlib/minitest
22
+ # assertions if you prefer.
23
+ config.expect_with :rspec do |expectations|
24
+ # This option will default to `true` in RSpec 4. It makes the `description`
25
+ # and `failure_message` of custom matchers include text for helper methods
26
+ # defined using `chain`, e.g.:
27
+ # be_bigger_than(2).and_smaller_than(4).description
28
+ # # => "be bigger than 2 and smaller than 4"
29
+ # ...rather than:
30
+ # # => "be bigger than 2"
31
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
32
+ end
33
+
34
+ # rspec-mocks config goes here. You can use an alternate test double
35
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
36
+ config.mock_with :rspec do |mocks|
37
+ # Prevents you from mocking or stubbing a method that does not exist on
38
+ # a real object. This is generally recommended, and will default to
39
+ # `true` in RSpec 4.
40
+ mocks.verify_partial_doubles = true
41
+ end
42
+
43
+ # The settings below are suggested to provide a good initial experience
44
+ # with RSpec, but feel free to customize to your heart's content.
45
+ =begin
46
+ # These two settings work together to allow you to limit a spec run
47
+ # to individual examples or groups you care about by tagging them with
48
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
49
+ # get run.
50
+ config.filter_run :focus
51
+ config.run_all_when_everything_filtered = true
52
+
53
+ # Allows RSpec to persist some state between runs in order to support
54
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
55
+ # you configure your source control system to ignore this file.
56
+ config.example_status_persistence_file_path = "spec/examples.txt"
57
+
58
+ # Limits the available syntax to the non-monkey patched syntax that is
59
+ # recommended. For more details, see:
60
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
61
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
62
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
63
+ config.disable_monkey_patching!
64
+
65
+ # This setting enables warnings. It's recommended, but in some cases may
66
+ # be too noisy due to issues in dependencies.
67
+ config.warnings = true
68
+
69
+ # Many RSpec users commonly either run the entire suite or an individual
70
+ # file, and it's useful to allow more verbose output when running an
71
+ # individual spec file.
72
+ if config.files_to_run.one?
73
+ # Use the documentation formatter for detailed output,
74
+ # unless a formatter has already been configured
75
+ # (e.g. via a command-line flag).
76
+ config.default_formatter = 'doc'
77
+ end
78
+
79
+ # Print the 10 slowest examples and example groups at the
80
+ # end of the spec run, to help surface which specs are running
81
+ # particularly slow.
82
+ config.profile_examples = 10
83
+
84
+ # Run specs in random order to surface order dependencies. If you find an
85
+ # order dependency and want to debug it, you can fix the order by providing
86
+ # the seed, which is printed after each run.
87
+ # --seed 1234
88
+ config.order = :random
89
+
90
+ # Seed global randomization in this process using the `--seed` CLI option.
91
+ # Setting this allows you to use `--seed` to deterministically reproduce
92
+ # test failures related to randomization by passing the same `--seed` value
93
+ # as the one that triggered the failure.
94
+ Kernel.srand config.seed
95
+ =end
96
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-scriptstacker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Max Cantor
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.7'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.3'
69
+ description:
70
+ email:
71
+ - max@maxcantor.net
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".rspec"
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - lib/rack/scriptstacker.rb
83
+ - lib/rack/scriptstacker/version.rb
84
+ - rack-scriptstacker.gemspec
85
+ - spec/scriptstacker_spec.rb
86
+ - spec/spec_helper.rb
87
+ homepage: http://github.com/mcantor/rack-scriptstacker
88
+ licenses:
89
+ - MIT
90
+ metadata: {}
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 2.4.5
108
+ signing_key:
109
+ specification_version: 4
110
+ summary: Quickly inject static file lists into served HTML.
111
+ test_files:
112
+ - spec/scriptstacker_spec.rb
113
+ - spec/spec_helper.rb