pancake 0.1.29 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/README.textile +0 -4
  2. data/Rakefile +1 -32
  3. data/TODO.textile +19 -0
  4. data/bin/pancake-gen +1 -0
  5. data/lib/pancake.rb +26 -39
  6. data/lib/pancake/bootloaders.rb +2 -2
  7. data/lib/pancake/configuration.rb +1 -1
  8. data/lib/pancake/core_ext/class.rb +3 -3
  9. data/lib/pancake/errors.rb +6 -8
  10. data/lib/pancake/generators.rb +1 -0
  11. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/config/environments/development.rb.tt +0 -3
  12. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/config/environments/production.rb.tt +0 -3
  13. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/config/environments/staging.rb.tt +0 -3
  14. data/lib/pancake/hooks/inheritable_inner_classes.rb +9 -10
  15. data/lib/pancake/hooks/on_inherit.rb +7 -7
  16. data/lib/pancake/logger.rb +1 -14
  17. data/lib/pancake/master.rb +7 -45
  18. data/lib/pancake/middleware.rb +11 -64
  19. data/lib/pancake/mixins/publish.rb +20 -20
  20. data/lib/pancake/mixins/render.rb +59 -69
  21. data/lib/pancake/mixins/render/template.rb +1 -1
  22. data/lib/pancake/mixins/render/view_context.rb +143 -7
  23. data/lib/pancake/mixins/request_helper.rb +38 -1
  24. data/lib/pancake/mixins/stack_helper.rb +2 -2
  25. data/lib/pancake/paths.rb +1 -1
  26. data/lib/pancake/router.rb +10 -2
  27. data/lib/pancake/stack/bootloader.rb +12 -1
  28. data/lib/pancake/stack/router.rb +2 -1
  29. data/lib/pancake/stack/stack.rb +60 -2
  30. data/lib/pancake/stacks/short/controller.rb +58 -3
  31. data/lib/pancake/stacks/short/default/views/base.html.haml +1 -1
  32. data/lib/pancake/stacks/short/default/views/error.html.haml +12 -0
  33. data/lib/pancake/stacks/short/stack.rb +1 -0
  34. data/spec/pancake/fixtures/render_templates/alternate.foo_env.html.haml +1 -0
  35. data/spec/pancake/fixtures/render_templates/alternate.html.haml +1 -0
  36. data/spec/pancake/fixtures/render_templates/view_context/capture_erb.erb +1 -1
  37. data/spec/pancake/fixtures/render_templates/view_context/capture_haml.haml +1 -1
  38. data/spec/pancake/fixtures/render_templates/view_context/concat_erb.erb +1 -1
  39. data/spec/pancake/fixtures/render_templates/view_context/concat_haml.haml +2 -1
  40. data/spec/pancake/middleware_spec.rb +4 -26
  41. data/spec/pancake/mixins/render/view_context_spec.rb +15 -23
  42. data/spec/pancake/mixins/render_spec.rb +54 -0
  43. data/spec/pancake/pancake_spec.rb +0 -22
  44. data/spec/spec.opts +2 -0
  45. data/spec/spec_helper.rb +1 -0
  46. metadata +193 -108
  47. data/TODO +0 -7
  48. data/bin/jeweler +0 -19
  49. data/lib/pancake/mixins/render/render.rb +0 -197
@@ -78,10 +78,6 @@ end</code></pre>
78
78
 
79
79
  A stack doesn't have to mount other stacks. Pancake stacks are full applications in their own right and can be used standalone as Rack endpoints, or as middleware.
80
80
 
81
- Rails 3 is shipping with a pluggable router which can be the awesome "Usher":http://github.com/joshbuddy/usher router. If you use Usher in your Rails app, you'll be able to mount Pancake stacks directly. For now, you can mount them as Metals.
82
-
83
- TODO: Demonstrate in a gist mounting pancake in a rails application
84
-
85
81
  All stacks are namespaced. Pancake makes heavy use of namespacing to help construct applications concisely.
86
82
 
87
83
  h2. Middleware In Stacks
data/Rakefile CHANGED
@@ -1,35 +1,7 @@
1
1
  require 'rubygems'
2
2
  require 'rake'
