Browse files

initial commit

  • Loading branch information...
0 parents commit 6ac3b1f9ae48b8b78f1f4ef622582f6f01181ca6 @ddollar committed Jun 12, 2010
1 .gitignore
@@ -0,0 +1 @@
+coverage
0 README.md
No changes.
58 Rakefile
@@ -0,0 +1,58 @@
+require "rake"
+require "rspec"
+require "rspec/core/rake_task"
+
+$:.unshift File.expand_path("../lib", __FILE__)
+require "asset_resource"
+
+task :default => :spec
+
+desc "Run all specs"
+Rspec::Core::RakeTask.new(:spec) do |t|
+ t.pattern = 'spec/**/*_spec.rb'
+end
+
+desc "Generate RCov code coverage report"
+task :rcov => "rcov:build" do
+ %x{ open coverage/index.html }
+end
+
+Rspec::Core::RakeTask.new("rcov:build") do |t|
+ t.pattern = 'spec/**/*_spec.rb'
+ t.rcov = true
+ t.rcov_opts = [ "--exclude", Gem.default_dir , "--exclude", "spec" ]
+end
+
+######################################################
+
+begin
+ require 'jeweler'
+ Jeweler::Tasks.new do |s|
+ s.name = "asset-resource"
+ s.version = AssetResource::VERSION
+
+ s.summary = "Manage CSS/JS assets as dynamic resources rather than static files"
+ s.description = s.summary
+ s.author = "David Dollar"
+ s.email = "ddollar@gmail.com"
+ s.homepage = "http://github.com/ddollar/asset-resource"
+
+ s.platform = Gem::Platform::RUBY
+ s.has_rdoc = false
+
+ s.files = %w(Rakefile README.md) + Dir["{bin,lib}/**/*"]
+ s.require_path = "lib"
+
+ s.add_development_dependency 'artifice', '~> 0.5'
+ s.add_development_dependency 'fakefs', '~> 0.2.1'
+ s.add_development_dependency 'haml', '~> 3.0.9'
+ s.add_development_dependency 'less', '~> 1.2.21'
+ s.add_development_dependency 'rake', '~> 0.8.7'
+ s.add_development_dependency 'rest-client', '~> 1.5.1'
+ s.add_development_dependency 'rcov', '~> 0.9.8'
+ s.add_development_dependency 'rspec', '~> 2.0.0'
+ end
+ Jeweler::GemcutterTasks.new
+rescue LoadError
+ puts "Jeweler not available. Install it with: sudo gem install jeweler"
+end
43 asset-resource.gemspec
@@ -0,0 +1,43 @@
+# Generated by jeweler
+# DO NOT EDIT THIS FILE DIRECTLY
+# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
+# -*- encoding: utf-8 -*-
+
+Gem::Specification.new do |s|
+ s.name = %q{asset-resource}
+ s.version = "0.0.1"
+
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
+ s.authors = ["David Dollar"]
+ s.date = %q{2010-06-11}
+ s.description = %q{Manage CSS/JS assets as dynamic resources rather than static files}
+ s.email = %q{ddollar@gmail.com}
+ s.extra_rdoc_files = [
+ "README.md"
+ ]
+ s.files = [
+ "README.md",
+ "Rakefile",
+ "lib/asset-resource.rb",
+ "lib/asset_resource.rb",
+ "lib/asset_resource/framework/rails.rb",
+ "lib/asset_resource/middleware.rb"
+ ]
+ s.has_rdoc = false
+ s.homepage = %q{http://github.com/ddollar/asset-resource}
+ s.rdoc_options = ["--charset=UTF-8"]
+ s.require_paths = ["lib"]
+ s.rubygems_version = %q{1.3.7}
+ s.summary = %q{Manage CSS/JS assets as dynamic resources rather than static files}
+
+ if s.respond_to? :specification_version then
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
+ s.specification_version = 3
+
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
+ else
+ end
+ else
+ end
+end
+
1 autotest/discover.rb
@@ -0,0 +1 @@
+Autotest.add_discovery { "rspec2" }
1 lib/asset-resource.rb
@@ -0,0 +1 @@
+require "asset_resource"
5 lib/asset_resource.rb
@@ -0,0 +1,5 @@
+module AssetResource
+ VERSION = "0.0.1"
+end
+
+require "asset_resource/framework/rails" if defined?("Rails")
7 lib/asset_resource/framework/rails.rb
@@ -0,0 +1,7 @@
+require "asset_resource/middleware"
+require "active_support"
+
+ActiveSupport.on_load(:before_configuration) do
+ Rails.application.config.middleware.use AssetResource::Middleware,
+ :base_path => Rails.root.join("public")
+end
89 lib/asset_resource/middleware.rb
@@ -0,0 +1,89 @@
+require "asset_resource"
+
+class AssetResource::Middleware
+
+ attr_reader :app, :options
+
+ def initialize(app, options={})
+ @app = app
+ @options = options
+
+ handle :scripts
+ handle :stylesheets
+
+ translator :less do |filename|
+ begin
+ require "less"
+ Less::Engine.new(File.read(filename)).to_css
+ rescue LoadError
+ raise "Tried to translate a less file but could not find the library.\nTry adding this to your Gemfile:\n gem \"less\""
+ end
+ end
+
+ translator :sass do |filename|
+ begin
+ require "sass"
+ Sass::Engine.new(File.read(filename), :load_paths => [File.dirname(filename)]).render
+ rescue LoadError
+ raise "Tried to translate a sass file but could not find the library.\nTry adding this to your Gemfile:\n gem \"haml\""
+ end
+ end
+ end
+
+ def call(env)
+ if env["PATH_INFO"] =~ %r{\A/assets/(.+)\B}
+ type = $1.split(".").first
+ return app.call(env) unless handles?(type)
+ return [200, asset_headers, process_files(files_for(type))]
+ end
+ app.call(env)
+ end
+
+private ######################################################################
+
+ def asset_headers
+ options[:asset_headers] || { "Cache-Control" => "public, max-age=86400" }
+ end
+
+ def base_path
+ options[:base_path] || "public"
+ end
+
+ def files_for(type)
+ Dir.glob(File.expand_path(File.join(base_path, type, "**", "*")))
+ end
+
+ def process_files(files)
+ data = files.inject("") do |accum, file|
+ ext = File.extname(file)[1..-1]
+ accum << translator(ext).call(file)
+ end
+ StringIO.new(data)
+ end
+
+ def handlers
+ @handler ||= []
+ end
+
+ def handle(type)
+ handlers << type.to_sym
+ end
+
+ def handles?(type)
+ handlers.include?(type.to_sym)
+ end
+
+ def default_translator
+ lambda { |filename| File.read(filename) }
+ end
+
+ def translators
+ @translators ||= Hash.new(default_translator)
+ end
+
+ def translator(type, &block)
+ translators[type.to_sym] = block if block_given?
+ translators[type.to_sym]
+ end
+
+end
39 spec/asset_resource/middleware_spec.rb
@@ -0,0 +1,39 @@
+require "spec_helper"
+require "asset_resource/middleware"
+
+describe AssetResource::Middleware do
+ let(:app) { lambda { |env| [ 200, {}, ['bar'] ]} }
+ let(:middleware) { AssetResource::Middleware.new(app, :base_path => asset_fixture) }
+
+ before(:each) do
+ Artifice.activate_with(middleware)
+ end
+
+ it "passes unhandled requests" do
+ RestClient.get("http://localhost/foo").to_s.should == "bar"
+ end
+
+ it "serves with cache headers" do
+ response = RestClient.get("http://localhost/assets/scripts.js")
+ response.headers[:cache_control].should =~ /public/
+ end
+
+ it "can set custom asset headers" do
+ middleware.options[:asset_headers] = { "X-Foo" => "Bar" }
+ response = RestClient.get("http://localhost/assets/scripts.js")
+ response.headers[:cache_control].should_not =~ /public/
+ response.headers[:x_foo].should == "Bar"
+ end
+
+ it "serves scripts" do
+ data = RestClient.get("http://localhost/assets/scripts.js")
+ data.should include "console.log('hello!')"
+ end
+
+ it "serves styles" do
+ data = RestClient.get("http://localhost/assets/stylesheets.css")
+ data.should include "color: #1e5500"
+ data.should include "color: #5a5500"
+ end
+
+end
8 spec/asset_resource_spec.rb
@@ -0,0 +1,8 @@
+require "spec_helper"
+require "asset_resource"
+
+describe AssetResource do
+ it "has a version" do
+ AssetResource::VERSION.should be_a String
+ end
+end
3 spec/fixtures/scripts/sample.js
@@ -0,0 +1,3 @@
+$(document).ready(function() {
+ console.log('hello!');
+});
9 spec/fixtures/stylesheets/sample.less
@@ -0,0 +1,9 @@
+@brand: #1e5500;
+
+#header {
+ color: @brand;
+}
+
+h2 {
+ color: @brand;
+}
7 spec/fixtures/stylesheets/sample.sass
@@ -0,0 +1,7 @@
+$brand: #5a5500
+
+#header
+ color: $brand
+
+h3
+ color: $brand
14 spec/spec_helper.rb
@@ -0,0 +1,14 @@
+require "rubygems"
+require "rspec"
+require "artifice"
+require "rest_client"
+
+$:.unshift "lib"
+
+def asset_fixture(name="")
+ File.expand_path("../fixtures/#{name}", __FILE__)
+end
+
+Rspec.configure do |config|
+ config.color_enabled = true
+end

0 comments on commit 6ac3b1f

Please sign in to comment.