Merge branch 'master' into edge
* master: [Blueprint] Add mixins for +prepend-top and +append-bottom and corresponding grid classes when generating the css grid classes. Use FSSM by Travis Tilley to monitor for filesystem changes. On mac this will use filesystem events instead of polling. Fixes an infinite looping issue when compilation errors occur.
This commit is contained in:
commit
3456f993d4
@ -66,6 +66,10 @@
|
||||
@for !n from 1 through !blueprint_grid_columns
|
||||
.push-#{!n}
|
||||
+push-margins(!n)
|
||||
.prepend-top
|
||||
+prepend-top
|
||||
.append-bottom
|
||||
+append-bottom
|
||||
|
||||
|
||||
// Columns
|
||||
@ -111,6 +115,12 @@
|
||||
=prepend(!n)
|
||||
:padding-left = (!blueprint_grid_outer_width) * !n
|
||||
|
||||
=append-bottom(!amount = 1.5em)
|
||||
:margin-bottom= !amount
|
||||
|
||||
=prepend-top(!amount = 1.5em)
|
||||
:margin-top= !amount
|
||||
|
||||
=pull-base
|
||||
+float-left
|
||||
:position relative
|
||||
|
@ -14,17 +14,30 @@ module Compass
|
||||
puts ""
|
||||
exit 0
|
||||
end
|
||||
|
||||
recompile
|
||||
|
||||
puts ">>> Compass is watching for changes. Press Ctrl-C to Stop."
|
||||
loop do
|
||||
# TODO: Make this efficient by using filesystem monitoring.
|
||||
compiler = new_compiler_instance(:quiet => true)
|
||||
remove_obsolete_css(compiler)
|
||||
recompile(compiler)
|
||||
sleep 1
|
||||
|
||||
require File.join(Compass.lib_directory, 'vendor', 'fssm')
|
||||
|
||||
FSSM.monitor do |monitor|
|
||||
Compass.configuration.sass_load_paths.each do |load_path|
|
||||
monitor.path load_path do |path|
|
||||
path.glob '**/*.sass'
|
||||
|
||||
path.update &method(:recompile)
|
||||
path.delete {|base, relative| remove_obsolete_css(base,relative); recompile(base, relative)}
|
||||
path.create &method(:recompile)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def remove_obsolete_css(compiler)
|
||||
def remove_obsolete_css(base = nil, relative = nil)
|
||||
compiler = new_compiler_instance(:quiet => true)
|
||||
sass_files = compiler.sass_files
|
||||
deleted_sass_files = (last_sass_files || []) - sass_files
|
||||
deleted_sass_files.each do |deleted_sass_file|
|
||||
@ -34,7 +47,8 @@ module Compass
|
||||
self.last_sass_files = sass_files
|
||||
end
|
||||
|
||||
def recompile(compiler)
|
||||
def recompile(base = nil, relative = nil)
|
||||
compiler = new_compiler_instance(:quiet => true)
|
||||
if file = compiler.out_of_date?
|
||||
begin
|
||||
puts ">>> Change detected to: #{file}"
|
||||
|
30
lib/vendor/fssm.rb
vendored
Normal file
30
lib/vendor/fssm.rb
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
module FSSM
|
||||
FileNotFoundError = Class.new(StandardError)
|
||||
CallbackError = Class.new(StandardError)
|
||||
|
||||
class << self
|
||||
def monitor(*args, &block)
|
||||
monitor = FSSM::Monitor.new
|
||||
context = args.empty? ? monitor : monitor.path(*args)
|
||||
if block && block.arity == 0
|
||||
context.instance_eval(&block)
|
||||
elsif block && block.arity == 1
|
||||
block.call(context)
|
||||
end
|
||||
monitor.run
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
$:.unshift(File.dirname(__FILE__))
|
||||
require 'pathname'
|
||||
require 'fssm/ext'
|
||||
require 'fssm/support'
|
||||
require 'fssm/path'
|
||||
require 'fssm/state'
|
||||
require 'fssm/monitor'
|
||||
|
||||
require "fssm/backends/#{FSSM::Support.backend.downcase}"
|
||||
FSSM::Backends::Default = FSSM::Backends.const_get(FSSM::Support.backend)
|
||||
$:.shift
|
||||
|
78
lib/vendor/fssm/backends/fsevents.rb
vendored
Normal file
78
lib/vendor/fssm/backends/fsevents.rb
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
module FSSM::Backends
|
||||
class FSEvents
|
||||
def initialize(options={})
|
||||
@streams = []
|
||||
@handlers = {}
|
||||
@allocator = options[:allocator] || OSX::KCFAllocatorDefault
|
||||
@context = options[:context] || nil
|
||||
@since = options[:since] || OSX::KFSEventStreamEventIdSinceNow
|
||||
@latency = options[:latency] || 0.0
|
||||
@flags = options[:flags] || 0
|
||||
end
|
||||
|
||||
def add_path(path, preload=true)
|
||||
@handlers["#{path}"] = FSSM::State.new(path, preload)
|
||||
|
||||
cb = lambda do |stream, context, number, paths, flags, ids|
|
||||
paths.regard_as('*')
|
||||
watched = OSX.FSEventStreamCopyPathsBeingWatched(stream).first
|
||||
@handlers["#{watched}"].refresh
|
||||
# TODO: support this level of granularity
|
||||
# number.times do |n|
|
||||
# @handlers["#{watched}"].refresh_path(paths[n])
|
||||
# end
|
||||
end
|
||||
|
||||
@streams << create_stream(cb, "#{path}")
|
||||
end
|
||||
|
||||
def run
|
||||
@streams.each do |stream|
|
||||
schedule_stream(stream)
|
||||
start_stream(stream)
|
||||
end
|
||||
|
||||
begin
|
||||
OSX.CFRunLoopRun
|
||||
rescue Interrupt
|
||||
@streams.each do |stream|
|
||||
stop_stream(stream)
|
||||
invalidate_stream(stream)
|
||||
release_stream(stream)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_stream(callback, paths)
|
||||
paths = [paths] unless paths.is_a?(Array)
|
||||
OSX.FSEventStreamCreate(@allocator, callback, @context, paths, @since, @latency, @flags)
|
||||
end
|
||||
|
||||
def schedule_stream(stream, options={})
|
||||
run_loop = options[:run_loop] || OSX.CFRunLoopGetCurrent
|
||||
loop_mode = options[:loop_mode] || OSX::KCFRunLoopDefaultMode
|
||||
|
||||
OSX.FSEventStreamScheduleWithRunLoop(stream, run_loop, loop_mode)
|
||||
end
|
||||
|
||||
def start_stream(stream)
|
||||
OSX.FSEventStreamStart(stream)
|
||||
end
|
||||
|
||||
def stop_stream(stream)
|
||||
OSX.FSEventStreamStop(stream)
|
||||
end
|
||||
|
||||
def invalidate_stream(stream)
|
||||
OSX.FSEventStreamInvalidate(stream)
|
||||
end
|
||||
|
||||
def release_stream(stream)
|
||||
OSX.FSEventStreamRelease(stream)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
24
lib/vendor/fssm/backends/polling.rb
vendored
Normal file
24
lib/vendor/fssm/backends/polling.rb
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
module FSSM::Backends
|
||||
class Polling
|
||||
def initialize(options={})
|
||||
@handlers = []
|
||||
@latency = options[:latency] || 1
|
||||
end
|
||||
|
||||
def add_path(path, preload=true)
|
||||
@handlers << FSSM::State.new(path, preload)
|
||||
end
|
||||
|
||||
def run
|
||||
begin
|
||||
loop do
|
||||
start = Time.now.to_f
|
||||
@handlers.each {|handler| handler.refresh}
|
||||
nap_time = @latency - (Time.now.to_f - start)
|
||||
sleep nap_time if nap_time > 0
|
||||
end
|
||||
rescue Interrupt
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
7
lib/vendor/fssm/ext.rb
vendored
Normal file
7
lib/vendor/fssm/ext.rb
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
class Pathname
|
||||
class << self
|
||||
def for(path)
|
||||
path.is_a?(Pathname) ? path : new(path)
|
||||
end
|
||||
end
|
||||
end
|
21
lib/vendor/fssm/monitor.rb
vendored
Normal file
21
lib/vendor/fssm/monitor.rb
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
class FSSM::Monitor
|
||||
def initialize(options={})
|
||||
@options = options
|
||||
@backend = FSSM::Backends::Default.new
|
||||
end
|
||||
|
||||
def path(*args, &block)
|
||||
path = FSSM::Path.new(*args)
|
||||
if block && block.arity == 0
|
||||
path.instance_eval(&block)
|
||||
elsif block && block.arity == 1
|
||||
block.call(path)
|
||||
end
|
||||
@backend.add_path(path)
|
||||
path
|
||||
end
|
||||
|
||||
def run
|
||||
@backend.run
|
||||
end
|
||||
end
|
88
lib/vendor/fssm/path.rb
vendored
Normal file
88
lib/vendor/fssm/path.rb
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
class FSSM::Path
|
||||
def initialize(path=nil, glob=nil, &block)
|
||||
set_path(path || '.')
|
||||
set_glob(glob || '**/*')
|
||||
init_callbacks
|
||||
if block && block.arity == 0
|
||||
self.instance_eval(&block)
|
||||
elsif block && block.arity == 1
|
||||
block.call(self)
|
||||
end
|
||||
end
|
||||
|
||||
def to_s
|
||||
@path.to_s
|
||||
end
|
||||
|
||||
def to_pathname
|
||||
@path
|
||||
end
|
||||
|
||||
def glob(value=nil)
|
||||
return @glob if value.nil?
|
||||
set_glob(value)
|
||||
end
|
||||
|
||||
def create(callback_or_path=nil, &block)
|
||||
callback_action(:create, (block_given? ? block : callback_or_path))
|
||||
end
|
||||
|
||||
def update(callback_or_path=nil, &block)
|
||||
callback_action(:update, (block_given? ? block : callback_or_path))
|
||||
end
|
||||
|
||||
def delete(callback_or_path=nil, &block)
|
||||
callback_action(:delete, (block_given? ? block : callback_or_path))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def init_callbacks
|
||||
do_nothing = lambda {|base, relative|}
|
||||
@callbacks = Hash.new(do_nothing)
|
||||
end
|
||||
|
||||
def callback_action(type, arg=nil)
|
||||
if arg.is_a?(Proc)
|
||||
set_callback(type, arg)
|
||||
elsif arg.nil?
|
||||
get_callback(type)
|
||||
else
|
||||
run_callback(type, arg)
|
||||
end
|
||||
end
|
||||
|
||||
def set_callback(type, arg)
|
||||
raise ArgumentError, "Proc expected" unless arg.is_a?(Proc)
|
||||
@callbacks[type] = arg
|
||||
end
|
||||
|
||||
def get_callback(type)
|
||||
@callbacks[type]
|
||||
end
|
||||
|
||||
def run_callback(type, arg)
|
||||
base, relative = split_path(arg)
|
||||
|
||||
begin
|
||||
@callbacks[type].call(base, relative)
|
||||
rescue Exception => e
|
||||
raise FSSM::CallbackError, "#{type} - #{base.join(relative)}: #{e.message}", e.backtrace
|
||||
end
|
||||
end
|
||||
|
||||
def split_path(path)
|
||||
path = Pathname.for(path)
|
||||
[@path, (path.relative? ? path : path.relative_path_from(@path))]
|
||||
end
|
||||
|
||||
def set_path(path)
|
||||
path = Pathname.for(path)
|
||||
raise FSSM::FileNotFoundError, "#{path}" unless path.exist?
|
||||
@path = path.realpath
|
||||
end
|
||||
|
||||
def set_glob(glob)
|
||||
@glob = glob.is_a?(Array) ? glob : [glob]
|
||||
end
|
||||
end
|
46
lib/vendor/fssm/state.rb
vendored
Normal file
46
lib/vendor/fssm/state.rb
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
class FSSM::State
|
||||
def initialize(path, preload=true)
|
||||
@path = path
|
||||
@snapshot = {}
|
||||
snapshot if preload
|
||||
end
|
||||
|
||||
def refresh
|
||||
previous = @snapshot
|
||||
current = snapshot
|
||||
|
||||
deleted(previous, current)
|
||||
created(previous, current)
|
||||
modified(previous, current)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def created(previous, current)
|
||||
(current.keys - previous.keys).each {|created| @path.create(created)}
|
||||
end
|
||||
|
||||
def deleted(previous, current)
|
||||
(previous.keys - current.keys).each {|deleted| @path.delete(deleted)}
|
||||
end
|
||||
|
||||
def modified(previous, current)
|
||||
(current.keys & previous.keys).each do |file|
|
||||
@path.update(file) if (current[file] <=> previous[file]) != 0
|
||||
end
|
||||
end
|
||||
|
||||
def snapshot
|
||||
snap = {}
|
||||
@path.glob.each {|glob| add_glob(snap, glob)}
|
||||
@snapshot = snap
|
||||
end
|
||||
|
||||
def add_glob(snap, glob)
|
||||
Pathname.glob(@path.to_pathname.join(glob)).each do |fn|
|
||||
next unless fn.file?
|
||||
snap["#{fn}"] = fn.mtime
|
||||
end
|
||||
end
|
||||
|
||||
end
|
26
lib/vendor/fssm/support.rb
vendored
Normal file
26
lib/vendor/fssm/support.rb
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
module FSSM::Support
|
||||
class << self
|
||||
# def backend
|
||||
# (mac? && carbon_core?) ? 'FSEvents' : 'Polling'
|
||||
# end
|
||||
|
||||
def backend
|
||||
'Polling'
|
||||
end
|
||||
|
||||
def mac?
|
||||
@@mac ||= RUBY_PLATFORM =~ /darwin/i
|
||||
end
|
||||
|
||||
def carbon_core?
|
||||
@@carbon_core ||= begin
|
||||
require 'osx/foundation'
|
||||
OSX.require_framework '/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework'
|
||||
true
|
||||
rescue LoadError
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user