hassox-pancake 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. data/LICENSE +20 -0
  2. data/README.textile +95 -0
  3. data/Rakefile +56 -0
  4. data/TODO +18 -0
  5. data/bin/jeweler +19 -0
  6. data/bin/pancake-gen +17 -0
  7. data/bin/rubyforge +19 -0
  8. data/lib/pancake.rb +48 -0
  9. data/lib/pancake/bootloaders.rb +180 -0
  10. data/lib/pancake/configuration.rb +140 -0
  11. data/lib/pancake/core_ext/class.rb +44 -0
  12. data/lib/pancake/core_ext/object.rb +22 -0
  13. data/lib/pancake/core_ext/symbol.rb +15 -0
  14. data/lib/pancake/errors.rb +61 -0
  15. data/lib/pancake/generators.rb +8 -0
  16. data/lib/pancake/generators/base.rb +12 -0
  17. data/lib/pancake/generators/flat_generator.rb +17 -0
  18. data/lib/pancake/generators/short_generator.rb +17 -0
  19. data/lib/pancake/generators/stack_generator.rb +17 -0
  20. data/lib/pancake/generators/templates/common/dotgitignore +22 -0
  21. data/lib/pancake/generators/templates/common/dothtaccess +17 -0
  22. data/lib/pancake/generators/templates/flat/%stack_name%/%stack_name%.rb.tt +8 -0
  23. data/lib/pancake/generators/templates/flat/%stack_name%/.gitignore +21 -0
  24. data/lib/pancake/generators/templates/flat/%stack_name%/config.ru.tt +12 -0
  25. data/lib/pancake/generators/templates/flat/%stack_name%/pancake.init.tt +1 -0
  26. data/lib/pancake/generators/templates/flat/%stack_name%/public/.empty_directory +0 -0
  27. data/lib/pancake/generators/templates/flat/%stack_name%/tmp/.empty_directory +0 -0
  28. data/lib/pancake/generators/templates/short/%stack_name%/.gitignore +21 -0
  29. data/lib/pancake/generators/templates/short/%stack_name%/LICENSE.tt +20 -0
  30. data/lib/pancake/generators/templates/short/%stack_name%/README.tt +7 -0
  31. data/lib/pancake/generators/templates/short/%stack_name%/Rakefile.tt +48 -0
  32. data/lib/pancake/generators/templates/short/%stack_name%/VERSION.tt +1 -0
  33. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%.rb.tt +5 -0
  34. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/%stack_name%.rb.tt +6 -0
  35. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/config.ru.tt +12 -0
  36. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/gems/cache/.empty_directory +0 -0
  37. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/mounts/.empty_directory +0 -0
  38. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/public/.empty_directory +0 -0
  39. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/tmp/.empty_directory +0 -0
  40. data/lib/pancake/generators/templates/short/%stack_name%/pancake.init.tt +1 -0
  41. data/lib/pancake/generators/templates/short/%stack_name%/spec/%stack_name%_spec.rb.tt +7 -0
  42. data/lib/pancake/generators/templates/short/%stack_name%/spec/spec_helper.rb.tt +9 -0
  43. data/lib/pancake/generators/templates/stack/%stack_name%/.gitignore +21 -0
  44. data/lib/pancake/generators/templates/stack/%stack_name%/LICENSE.tt +20 -0
  45. data/lib/pancake/generators/templates/stack/%stack_name%/README.tt +7 -0
  46. data/lib/pancake/generators/templates/stack/%stack_name%/Rakefile.tt +48 -0
  47. data/lib/pancake/generators/templates/stack/%stack_name%/VERSION.tt +1 -0
  48. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%.rb.tt +3 -0
  49. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config.ru.tt +12 -0
  50. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config/environments/development.rb.tt +18 -0
  51. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config/environments/production.rb.tt +18 -0
  52. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config/router.rb.tt +6 -0
  53. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/gems/cache/.empty_directory +0 -0
  54. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/mounts/.empty_directory +0 -0
  55. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/public/.empty_directory +0 -0
  56. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/tmp/.empty_directory +0 -0
  57. data/lib/pancake/generators/templates/stack/%stack_name%/pancake.init.tt +1 -0
  58. data/lib/pancake/generators/templates/stack/%stack_name%/spec/%stack_name%_spec.rb.tt +7 -0
  59. data/lib/pancake/generators/templates/stack/%stack_name%/spec/spec_helper.rb.tt +9 -0
  60. data/lib/pancake/hooks/inheritable_inner_classes.rb +60 -0
  61. data/lib/pancake/hooks/on_inherit.rb +34 -0
  62. data/lib/pancake/master.rb +87 -0
  63. data/lib/pancake/middleware.rb +354 -0
  64. data/lib/pancake/mime_types.rb +265 -0
  65. data/lib/pancake/mixins/publish.rb +125 -0
  66. data/lib/pancake/mixins/publish/action_options.rb +104 -0
  67. data/lib/pancake/mixins/render.rb +61 -0
  68. data/lib/pancake/mixins/request_helper.rb +92 -0
  69. data/lib/pancake/mixins/stack_helper.rb +44 -0
  70. data/lib/pancake/mixins/url.rb +10 -0
  71. data/lib/pancake/more/controller.rb +4 -0
  72. data/lib/pancake/more/controller/base.rb +34 -0
  73. data/lib/pancake/paths.rb +218 -0
  74. data/lib/pancake/router.rb +99 -0
  75. data/lib/pancake/stack/app.rb +10 -0
  76. data/lib/pancake/stack/bootloader.rb +79 -0
  77. data/lib/pancake/stack/configuration.rb +44 -0
  78. data/lib/pancake/stack/middleware.rb +0 -0
  79. data/lib/pancake/stack/router.rb +18 -0
  80. data/lib/pancake/stack/stack.rb +57 -0
  81. data/lib/pancake/stacks/short.rb +2 -0
  82. data/lib/pancake/stacks/short/controller.rb +105 -0
  83. data/lib/pancake/stacks/short/stack.rb +194 -0
  84. data/spec/helpers/helpers.rb +20 -0
  85. data/spec/helpers/matchers.rb +25 -0
  86. data/spec/pancake/bootloaders_spec.rb +109 -0
  87. data/spec/pancake/configuration_spec.rb +177 -0
  88. data/spec/pancake/fixtures/foo_stack/pancake.init +0 -0
  89. data/spec/pancake/fixtures/paths/controllers/controller1.rb +0 -0
  90. data/spec/pancake/fixtures/paths/controllers/controller2.rb +0 -0
  91. data/spec/pancake/fixtures/paths/controllers/controller3.rb +0 -0
  92. data/spec/pancake/fixtures/paths/models/model1.rb +0 -0
  93. data/spec/pancake/fixtures/paths/models/model2.rb +0 -0
  94. data/spec/pancake/fixtures/paths/models/model3.rb +0 -0
  95. data/spec/pancake/fixtures/paths/stack/controllers/controller1.rb +0 -0
  96. data/spec/pancake/fixtures/paths/stack/models/model3.rb +0 -0
  97. data/spec/pancake/fixtures/paths/stack/views/view1.erb +0 -0
  98. data/spec/pancake/fixtures/paths/stack/views/view1.rb +0 -0
  99. data/spec/pancake/fixtures/paths/stack/views/view2.erb +0 -0
  100. data/spec/pancake/fixtures/paths/stack/views/view2.haml +0 -0
  101. data/spec/pancake/fixtures/render_templates/context_template.html.erb +1 -0
  102. data/spec/pancake/fixtures/render_templates/erb_template.html.erb +1 -0
  103. data/spec/pancake/fixtures/render_templates/erb_template.json.erb +1 -0
  104. data/spec/pancake/fixtures/render_templates/haml_template.html.haml +1 -0
  105. data/spec/pancake/fixtures/render_templates/haml_template.xml.haml +1 -0
  106. data/spec/pancake/hooks/on_inherit_spec.rb +65 -0
  107. data/spec/pancake/inheritance_spec.rb +100 -0
  108. data/spec/pancake/middleware_spec.rb +401 -0
  109. data/spec/pancake/mime_types_spec.rb +234 -0
  110. data/spec/pancake/mixins/publish_spec.rb +94 -0
  111. data/spec/pancake/mixins/render_spec.rb +55 -0
  112. data/spec/pancake/mixins/stack_helper_spec.rb +46 -0
  113. data/spec/pancake/pancake_spec.rb +31 -0
  114. data/spec/pancake/paths_spec.rb +210 -0
  115. data/spec/pancake/stack/app_spec.rb +28 -0
  116. data/spec/pancake/stack/bootloader_spec.rb +41 -0
  117. data/spec/pancake/stack/middleware_spec.rb +0 -0
  118. data/spec/pancake/stack/router_spec.rb +266 -0
  119. data/spec/pancake/stack/stack_configuration_spec.rb +101 -0
  120. data/spec/pancake/stack/stack_spec.rb +55 -0
  121. data/spec/pancake/stacks/short/controller_spec.rb +287 -0
  122. data/spec/pancake/stacks/short/router_spec.rb +132 -0
  123. data/spec/pancake/stacks/short/stack_spec.rb +40 -0
  124. data/spec/spec_helper.rb +21 -0
  125. metadata +238 -0
