big_band 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +27 -0
- data/README.rdoc +303 -0
- data/README.rdoc.erb +39 -0
- data/Rakefile +129 -0
- data/big_band.gemspec +29 -0
- data/example/example.rb +13 -0
- data/example/views/index.haml +8 -0
- data/example/views/layout.haml +2 -0
- data/example/views/stylesheets/_base.sass +1 -0
- data/example/views/stylesheets/screen.sass +12 -0
- data/lib/big_band/advanced_routes.rb +184 -0
- data/lib/big_band/basic_extensions.rb +176 -0
- data/lib/big_band/compass/big_band.rb +4 -0
- data/lib/big_band/compass/stylesheets/_big_band.sass +1 -0
- data/lib/big_band/compass/stylesheets/big_band/_blueprint.sass +1 -0
- data/lib/big_band/compass/stylesheets/big_band/_utilities.sass +6 -0
- data/lib/big_band/compass/stylesheets/big_band/blueprint/_html5.sass +4 -0
- data/lib/big_band/compass/stylesheets/big_band/layouts/_inspector.sass +103 -0
- data/lib/big_band/compass/stylesheets/big_band/utilities/_border_radius.sass +27 -0
- data/lib/big_band/compass/stylesheets/big_band/utilities/_css3_prefix.sass +14 -0
- data/lib/big_band/compass/stylesheets/big_band/utilities/_fancy_buttons.sass +62 -0
- data/lib/big_band/compass/stylesheets/big_band/utilities/_html5.sass +3 -0
- data/lib/big_band/compass.rb +94 -0
- data/lib/big_band/files/overlay-button.png +0 -0
- data/lib/big_band/integration/bacon.rb +10 -0
- data/lib/big_band/integration/monk.rb +26 -0
- data/lib/big_band/integration/rake.rb +60 -0
- data/lib/big_band/integration/rspec.rb +11 -0
- data/lib/big_band/integration/test/spec.rb +2 -0
- data/lib/big_band/integration/test/unit.rb +2 -0
- data/lib/big_band/integration/test.rb +42 -0
- data/lib/big_band/integration/test_spec.rb +8 -0
- data/lib/big_band/integration/test_unit.rb +10 -0
- data/lib/big_band/integration/yard.rb +104 -0
- data/lib/big_band/integration.rb +42 -0
- data/lib/big_band/more_helpers.rb +50 -0
- data/lib/big_band/more_server/rainbows.rb +13 -0
- data/lib/big_band/more_server/unicorn.rb +28 -0
- data/lib/big_band/more_server.rb +14 -0
- data/lib/big_band/reloader.rb +113 -0
- data/lib/big_band/sass.rb +28 -0
- data/lib/big_band/version.rb +3 -0
- data/lib/big_band/web_inspector.rb +178 -0
- data/lib/big_band.rb +239 -0
- data/lib/big_bang.rb +6 -0
- data/lib/yard-sinatra.rb +2 -0
- data/spec/big_band/advanced_routes_spec.rb +70 -0
- data/spec/big_band/basic_extensions_spec.rb +39 -0
- data/spec/big_band/more_server_spec.rb +7 -0
- data/spec/big_band/sass_spec.rb +21 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +4 -0
- data/yard-sinatra.gemspec +24 -0
- metadata +167 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
require "monk"
|
2
|
+
require "big_band/integration"
|
3
|
+
|
4
|
+
module BigBand::Integration
|
5
|
+
# In your Thorfile, place:
|
6
|
+
#
|
7
|
+
# require "big_band/integration/monk"
|
8
|
+
# class Monk < Thor
|
9
|
+
# routes_task :list_routes
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# Now, running 'monk list_routes' in you project directory should
|
13
|
+
# give you a list of all your routes.
|
14
|
+
module Monk
|
15
|
+
def routes_task(name = :routes)
|
16
|
+
desc "#{routes} [FILES=#{GLOBBER.inspect}]", "lists all routes"
|
17
|
+
define_method :routes do |files|
|
18
|
+
BigBand::Integration.each_route(files || GLOBBER) { |v,p| say_status v, p }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Monk < Thor
|
25
|
+
extend BigBand::Integration::Monk
|
26
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require "big_band/integration"
|
2
|
+
require "rake"
|
3
|
+
require "rake/tasklib"
|
4
|
+
|
5
|
+
module BigBand::Integration
|
6
|
+
# In your Rakefile, do the following:
|
7
|
+
#
|
8
|
+
# require "big_band/integration/rake"
|
9
|
+
# include BigBand::Integration::Rake
|
10
|
+
#
|
11
|
+
# RoutesTask.new
|
12
|
+
#
|
13
|
+
# then you can run 'rake routes' from your
|
14
|
+
# project directory and it will list all routes
|
15
|
+
# of your app. Per default it will scan for routes
|
16
|
+
# defined in ruby files in the directories lib, app,
|
17
|
+
# routes, models, views, and controllers (ignoring
|
18
|
+
# non-existant directories, of course). You can change
|
19
|
+
# that behavior by setting +source+ to another pattern:
|
20
|
+
#
|
21
|
+
# RoutesTask.new { |t| t.source = "**/*.rb" }
|
22
|
+
#
|
23
|
+
# However, you may also just pass in a Sinatra app, so it
|
24
|
+
# will not have to scan through the source files:
|
25
|
+
#
|
26
|
+
# require "my_app"
|
27
|
+
# RoutesTask.new { |t| t.source = MyApp }
|
28
|
+
#
|
29
|
+
# Keep in mind that a broken my_app in this case would also make
|
30
|
+
# your Rakefile unusable.
|
31
|
+
#
|
32
|
+
# Also, you may set another name for the task either by setting
|
33
|
+
# the first argument or calling #name=:
|
34
|
+
#
|
35
|
+
# RoutesTask.new(:some_routes) { |t| t.source = SomeApp }
|
36
|
+
# RoutesTask.new do |t|
|
37
|
+
# t.source = AnotherApp
|
38
|
+
# t.name = :other_routes
|
39
|
+
# end
|
40
|
+
module Rake
|
41
|
+
class RoutesTask < ::Rake::TaskLib
|
42
|
+
attr_accessor :source, :name
|
43
|
+
|
44
|
+
def initialize(name = :routes)
|
45
|
+
@name = name
|
46
|
+
@source = BigBand::Integration::GLOBBER
|
47
|
+
yield self if block_given?
|
48
|
+
define
|
49
|
+
end
|
50
|
+
|
51
|
+
def define
|
52
|
+
desc "Lists routes defined in #{source}"
|
53
|
+
task(name) do
|
54
|
+
BigBand::Integration.each_route(source) { |v,p| puts "#{v.ljust 4} #{p}" }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "big_band/integration/test"
|
2
|
+
require "spec"
|
3
|
+
|
4
|
+
module BigBand::Integration
|
5
|
+
# Some RSpec example and description goes here.
|
6
|
+
module RSpec
|
7
|
+
include BigBand::Integration::Test
|
8
|
+
::Spec::Runner.configure { |c| c.include self }
|
9
|
+
end
|
10
|
+
Rspec = RSpec
|
11
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "sinatra"
|
2
|
+
Sinatra::Base.set :environment, :test
|
3
|
+
|
4
|
+
require "big_band"
|
5
|
+
require "big_band/integration"
|
6
|
+
|
7
|
+
require "rack/test"
|
8
|
+
#require "webrat"
|
9
|
+
#Webrat.configure { |config| config.mode = :sinatra }
|
10
|
+
|
11
|
+
module BigBand::Integration
|
12
|
+
# This encapsulates general test helpers. See Bacon, RSpec, Test::Spec and Test::Unit for examples.
|
13
|
+
module Test
|
14
|
+
|
15
|
+
#include Webrat::Methods
|
16
|
+
include Rack::Test::Methods
|
17
|
+
|
18
|
+
attr_writer :app
|
19
|
+
def app(*options, &block)
|
20
|
+
unless block.nil? and options.empty?
|
21
|
+
superclass = options.first if options.size == 1 and options.first.is_a? Class
|
22
|
+
superclass ||= BigBand(*options)
|
23
|
+
@app = Class.new(superclass, &block)
|
24
|
+
inspection = "app"
|
25
|
+
inspection << "(" << options.map { |o| o.inspect }.join(", ") << ")" unless options.empty?
|
26
|
+
inspection << " { ... }" if block
|
27
|
+
@app.class_eval "def self.inspect; #{inspection.inspect}; end"
|
28
|
+
end
|
29
|
+
@app || BigBand.applications.last || Sinatra::Application
|
30
|
+
end
|
31
|
+
|
32
|
+
def define_route(verb, *args, &block)
|
33
|
+
app.send(verb, *args, &block)
|
34
|
+
end
|
35
|
+
|
36
|
+
def browse_route(verb, *args, &block)
|
37
|
+
send(verb, *args, &block)
|
38
|
+
last_response
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require "big_band/integration"
|
2
|
+
require "yard"
|
3
|
+
|
4
|
+
module BigBand::Integration
|
5
|
+
# Some YARD example and description goes here.
|
6
|
+
module YARD
|
7
|
+
|
8
|
+
module CodeObjects
|
9
|
+
class RouteObject < ::YARD::CodeObjects::MethodObject
|
10
|
+
|
11
|
+
ISEP = ::YARD::CodeObjects::ISEP
|
12
|
+
|
13
|
+
attr_accessor :http_verb, :http_path, :real_name
|
14
|
+
def name(prefix = false)
|
15
|
+
return super unless show_real_name?
|
16
|
+
prefix ? (sep == ISEP ? "#{sep}#{real_name}" : real_name.to_s) : real_name.to_sym
|
17
|
+
end
|
18
|
+
|
19
|
+
def show_real_name?
|
20
|
+
real_name and caller[1] =~ /`signature'/
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module Handlers
|
27
|
+
|
28
|
+
# Displays Sinatra routes in YARD documentation.
|
29
|
+
# Can also be used to parse routes from files without executing those files.
|
30
|
+
module Sinatra
|
31
|
+
|
32
|
+
# Logic both handlers have in common.
|
33
|
+
module AbstractRouteHandler
|
34
|
+
|
35
|
+
def self.routes
|
36
|
+
@routes ||= []
|
37
|
+
end
|
38
|
+
|
39
|
+
def process
|
40
|
+
path = http_path
|
41
|
+
path = $1 if path =~ /^"(.*)"$/
|
42
|
+
register_route(http_verb, path)
|
43
|
+
register_route('HEAD', path) if http_verb == 'GET'
|
44
|
+
end
|
45
|
+
|
46
|
+
def register_route(verb, path, doc = nil)
|
47
|
+
# HACK: Removing some illegal letters.
|
48
|
+
method_name = "" << verb << "_" << path.gsub(/[^\w_]/, "_")
|
49
|
+
real_name = "" << verb << " " << path
|
50
|
+
route = register CodeObjects::RouteObject.new(namespace, method_name, :instance) do |o|
|
51
|
+
o.visibility = "public"
|
52
|
+
o.source = statement.source
|
53
|
+
o.signature = real_name
|
54
|
+
o.explicit = true
|
55
|
+
o.scope = scope
|
56
|
+
o.docstring = statement.comments
|
57
|
+
o.http_verb = verb
|
58
|
+
o.http_path = path
|
59
|
+
o.real_name = real_name
|
60
|
+
o.add_file(parser.file, statement.line)
|
61
|
+
end
|
62
|
+
AbstractRouteHandler.routes << route
|
63
|
+
yield(route) if block_given?
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
# Route handler for YARD's source parser.
|
69
|
+
class RouteHandler < ::YARD::Handlers::Ruby::Base
|
70
|
+
include AbstractRouteHandler
|
71
|
+
handles method_call(:get)
|
72
|
+
handles method_call(:post)
|
73
|
+
handles method_call(:put)
|
74
|
+
handles method_call(:delete)
|
75
|
+
handles method_call(:head)
|
76
|
+
def http_verb
|
77
|
+
statement.method_name(true).to_s.upcase
|
78
|
+
end
|
79
|
+
def http_path
|
80
|
+
statement.parameters.first.source
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Route handler for YARD's legacy parser.
|
85
|
+
module Legacy
|
86
|
+
class RouteHandler < ::YARD::Handlers::Ruby::Legacy::Base
|
87
|
+
include AbstractRouteHandler
|
88
|
+
handles /\A(get|post|put|delete|head)[\s\(].*/m
|
89
|
+
def http_verb
|
90
|
+
statement.tokens.first.text.upcase
|
91
|
+
end
|
92
|
+
def http_path
|
93
|
+
statement.tokens[2].text
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
Yard = YARD
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
unless defined? Sinatra::Base
|
2
|
+
module Sinatra # :nodoc:
|
3
|
+
class Base # :nodoc:
|
4
|
+
end
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class BigBand < Sinatra::Base
|
9
|
+
module Integration
|
10
|
+
GLOBBER = "{lib/**,app/**,routes/**,models/**,views/**,controllers/**,.}/*.rb"
|
11
|
+
|
12
|
+
def self.routes_for(source)
|
13
|
+
case source
|
14
|
+
when Class
|
15
|
+
source.routes
|
16
|
+
when String
|
17
|
+
require "big_band/integration/yard"
|
18
|
+
::YARD::Registry.load(Dir[source], true)
|
19
|
+
YARD::Handlers::Sinatra::AbstractRouteHandler.routes.inject({}) do |routes, route_object|
|
20
|
+
routes[route_object.http_verb] ||= []
|
21
|
+
routes[route_object.http_verb] << route_object.http_path
|
22
|
+
routes
|
23
|
+
end
|
24
|
+
else
|
25
|
+
raise ArgumentError, "cannot retrieve routes for #{source.inspect}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.each_route(source)
|
30
|
+
routes_for(source).each do |verb, routes|
|
31
|
+
routes.each do |route|
|
32
|
+
path = route.path if route.respond_to? :path
|
33
|
+
path ||= route.pattern if route.respond_to? :pattern
|
34
|
+
path ||= route[0] if route.is_a? Array
|
35
|
+
path ||= route
|
36
|
+
yield(verb, path)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "haml"
|
2
|
+
require "big_band/integration" unless defined? BigBand # so this is usable without sinatra
|
3
|
+
|
4
|
+
class BigBand < Sinatra::Base
|
5
|
+
|
6
|
+
# Adds more helper methods (more docs coming soon).
|
7
|
+
module MoreHelpers
|
8
|
+
|
9
|
+
module InstanceMethods
|
10
|
+
include Haml::Helpers
|
11
|
+
|
12
|
+
def content_for(name, &block)
|
13
|
+
name = name.to_s
|
14
|
+
@content_for ||= Hash.new {|h,k| h[k] = [] }
|
15
|
+
@content_for[name] << block if block
|
16
|
+
@content_for[name]
|
17
|
+
end
|
18
|
+
|
19
|
+
def yield_content(name, *args)
|
20
|
+
haml_helper do
|
21
|
+
content_for(name).each do |block|
|
22
|
+
result = block.call(*args)
|
23
|
+
haml_concat result unless block_is_haml? block
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_content(name, *args)
|
29
|
+
non_haml { yield_content(name, *args) }
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# Will make use of capture_haml depending on whether it is called from
|
35
|
+
# within Haml code or not. Thus helpers may be shared between Haml and
|
36
|
+
# others (like ERB), but still enjoy all the fancy Haml::Helpers tools.
|
37
|
+
def haml_helper(&block)
|
38
|
+
return capture_haml(&block) unless is_haml?
|
39
|
+
yield
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.registered(klass)
|
45
|
+
# Just in case #helpers does more magic some day.
|
46
|
+
klass.helpers InstanceMethods
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "big_band/more_server/unicorn"
|
2
|
+
require "rainbows"
|
3
|
+
|
4
|
+
class BigBand < Sinatra::Base
|
5
|
+
module MoreServer
|
6
|
+
# Rack Handler to use Rainbows for Sinatra::Base.run!
|
7
|
+
module Rainbows
|
8
|
+
def self.run(app, options = {})
|
9
|
+
BigBand::MoreServer::Unicorn.run app, options.merge(:Backend => ::Rainbows)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "sinatra/base"
|
2
|
+
require "unicorn"
|
3
|
+
require "rack/content_length"
|
4
|
+
require "rack/chunked"
|
5
|
+
|
6
|
+
class BigBand < Sinatra::Base
|
7
|
+
module MoreServer
|
8
|
+
# Rack Handler to use Unicorn for Sinatra::Base.run!
|
9
|
+
module Unicorn
|
10
|
+
def self.run(app, options={})
|
11
|
+
app = Rack::Builder.new do
|
12
|
+
# TODO: env dependend stuff.
|
13
|
+
use Rack::CommonLogger, $stderr
|
14
|
+
use Rack::ShowExceptions
|
15
|
+
use Rack::Lint
|
16
|
+
run app
|
17
|
+
end.to_app
|
18
|
+
options[:Backend] ||= ::Unicorn
|
19
|
+
options[:Host] ||= ::Unicorn::Const::DEFAULT_HOST
|
20
|
+
options[:Port] ||= ::Unicorn::Const::DEFAULT_PORT
|
21
|
+
options[:listeners] = ["#{options.delete :Host}:#{options.delete :Port}"]
|
22
|
+
server = options.delete(:Backend)::HttpServer.new app, options
|
23
|
+
yield server if block_given?
|
24
|
+
server.start.join
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "sinatra/base"
|
2
|
+
|
3
|
+
class BigBand < Sinatra::Base
|
4
|
+
# Adds more servers to Sinatra::Base#run! (currently unicorn and rainbows).
|
5
|
+
module MoreServer
|
6
|
+
autoload :Unicorn, "big_band/more_server/unicorn"
|
7
|
+
autoload :Rainbows, "big_band/more_server/rainbows"
|
8
|
+
def self.registered(klass)
|
9
|
+
Rack::Handler.register "unicorn", "BigBand::MoreServer::Unicorn"
|
10
|
+
Rack::Handler.register "rainbows", "BigBand::MoreServer::Rainbows"
|
11
|
+
klass.server.unshift "rainbows", "unicorn"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require "sinatra/base"
|
2
|
+
require "big_band/basic_extensions"
|
3
|
+
|
4
|
+
class BigBand < Sinatra::Base
|
5
|
+
|
6
|
+
# Advanced reloader for sinatra. Reloads only files that have changed and automatically
|
7
|
+
# detects orphaned routes that have to be removed. Files defining routes will be added
|
8
|
+
# to the reload list per default. Avoid reloading with dont_reload. Add other files to
|
9
|
+
# the reload list with also_reload.
|
10
|
+
#
|
11
|
+
# Usage:
|
12
|
+
#
|
13
|
+
# require "big_band"
|
14
|
+
# class Foo < Sinatra::Base
|
15
|
+
# configure(:development) do
|
16
|
+
# register BigBand::Reloader
|
17
|
+
# also_reload "app/models/*.rb"
|
18
|
+
# dont_reload "lib/**/*.rb"
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# Per default this will only be acitvated in development mode.
|
23
|
+
module Reloader
|
24
|
+
|
25
|
+
class FileWatcher < Array
|
26
|
+
|
27
|
+
attr_reader :file, :mtime
|
28
|
+
|
29
|
+
extend Enumerable
|
30
|
+
@map ||= {}
|
31
|
+
|
32
|
+
def self.register(route)
|
33
|
+
new(route.file) << route if route.file?
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.new(file)
|
37
|
+
@map[file.expand_path] ||= super(file)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.each(&block)
|
41
|
+
@map.values.each(&block)
|
42
|
+
end
|
43
|
+
|
44
|
+
def initialize(file)
|
45
|
+
@reload = true
|
46
|
+
@file, @mtime = file, File.mtime(file)
|
47
|
+
super()
|
48
|
+
end
|
49
|
+
|
50
|
+
def changed?
|
51
|
+
@mtime != File.mtime(file)
|
52
|
+
end
|
53
|
+
|
54
|
+
def dont_reload!(dont = true)
|
55
|
+
@reload = false
|
56
|
+
end
|
57
|
+
|
58
|
+
def reload?
|
59
|
+
@reload and changed?
|
60
|
+
end
|
61
|
+
|
62
|
+
def reload
|
63
|
+
reload! if reload?
|
64
|
+
end
|
65
|
+
|
66
|
+
def reload!
|
67
|
+
puts "reloading #{file}"
|
68
|
+
each { |route| route.deactivate }
|
69
|
+
$LOAD_PATH.delete file
|
70
|
+
$LOAD_PATH.delete file.expand_path
|
71
|
+
clear
|
72
|
+
require file
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
module ClassMethods
|
78
|
+
|
79
|
+
def dont_reload(*files)
|
80
|
+
files.flatten.each do |file|
|
81
|
+
FileWatcher.new(file).dont_reload!
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def also_relaod(*files)
|
86
|
+
files.flatten.each do |file|
|
87
|
+
FileWatcher.new(file).dont_reload! false
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.registered(klass)
|
93
|
+
klass.register AdvancedRoutes
|
94
|
+
klass.extend ClassMethods
|
95
|
+
klass.each_route { |route| advanced_route_added(route) }
|
96
|
+
klass.before { Reloader.reload_routes }
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.advanced_route_added(route)
|
100
|
+
FileWatcher.register(route)
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.thread_safe?
|
104
|
+
Thread and Thread.list.size > 1 and Thread.respond_to? :exclusive
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.reload_routes(thread_safe = true)
|
108
|
+
return Thread.exclusive { reload_routes(false) } if thread_safe and thread_safe?
|
109
|
+
FileWatcher.each { |file| file.reload }
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "sass"
|
2
|
+
require "big_band/integration" unless defined? BigBand # so this is usable without sinatra
|
3
|
+
|
4
|
+
class BigBand < Sinatra::Base
|
5
|
+
|
6
|
+
# BigBand::Sass extends SassScript with more functions like min or max.
|
7
|
+
#
|
8
|
+
# Example:
|
9
|
+
# .someClass
|
10
|
+
# width = max(!default_width - 10px, 200px)
|
11
|
+
#
|
12
|
+
# This can be used without BigBand or even Sinatra.
|
13
|
+
module Sass
|
14
|
+
module Functions
|
15
|
+
::Sass::Script::Functions.send :include, self
|
16
|
+
|
17
|
+
def min(*args)
|
18
|
+
args.min { |a, b| a.value <=> b.value }
|
19
|
+
end
|
20
|
+
|
21
|
+
def max(*args)
|
22
|
+
args.max { |a, b| a.value <=> b.value }
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|