3
-
4
- begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gem|
7
- gem.name = "pancake"
8
- gem.summary = %Q{Eat Pancake Stacks for Breakfast}
9
- gem.description = %Q{Eat Pancake Stacks for Breakfast}
10
- gem.email = "has.sox@gmail.com"
11
- gem.homepage = "http://github.com/hassox/pancake"
12
- gem.authors = ["Daniel Neighman"]
13
- gem.add_development_dependency "rspec"
14
- gem.add_dependency "usher", ">=0.6.4"
15
- gem.add_development_dependency "extlib"
16
- gem.add_development_dependency "thor"
17
- gem.add_dependency "rack"
18
- gem.add_dependency "tilt", ">=0.3"
19
- gem.add_dependency "hashie", ">=0.1.4"
20
- gem.add_dependency "rack-accept-media-types"
21
- gem.require_path = 'lib'
22
- gem.autorequire = 'pancake'
23
- gem.bindir = "bin"
24
- gem.executables = %w( pancake-gen )
25
- gem.files = %w(LICENSE README.textile Rakefile TODO) + Dir.glob("{lib,spec,bin}/**/{*,.[a-z]*}")
26
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
27
- end
28
- rescue LoadError
29
- puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
30
- end
31
-
32
3
  require 'spec/rake/spectask'
4
+
33
5
  Spec::Rake::SpecTask.new(:spec) do |spec|
34
6
  spec.libs << 'lib' << 'spec'
35
7
  spec.spec_opts = %w(--format progress --color)
@@ -41,9 +13,6 @@ Spec::Rake::SpecTask.new(:rcov) do |spec|
41
13
  spec.pattern = 'spec/**/*_spec.rb'
42
14
  spec.rcov = true
43
15
  end
44
-
45
- task :spec => :check_dependencies
46
-
47
16
  task :default => :spec
48
17
 
49
18
  require 'rake/rdoctask'
@@ -0,0 +1,19 @@
1
+ h1. TODO
2
+
3
+ * Port to active support (minimal) & remove extlib
4
+ * Simplify middleware implementation to use TSort
5
+ * Incorporate url_mount (or simliar) into the router for open route mounting
6
+ * Add before / after filters to short stack
7
+ * Provide a streamlined way to specify middleware in an application
8
+ * Create a syrup gem that configures some basic middlewares
9
+ ** Provide a way to turn middleware on and off
10
+ ** Possible inclusions:
11
+ *** Wrapt
12
+ *** Compass
13
+ *** ESI
14
+ * Remove automatic asset path namespacing
15
+ * Reduce complexity of bootloaders
16
+ * Proivde easy to use hooks in the bootloaders
17
+ * Add a to_s method on the configuration so that configuation may be easily interrogated
18
+ * Add an example into the generated applications showing how to add mime types
19
+ * Error handling in stacks needs improvement
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'rubygems'
3
3
  require 'thor'
4
+ require 'thor/group'
4
5
  require 'thor/runner'
5
6
  require 'pancake/generators'
6
7
 
@@ -1,67 +1,54 @@
1
1
  require 'rubygems'
2
2
  require 'hashie'
3
- require 'extlib/class'
4
- require 'extlib/boolean'
5
- require 'extlib/module'
6
- require 'extlib/nil'
7
- require 'extlib/numeric'
8
- require 'extlib/object'
9
- require 'extlib/symbol'
10
- require 'extlib/blank'
11
- require "extlib/dictionary"
12
- require 'extlib/logger'
13
- require 'extlib/mash'
14
- require 'extlib/hash'
3
+ require 'active_support/core_ext/class'
4
+ require 'active_support/inflector'
5
+ require 'active_support/core_ext/string/inflections'
6
+ require 'active_support/ordered_hash'
15
7
  require 'usher'
16
8
  require 'usher/interface/rack'
17
9
  require 'tilt'
18
10
 
19
11
  module Pancake
20
- autoload :Logger, "pancake/logger"
21
- autoload :Constants, "pancake/constants"
22
- autoload :Console, "pancake/console"
12
+ autoload :Logger, "pancake/logger"
13
+ autoload :Constants, "pancake/constants"
14
+ autoload :Console, "pancake/console"
15
+ autoload :Paths, "pancake/paths"
16
+ autoload :Configuration, "pancake/configuration"
17
+ autoload :BootLoaderMixin, "pancake/bootloaders"
18
+ autoload :MimeTypes, "pancake/mime_types"
19
+ autoload :Middleware, "pancake/middleware"
20
+ autoload :Router, "pancake/router"
21
+ autoload :Errors, "pancake/errors"
22
+ autoload :Stack, "pancake/stack/stack"
23
23
 
24
24
  module Stacks
25
25
  autoload :Short, "pancake/stacks/short"
26
26
  end
27
27
 
28
+ module Hooks
29
+ autoload :OnInherit, 'pancake/hooks/on_inherit'
30
+ autoload :InheritableInnerClasses, 'pancake/hooks/inheritable_inner_classes'
31
+ end
32
+
28
33
  module Mixins