@@ -0,0 +1,34 @@
1
+ module Pancake
2
+ # TODOS:
3
+ # * Sketch out how action dispatch will work
4
+ # * What helpers do we need for dealing with different formats?
5
+ # * What are the different errors that might arise in dispatch? 404 etc.
6
+ # * Get before and after hooks working. These wrap around all action calls
7
+ # by default, so the hooks in extlib aren’t useful. Additionally, the
8
+ # the dispatch step gives us a point to hook in before and after the call.
9
+ class Controller
10
+ extend Mixins::Publish
11
+
12
+ def self.call(env)
13
+ new(env)
14
+ end
15
+
16
+ def initialize(env)
17
+
18
+ end
19
+
20
+ # Returns the rack environment
21
+ def request
22
+
23
+ end
24
+
25
+ # Returns a hash of parameters
26
+ def params
27
+
28
+ end
29
+
30
+ def render(opts = {})
31
+
32
+ end
33
+ end # Controller
34
+ end # Pancake
@@ -0,0 +1,218 @@
1
+ module Pancake
2
+ # Pancake::Paths provides a mixin for path management.
3
+ # A path consists of a name, and paths + globs, and makes use of the Klass.roots that have been set as
4
+ # file roots for each path and glob to be applied to.
5
+ # Each name may have many (path + glob)s, so that many root paths may be added to the same name
6
+ #
7
+ # @example Adding Paths:
8
+ # class Foo
9
+ # extend Pancake::Paths
10
+ # end
11
+ #
12
+ # Foo.push_paths(:model, "relative/path/to/models", "**/*.rb")
13
+ # Foo.push_paths(:model, "another/path/to/models", "**/*.rb")
14
+ # Foo.push_paths(:model, "yet/another")
15
+ #
16
+ # This will make available the directory and or full file paths for :model in the order they
17
+ # were declared.
18
+ #
19
+ # When no glob is provided, the glob will be returned as nil
20
+ #
21
+ # @example Reading Paths:
22
+ # Foo.dirs_for(:model) == ["#{root}/relative/path/to/models", "#{root}/another/path/to/models", "#{root}/yet/another"]
23
+ #
24
+ # Foo.dirs_and_glob_for(:model) == [
25
+ # ["#{root}/relative/path/to/models", "**/*.rb"],
26
+ # ["#{root}//another/path/to/models", "**/*.rb"],
27
+ # ["#{root}//yet/another", nil]
28
+ # ]
29
+ #
30
+ # Foo.paths_for(:model) == [
31
+ # ["#{root}/relative/path/to/models", "/model1.rb"],
32
+ # ["#{root}/path/to/models", "/model2.rb"],
33
+ # ["#{root}/path/to/models/sub", "/model1.rb"],
34
+ # ["#{root}/another/path/to/models", "/model3.rb"]
35
+ # ]
36
+ #
37
+ # The paths are fully inheritable once they have extended a class.
38
+ module Paths
39
+ class NoPathsGiven < ArgumentError; end
40
+
41
+ def self.extended(base) #:nodoc:#
42
+ base.class_eval do
43
+ deep_copy_class_inheritable_reader :_load_paths, :roots
44
+ @_load_paths = Dictionary.new
45
+ @roots = []
46
+ end
47
+ end
48
+
49
+ # Push a named path and optional glob onto the list of paths associated with <name>
50
+ #
51
+ # @param [Symbol] name The name to associate with the given path and glob
52
+ # @param [String, Array] paths A path or paths to associate with the namd and glob
53
+ # @param [String, Nil] glob The glob to associate with the given path(s) and name
54
+ #
55
+ # @example No Glob:
56
+ # MyClass.push_paths(:foo, "path/for/foo")
57
+ #
58
+ # @example Using a Glob:
59
+ # MyClass.push_paths(:foo, "path/for/foo", "**/*.rb")
60
+ #
61
+ # @example Using Multiple paths:
62
+ # MyClass.push_paths(:foo, ["path/one", "path/two"], "**/*.rb")
63
+ #
64
+ # @raise [Pancake::NoPathsGiven] raised when an empty paths array is provided
65
+ # @author Daniel Neighman
66
+ # @since 0.1.1
67
+ # @api public
68
+ def push_paths(name, paths, glob = nil)
69
+ paths = [paths].flatten
70
+ raise NoPathsGiven if paths.blank?
71
+ _load_paths[name] ||= []
72
+ _load_paths[name] << [paths, glob]
73
+ end
74
+
75
+ # Provides the directories or raw paths that are associated with a given name.
76
+ #
77
+ # @param [Symbol] name The name for the paths group
78
+ # @param [Hash] opts An options hash
79
+ # @option opts [Boolean] :invert (false) inverts the order of the returned paths
80
+ #
81
+ # @example Read Directories:
82
+ # MyClass.dirs_for(:models)
83
+ #
84
+ # @example Inverted Read:
85
+ # MyClass.dirs_for(:models, :invert => true)
86
+ #
87
+ # @return [Array] An array of the paths
88
+ # Returned in declared order unless the :invert option is set
89
+ # @api public
90
+ # @since 0.1.1
91
+ # @author Daniel Neighman
92
+ def dirs_for(name, opts = {})
93
+ if _load_paths[name].blank?
94
+ []
95
+ else
96
+ result = []
97
+ invert = !!opts[:invert]
98
+ load_paths = invert ? _load_paths[name].reverse : _load_paths[name]
99
+ roots.each do |root|
100
+ load_paths.each do |paths, glob|
101
+ paths = paths.reverse if invert
102
+ result << paths.map{|p| File.join(root, p)}
103
+ end
104
+ end
105
+ result.flatten
106
+ end # if
107
+ end
108
+
109
+ # Provides the list of paths (directories) and the associated globs for a given name.
110
+ #
111
+ # @param [Symbol] name The name of the path group
112
+ # @param [Hash] opts A hash of options
113
+ # @option opts [Boolean] :invert (false) Inverts the order of the paths
114
+ #
115
+ # @example
116
+ # MyClass.dirs_and_glob_for(:models)
117
+ #
118
+ # @return [Array] An array of [path, glob] arrays
119
+ # Returned in declared order unless the :invert option is set
120
+ # @api public
121
+ # @since 0.1.1
122
+ # @author Daniel Neighman
123
+ def dirs_and_glob_for(name, opts = {})
124
+ if _load_paths[name].blank?
125
+ []
126
+ else
127
+ result = []
128
+ invert = !!opts[:invert]
129
+ load_paths = invert ? _load_paths[name].reverse : _load_paths[name]
130
+ roots.each do |root|
131
+ load_paths.each do |paths, glob|
132
+ paths = paths.reverse if invert
133
+ paths.each do |path|
134
+ result << [File.join(root, path), glob]
135
+ end # paths.each
136
+ end # load_paths.each
137
+ end # roots.each
138
+ result
139
+ end # if
140
+ end
141
+
142
+ # Provides an expanded, globbed list of paths and files for a given name.
143
+ #
144
+ # @param [Symbol] name The name of the paths group
145
+ # @param [Hash] opts An options hash
146
+ # @option opts [Boolean] :invert (false) Inverts the order of the returned values
147
+ #
148
+ # @example
149
+ # MyClass.paths_for(:model)
150
+ # MyClass.paths_for(:model, :invert => true)
151
+ #
152
+ # @return [Array]
153
+ # An array of [path, file] arrays. These may be joined to get the full path.
154
+ # All matched files for [paths, glob] will be returned in declared and then found order unless +:invert+ is true.
155
+ # Any path that has a +nil+ glob associated with it will be excluded.
156
+ #
157
+ # @api public
158
+ # @since 0.1.1
159
+ # @author Daniel Neighman
160
+ def paths_for(name, opts = {})
161
+ result = []
162
+ dirs_and_glob_for(name, opts).each do |path, glob|
163
+ next if glob.nil?
164
+ paths = Dir[File.join(path, glob)]
165
+ paths = paths.reverse if opts[:invert]
166
+ paths.each do |full_path|
167
+ result << [path, full_path.gsub(path, "")]
168
+ end
169
+ end
170
+ result
171
+ end
172
+
173
+ # Provides an expanded, globbed list of paths and files for a given name.
174
+ # The result includes only the last matched file of a given sub path and name.
175
+ #
176
+ # @param [Symbol] name The name of the paths group
177
+ # @param [Hash] opts An options hash
178
+ # @option opts [Boolean] :invert (false) Inverts the order of returned paths and files
179
+ #
180
+ # @example
181
+ # #Given the following:
182
+ # # /path/one/file1.rb
183
+ # # /path/one/file2.rb
184
+ # # /path/two/file1.rb
185
+ #
186
+ # MyClass.push_path(:files, ["/path/one", "/path/two"], "**/*.rb")
187
+ #
188
+ # MyClass.unique_paths_for(:files)
189
+ # MyClass.unique_paths_for(:files, :invert => true)
190
+ #
191
+ # @return [Array]
192
+ # Returns an array of [path, file] arrays
193
+ # Results are retuned in declared order. Only unique files are returned (the file part - the path)
194
+ # In the above example, the following would be returned for the standard call
195
+ # [
196
+ # ["#{root}/path/one", "/file2.rb"],
197
+ # ["#{root}/path/two", "/file1.rb"]
198
+ # ]
199
+ # For the inverted example the following is returned:
200
+ # [
201
+ # ["#{root}/path/one/file2.rb"],
202
+ # ["#{root}/path/one/file1.rb"]
203
+ # ]
204
+ #
205
+ # @api public
206
+ # @since 0.1.1
207
+ # @author Daniel Neighman
208
+ def unique_paths_for(name, opts = {})
209
+ tally = {}
210
+ output = []
211
+ paths_for(name, opts).reverse.each do |ary|
212
+ tally[ary[1]] ||= ary[0]
213
+ output << ary if tally[ary[1]] == ary[0]
214
+ end
215
+ output.reverse
216
+ end # unique_paths_for
217
+ end
218
+ end
@@ -0,0 +1,99 @@
1
+ module Pancake
2
+ # Get the ability to mark this as a consuming route.
3
+ class ::Usher::Route
4
+ attr_accessor :consuming
5
+ end
6
+
7
+ # Generate a url for any pancake configuration that has a router
8
+ #
9
+ # @example
10
+ # Pancake.url(UserManamgent, :login) # => "/users/login"
11
+ # @api public
12
+ def self.url(app_name, name_or_opts, opts = {})
13
+ config = Pancake.configuration.configs(app_name)
14
+ the_router = if config && config.router
15
+ config.router
16
+ elsif app_name.respond_to?(:router)
17
+ app_name.router
18
+ else
19
+ raise Pancake::Errors::UnknownRouter
20
+ end
21
+ the_router.url(name_or_opts, opts)
22
+ end
23
+
24
+ # The pancake router is a customized version of the Usher router.
25
+ # Usher is a fast tree based router that can generate routes, have
26
+ # nested routers, and even generate from nested routers.
27
+ # @see http://github.com/joshbuddy/usher
28
+ # @since 0.1.2
29
+ # @author Daniel Neighman
30
+ class Router < Usher::Interface::RackInterface
31
+ CONFIGURATION_KEY = "pancake.request.configuration".freeze
32
+
33
+ class RackApplicationExpected < ArgumentError; end
34
+ attr_accessor :configuration
35
+
36
+ # Mounts an application in the router as a sub application in the
37
+ # url space. This will route directly to the sub application and
38
+ # skip any middlewares etc.
39
+ def mount(mounted_app, path, options = {})
40
+ raise RackApplicationExpected unless mounted_app.respond_to?(:call)
41
+ exact_match = options.delete(:_exact)
42
+ route = add(path, options)
43
+ route.consuming = true
44
+ route.match_partially! unless exact_match
45
+ route.to(mounted_app)
46
+ end
47
+
48
+ # Adds a route to the router.
49
+ # @see Usher::Interface::RackInterface#add
50
+ def add(path, opts = {}, &block)
51
+ opts = cooerce_options_to_usher(opts)
52
+ route = super(path, opts)
53
+ if block_given?
54
+ route.to(block)
55
+ end
56
+ route
57
+ end
58
+
59
+ # Generate a url
60
+ def url(name_or_path, options = {})
61
+ if Hash === name_or_path
62
+ name = nil
63
+ options = name_or_path
64
+ else
65
+ name = name_or_path
66
+ end
67
+ generate(name, options)
68
+ end
69
+
70
+ def call(env)
71
+ orig_config = env[CONFIGURATION_KEY]
72
+ env[CONFIGURATION_KEY] = configuration
73
+ super(env)
74
+ ensure
75
+ env[CONFIGURATION_KEY] = orig_config
76
+ end
77
+
78
+ private
79
+ # Canoodles the options into a format that usher is happy to
80
+ # accept. This is so that we can have a different interface from
81
+ # the raw usher when we're first declaring the route.
82
+ # @api private
83
+ def cooerce_options_to_usher(opts)
84
+ defaults = opts.delete(:_defaults)
85
+ opts[:default_values] ||= {}
86
+ opts[:default_values].merge!(defaults) if defaults
87
+ opts
88
+ end
89
+
90
+ # Overwrites the method in Rack::Interface::RackInterface to mash
91
+ # the usher.params into the rack request.params
92
+ # @api private
93
+ def after_match(request, response)
94
+ super
95
+ consume_path!(request, response) if !response.partial_match? && response.path.route.consuming
96
+ request.params.merge!(request.env['usher.params']) unless request.env['usher.params'].empty?
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,10 @@
1
+ module Pancake
2
+ class Stack
3
+ # get a new instance of the application for this stack
4
+ # Ovewrite this to provide custom application initialization
5
+ # :api: overwritable
6
+ def self.new_app_instance
7
+ MISSING_APP
8
+ end
9
+ end # Pancake
10
+ end # Pancake
@@ -0,0 +1,79 @@
1
+ module Pancake
2
+ class Stack
3
+ inheritable_inner_classes :BootLoader
4
+
5
+ # The default bootloader is where the stack default bootloaders are stored
6
+ # These are shared across all bootloaders
7
+ class BootLoader # :nodoc:
8
+ extend ::Pancake::BootLoaderMixin
9
+ end
10
+
11
+ end # Stack
12
+ end # Pancake
13
+
14
+ #################### Define the bootloaders here #############################
15
+ # :level => :init bootloaders only have the stack class available
16
+ # They do not have :stack available
17
+ # These are not run directly, but are run from inherited stacks
18
+ Pancake::Stack::BootLoader.add(:mount_applications, :level => :init) do
19
+ def run!
20
+ # Mount any stacks this stack may have in it.
21
+ stack_class.roots.each do |root|
22
+ Dir["#{root}/mounts/*/pancake.init"].each{|f| load f if File.exists?(f)}
23
+ end
24
+ end
25
+ end
26
+
27
+ Pancake::Stack::BootLoader.add(:load_configuration, :level => :init) do
28
+ def run!
29
+ stack_class.roots.each do |root|
30
+ stack_class.paths_for(:config).each{|f| require f.join}
31
+ end
32
+ end
33
+ end
34
+
35
+ Pancake::Stack::BootLoader.add(:load_application, :level => :init) do
36
+ def run!
37
+ stack_class.roots.each do |root|
38
+ [:models, :controllers].each do |type|
39
+ stack_class.paths_for(type).each{|f| require f.join}
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ Pancake::Stack::BootLoader.add(:load_routes, :level => :init) do
46
+ def run!
47
+ stack_class.roots.each do |root|
48
+ stack_class.paths_for(:router).each{|f| require f.join}
49
+ end
50
+ end
51
+ end
52
+
53
+ ###### -================== Stack Building BootLoaders
54
+ # Pancake stacks need to be built with the following options
55
+ # MyApp::BootLoader.run!({
56
+ # :stack_class => self.class,
57
+ # :stack => self,
58
+ # :app => app,
59
+ # :app_name => app_name,
60
+ # })
61
+ #
62
+ #
63
+
64
+ Pancake::Stack::BootLoader.add(:initialize_application) do
65
+ def run!
66
+ config[:app] ||= stack_class.new_app_instance
67
+ end
68
+ end
69
+
70
+ Pancake::Stack::BootLoader.add(:build_stack) do
71
+ def run!
72
+ mwares = stack_class.middlewares(Pancake.stack_labels)
73
+ app = Pancake::Middleware.build(config[:app], mwares)
74
+ app_config = Pancake.configuration.configs(config[:app_name])
75
+ app_config.app = app
76
+ app_config.stack = stack_class
77
+ app_config.router.configuration = app_config
78
+ end
79
+ end
@@ -0,0 +1,44 @@
1
+ module Pancake
2
+ class Stack
3
+
4
+ class Configuration < Pancake::Configuration::Base
5
+ end
6
+
7
+ # Provides access to the configuration block for the stack.
8
+ # If a block is provided, it opens the specific configuration instances anonymous class
9
+ # and allows you to edit it.
10
+ # If no block is provided, it just returns the configuration object.
11
+ #
12
+ # :api: public
13
+ def self.configuration(label = self, &block)
14
+ config = Pancake.configuration.configs[label] ||= self::Configuration.new
15
+ config.class.class_eval(&block) if block
16
+ config
17
+ end
18
+
19
+ def configuration(label = self.class)
20
+ yield self.class.configuration(label) if block_given?
21
+ self.class.configuration(label)
22
+ end
23
+
24
+ end # Stack
25
+ end # Pancake
26
+
27
+ ####################
28
+ # Setup the default configuration for each stack
29
+ class Pancake::Stack::Configuration
30
+ default :router, lambda{ _router }, "The router for this stack"
31
+
32
+ def _router
33
+ @_router ||= begin
34
+ unless stack.nil?
35
+ r = stack.router.dup
36
+ r.configuration = self
37
+ r.app = app
38
+ r.configuration = self
39
+ r
40
+ end
41
+
42
+ end
43
+ end
44
+ end