rack-asset-compiler 0.0.2

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.
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
+