pancake 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (172) hide show
  1. data/LICENSE +20 -0
  2. data/README.textile +95 -0
  3. data/Rakefile +56 -0
  4. data/TODO +17 -0
  5. data/bin/jeweler +19 -0
  6. data/bin/pancake-gen +17 -0
  7. data/bin/rubyforge +19 -0
  8. data/lib/pancake/bootloaders.rb +180 -0
  9. data/lib/pancake/configuration.rb +145 -0
  10. data/lib/pancake/constants.rb +5 -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/defaults/configuration.rb +22 -0
  15. data/lib/pancake/defaults/middlewares.rb +1 -0
  16. data/lib/pancake/errors.rb +61 -0
  17. data/lib/pancake/generators/base.rb +12 -0
  18. data/lib/pancake/generators/micro_generator.rb +17 -0
  19. data/lib/pancake/generators/short_generator.rb +17 -0
  20. data/lib/pancake/generators/stack_generator.rb +17 -0
  21. data/lib/pancake/generators/templates/common/dotgitignore +22 -0
  22. data/lib/pancake/generators/templates/common/dothtaccess +17 -0
  23. data/lib/pancake/generators/templates/micro/%stack_name%/%stack_name%.rb.tt +8 -0
  24. data/lib/pancake/generators/templates/micro/%stack_name%/config.ru.tt +12 -0
  25. data/lib/pancake/generators/templates/micro/%stack_name%/pancake.init.tt +1 -0
  26. data/lib/pancake/generators/templates/micro/%stack_name%/public/.empty_directory +0 -0
  27. data/lib/pancake/generators/templates/micro/%stack_name%/tmp/.empty_directory +0 -0
  28. data/lib/pancake/generators/templates/micro/%stack_name%/views/root.html.haml +1 -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 +50 -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%/%stack_name%.rb.tt +6 -0
  34. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/config.ru.tt +10 -0
  35. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/mounts/.empty_directory +0 -0
  36. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/public/.empty_directory +0 -0
  37. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/tmp/.empty_directory +0 -0
  38. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/views/root.html.haml +2 -0
  39. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%.rb.tt +5 -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%/LICENSE.tt +20 -0
  44. data/lib/pancake/generators/templates/stack/%stack_name%/README.tt +7 -0
  45. data/lib/pancake/generators/templates/stack/%stack_name%/Rakefile.tt +50 -0
  46. data/lib/pancake/generators/templates/stack/%stack_name%/VERSION.tt +1 -0
  47. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config/environments/development.rb.tt +18 -0
  48. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config/environments/production.rb.tt +18 -0
  49. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config/router.rb.tt +6 -0
  50. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config.ru.tt +12 -0
  51. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/gems/cache/.empty_directory +0 -0
  52. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/mounts/.empty_directory +0 -0
  53. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/public/.empty_directory +0 -0
  54. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/tmp/.empty_directory +0 -0
  55. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%.rb.tt +3 -0
  56. data/lib/pancake/generators/templates/stack/%stack_name%/pancake.init.tt +1 -0
  57. data/lib/pancake/generators/templates/stack/%stack_name%/spec/%stack_name%_spec.rb.tt +7 -0
  58. data/lib/pancake/generators/templates/stack/%stack_name%/spec/spec_helper.rb.tt +9 -0
  59. data/lib/pancake/generators.rb +8 -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/logger.rb +200 -0
  63. data/lib/pancake/master.rb +123 -0
  64. data/lib/pancake/middleware.rb +347 -0
  65. data/lib/pancake/middlewares/logger.rb +16 -0
  66. data/lib/pancake/middlewares/static.rb +38 -0
  67. data/lib/pancake/mime_types.rb +265 -0
  68. data/lib/pancake/mixins/publish/action_options.rb +104 -0
  69. data/lib/pancake/mixins/publish.rb +125 -0
  70. data/lib/pancake/mixins/render/render.rb +168 -0
  71. data/lib/pancake/mixins/render/template.rb +23 -0
  72. data/lib/pancake/mixins/render/view_context.rb +21 -0
  73. data/lib/pancake/mixins/render.rb +109 -0
  74. data/lib/pancake/mixins/request_helper.rb +100 -0
  75. data/lib/pancake/mixins/stack_helper.rb +46 -0
  76. data/lib/pancake/mixins/url.rb +10 -0
  77. data/lib/pancake/paths.rb +218 -0
  78. data/lib/pancake/router.rb +99 -0
  79. data/lib/pancake/stack/app.rb +10 -0
  80. data/lib/pancake/stack/bootloader.rb +79 -0
  81. data/lib/pancake/stack/configuration.rb +44 -0
  82. data/lib/pancake/stack/middleware.rb +0 -0
  83. data/lib/pancake/stack/router.rb +21 -0
  84. data/lib/pancake/stack/stack.rb +66 -0
  85. data/lib/pancake/stacks/short/bootloaders.rb +13 -0
  86. data/lib/pancake/stacks/short/controller.rb +116 -0
  87. data/lib/pancake/stacks/short/default/views/base.html.haml +5 -0
  88. data/lib/pancake/stacks/short/stack.rb +187 -0
  89. data/lib/pancake/stacks/short.rb +3 -0
  90. data/lib/pancake.rb +58 -0
  91. data/spec/helpers/helpers.rb +20 -0
  92. data/spec/helpers/matchers.rb +25 -0
  93. data/spec/pancake/bootloaders_spec.rb +109 -0
  94. data/spec/pancake/configuration_spec.rb +177 -0
  95. data/spec/pancake/constants_spec.rb +7 -0
  96. data/spec/pancake/defaults/configuration_spec.rb +58 -0
  97. data/spec/pancake/fixtures/foo_stack/pancake.init +0 -0
  98. data/spec/pancake/fixtures/middlewares/other_public/two.html +1 -0
  99. data/spec/pancake/fixtures/middlewares/public/foo#bar.html +1 -0
  100. data/spec/pancake/fixtures/middlewares/public/one.html +1 -0
  101. data/spec/pancake/fixtures/paths/controllers/controller1.rb +0 -0
  102. data/spec/pancake/fixtures/paths/controllers/controller2.rb +0 -0
  103. data/spec/pancake/fixtures/paths/controllers/controller3.rb +0 -0
  104. data/spec/pancake/fixtures/paths/models/model1.rb +0 -0
  105. data/spec/pancake/fixtures/paths/models/model2.rb +0 -0
  106. data/spec/pancake/fixtures/paths/models/model3.rb +0 -0
  107. data/spec/pancake/fixtures/paths/stack/controllers/controller1.rb +0 -0
  108. data/spec/pancake/fixtures/paths/stack/models/model3.rb +0 -0
  109. data/spec/pancake/fixtures/paths/stack/views/view1.erb +0 -0
  110. data/spec/pancake/fixtures/paths/stack/views/view1.rb +0 -0
  111. data/spec/pancake/fixtures/paths/stack/views/view2.erb +0 -0
  112. data/spec/pancake/fixtures/paths/stack/views/view2.haml +0 -0
  113. data/spec/pancake/fixtures/render_templates/context_template.html.erb +2 -0
  114. data/spec/pancake/fixtures/render_templates/erb_template.html.erb +1 -0
  115. data/spec/pancake/fixtures/render_templates/erb_template.json.erb +1 -0
  116. data/spec/pancake/fixtures/render_templates/haml_template.html.haml +1 -0
  117. data/spec/pancake/fixtures/render_templates/haml_template.xml.haml +1 -0
  118. data/spec/pancake/fixtures/render_templates/templates/context.erb +2 -0
  119. data/spec/pancake/fixtures/render_templates/view_context/capture_erb.erb +5 -0
  120. data/spec/pancake/fixtures/render_templates/view_context/capture_haml.haml +4 -0
  121. data/spec/pancake/fixtures/render_templates/view_context/concat_erb.erb +2 -0
  122. data/spec/pancake/fixtures/render_templates/view_context/concat_haml.haml +2 -0
  123. data/spec/pancake/fixtures/render_templates/view_context/context.erb +3 -0
  124. data/spec/pancake/fixtures/render_templates/view_context/context2.erb +3 -0
  125. data/spec/pancake/fixtures/render_templates/view_context/helper_methods.erb +3 -0
  126. data/spec/pancake/fixtures/render_templates/view_context/inherited_erb_from_haml.erb +5 -0
  127. data/spec/pancake/fixtures/render_templates/view_context/inherited_erb_level_0.erb +5 -0
  128. data/spec/pancake/fixtures/render_templates/view_context/inherited_erb_level_1.erb +5 -0
  129. data/spec/pancake/fixtures/render_templates/view_context/inherited_haml_from_erb.haml +4 -0
  130. data/spec/pancake/fixtures/render_templates/view_context/inherited_haml_level_0.haml +4 -0
  131. data/spec/pancake/fixtures/render_templates/view_context/inherited_haml_level_1.haml +4 -0
  132. data/spec/pancake/fixtures/render_templates/view_context/nested_content_level_0.haml +6 -0
  133. data/spec/pancake/fixtures/render_templates/view_context/nested_content_level_1.haml +4 -0
  134. data/spec/pancake/fixtures/render_templates/view_context/nested_inner.erb +1 -0
  135. data/spec/pancake/fixtures/render_templates/view_context/nested_outer.erb +3 -0
  136. data/spec/pancake/fixtures/render_templates/view_context/super_erb_from_erb_0.erb +5 -0
  137. data/spec/pancake/fixtures/render_templates/view_context/super_erb_from_erb_1.erb +6 -0
  138. data/spec/pancake/fixtures/render_templates/view_context/super_erb_from_haml_0.erb +5 -0
  139. data/spec/pancake/fixtures/render_templates/view_context/super_erb_from_haml_1.erb +6 -0
  140. data/spec/pancake/fixtures/render_templates/view_context/super_haml_from_erb_0.haml +4 -0
  141. data/spec/pancake/fixtures/render_templates/view_context/super_haml_from_erb_1.haml +5 -0
  142. data/spec/pancake/fixtures/render_templates/view_context/super_haml_from_haml_0.haml +5 -0
  143. data/spec/pancake/fixtures/render_templates/view_context/super_haml_from_haml_1.haml +5 -0
  144. data/spec/pancake/fixtures/stacks/short/foobar/other_root/views/base.html.haml +4 -0
  145. data/spec/pancake/fixtures/stacks/short/foobar/views/basic.html.haml +1 -0
  146. data/spec/pancake/fixtures/stacks/short/foobar/views/inherited_from_base.html.haml +5 -0
  147. data/spec/pancake/hooks/on_inherit_spec.rb +65 -0
  148. data/spec/pancake/inheritance_spec.rb +100 -0
  149. data/spec/pancake/middleware_spec.rb +401 -0
  150. data/spec/pancake/middlewares/logger_spec.rb +29 -0
  151. data/spec/pancake/middlewares/static_spec.rb +83 -0
  152. data/spec/pancake/mime_types_spec.rb +234 -0
  153. data/spec/pancake/mixins/publish_spec.rb +94 -0
  154. data/spec/pancake/mixins/render/template_spec.rb +69 -0
  155. data/spec/pancake/mixins/render/view_context_spec.rb +248 -0
  156. data/spec/pancake/mixins/render_spec.rb +56 -0
  157. data/spec/pancake/mixins/request_helper_spec.rb +27 -0
  158. data/spec/pancake/mixins/stack_helper_spec.rb +46 -0
  159. data/spec/pancake/pancake_spec.rb +90 -0
  160. data/spec/pancake/paths_spec.rb +210 -0
  161. data/spec/pancake/stack/app_spec.rb +28 -0
  162. data/spec/pancake/stack/bootloader_spec.rb +41 -0
  163. data/spec/pancake/stack/middleware_spec.rb +0 -0
  164. data/spec/pancake/stack/router_spec.rb +282 -0
  165. data/spec/pancake/stack/stack_configuration_spec.rb +101 -0
  166. data/spec/pancake/stack/stack_spec.rb +60 -0
  167. data/spec/pancake/stacks/short/controller_spec.rb +322 -0
  168. data/spec/pancake/stacks/short/middlewares_spec.rb +22 -0
  169. data/spec/pancake/stacks/short/router_spec.rb +136 -0
  170. data/spec/pancake/stacks/short/stack_spec.rb +64 -0
  171. data/spec/spec_helper.rb +23 -0
  172. metadata +294 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Daniel Neighman
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,95 @@
1
+ __This read me is getting thrown to get there in little bits of time snatched between other bits of snatched time... it will be magnificient, eventually... please bare with it...__
2
+
3
+ h3. Whats this then
4
+
5
+ A tool for making pancake stacks. Where, as you know, pancake == ruby web thing.
6
+
7
+ It essentially takes the awesome "rack":rack.github.com and "rack router":http://github.com/carllerche/rack-router/ and mixes it with flour and water and eggs to bind it together into a pancake thin layer of goodness providing a structured way of orgnaising (stacking) your assortment of ruby web things. In doing so, it allows you to provide each of your ruby web things (lets call them "middlewares") with some underlying contextual functionality.
8
+
9
+ h3. Why stack pancakes?
10
+
11
+ Well, simply put, reuse! I'm building something... and what do you know i need another forum/asset manager/bla thing etc. Typically I can:
12
+
13
+ * Write/include the functionality directly in to my current app.
14
+ * Add a second app, theme it up similarly and use apache/nginx/other configs to glue it up, and perhaps come up with a devious approach for auth with some cunning SSO... or not
15
+
16
+ What we'd like to facilitate with pancake is you take your existing much loved forum/asset manager/bla thing etc and mount it into pancake, sharing auth and other contextual information between apps.
17
+
18
+ Insert helpful diagram here...
19
+
20
+ h3. Getting Started
21
+
22
+ h4. You'll need to have installed (as well as your usual ruby stuffs)...
23
+
24
+ * wycats-thor
25
+ * Carllerches rack router
26
+
27
+ h4. Installing
28
+
29
+ <pre>
30
+ $sudo gem install hassox-pancake
31
+ </pre>
32
+
33
+ h4. Create your own stack
34
+
35
+ <pre>
36
+ $pancake-gen stack yummy-app
37
+ </pre>
38
+
39
+ h4. Does it work?
40
+
41
+ (I've used curl here, feel free to use your point your browser to http://localhost:9292/ instead)
42
+ <pre>
43
+ $cd yummy-app/lib/yummy-app
44
+ $rackup config.ru
45
+ Loading Development Environment
46
+ </pre>
47
+
48
+ Now in your browser, visit http://localhost:9292/
49
+ Or, with curl like here:
50
+ <pre>
51
+ $curl -I localhost:9292
52
+ 127.0.0.1 - - [26/Jul/2009 15:42:55] "HEAD / HTTP/1.1" 404 9 0.0011
53
+ HTTP/1.1 404 Not Found
54
+ Connection: close
55
+ Date: Sun, 26 Jul 2009 05:42:55 GMT
56
+ Content-Type: text/plain
57
+ Content-Length: 9
58
+ </pre>
59
+
60
+ You should see 'NOT FOUND' in your browser window and something like this appear in your rackup console window.
61
+
62
+ <pre>
63
+ 127.0.0.1 - - [26/Jul/2009 15:42:55] "GET / HTTP/1.1" 404 9 0.0011
64
+ </pre>
65
+
66
+ That 404 is good news! The stack is running.. we just haven't cooked any pancakes yet, theres nothing to find. Next step add something...
67
+
68
+ h4. Routing
69
+
70
+ Edit config/router.rb with:
71
+ <pre>
72
+ home = lambda {|e| [200,{"Content-Type" => "text/plain", "Content-Length" => "12"}, "Welcome home" ]}
73
+
74
+ YummyApp.add_routes do |r|
75
+ r.map "/", :to => home
76
+ end
77
+ </pre>
78
+ Now, restart the server (^C) and try again:
79
+ <pre>
80
+ $rackup config.ru
81
+ Loading Development Environment
82
+ </pre>
83
+ Reload you page and you should see "Welcome home".
84
+ And, in your console window, rack should log the request like so:
85
+ <pre>
86
+ 127.0.0.1 - - [26/Jul/2009 16:16:23] "GET / HTTP/1.1" 200 12 0.0012
87
+ 127.0.0.1 - - [26/Jul/2009 16:16:23] "GET /favicon.ico HTTP/1.1" 200 12 0.0012
88
+ </pre>
89
+
90
+ h4. Whats next:
91
+
92
+ Well we don't want to be writing our apps as lambdas jemmied into the router, instead next we start to build stacks, out of other middlewares... merbs, other pancake stacks, some sinatra, more rack ups or what ever.
93
+
94
+ To be continued...
95
+
data/Rakefile ADDED
@@ -0,0 +1,56 @@
1
+ require 'rubygems'
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.5.5"
15
+ gem.add_dependency "mynyml-rack-accept-media-types"
16
+ gem.require_path = 'lib'
17
+ gem.autorequire = 'pancake'
18
+ gem.bindir = "bin"
19
+ gem.executables = %w( pancake-gen )
20
+ gem.files = %w(LICENSE README.textile Rakefile TODO) + Dir.glob("{lib,spec,bin}/**/{*,.[a-z]*}")
21
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
22
+ end
23
+ rescue LoadError
24
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
25
+ end
26
+
27
+ require 'spec/rake/spectask'
28
+ Spec::Rake::SpecTask.new(:spec) do |spec|
29
+ spec.libs << 'lib' << 'spec'
30
+ spec.spec_opts = %w(--format progress --color)
31
+ spec.spec_files = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
35
+ spec.libs << 'lib' << 'spec'
36
+ spec.pattern = 'spec/**/*_spec.rb'
37
+ spec.rcov = true
38
+ end
39
+
40
+ task :spec => :check_dependencies
41
+
42
+ task :default => :spec
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ if File.exist?('VERSION')
47
+ version = File.read('VERSION')
48
+ else
49
+ version = ""
50
+ end
51
+
52
+ rdoc.rdoc_dir = 'rdoc'
53
+ rdoc.title = "pancake #{version}"
54
+ rdoc.rdoc_files.include('README*')
55
+ rdoc.rdoc_files.include('lib/**/*.rb')
56
+ end
data/TODO ADDED
@@ -0,0 +1,17 @@
1
+ TODO:
2
+
3
+ * Add default middleware to the short stack
4
+ * Add a default base template and some default css to the short stack
5
+ * Add a global logger
6
+ * Add some view helpers
7
+ ** url, link_to, form_for, form_field_helpers (can we use formtastic), v[:data]
8
+ * Add partial support
9
+ * Add sass support so that a stack can compile sass
10
+ * Add a mechanism for a rake task to be called on the parent and all mounted stacks
11
+ * Add a way to cache public files into the pancake roots public directory
12
+ * Add bundler support
13
+ * Do some introductory posts
14
+ * optimise template lookup
15
+ * Add caching / symlinking option for static middlware to prevent lookup
16
+ * Add a rake task to copy / symlink all mounted apps public files into the public Pancake.public directory
17
+
data/bin/jeweler ADDED
@@ -0,0 +1,19 @@
1
+ #!/opt/local/bin/ruby
2
+ #
3
+ # This file was generated by RubyGems.
4
+ #
5
+ # The application 'jeweler' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'rubygems'
10
+
11
+ version = ">= 0"
12
+
13
+ if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
14
+ version = $1
15
+ ARGV.shift
16
+ end
17
+
18
+ gem 'jeweler', version
19
+ load Gem.bin_path('jeweler', 'jeweler', version)
data/bin/pancake-gen ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'thor'
4
+ require 'thor/runner'
5
+ require 'pancake/generators'
6
+
7
+ # TODO update for pancake to have a version
8
+ case ARGV.shift
9
+ when "stack"
10
+ Pancake::Generators::Stack.start
11
+ when "short"
12
+ Pancake::Generators::Short.start
13
+ when "micro"
14
+ Pancake::Generators::Micro.start
15
+ else
16
+ puts "Unknown Generator"
17
+ end
data/bin/rubyforge ADDED
@@ -0,0 +1,19 @@
1
+ #!/opt/local/bin/ruby
2
+ #
3
+ # This file was generated by RubyGems.
4
+ #
5
+ # The application 'rubyforge' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'rubygems'
10
+
11
+ version = ">= 0"
12
+
13
+ if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
14
+ version = $1
15
+ ARGV.shift
16
+ end
17
+
18
+ gem 'rubyforge', version
19
+ load Gem.bin_path('rubyforge', 'rubyforge', version)
@@ -0,0 +1,180 @@
1
+ require 'set'
2
+ module Pancake
3
+ module BootLoaderMixin
4
+ include Enumerable
5
+ class Base
6
+ # :api: :public
7
+ attr_accessor :config
8
+
9
+ # Sets options for the bootloder
10
+ # By including conditions in the bootloader when you declare it
11
+ # You can selectively run bootloaders later
12
+ # :api: private
13
+ def self.options=(opts={}) # :nodoc:
14
+ @options = opts
15
+ @options[:level] ||= :default
16
+ end
17
+
18
+ # Provides access to the bootloader options
19
+ # :api: private
20
+ def self.options # :nodoc:
21
+ @options ||= {}
22
+ end
23
+
24
+ def stack
25
+ raise "No Stack Configured" unless @config[:stack]
26
+ @config[:stack]
27
+ end
28
+
29
+ def stack_class
30
+ raise "No Stack Class Configured" unless @config[:stack_class]
31
+ @config[:stack_class]
32
+ end
33
+
34
+ def initialize(config)
35
+ @config = config
36
+ end
37
+
38
+ # Creates a new instance and runs it
39
+ # :api: private
40
+ def self.call(config)
41
+ new(config).run!
42
+ end
43
+
44
+ # Checks the conditions with the options of the bootloader
45
+ # To see if this one should be run
46
+ # Only the central bootloaders with the conditions will be checked
47
+ # :api: private
48
+ def self.run?(conditions = {})
49
+ opts = options
50
+ if conditions.keys.include?(:only)
51
+ return conditions[:only].all?{|k,v| opts[k] == v}
52
+ end
53
+ if conditions.keys.include?(:except)
54
+ return conditions[:except].all?{|k,v| opts[k] != v}
55
+ end
56
+ true
57
+ end
58
+ end
59
+
60
+ def self.extended(base)
61
+ base.class_eval do
62
+ class_inheritable_reader :_bootloaders, :_central_bootloaders, :_bootloader_map
63
+ @_bootloaders, @_central_bootloaders = {}, []
64
+ @_bootloader_map = Hash.new{|h,k| h[k] = {:before => [], :after => []}}
65
+ end
66
+ end
67
+
68
+ # Provides access to an individual bootloader
69
+ # :api: public
70
+ def [](name)
71
+ _bootloaders[name]
72
+ end
73
+
74
+ # Add a bootloader. Inside the block we're inside a class definition.
75
+ # Requirements: define a +run!+ method
76
+ #
77
+ # Example
78
+ # FooStack::BootLoader.add(:foo) do
79
+ # def run!
80
+ # # stuff
81
+ # end
82
+ # end
83
+ #
84
+ # :api: public
85
+ def add(name, opts = {}, &block)
86
+ _bootloaders[name] = Class.new(Pancake::BootLoaderMixin::Base, &block)
87
+ raise "You must declare a #run! method on your bootloader" unless _bootloaders[name].method_defined?(:run!)
88
+ before = opts[:before]
89
+ after = opts[:after]
90
+
91
+ if opts[:level]
92
+ levels << opts[:level]
93
+ levels.uniq!
94
+ end
95
+
96
+ # If there are no before or after keys, add it to the central bootloaders
97
+ if before
98
+ _bootloader_map[before][:before] << name
99
+ elsif after
100
+ _bootloader_map[after][:after] << name
101
+ else
102
+ _central_bootloaders << name unless _central_bootloaders.include?(name)
103
+ end
104
+ _bootloaders[name].options = opts
105
+ _bootloaders[name]
106
+ end
107
+
108
+ # Runs the bootloaders in order
109
+ # :api: private
110
+ def run!(options = {}) # :nodoc:
111
+ unless options.keys.include?(:only) || options.keys.include?(:except)
112
+ options[:only] = {:level => :default}
113
+ end
114
+ conditions = if options[:only]
115
+ {:only => options.delete(:only)}
116
+ else
117
+ {:except => options.delete(:except)}
118
+ end
119
+ options[:stack_class] ||= stack
120
+
121
+ each(conditions) do |name, bl|
122
+ bl.call(options)
123
+ end
124
+ end
125
+
126
+ # Set the stack that this bootloader is responsible for.
127
+ # :api: private
128
+ def stack=(stack) # :nodoc:
129
+ @stack = stack
130
+ end
131
+
132
+ # Access to the stack that this bootloader is responsible for
133
+ # :api: public
134
+ def stack
135
+ @stack ||= Object.full_const_get(self.name.split("::")[0..-2].join("::"))
136
+ end
137
+
138
+ # Resets the bootloaders on the stack
139
+ # :api: public
140
+ def reset!
141
+ _central_bootloaders.clear
142
+ _bootloaders.clear
143
+ _bootloader_map.clear
144
+ end
145
+
146
+ # Yields each bootloader in order along with it's name
147
+ #
148
+ # Example
149
+ # FooStack::BootLoader.each do |name, bootloader|
150
+ # # do stuff
151
+ # end
152
+ #
153
+ # :api: public
154
+ def each(conditions = {})
155
+ _map_bootloaders(_central_bootloaders, conditions).each do |n|
156
+ yield n, _bootloaders[n]
157
+ end
158
+ end
159
+
160
+ private
161
+ # Map out the bootloaders by name to run.
162
+ # :api: private
163
+ def _map_bootloaders(*names)
164
+ conditions = Hash === names.last ? names.pop : {}
165
+ names.flatten.map do |name|
166
+ if _bootloaders[name].run?(conditions)
167
+ r = []
168
+ r << _map_bootloaders(_bootloader_map[name][:before])
169
+ r << name
170
+ r << _map_bootloaders(_bootloader_map[name][:after])
171
+ end
172
+ end.flatten.compact
173
+ end
174
+
175
+ def levels
176
+ @levels ||= [:default]
177
+ end
178
+
179
+ end # BootLoaders
180
+ end # Pancake
@@ -0,0 +1,145 @@
1
+ module Pancake
2
+ class Configuration
3
+
4
+ class Base
5
+ class_inheritable_reader :defaults
6
+ @defaults = Hash.new{|h,k| h[k] = {:value => nil, :description => ""}}
7
+
8
+ # Set a default on the the configuartion
9
+ class << self
10
+
11
+ # Set a default for this configuration class
12
+ # Provide a field/method name and a value to set this to.
13
+ # If you don't provide a value, and instead provide a block, then
14
+ # a proc will be called lazily when requested.
15
+ #
16
+ # Example
17
+ # config_klass = Pancake::Configuration.make
18
+ # config_class.default :foo, :bar, "This foo is a bar"
19
+ # config = config_class.new
20
+ #
21
+ # :api: public
22
+ def default(meth, *args, &block)
23
+ value, description = args
24
+ if block
25
+ description = value
26
+ value = block
27
+ end
28
+ defaults[meth][:value] = value
29
+ defaults[meth][:description] = description || ""
30
+ end
31
+
32
+ # Provides aaccess to the description for a default setting
33
+ #
34
+ # :api: public
35
+ def description_for(field)
36
+ defaults.keys.include?(field) ? defaults[field][:description] : ""
37
+ end
38
+ end
39
+
40
+ # access to the singleton class
41
+ # :api: private
42
+ def singleton_class # :nodoc:
43
+ class << self; self; end
44
+ end
45
+
46
+ # Access to the configuration defaults via the instance. Defers to the
47
+ # clas smethod for defaults
48
+ # :api: public
49
+ def defaults
50
+ self.class.defaults
51
+ end
52
+
53
+ # Access to the class descritpion for defaults
54
+ # :api: public
55
+ def description_for(field)
56
+ self.class.description_for(field)
57
+ end
58
+
59
+ # Access to the currently set values for this configuration object
60
+ # :api: public
61
+ def values
62
+ @values ||= {}
63
+ end
64
+
65
+ private
66
+ def method_missing(name, *args)
67
+ if name.to_s =~ /(.*?)=$/
68
+ set_actual_value($1.to_sym, args.first)
69
+ else
70
+ if defaults.keys.include?(name) # We don't want to trigger a default value if we're blindly setting it
71
+ # If the default is a proc, do not cache it
72
+ case defaults[name][:value]
73
+ when Proc
74
+ instance_eval(&defaults[name][:value])
75
+ else
76
+ val = defaults[name][:value]
77
+ val = val.dup rescue val
78
+ set_actual_value(name, val)
79
+ end
80
+ else
81
+ nil
82
+ end
83
+ end
84
+ end
85
+
86
+ # Caches the values via a method rather than going through method_missing
87
+ # :api: private
88
+ def set_actual_value(name, val) # :nodoc:
89
+ singleton_class.class_eval <<-RUBY
90
+ def #{name}=(val) # def foo=(val)
91
+ values[#{name.inspect}] = val # values[:foo] = val
92
+ end # end
93
+
94
+ def #{name} # def foo
95
+ values[#{name.inspect}] # values[:foo]
96
+ end # end
97
+ RUBY
98
+ values[name] = val
99
+ end
100
+
101
+ end # Base
102
+
103
+ class << self
104
+
105
+ # Make a new configuration class
106
+ # :api: public
107
+ def make(&block)
108
+ Class.new(Pancake::Configuration::Base, &block)
109
+ end
110
+
111
+ end # self
112
+ end # Configuration
113
+
114
+ class PancakeConfig < Configuration::Base
115
+ def stacks(label = nil)
116
+ @stacks ||= {}
117
+ result = label.nil? ? @stacks : @stacks[label]
118
+ yield result if block_given?
119
+ result
120
+ end
121
+
122
+ def configs(label = nil)
123
+ @configs ||= Hash.new do |h,k|
124
+ if (k.is_a?(Class) || k.is_a?(Module)) && defined?(k::Configuration)
125
+ h[k] = k::Configuration.new
126
+ else
127
+ nil
128
+ end
129
+ end
130
+ result = label.nil? ? @configs : @configs[label]
131
+ yield result if block_given?
132
+ result
133
+ end
134
+ end
135
+
136
+ def self.configuration
137
+ @configuration ||= PancakeConfig.new
138
+ end
139
+
140
+ def self.reset_configuration
141
+ @configuration = nil
142
+ end
143
+
144
+ end # Pancake
145
+
@@ -0,0 +1,5 @@
1
+ module Pancake
2
+ module Constants
3
+ ENV_LOGGER_KEY = "rack.logger"
4
+ end
5
+ end
@@ -0,0 +1,44 @@
1
+ class Class
2
+ # Taken from extlib but uses a full Marshall.dump rather than just a dup.
3
+ # This may not work for some data types. The data must be marshalable to use this method.
4
+ #
5
+ # Defines class-level inheritable attribute reader. Attributes are available to subclasses,
6
+ # each subclass has a copy of parent's attribute.
7
+ #
8
+ # @param *syms<Array[#to_s]> Array of attributes to define inheritable reader for.
9
+ # @return <Array[#to_s]> Array of attributes converted into inheritable_readers.
10
+ #
11
+ # @api public
12
+ #
13
+ # @todo Do we want to block instance_reader via :instance_reader => false
14
+ # @todo It would be preferable that we do something with a Hash passed in
15
+ # (error out or do the same as other methods above) instead of silently
16
+ # moving on). In particular, this makes the return value of this function
17
+ # less useful.
18
+ def deep_copy_class_inheritable_reader(*ivars)
19
+ instance_reader = ivars.pop[:reader] if ivars.last.is_a?(Hash)
20
+
21
+ ivars.each do |ivar|
22
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
23
+ def self.#{ivar}
24
+ return @#{ivar} if self == #{self} || defined?(@#{ivar})
25
+ ivar = superclass.#{ivar}
26
+ return nil if ivar.nil? && !#{self}.instance_variable_defined?("@#{ivar}")
27
+ @#{ivar} = ivar && !ivar.is_a?(Module) && !ivar.is_a?(Numeric) ? Marshal.load(Marshal.dump(ivar)) : ivar
28
+ end
29
+ RUBY
30
+ unless instance_reader == false
31
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
32
+ def #{ivar}
33
+ self.class.#{ivar}
34
+ end
35
+ RUBY
36
+ end # unless
37
+ end # ivars.each
38
+ end # self.deep_inheritable_reader
39
+
40
+ def deep_copy_class_inheritable_accessor(*ivars)
41
+ deep_copy_class_inheritable_reader(*ivars)
42
+ class_inheritable_writer(*ivars)
43
+ end
44
+ end # Class
@@ -0,0 +1,22 @@
1
+ class Object
2
+ extend ::Pancake::Hooks::InheritableInnerClasses
3
+ end
4
+
5
+ # Vendored from http://eigenclass.org/hiki/instance_exec
6
+ # 2009-06-02
7
+ # Adapted for ruby 1.9 where the method is deinfed on Object
8
+ unless Object.method_defined?(:instance_exec)
9
+ class Object
10
+ # Like instace_eval but allows parameters to be passed.
11
+ def instance_exec(*args, &block)
12
+ mname = "__instance_exec_#{Thread.current.object_id.abs}_#{object_id.abs}"
13
+ Object.class_eval{ define_method(mname, &block) }
14
+ begin
15
+ ret = send(mname, *args)
16
+ ensure
17
+ Object.class_eval{ undef_method(mname) } rescue nil
18
+ end
19
+ ret
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ # Taken from Rails d6b9f8410c990b3d68d1970f1461a1d385d098d7 20090731
2
+ unless :to_proc.respond_to?(:to_proc)
3
+ class Symbol
4
+ # Turns the symbol into a simple proc, which is especially useful for enumerations. Examples:
5
+ #
6
+ # # The same as people.collect { |p| p.name }
7
+ # people.collect(&:name)
8
+ #
9
+ # # The same as people.select { |p| p.manager? }.collect { |p| p.salary }
10
+ # people.select(&:manager?).collect(&:salary)
11
+ def to_proc
12
+ Proc.new { |*args| args.shift.__send__(self, *args) }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ class Pancake::PancakeConfig
2
+ default :log_path, Proc.new{ "log/pancake_#{Pancake.env}.log"}
3
+ default :log_level, :info
4
+ default :log_delimiter, " ~ "
5
+ default :log_auto_flush, true
6
+ default :log_to_file, Proc.new{ Pancake.env == "production" }
7
+ default :log_stream, Proc.new{ _log_stream }
8
+
9
+ def _log_stream
10
+ if Pancake.configuration.log_to_file
11
+ log_dir = File.expand_path(File.join(Pancake.root, File.dirname(log_path)))
12
+ FileUtils.mkdir_p(log_dir)
13
+ File.join(log_dir, File.basename(log_path))
14
+ else
15
+ STDOUT
16
+ end
17
+ end
18
+
19
+ def reset_log_stream!
20
+ values.delete(:log_stream)
21
+ end
22
+ end
@@ -0,0 +1 @@
1
+ Pancake.stack(:logger).use(Pancake::Middlewares::Logger)