big_band 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/LICENSE +27 -0
  2. data/README.rdoc +303 -0
  3. data/README.rdoc.erb +39 -0
  4. data/Rakefile +129 -0
  5. data/big_band.gemspec +29 -0
  6. data/example/example.rb +13 -0
  7. data/example/views/index.haml +8 -0
  8. data/example/views/layout.haml +2 -0
  9. data/example/views/stylesheets/_base.sass +1 -0
  10. data/example/views/stylesheets/screen.sass +12 -0
  11. data/lib/big_band/advanced_routes.rb +184 -0
  12. data/lib/big_band/basic_extensions.rb +176 -0
  13. data/lib/big_band/compass/big_band.rb +4 -0
  14. data/lib/big_band/compass/stylesheets/_big_band.sass +1 -0
  15. data/lib/big_band/compass/stylesheets/big_band/_blueprint.sass +1 -0
  16. data/lib/big_band/compass/stylesheets/big_band/_utilities.sass +6 -0
  17. data/lib/big_band/compass/stylesheets/big_band/blueprint/_html5.sass +4 -0
  18. data/lib/big_band/compass/stylesheets/big_band/layouts/_inspector.sass +103 -0
  19. data/lib/big_band/compass/stylesheets/big_band/utilities/_border_radius.sass +27 -0
  20. data/lib/big_band/compass/stylesheets/big_band/utilities/_css3_prefix.sass +14 -0
  21. data/lib/big_band/compass/stylesheets/big_band/utilities/_fancy_buttons.sass +62 -0
  22. data/lib/big_band/compass/stylesheets/big_band/utilities/_html5.sass +3 -0
  23. data/lib/big_band/compass.rb +94 -0
  24. data/lib/big_band/files/overlay-button.png +0 -0
  25. data/lib/big_band/integration/bacon.rb +10 -0
  26. data/lib/big_band/integration/monk.rb +26 -0
  27. data/lib/big_band/integration/rake.rb +60 -0
  28. data/lib/big_band/integration/rspec.rb +11 -0
  29. data/lib/big_band/integration/test/spec.rb +2 -0
  30. data/lib/big_band/integration/test/unit.rb +2 -0
  31. data/lib/big_band/integration/test.rb +42 -0
  32. data/lib/big_band/integration/test_spec.rb +8 -0
  33. data/lib/big_band/integration/test_unit.rb +10 -0
  34. data/lib/big_band/integration/yard.rb +104 -0
  35. data/lib/big_band/integration.rb +42 -0
  36. data/lib/big_band/more_helpers.rb +50 -0
  37. data/lib/big_band/more_server/rainbows.rb +13 -0
  38. data/lib/big_band/more_server/unicorn.rb +28 -0
  39. data/lib/big_band/more_server.rb +14 -0
  40. data/lib/big_band/reloader.rb +113 -0
  41. data/lib/big_band/sass.rb +28 -0
  42. data/lib/big_band/version.rb +3 -0
  43. data/lib/big_band/web_inspector.rb +178 -0
  44. data/lib/big_band.rb +239 -0
  45. data/lib/big_bang.rb +6 -0
  46. data/lib/yard-sinatra.rb +2 -0
  47. data/spec/big_band/advanced_routes_spec.rb +70 -0
  48. data/spec/big_band/basic_extensions_spec.rb +39 -0
  49. data/spec/big_band/more_server_spec.rb +7 -0
  50. data/spec/big_band/sass_spec.rb +21 -0
  51. data/spec/spec.opts +5 -0
  52. data/spec/spec_helper.rb +4 -0
  53. data/yard-sinatra.gemspec +24 -0
  54. metadata +167 -0
@@ -0,0 +1,10 @@
1
+ require "big_band/integration/test"
2
+ require "bacon"
3
+
4
+ module BigBand::Integration
5
+ # Some Bacon example and description goes here.
6
+ module Bacon
7
+ ::Bacon::Context.send :include, self
8
+ include BigBand::Integration::Test
9
+ end
10
+ end
@@ -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,2 @@
1
+ require "big_band/integration/test_spec"
2
+ BigBand::Integration::Test::Spec = BigBand::Integration::TestSpec
@@ -0,0 +1,2 @@
1
+ require "big_band/integration/test_unit"
2
+ BigBand::Integration::Test::Unit = BigBand::Integration::TestUnit
@@ -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,8 @@
1
+ require "big_band/integration/test_unit"
2
+
3
+ module BigBand::Integration
4
+ # Some TestSpec example and description goes here.
5
+ module TestSpec
6
+ ::Test::Unit::TestCase.send :include, self
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ require "big_band/integration/test"
2
+ require "test/unit"
3
+
4
+ module BigBand::Integration
5
+ # Some TestUnit example and description goes here.
6
+ module TestUnit
7
+ ::Test::Unit::TestCase.send :include, self
8
+ include BigBand::Integration::Test
9
+ end
10
+ 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
@@ -0,0 +1,3 @@
1
+ require "big_band/integration" unless defined? BigBand
2
+ BigBand::VERSION = "0.2.1"
3
+ BigBand::DATE = "2009-12-28"