Class: Vitrine::AssetCompiler

Inherits:
Sinatra::Base
  • Object
show all
Defined in:
lib/asset_compiler.rb

Overview

The part of Vitrine responsible for SASS and CoffeeScript compilation and caching. By default it will assume your public directory is set on the inner app in the Rack stack, and can be retreived using the standard Sinatra settings protocol, like so:

@app.settings.public_folder

However, you can also set this setting on the app object using the AssetCompiler#public_dir accessor.

use Vitrine::AssetCompiler do | compiler |
  compiler.public_dir = File.dirname(__FILE__) + '/public'
end

This allows you to use the asset compiler when the inner app is not a Sinatra application.

Obviously, the usual limitation apply for this kind of workflow - you pretty much have to have an ExecJS env on yourserver, or else…

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#public_dirObject

An explicit override for public_folder setting, if set will take precedence over the setting



27
28
29
# File 'lib/asset_compiler.rb', line 27

def public_dir
  @public_dir
end

Instance Method Details

#forward_or_halt(msg) ⇒ Object



135
136
137
138
139
140
141
142
# File 'lib/asset_compiler.rb', line 135

def forward_or_halt msg
  if @app
    log "Forwarding, #{msg} -> pub #{get_public.inspect}"
    forward 
  else
    halt 404, msg
  end
end

#get_publicObject

Get path to the public directory, trying (in order:) self.public_dir reader the inner app’s public_folder setting my own public_folder setting



125
126
127
128
129
130
131
132
133
# File 'lib/asset_compiler.rb', line 125

def get_public
  inner_public = if @app && @app.respond_to?(:settings)
    @app.settings.public_folder
  else
    nil
  end
  choices = [@public_dir, inner_public, settings.public_dir]
  choices.compact.shift
end

#log(mgs) ⇒ Object



144
145
146
# File 'lib/asset_compiler.rb', line 144

def log(mgs)
  env['captivity.logger'].debug(msg) if env['captivity.logger']
end

#mtime_cache(path, &blk) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/asset_compiler.rb', line 95

def mtime_cache(path, &blk)
  # Mix in the request URL into the cache key so that we can hash
  # .map sourcemaps and .js compiles based off of the same file path
  # and mtime
  key = [File.expand_path(path), File.mtime(path), request.path_info, get_public]
  cache_sha = Digest::SHA1.hexdigest(Marshal.dump(key))
  
  # Store in a temp dir
  FileUtils.mkdir_p '/tmp/vitrine'
  p = '/tmp/vitrine/%s' % cache_sha
  
  # Only write it out unless a file with the same SHA does not exist
  unless File.exist?(p)
    Vitrine.atomic_write(p) do |f|
      log "---> Recompiling #{path} for #{request.path_info}"
      f.write(yield)
    end
  end
  
  # And send out the file that's been written
  last_modified(File.mtime(p))
  etag File.mtime(p).to_i.to_s
  File.read(p)
end