29
- autoload :RequestHelper,"pancake/mixins/request_helper"
30
- autoload :Publish, "pancake/mixins/publish"
31
- autoload :Render, "pancake/mixins/render"
32
- autoload :StackHelper, "pancake/mixins/stack_helper"
33
- autoload :ResponseHelper, "pancake/mixins/response_helper"
34
+ autoload :RequestHelper, "pancake/mixins/request_helper"
35
+ autoload :Publish, "pancake/mixins/publish"
36
+ autoload :Render, "pancake/mixins/render"
37
+ autoload :StackHelper, "pancake/mixins/stack_helper"
38
+ autoload :ResponseHelper, "pancake/mixins/response_helper"
34
39
  end
35
40
 
36
41
  module Middlewares
37
42
  autoload :Static, "pancake/middlewares/static"
38
- autoload :Logger, "pancake/middlewares/logger"
43
+ autoload :Logger, "pancake/middlewares/logger"
39
44
  end
40
45
 
41
46
  module Test
42
47
  autoload :Matchers, "pancake/test/matchers"
43
48
  end
44
-
45
49
  end
46
50
 
47
- require 'pancake/paths'
48
- require 'pancake/hooks/on_inherit'
49
- require 'pancake/hooks/inheritable_inner_classes'
50
51
  require 'pancake/core_ext/class'
51
52
  require 'pancake/core_ext/object'
52
53
  require 'pancake/core_ext/symbol'
53
- require 'pancake/configuration'
54
- require 'pancake/bootloaders'
55
- require 'pancake/mime_types'
56
- require 'pancake/middleware'
57
- require 'pancake/router'
58
54
  require 'pancake/master'
59
- require 'pancake/errors'
60
- require 'pancake/stack/stack'
61
- require 'pancake/stack/configuration'
62
- require 'pancake/stack/router'
63
- require 'pancake/stack/bootloader'
64
- require 'pancake/stack/app'
65
- require 'pancake/mixins/request_helper'
66
- require 'pancake/defaults/middlewares'
67
- require 'pancake/defaults/configuration'
@@ -59,7 +59,7 @@ module Pancake
59
59
 
60
60
  def self.extended(base)
61
61
  base.class_eval do
62
- class_inheritable_reader :_bootloaders, :_central_bootloaders, :_bootloader_map
62
+ extlib_inheritable_reader :_bootloaders, :_central_bootloaders, :_bootloader_map
63
63
  @_bootloaders, @_central_bootloaders = {}, []
64
64
  @_bootloader_map = Hash.new{|h,k| h[k] = {:before => [], :after => []}}
65
65
  end
@@ -139,7 +139,7 @@ module Pancake
139
139
  # Access to the stack that this bootloader is responsible for
140
140
  # :api: public
141
141
  def stack
142
- @stack ||= Object.full_const_get(self.name.split("::")[0..-2].join("::"))
142
+ @stack ||= self.name.split("::")[0..-2].join("::").constantize
143
143
  end
144
144
 
145
145
  # Resets the bootloaders on the stack
@@ -2,7 +2,7 @@ module Pancake
2
2
  class Configuration
3
3
 
4
4
  class Base
5
- class_inheritable_reader :defaults
5
+ extlib_inheritable_reader :defaults
6
6
  @defaults = Hash.new{|h,k| h[k] = {:value => nil, :description => ""}}
7
7
 
8
8
  # Set a default on the the configuartion
@@ -36,9 +36,9 @@ class Class
36
36
  end # unless
37
37
  end # ivars.each
38
38
  end # self.deep_inheritable_reader
39
-
39
+
40
40
  def deep_copy_class_inheritable_accessor(*ivars)
41
41
  deep_copy_class_inheritable_reader(*ivars)
42
- class_inheritable_writer(*ivars)
42
+ extlib_inheritable_writer(*ivars)
43
43
  end
44
- end # Class
44
+ end # Class
@@ -1,7 +1,7 @@
1
1
  module Pancake
2
2
  module Errors
3
3
  class HttpError < StandardError
4
- class_inheritable_accessor :name, :code, :description
4
+ extlib_inheritable_accessor :error_name, :code, :description
5
5
 
6
6
  def name; self.class.name; end
7
7
 
@@ -12,7 +12,7 @@ module Pancake
12
12
  end
13
13
 
14
14
  class NotFound < HttpError
15
- self.name = "Not Found"
15
+ self.error_name = "Not Found"
16
16
  self.code = 404
17
17
  self.description = "The requested resource could not be found but may be available again in the future."
18
18
  end
@@ -26,13 +26,13 @@ module Pancake
26
26
  end
27
27
 
