rack-asset-compiler 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE.txt ADDED
@@ -0,0 +1,19 @@
1
+ Copyright 2011 Jonathan Baudanza
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "rspec/core"
2
+ require "rspec/core/rake_task"
3
+
4
+ desc "Run all specs"
5
+ RSpec::Core::RakeTask.new(:default) do |t|
6
+ t.rspec_opts = ["--color", "--format", "documentation"]
7
+ t.verbose = true
8
+ t.pattern = ['spec/*.rb']
9
+ end
data/Readme.md ADDED
@@ -0,0 +1,76 @@
1
+ # rack-asset-compiler
2
+
3
+ rack-asset-compiler is a Rack middleware that provides a generic interface for compiling static files, such as Sass or CoffeeScript files.
4
+
5
+ rack-asset-compiler does not use any local file storage and makes use of caching headers such as "Cache-Control" and "If-Modified-Since". This makes it ideal for running on read-only filesystem systems such as Heroku.
6
+
7
+ ## Installation
8
+
9
+ gem install rack-asset-compiler
10
+
11
+ ## Generic form
12
+
13
+ In this example, we have a set of text files with the extension .lower in the 'lowercase' directory, and
14
+ we want to server .uppercase files out of http://yourhost.com/uppercase
15
+
16
+ The compilation step is given in the form of a lambda passed as the `:compiler` option. This lambda will
17
+ be invoked whenever a client requests a file that needs to be compiled. The source filename will be passed
18
+ in and the compiled output is expected to be returned.
19
+
20
+ require 'rack/asset_compiler'
21
+
22
+ use Rack::AssetCompiler(
23
+ :source_dir => 'lowercase',
24
+ :url => '/uppercase',
25
+ :content_type => 'text/plain',
26
+ :source_extension => 'lower',
27
+ :compiler => lamba { |source_file|
28
+ File.read(source_file).upcase
29
+ }
30
+ )
31
+
32
+ ## Subclassing
33
+ An alternative to passing in a lambda to the :compiler option is to subclass Rack::AssetCompiler and
34
+ override the `compile` method.
35
+
36
+ This gem comes with two subclasses: one for compiling CoffeeScript and one for Sass.
37
+
38
+ ## Compiling CoffeeScript
39
+
40
+ config.ru
41
+ require 'rack/coffee_compiler'
42
+
43
+ use Rack::CoffeeCompiler,
44
+ :source_dir => 'app/coffeescripts'),
45
+ :url => '/javascripts',
46
+ :alert_on_error => true # Generates a window.alert on compile error. Defaults to (RACK_ENV != 'production')
47
+
48
+ Gemfile
49
+ gem 'therubyracer'
50
+ gem 'coffee-script'
51
+
52
+ # On heroku, use this gem instead of therubyracer
53
+ gem 'therubyracer-heroku', '0.8.1.pre3'
54
+
55
+ See [examples/jasmine_config.rb](https://github.com/jbaudanza/rack-asset-compiler/tree/master/examples/jasmine_config.rb) for an example of how to use CoffeeScript with your jasmine specs.
56
+
57
+ ## Compiling Sass
58
+
59
+ On Rails
60
+
61
+ require 'rack/sass_compiler'
62
+
63
+ # Disable the standard Sass plugin which will write to the filesystem
64
+ Rails.application.config.middleware.delete(Sass::Plugin::Rack)
65
+
66
+ # Insert the new middleware
67
+ Rails.application.config.middleware.use Rack::SassCompiler,
68
+ :source_dir => 'app/sass',
69
+ :url => '/javascripts',
70
+ :syntax => :scss # :sass or :scss, defaults to :scss
71
+
72
+ ## Thanks
73
+ asset-compiler was inspired by [rack-coffee] by [Matthew Lyon][mattly]
74
+
75
+ [rack-coffee]: https://github.com/mattly/rack-coffee
76
+ [mattly]: https://github.com/mattly/rack-coffee
@@ -0,0 +1,42 @@
1
+ #
2
+ # spec/javascripts/support/jasmine_config.rb
3
+ #
4
+ require 'rack/coffee_compiler'
5
+
6
+ module Jasmine
7
+ class Config
8
+
9
+ alias_method :old_js_files, :js_files
10
+
11
+ def js_files(spec_filter = nil)
12
+ # Convert all .coffee files into .js files before putting them in a script tag
13
+ old_js_files(spec_filter).map do |filename|
14
+ filename.sub(/\.coffee/, '.js')
15
+ end
16
+ end
17
+
18
+ def start_server(port=8888)
19
+ # We can't access the RAILS_ROOT constant from here
20
+ root = File.expand_path(File.join(File.dirname(__FILE__), '../../..'))
21
+
22
+ config = self
23
+
24
+ app = Rack::Builder.new do
25
+ # Compiler for your specs
26
+ use Rack::CoffeeCompiler,
27
+ :source_dir => File.join(root, 'spec/javascripts'),
28
+ :url => config.spec_path
29
+
30
+ # Compiler for your app files
31
+ use Rack::CoffeeCompiler,
32
+ :source_dir => File.join(root, 'public/javascripts'),
33
+ :url => '/public/javascripts'
34
+
35
+ run Jasmine.app(config)
36
+ end
37
+
38
+ handler = Rack::Handler.default
39
+ handler.run app, :Port => port, :AccessLog => []
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,95 @@
1
+ module Rack
2
+ class AssetCompiler
3
+ attr_accessor :url, :source_dir, :source_extension
4
+
5
+ F = ::File
6
+
7
+ def initialize(app, options={}, &block)
8
+ @app = app
9
+
10
+ options = {
11
+ :compiler => block,
12
+ :source_dir => Dir.pwd,
13
+ :url => '/',
14
+ :cache => ENV['RACK_ENV'] == 'production'
15
+ }.merge(options)
16
+
17
+ %w(source_extension content_type).each do |field|
18
+ raise "Missing required option :#{field}" unless options.has_key?(field.to_sym)
19
+ end
20
+
21
+ @compiler = options[:compiler]
22
+ @source_dir = options[:source_dir]
23
+ @url = options[:url]
24
+ @source_extension = options[:source_extension]
25
+ @content_type = options[:content_type]
26
+
27
+ @cache_ttl = options[:cache]
28
+
29
+ # Default cache duration is 1 week
30
+ if(@cache_ttl && !@cache_ttl.kind_of?(Integer))
31
+ @cache_ttl = 60 * 60 * 24 * 7
32
+ end
33
+ end
34
+
35
+ def response(status, body)
36
+ body += "\r\n"
37
+ [status, {"Content-Type" => 'text/plain',
38
+ "Content-Length" => body.size.to_s},
39
+ [body]]
40
+ end
41
+
42
+ def compile(source_file)
43
+ if @compiler
44
+ @compiler.call(source_file)
45
+ else
46
+ raise "Missing compiler"
47
+ end
48
+ end
49
+
50
+ def call(env)
51
+ request_path = Utils.unescape(env["PATH_INFO"])
52
+ return response( 403, 'Forbidden') if request_path.include? ".."
53
+
54
+ match_parts = url.split('/').select{ |str| str.length > 0 }
55
+ request_parts = request_path.split('/').select{ |str| str.length > 0 }
56
+
57
+ if(request_parts.take(match_parts.length) == match_parts)
58
+ request_base = request_parts[match_parts.length..-1]
59
+
60
+ # Swap in the source file extension
61
+ request_base[-1].sub!(/\.\w+$/, '.' + source_extension)
62
+
63
+ source_file = F.join(source_dir, request_base)
64
+
65
+ if F.exists?(source_file)
66
+ last_modified_time = F.mtime(source_file)
67
+
68
+ if env['HTTP_IF_MODIFIED_SINCE']
69
+ cached_time = Time.parse(env['HTTP_IF_MODIFIED_SINCE'])
70
+ if last_modified_time <= cached_time
71
+ return [304, {}, "Not modified\r\n"]
72
+ end
73
+ end
74
+
75
+ body = compile(source_file)
76
+
77
+ headers = {
78
+ 'Content-Type' => @content_type,
79
+ 'Content-Length' => body.length.to_s,
80
+ 'Last-Modified' => last_modified_time.httpdate
81
+ }
82
+
83
+ if @cache_ttl
84
+ headers['Expires'] = (Time.now + @cache_ttl).strftime('%a, %d %b %Y %H:%M:%S GMT')
85
+ headers['Cache-Control'] = "public,max-age=#{@cache_ttl}"
86
+ end
87
+
88
+ return [200, headers, body]
89
+ end
90
+ end
91
+
92
+ @app.call(env)
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,43 @@
1
+ require 'rack/asset_compiler'
2
+ require 'coffee-script'
3
+
4
+ module Rack
5
+ class CoffeeCompiler < AssetCompiler
6
+ LOCK = Mutex.new
7
+
8
+ def initialize(app, options={})
9
+ options = {
10
+ :url => '/javascripts',
11
+ :content_type => 'text/javascript',
12
+ :source_extension => 'coffee',
13
+ :alert_on_error => ENV['RACK_ENV'] != 'production',
14
+ :lock => LOCK
15
+ }.merge(options)
16
+
17
+ @alert_on_error = options[:alert_on_error]
18
+ @lock = options[:lock]
19
+ super
20
+ end
21
+
22
+ def compile(source_file)
23
+ if @lock
24
+ @lock.synchronize{ unsynchronized_compile(source_file) }
25
+ else
26
+ unsynchronized_compile(source_file)
27
+ end
28
+ end
29
+
30
+ def unsynchronized_compile(source_file)
31
+ begin
32
+ CoffeeScript.compile(::File.read(source_file))
33
+ rescue CoffeeScript::CompilationError => e
34
+ if @alert_on_error
35
+ error_msg = "CoffeeScript compilation error in #{source_file}.coffee:\n\n #{e.to_s}"
36
+ "window.alert(#{error_msg.to_json});"
37
+ else
38
+ raise e
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,31 @@
1
+ require 'rack/asset_compiler'
2
+ require 'sass'
3
+
4
+ module Rack
5
+ class SassCompiler < AssetCompiler
6
+ attr_accessor :syntax
7
+
8
+ def initialize(app, options={})
9
+ options
10
+
11
+ options = {
12
+ :url => '/stylesheets',
13
+ :content_type => 'text/css',
14
+ :syntax => :scss
15
+ }.merge(options)
16
+
17
+ @syntax = options[:syntax]
18
+ options[:source_extension] ||= syntax.to_s
19
+ super
20
+ end
21
+
22
+ def compile(source_file)
23
+ sass_options = {
24
+ :syntax => syntax,
25
+ :cache => false,
26
+ :load_paths => [source_dir]
27
+ }
28
+ Sass::Engine.new(::File.read(source_file), sass_options).render
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,18 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'rack-asset-compiler'
3
+ s.version = "0.0.2"
4
+ s.author = 'Jonathan Baudanza'
5
+ s.email = 'jon@jonb.org'
6
+ s.summary = 'Rack Middleware to facilitate the generic compiling static assets.'
7
+ s.homepage = 'http://www.github.com/jbaudanza/rack-asset-compiler'
8
+ s.add_dependency 'rack'
9
+ s.files = [ "rack-asset-compiler.gemspec", "Rakefile", "Readme.md", "LICENSE.txt" ]
10
+ s.files += Dir['lib/rack/*.rb'] + Dir['spec/**/*']
11
+ s.files += [ "examples/jasmine_config.rb" ]
12
+
13
+ s.description = <<END
14
+ rack-asset-compiler is a Rack middleware that provides a generic interface for compiling static files, such as Sass or CoffeeScript files.
15
+
16
+ rack-asset-compiler does not use any local file storage and makes use of caching headers such as "Cache-Control" and "If-Modified-Since". This makes it ideal for running on read-only filesystem systems such as Heroku.
17
+ END
18
+ end
@@ -0,0 +1,123 @@
1
+ require 'rack/asset_compiler'
2
+ require 'rack/lobster'
3
+ require "rack/test"
4
+
5
+ include Rack::Test::Methods
6
+
7
+ describe "AssetCompiler" do
8
+ before do
9
+ @compiler = lambda do |source_file|
10
+ @source_file = source_file
11
+ 'chickenscript'
12
+ end
13
+
14
+ @source_dir = File.join(File.dirname(__FILE__), 'fixtures/eggscripts')
15
+
16
+ @options = {
17
+ :url => '/chickenscripts/',
18
+ :source_dir => @source_dir,
19
+ :source_extension => 'eggscript',
20
+ :content_type => 'text/chicken-script',
21
+ :compiler => @compiler
22
+ }
23
+ end
24
+
25
+ def app
26
+ options = @options
27
+ Rack::Builder.new {
28
+ use Rack::Lint
29
+ use Rack::AssetCompiler, options
30
+ run Rack::Lobster.new
31
+ }
32
+ end
33
+
34
+ it "should raise an error if required options are missing" do
35
+ lambda {
36
+ @options.delete(:content_type)
37
+ get '/oops'
38
+ }.should raise_error
39
+ end
40
+
41
+ it "should match files directly beneath the URL" do
42
+ get '/chickenscripts/application.chickenscript'
43
+ @source_file.should == "#{@source_dir}/application.eggscript"
44
+ last_response.body.should == 'chickenscript'
45
+ end
46
+
47
+ it "should match files underneath a subdirectry" do
48
+ get '/chickenscripts/subdir/application.chickenscript'
49
+ @source_file.should == "#{@source_dir}/subdir/application.eggscript"
50
+ last_response.body.should == 'chickenscript'
51
+ end
52
+
53
+ it "should not call the compiler for missing files" do
54
+ get '/chickenscripts/missing.chickenscript'
55
+ @source_file.should be_nil
56
+ end
57
+
58
+ it "should use the correct content-type" do
59
+ get '/chickenscripts/application.chickenscript'
60
+ last_response.content_type.should == 'text/chicken-script'
61
+ end
62
+
63
+ it "should not match files outside the URL parameter" do
64
+ get '/lobster'
65
+ last_response.body.should include('Lobstericious')
66
+ end
67
+
68
+ it "should include a last-modified header" do
69
+ get '/chickenscripts/application.chickenscript'
70
+ last_response.headers["Last-Modified"].should == File.mtime("#{@source_dir}/application.eggscript").httpdate
71
+ end
72
+
73
+ it "should respond with a 304 on a last-modified hit" do
74
+ last_modified_time = File.mtime("#{@source_dir}/application.eggscript").httpdate
75
+ get '/chickenscripts/application.chickenscript', {}, {'HTTP_IF_MODIFIED_SINCE' => last_modified_time}
76
+ last_response.status.should == 304
77
+ last_response.body.should == "Not modified\r\n"
78
+ end
79
+
80
+ it "should return the compiled code on a last-modified miss" do
81
+ last_modified_time = (File.mtime("#{@source_dir}/application.eggscript") - 10).httpdate
82
+ get '/chickenscripts/application.chickenscript', {}, {'HTTP_IF_MODIFIED_SINCE' => last_modified_time}
83
+ last_response.status.should == 200
84
+ last_response.body.should == "chickenscript"
85
+ end
86
+
87
+ it "should reject requests with a .." do
88
+ get '/chickenscript/../somethingbad'
89
+ last_response.status.should == 403
90
+ end
91
+
92
+ describe "Caching" do
93
+ it "should not cache by default" do
94
+ @options.delete(:cache)
95
+ get '/chickenscripts/application.chickenscript'
96
+ last_response.headers.should_not include('Cache-Control')
97
+ end
98
+
99
+ it "should cache by default on production" do
100
+ @options.delete(:cache)
101
+ old_rack_env = ENV['RACK_ENV']
102
+ ENV['RACK_ENV'] = 'production'
103
+ get '/chickenscripts/application.chickenscript'
104
+ ENV['RACK_ENV'] = old_rack_env
105
+
106
+ last_response.headers.should include('Cache-Control')
107
+ end
108
+
109
+ it "should set not the cache header when the cache options is false" do
110
+ @options[:cache] = false
111
+ get '/chickenscripts/application.chickenscript'
112
+ last_response.headers.should_not include('Cache-Control')
113
+ last_response.headers.should_not include('Expires')
114
+ end
115
+
116
+ it "should set the cache header to a duration of one week when the cache options is true" do
117
+ @options[:cache] = true
118
+ get '/chickenscripts/application.chickenscript'
119
+ last_response.headers['Cache-Control'].should == "public,max-age=604800"
120
+ last_response.headers.should include('Expires')
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,62 @@
1
+ require 'rack/coffee_compiler'
2
+ require 'rack/lobster'
3
+ require "rack/test"
4
+
5
+ include Rack::Test::Methods
6
+
7
+ describe "CoffeeCompiler" do
8
+ before do
9
+ @source_dir = File.join(File.dirname(__FILE__), 'fixtures/coffeescripts')
10
+
11
+ @options = {
12
+ :source_dir => @source_dir
13
+ }
14
+ end
15
+
16
+ def app
17
+ options = @options
18
+ Rack::Builder.new {
19
+ use Rack::Lint
20
+ use Rack::CoffeeCompiler, options
21
+ run Rack::Lobster.new
22
+ }
23
+ end
24
+
25
+ it "should compile the coffeescript" do
26
+ get '/javascripts/application.js'
27
+ last_response.body.should == CoffeeScript.compile(File.read("#{@source_dir}/application.coffee"))
28
+ last_response.status.should == 200
29
+ last_response.content_type.should == 'text/javascript'
30
+ end
31
+
32
+ describe "when compiling a file with a syntax error" do
33
+ def do_get
34
+ get '/javascripts/syntax_error.js'
35
+ end
36
+
37
+ it "should render a window.alert by default" do
38
+ @options.delete(:alert_on_error)
39
+ do_get
40
+ last_response.body.should include('window.alert')
41
+ end
42
+
43
+ it "should not render a window.alert by default on production" do
44
+ @options.delete(:alert_on_error)
45
+ old_rack_env = ENV['RACK_ENV']
46
+ ENV['RACK_ENV'] = 'production'
47
+ lambda { do_get }.should raise_error(CoffeeScript::CompilationError)
48
+ ENV['RACK_ENV'] = old_rack_env
49
+ end
50
+
51
+ it "should not render a window.alert if alert_on_error is false" do
52
+ @options[:alert_on_error] = false
53
+ lambda { do_get }.should raise_error(CoffeeScript::CompilationError)
54
+ end
55
+
56
+ it "should render a window.alert if alert_on_error is true" do
57
+ @options[:alert_on_error] = true
58
+ do_get
59
+ last_response.body.should include('window.alert')
60
+ end
61
+ end
62
+ end
@@ -0,0 +1 @@
1
+ console.log('hello world')
@@ -0,0 +1 @@
1
+ almost_called_a_function(1,2
@@ -0,0 +1 @@
1
+ EggScript is an imaginary language that can be compiled into ChickenScript
@@ -0,0 +1 @@
1
+ EggScript is an imaginary language that can be compiled into ChickenScript
@@ -0,0 +1,2 @@
1
+ #compiled_with_sass
2
+ background-color: red
@@ -0,0 +1,3 @@
1
+ #compiled_with_scss {
2
+ background-color: blue;
3
+ }
@@ -0,0 +1,41 @@
1
+ require 'rack/sass_compiler'
2
+ require 'rack/lobster'
3
+ require "rack/test"
4
+
5
+ include Rack::Test::Methods
6
+
7
+ describe "SassCompiler" do
8
+ before do
9
+ @source_dir = File.join(File.dirname(__FILE__), 'fixtures/sass')
10
+
11
+ @options = {
12
+ :source_dir => @source_dir
13
+ }
14
+ end
15
+
16
+ def app
17
+ options = @options
18
+ Rack::Builder.new {
19
+ use Rack::Lint
20
+ use Rack::SassCompiler, options
21
+ run Rack::Lobster.new
22
+ }
23
+ end
24
+
25
+ it "should compile scss" do
26
+ get '/stylesheets/style.css'
27
+ last_response.body.should ==
28
+ Sass::Engine.new(File.read("#{@source_dir}/style.scss"), :syntax => :scss).render
29
+ last_response.status.should == 200
30
+ last_response.content_type.should == 'text/css'
31
+ end
32
+
33
+ it "should compile sass" do
34
+ @options[:syntax] = :sass
35
+ get '/stylesheets/style.css'
36
+ last_response.body.should ==
37
+ Sass::Engine.new(File.read("#{@source_dir}/style.sass"), :syntax => :sass).render
38
+ last_response.status.should == 200
39
+ last_response.content_type.should == 'text/css'
40
+ end
41
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-asset-compiler
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 2
10
+ version: 0.0.2
11
+ platform: ruby
12
+ authors:
13
+ - Jonathan Baudanza
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-02-25 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rack
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ description: |
36
+ rack-asset-compiler is a Rack middleware that provides a generic interface for compiling static files, such as Sass or CoffeeScript files.
37
+
38
+ rack-asset-compiler does not use any local file storage and makes use of caching headers such as "Cache-Control" and "If-Modified-Since". This makes it ideal for running on read-only filesystem systems such as Heroku.
39
+
40
+ email: jon@jonb.org
41
+ executables: []
42
+
43
+ extensions: []
44
+
45
+ extra_rdoc_files: []
46
+
47
+ files:
48
+ - rack-asset-compiler.gemspec
49
+ - Rakefile
50
+ - Readme.md
51
+ - LICENSE.txt
52
+ - lib/rack/asset_compiler.rb
53
+ - lib/rack/coffee_compiler.rb
54
+ - lib/rack/sass_compiler.rb
55
+ - spec/asset_compiler_spec.rb
56
+ - spec/coffee_compiler_spec.rb
57
+ - spec/fixtures/coffeescripts/application.coffee
58
+ - spec/fixtures/coffeescripts/syntax_error.coffee
59
+ - spec/fixtures/eggscripts/application.eggscript
60
+ - spec/fixtures/eggscripts/subdir/application.eggscript
61
+ - spec/fixtures/sass/style.sass
62
+ - spec/fixtures/sass/style.scss
63
+ - spec/sass_compiler_spec.rb
64
+ - examples/jasmine_config.rb
65
+ has_rdoc: true
66
+ homepage: http://www.github.com/jbaudanza/rack-asset-compiler
67
+ licenses: []
68
+
69
+ post_install_message:
70
+ rdoc_options: []
71
+
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ hash: 3
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ hash: 3
89
+ segments:
90
+ - 0
91
+ version: "0"
92
+ requirements: []
93
+
94
+ rubyforge_project:
95
+ rubygems_version: 1.5.0
96
+ signing_key:
97
+ specification_version: 3
98
+ summary: Rack Middleware to facilitate the generic compiling static assets.
99
+ test_files: []
100
+