Permalink
Browse files

proper caching of built resources

  • Loading branch information...
1 parent 9e6f50e commit afc5637347487128bdde3d64afc41958c617d208 @darwin committed Jan 14, 2009
@@ -0,0 +1,71 @@
+$cache = {}
+
+def produce(checkout, path)
+ begin
+ file_path = checkout.serve(path)
+ rescue IntermediateFileError
+ throw :halt, [404, 'Requested intermediate resource. This resource won\'t be present on production. See index.js instead.']
+ rescue ResourceNotFoundError => e
+ throw :halt, [404, 'resource not found']
+ rescue YUICompressorError => e
+ throw :halt, [404, 'YUI compressor error: ' + $!.message]
+ end
+end
+
+def serve(mod, path)
+ url = "http://localhost:9876/#{mod}"
+ checkout = $cache[url.to_sym]
+ unless checkout
+ begin
+ resource_path = File.join($workspace, mod)
+ checkout = $cache[url.to_sym] = eval(mod.capitalize+"Checkout").new($mode, mod.to_sym, resource_path, File.join($workspace, "temp"), url)
+ rescue NoSuchPathError
+ throw :halt, [404, 'file not found']
+ end
+ end
+ file_path = produce(checkout, path)
+ send_file(file_path, {
+ :disposition => 'inline'
+ })
+end
+
+def serve_widget(path, name, author, kind)
+ case kind
+ when "widgets"
+ klass = WidgetCheckout
+ prefix = "pbw"
+ when "skins"
+ klass = SkinCheckout
+ prefix = "pbs"
+ else
+ throw :halt, [404, 'bad resource kind']
+ end
+
+ url = "http://localhost:9876/#{kind}/#{author}/#{name}"
+ checkout = $cache[url.to_sym]
+ unless checkout
+ temp = File.join($workspace, "temp")
+ begin
+ resource_path = File.join($workspace, kind, author, name)
+ checkout = $cache[url.to_sym] = klass.new($mode, :widget, resource_path, temp, url)
+ rescue NoSuchPathError
+ if name.index("-") then
+ # try without prefix
+ name = name.split("-")[1..-1].join("-")
+ else
+ # try with prefix
+ name = prefix + "-" + name
+ end
+ begin
+ resource_path = File.join($workspace, kind, author, name)
+ checkout = $cache[url.to_sym] = klass.new($mode, :widget, resource_path, temp, url)
+ rescue NoSuchPathError
+ throw :halt, [404, 'file not found']
+ end
+ end
+ end
+ file_path = produce(checkout, path)
+ return send_file(file_path, {
+ :disposition => 'inline'
+ })
+end
View
@@ -1,32 +1,3 @@
-OSX = PLATFORM =~ /darwin/
-WIN = PLATFORM =~ /win32/
-NIX = !(OSX || WIN)
-
-# http://kpumuk.info/ruby-on-rails/colorizing-console-ruby-script-output/
-begin
- require 'Win32/Console/ANSI' if WIN
-rescue LoadError
- raise 'Run "gem install win32console" to use terminal colors on Windows'
-end
-
-def colorize(text, color_code)
- "#{color_code}#{text}\e[0m"
-end
-
-def red(text); colorize(text, "\e[31m"); end
-def green(text); colorize(text, "\e[32m"); end
-def yellow(text); colorize(text, "\e[33m"); end
-def blue(text); colorize(text, "\e[34m"); end
-def magenta(text); colorize(text, "\e[35m"); end
-def azure(text); colorize(text, "\e[36m"); end
-def white(text); colorize(text, "\e[37m"); end
-def black(text); colorize(text, "\e[30m"); end
-
-def die(s)
- $stderr.puts red(s)
- exit(1)
-end
-
$workspace = File.expand_path(ENV["PBDEV_WORKSPACE"] || ".")
$mode = (ENV["PBDEV_MODE"] || "development").to_sym
View
@@ -9,6 +9,7 @@
end
require 'pbdev-server-init'
+require 'pbdev-server-helpers'
include PBDev
@@ -41,113 +42,29 @@
end
get '/engine/*' do
- begin
- resource_path = File.join($workspace, "engine")
- checkout = EngineCheckout.new(resource_path, File.join($workspace, "temp"), "http://localhost:9876/engine")
- rescue NoSuchPathError
- throw :halt, [404, 'file not found']
- end
-
path = params["splat"][0]
- file_path = checkout.serve(path, $mode)
-
- return send_file(file_path, {
- :disposition => 'inline'
- })
+ serve("engine", path)
end
get '/editor/*' do
- begin
- resource_path = File.join($workspace, "editor")
- checkout = EditorCheckout.new(resource_path, File.join($workspace, "temp"), "http://localhost:9876/editor")
- rescue NoSuchPathError
- throw :halt, [404, 'file not found']
- end
-
path = params["splat"][0]
- file_path = checkout.serve(path, $mode)
-
- return send_file(file_path, {
- :disposition => 'inline'
- })
+ serve("editor", path)
end
get '/system/*' do
- begin
- resource_path = File.join($workspace, "system")
- checkout = SystemCheckout.new(resource_path, File.join($workspace, "temp"), "http://localhost:9876/system")
- rescue NoSuchPathError
- throw :halt, [404, 'file not found']
- end
-
path = params["splat"][0]
- file_path = checkout.serve(path, $mode)
-
- return send_file(file_path, {
- :disposition => 'inline'
- })
+ serve("system", path)
end
get '/redbug/*' do
- begin
- resource_path = File.join($workspace, "redbug")
- checkout = RedbugCheckout.new(resource_path, File.join($workspace, "temp"), "http://localhost:9876/redbug")
- rescue NoSuchPathError
- throw :halt, [404, 'file not found']
- end
-
path = params["splat"][0]
- file_path = checkout.serve(path, $mode)
-
- return send_file(file_path, {
- :disposition => 'inline'
- })
+ serve("redbug", path)
end
get '/:kind/:author/:name/*' do
path = params["splat"][0]
name = params[:name] # e.g. pbw.tabs
author = params[:author] # github username e.g. darwin
kind = params[:kind] # e.g. widgets or skins
-
- case kind
- when "widgets"
- klass = WidgetCheckout
- prefix = "pbw"
- when "skins"
- klass = SkinCheckout
- prefix = "pbs"
- else
- throw :halt, [404, 'bad resource kind']
- end
-
- begin
- resource_path = File.join($workspace, kind, author, name)
- checkout = klass.new(resource_path, File.join($workspace, "temp"), "http://localhost:9876/#{kind}/#{author}/#{name}")
- rescue NoSuchPathError
- if name.index("-") then
- # try without prefix
- name = name.split("-")[1..-1].join("-")
- else
- # try with prefix
- name = prefix + "-" + name
- end
- begin
- resource_path = File.join($workspace, kind, author, name)
- checkout = klass.new(resource_path, File.join($workspace, "temp"), "http://localhost:9876/#{kind}/#{author}/#{name}")
- rescue NoSuchPathError
- throw :halt, [404, 'file not found']
- end
- end
- begin
- file_path = checkout.serve(path, $mode)
- rescue IntermediateFileError
- throw :halt, [404, 'Requested intermediate resource. This resource won\'t be present on production. See index.js instead.']
- rescue ResourceNotFoundError
- throw :halt, [404, 'resource not found']
- end
-
- return send_file(file_path, {
- :disposition => 'inline'
- })
+ serve_widget(path, name, author, kind)
end
View
@@ -2,13 +2,46 @@
require 'fileutils'
require 'grit/lib/grit.rb'
+OSX = PLATFORM =~ /darwin/
+WIN = PLATFORM =~ /win32/
+NIX = !(OSX || WIN)
+
+# http://kpumuk.info/ruby-on-rails/colorizing-console-ruby-script-output/
+begin
+ require 'Win32/Console/ANSI' if WIN
+rescue LoadError
+ raise 'Run "gem install win32console" to use terminal colors on Windows'
+end
+
+def colorize(text, color_code)
+ "#{color_code}#{text}\e[0m"
+end
+
+def red(text); colorize(text, "\e[31m"); end
+def green(text); colorize(text, "\e[32m"); end
+def yellow(text); colorize(text, "\e[33m"); end
+def blue(text); colorize(text, "\e[34m"); end
+def magenta(text); colorize(text, "\e[35m"); end
+def azure(text); colorize(text, "\e[36m"); end
+def white(text); colorize(text, "\e[37m"); end
+def black(text); colorize(text, "\e[30m"); end
+
+def die(s)
+ $stderr.puts red(s)
+ exit(1)
+end
+
class Loggerx
def debug(s)
- $stderr.puts s
+ #$stderr.puts yellow(s)
+ end
+
+ def info(s)
+ $stderr.puts blue(s)
end
def fatal(s)
- $stderr.puts s
+ $stderr.puts red(s)
end
end
View
@@ -221,6 +221,7 @@ def build_entries(entries, opts={})
if !opts[:force] && File.exists?(entry.build_path)
source_mtime = entry.source_path_mtime
if source_mtime && (File.mtime(entry.build_path) >= source_mtime)
+ entry.fresh = false
PB.logger.debug("~ Skipping Entry: #{entry.filename} because it has not changed")
next
end
@@ -233,6 +234,7 @@ def build_entries(entries, opts={})
else
PB.logger.debug("~ Building #{entry.type.to_s.capitalize}: #{entry.filename}")
PBDev.send("build_#{entry.type}".to_sym, entry, self)
+ entry.fresh = true
end
end
View
@@ -3,30 +3,47 @@
module PBDev
class Checkout
- def initialize(path, temp, url)
+ def initialize(mode, kind, path, temp, url)
epath = File.expand_path(path)
raise NoSuchPathError.new(epath) unless File.exists? epath
+ @mode = mode
@path = epath
@temp = temp
@url = url
+ @kind = kind
+ prepare_bundle()
+ end
+
+ def prepare_bundle()
+ @bundle = Bundle.new("xxx", {
+ :source_root => @path,
+ :build_mode => @mode,
+ :build_root => temp(),
+ :build_kind => @kind
+ })
+ @bundle.build()
end
def serve(path)
File.join(@path, path)
end
- def temp(path)
+ def temp(path = "")
digest = Digest::MD5.hexdigest(self.class.name + @url + path)
File.join(@temp, digest)
end
- def prepare_final(path, *results)
+ def final_path(path, *results)
results = results.reject { |x| x.nil? }
base = path
results.each do |result|
base << result.gsub(".", "_")
end
final = File.join(temp(base), "result.js")
+ end
+
+ def prepare_final(final, *results)
+ results = results.reject { |x| x.nil? }
FileUtils.makedirs(File.dirname(final))
File.open(final, "w") do |f|
results.each do |result|
@@ -41,12 +58,39 @@ def minify(path)
yui_root = File.expand_path(File.join(File.dirname(__FILE__), '..', 'yui-compressor'))
jar_path = File.join(yui_root, 'yuicompressor-2.4.2.jar')
filecompress = "java -jar \"" + jar_path + "\" --charset utf-8 \"" + path + "\" -o \"" + path + "\""
- puts 'Compressing with YUI .... '+ path
- puts `#{filecompress}`
+ PB.logger.info('Compressing with YUI .... '+ path)
+ res = `#{filecompress} 2>&1`
if $?.exitstatus != 0
PB.logger.fatal("!!!!YUI compressor failed, please check that your js code is valid and doesn't contain reserved statements like debugger;")
PB.logger.fatal("!!!!Failed compressing ... "+ path)
+ PB.logger.fatal(res)
+ failed_path = File.join(File.dirname(path), "failed_"+File.basename(path))
+ `mv "#{path}" "#{failed_path}"`
+ raise YUICompressorError.new(failed_path + "\n\n" + res)
+ end
+ end
+
+ def bakein(path, bundle=nil)
+ bundle = @bundle unless bundle
+ bundle.reload!
+ results = []
+ fresh = []
+ %w(js css tpl html).each do |ext|
+ baked = bundle.entry_for("baked_index.#{ext}")
+ next unless baked
+ bundle.build_entry(baked)
+ results << baked.build_path
+ fresh << baked.fresh
+ end
+ final_path = final_path(path, *results)
+ if File.exists?(final_path) && !(fresh.any? {|x| x }) then
+ PB.logger.debug("~ Skipping Entry: #{final_path} because it has not changed")
+ return final_path
end
+ PB.logger.info("Baking #{@url}/#{path} ...")
+ prepare_final(final_path, *results)
+ minify(final_path) if bundle.minify?
+ final_path
end
end
Oops, something went wrong.

0 comments on commit afc5637

Please sign in to comment.