28
28
  class Unauthorized < HttpError
29
- self.name = "Unauthorized"
29
+ self.error_name = "Unauthorized"
30
30
  self.code = 401
31
31
  self.description = "Authentication is required to access this resource."
32
32
  end
33
33
 
34
34
  class Forbidden < HttpError
35
- self.name = "Forbidden"
35
+ self.error_name = "Forbidden"
36
36
  self.code = 403
37
37
  self.description = "Access to this resource is denied."
38
38
  end
@@ -40,7 +40,7 @@ module Pancake
40
40
  class Server < HttpError
41
41
  attr_accessor :exceptions
42
42
 
43
- self.name = "Server Error"
43
+ self.error_name = "Server Error"
44
44
  self.code = 500
45
45
  self.description = "An internal server error"
46
46
 
@@ -51,12 +51,10 @@ module Pancake
51
51
  end
52
52
 
53
53
  class NotAcceptable < HttpError
54
- self.name = "Not Acceptable"
54
+ self.error_name = "Not Acceptable"
55
55
  self.code = 406
56
56
  self.description = "The requeseted format could not be provided"
57
57
  end
58
58
 
59
-
60
-
61
59
  end
62
60
  end
@@ -1,4 +1,5 @@
1
1
  require 'thor'
2
+ require 'thor/group'
2
3
  require 'extlib'
3
4
 
4
5
  require File.join(File.dirname(__FILE__), "generators", "base.rb")
@@ -1,8 +1,5 @@
1
1
  Pancake.logger.info "Loading Development Environment"
2
2
 
3
- # Set the middleware lables to load
4
- Pancake.stack_labels = [:development]
5
-
6
3
  # Pancake.handle_errors!(true) # uncomment to have the stack handle any errors that occur
7
4
 
8
5
  class <%= stack_name.camel_case %>
@@ -1,8 +1,5 @@
1
1
  Pancake.logger.info "Loading Production Environment"
2
2
 
3
- # Set the middleware lables to load
4
- Pancake.stack_labels = [:production]
5
-
6
3
  Pancake.handle_errors!(true) # uncomment to have the stack handle any errors that occur
7
4
 
8
5
  class <%= stack_name.camel_case %>
@@ -1,8 +1,5 @@
1
1
  Pancake.logger.info "Loading Staging Environment"
2
2
 
3
- # Set the middleware lables to load
4
- Pancake.stack_labels = [:staging]
5
-
6
3
  Pancake.handle_errors!(true) # uncomment to have the stack handle any errors that occur
7
4
 
8
5
  class <%= stack_name.camel_case %>
@@ -1,30 +1,30 @@
1
1
  module Pancake
2
- module Hooks
2
+ module Hooks
3
3
  module InheritableInnerClasses
4
4
  def self.extended(base)
5
5
  base.class_eval do
6
- class_inheritable_reader :_inhertiable_inner_classes
6
+ extlib_inheritable_reader :_inhertiable_inner_classes
7
7
  @_inhertiable_inner_classes = []
8
8
  end
9
9
  end # extended
10
-
10
+
11
11
  # Declare inner classes to be inherited when the outer class in inherited
12
12
  # The best way to show this is by example:
13
13
  #
14
- # @example
14
+ # @example
15
15
  # class Foo
16
16
  # inheritable_inner_class :Bar
17
17
  #
18
18
  # class Bar
19
19
  # end
20
20
  # end
21
- #
21
+ #
22
22
  # class Baz < Foo
23
23
  # # When Foo is inherited, the following occurs
24
24
  # class Bar < Foo::Bar; end
25
25
  # end
26
26
  #
27
- # This provides a more organic inheritance where the child gets their own
27
+ # This provides a more organic inheritance where the child gets their own
28
28
  # version of the inner class which is actually inherited from the parents inner class.
29
29
  # The inheritance chain remains intact.
30
30
  #
@@ -39,7 +39,7 @@ module Pancake
39
39
  end
40
40
  _inhertiable_inner_classes
41
41
  end
42
-
42
+
43
43
  # The inherited hook that sets up inherited inner classes. Remember if you overwrite this method, you should
44
44
  # call super!
45
45
  #
@@ -51,10 +51,9 @@ module Pancake
51
51
  class_defs = inheritable_inner_classes.map do |klass|
52
52
  "class #{klass} < superclass::#{klass}; end\n"
53
53
  end
54
- # puts "#{base.name} is INHERITING INNER CLASSES #{class_defs.inspect}"
55
54
  base.class_eval(class_defs.join)
56
55
  end
57
-
56
+
58
57
  end # InheritableInnerClasses
59
58
  end # Hooks
60
- end # Pancake
59
+ end # Pancake
@@ -3,22 +3,22 @@ module Pancake
3
3
  module OnInherit
4
4
  def self.extended(base)
5
5
  base.class_eval do
6
- class_inheritable_reader :_on_inherit
6
+ extlib_inheritable_reader :_on_inherit
7
7
  @_on_inherit = []
8
8
  end
9
9
  end
10
-
10
+
11
11
  # Provides an inheritance hook to all extended classes
12
- # Allows ou to hook into the inheritance
12
+ # Allows ou to hook into the inheritance
13
13
  def inherited(base)
14
14
  super
15
15
  _on_inherit.each{|b| b.call(base,self)}
16
16
  end
17
-
17
+
18
18
  # A hook to add code when the stack is inherited
19
19
  # The code will be executed when the class is inherited
20
- #
21
- # @example
20
+ #
21
+ # @example
22
22
  # MyClass.on_inherit do |base, parent|
23
23
  # # do stuff here between the child and parent
24
24
  # end
@@ -31,4 +31,4 @@ module Pancake
31
31
  end
32
32
  end # OnInherit
33
33
  end # Hooks
34
- end # Pancake
34
+ end # Pancake
@@ -1,16 +1,3 @@
1
- # Pancake::Logger == Merb::Logger
2
- class Pancake::Logger < Extlib::Logger
3
- # :api: public
4
- def verbose!(message, level = :warn)
5
- send("#{level}!", message) if Pancake.configuration.verbose_logging
6
- end
7
-
8
- # :api: public
9
- def verbose(message, level = :warn)
10
- send(level, message) if Pancake.configuration.verbose_logging
11
- end
12
- end
13
-
14
1
  # require "time" # httpdate
15
2
  # ==== Public Pancake Logger API
16
3
  #
@@ -62,7 +49,7 @@ module Pancake
62
49
  # :warn:: A warning
63
50
  # :info:: generic (useful) information about system operation
64
51
  # :debug:: low-level information for developers
65
- Levels = Mash.new({
52
+ Levels = Hashie::Mash.new({
66
53
  :fatal => 7,
67
54
  :error => 6,
68
55
  :warn => 4,
@@ -19,8 +19,7 @@ module Pancake
19
19
  # @api public
20
20
  # @author Daniel Neighman
21
21
  def start(opts, &block)
22
- raise "You must specify a root directory for pancake" unless opts[:root]
23
- self.root = opts[:root]
22
+ self.root = opts[:root] || Dir.pwd
24
23
 
25
24
  # Build Pancake
26
25
  the_app = instance_eval(&block)
@@ -45,52 +44,15 @@ module Pancake
45
44
  File.expand_path(File.join(File.dirname(file), *args))
46
45
  end
47
46
 
48
- # Labels that specify what kind of stack you're intending on loading.
49
- # This is a simliar concept to environments but it is in fact seperate conceptually.
50
- #
51
- # The reasoning is that you may want to use a particular stack type or types.
52
- # By using stack labels, you can define middleware to be active.
53
- #
54
- # @example
55
- # Pancake.stack_labels == [:development, :demo]
56
- #
57
- # # This would activate middleware marked with :development or :demo or the implicit :any label
58
- #
59
- # @return [Array<Symbol>]
60
- # An array of labels to activate
61
- # The default is [:production]
62
- # @see Pancake.stack_labels= to set the labels for this stack
63
- # @see Pancake::Middleware#stack to see how to specify middleware to be active for the given labels
64
- # @api public
65
- # @author Daniel Neighman
66
- def stack_labels
67
- return @stack_labels unless @stack_labels.nil? || @stack_labels.empty?
68
- self.stack_labels = [:production]
69
- end
70
-
71
- # Sets the stack labels to activate the associated middleware
72
- #
73
- # @param [Array<Symbol>, Symbol] An array of labels or a single label, specifying the middlewares to activate
74
- #
75
- # @example
76
- # Pancake.stack_labels = [:demo, :production]
77
- #
78
- # @see Pancake.stack_labels
79
- # @see Pancake::Middleware#stack
80
- # @api public
81
- # @author Daniel Neighman
82
- def stack_labels=(*labels)
83
- @stack_labels = labels.flatten.compact
84
- end
85
47
 
86
48
  def handle_errors!(*args)
87
49
  @handle_errors = begin
88
- if args.size > 1
89
- args.flatten
90
- else
91
- args.first
92
- end
93
- end
50
+ if args.size > 1
51
+ args.flatten
52
+ else
53
+ args.first
54
+ end
55
+ end
94
56
  end
95
57
 
96
58
  def handle_errors?