hassox-pancake 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.textile +95 -0
- data/Rakefile +56 -0
- data/TODO +18 -0
- data/bin/jeweler +19 -0
- data/bin/pancake-gen +17 -0
- data/bin/rubyforge +19 -0
- data/lib/pancake.rb +48 -0
- data/lib/pancake/bootloaders.rb +180 -0
- data/lib/pancake/configuration.rb +140 -0
- data/lib/pancake/core_ext/class.rb +44 -0
- data/lib/pancake/core_ext/object.rb +22 -0
- data/lib/pancake/core_ext/symbol.rb +15 -0
- data/lib/pancake/errors.rb +61 -0
- data/lib/pancake/generators.rb +8 -0
- data/lib/pancake/generators/base.rb +12 -0
- data/lib/pancake/generators/flat_generator.rb +17 -0
- data/lib/pancake/generators/short_generator.rb +17 -0
- data/lib/pancake/generators/stack_generator.rb +17 -0
- data/lib/pancake/generators/templates/common/dotgitignore +22 -0
- data/lib/pancake/generators/templates/common/dothtaccess +17 -0
- data/lib/pancake/generators/templates/flat/%stack_name%/%stack_name%.rb.tt +8 -0
- data/lib/pancake/generators/templates/flat/%stack_name%/.gitignore +21 -0
- data/lib/pancake/generators/templates/flat/%stack_name%/config.ru.tt +12 -0
- data/lib/pancake/generators/templates/flat/%stack_name%/pancake.init.tt +1 -0
- data/lib/pancake/generators/templates/flat/%stack_name%/public/.empty_directory +0 -0
- data/lib/pancake/generators/templates/flat/%stack_name%/tmp/.empty_directory +0 -0
- data/lib/pancake/generators/templates/short/%stack_name%/.gitignore +21 -0
- data/lib/pancake/generators/templates/short/%stack_name%/LICENSE.tt +20 -0
- data/lib/pancake/generators/templates/short/%stack_name%/README.tt +7 -0
- data/lib/pancake/generators/templates/short/%stack_name%/Rakefile.tt +48 -0
- data/lib/pancake/generators/templates/short/%stack_name%/VERSION.tt +1 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%.rb.tt +5 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/%stack_name%.rb.tt +6 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/config.ru.tt +12 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/gems/cache/.empty_directory +0 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/mounts/.empty_directory +0 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/public/.empty_directory +0 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/tmp/.empty_directory +0 -0
- data/lib/pancake/generators/templates/short/%stack_name%/pancake.init.tt +1 -0
- data/lib/pancake/generators/templates/short/%stack_name%/spec/%stack_name%_spec.rb.tt +7 -0
- data/lib/pancake/generators/templates/short/%stack_name%/spec/spec_helper.rb.tt +9 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/.gitignore +21 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/LICENSE.tt +20 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/README.tt +7 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/Rakefile.tt +48 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/VERSION.tt +1 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%.rb.tt +3 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config.ru.tt +12 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config/environments/development.rb.tt +18 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config/environments/production.rb.tt +18 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config/router.rb.tt +6 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/gems/cache/.empty_directory +0 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/mounts/.empty_directory +0 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/public/.empty_directory +0 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/tmp/.empty_directory +0 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/pancake.init.tt +1 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/spec/%stack_name%_spec.rb.tt +7 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/spec/spec_helper.rb.tt +9 -0
- data/lib/pancake/hooks/inheritable_inner_classes.rb +60 -0
- data/lib/pancake/hooks/on_inherit.rb +34 -0
- data/lib/pancake/master.rb +87 -0
- data/lib/pancake/middleware.rb +354 -0
- data/lib/pancake/mime_types.rb +265 -0
- data/lib/pancake/mixins/publish.rb +125 -0
- data/lib/pancake/mixins/publish/action_options.rb +104 -0
- data/lib/pancake/mixins/render.rb +61 -0
- data/lib/pancake/mixins/request_helper.rb +92 -0
- data/lib/pancake/mixins/stack_helper.rb +44 -0
- data/lib/pancake/mixins/url.rb +10 -0
- data/lib/pancake/more/controller.rb +4 -0
- data/lib/pancake/more/controller/base.rb +34 -0
- data/lib/pancake/paths.rb +218 -0
- data/lib/pancake/router.rb +99 -0
- data/lib/pancake/stack/app.rb +10 -0
- data/lib/pancake/stack/bootloader.rb +79 -0
- data/lib/pancake/stack/configuration.rb +44 -0
- data/lib/pancake/stack/middleware.rb +0 -0
- data/lib/pancake/stack/router.rb +18 -0
- data/lib/pancake/stack/stack.rb +57 -0
- data/lib/pancake/stacks/short.rb +2 -0
- data/lib/pancake/stacks/short/controller.rb +105 -0
- data/lib/pancake/stacks/short/stack.rb +194 -0
- data/spec/helpers/helpers.rb +20 -0
- data/spec/helpers/matchers.rb +25 -0
- data/spec/pancake/bootloaders_spec.rb +109 -0
- data/spec/pancake/configuration_spec.rb +177 -0
- data/spec/pancake/fixtures/foo_stack/pancake.init +0 -0
- data/spec/pancake/fixtures/paths/controllers/controller1.rb +0 -0
- data/spec/pancake/fixtures/paths/controllers/controller2.rb +0 -0
- data/spec/pancake/fixtures/paths/controllers/controller3.rb +0 -0
- data/spec/pancake/fixtures/paths/models/model1.rb +0 -0
- data/spec/pancake/fixtures/paths/models/model2.rb +0 -0
- data/spec/pancake/fixtures/paths/models/model3.rb +0 -0
- data/spec/pancake/fixtures/paths/stack/controllers/controller1.rb +0 -0
- data/spec/pancake/fixtures/paths/stack/models/model3.rb +0 -0
- data/spec/pancake/fixtures/paths/stack/views/view1.erb +0 -0
- data/spec/pancake/fixtures/paths/stack/views/view1.rb +0 -0
- data/spec/pancake/fixtures/paths/stack/views/view2.erb +0 -0
- data/spec/pancake/fixtures/paths/stack/views/view2.haml +0 -0
- data/spec/pancake/fixtures/render_templates/context_template.html.erb +1 -0
- data/spec/pancake/fixtures/render_templates/erb_template.html.erb +1 -0
- data/spec/pancake/fixtures/render_templates/erb_template.json.erb +1 -0
- data/spec/pancake/fixtures/render_templates/haml_template.html.haml +1 -0
- data/spec/pancake/fixtures/render_templates/haml_template.xml.haml +1 -0
- data/spec/pancake/hooks/on_inherit_spec.rb +65 -0
- data/spec/pancake/inheritance_spec.rb +100 -0
- data/spec/pancake/middleware_spec.rb +401 -0
- data/spec/pancake/mime_types_spec.rb +234 -0
- data/spec/pancake/mixins/publish_spec.rb +94 -0
- data/spec/pancake/mixins/render_spec.rb +55 -0
- data/spec/pancake/mixins/stack_helper_spec.rb +46 -0
- data/spec/pancake/pancake_spec.rb +31 -0
- data/spec/pancake/paths_spec.rb +210 -0
- data/spec/pancake/stack/app_spec.rb +28 -0
- data/spec/pancake/stack/bootloader_spec.rb +41 -0
- data/spec/pancake/stack/middleware_spec.rb +0 -0
- data/spec/pancake/stack/router_spec.rb +266 -0
- data/spec/pancake/stack/stack_configuration_spec.rb +101 -0
- data/spec/pancake/stack/stack_spec.rb +55 -0
- data/spec/pancake/stacks/short/controller_spec.rb +287 -0
- data/spec/pancake/stacks/short/router_spec.rb +132 -0
- data/spec/pancake/stacks/short/stack_spec.rb +40 -0
- data/spec/spec_helper.rb +21 -0
- metadata +238 -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,18 @@
|
|
1
|
+
TODO:
|
2
|
+
|
3
|
+
Controller Publish Declaration:
|
4
|
+
Allow requirements to be declared for multiple controllers at once
|
5
|
+
Support syntax for coercing multiple values into a single param entry i.e. two date strings into a range
|
6
|
+
Default values should be generated with a method rather than a static value alone
|
7
|
+
The list of params should be able to be flagged as exclusive i.e. no additional parameters may be passed in
|
8
|
+
Handle nested params
|
9
|
+
Collect options suitable for a OPTIONS request from a client
|
10
|
+
Mechanism to whitelist fields from a model
|
11
|
+
|
12
|
+
Renderable Mixin
|
13
|
+
Design interface for adapters -- adapters allow support for different template libs
|
14
|
+
Compiled templates need to be cached
|
15
|
+
Options used by the mixin need to be configurable
|
16
|
+
Templates should be inheritable
|
17
|
+
The target class should be able to inject arbitrary helpers into the template context
|
18
|
+
Layouts, views and partials should be supported
|
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 "flat"
|
14
|
+
Pancake::Generators::Flat.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)
|
data/lib/pancake.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'extlib/class'
|
3
|
+
require 'extlib/boolean'
|
4
|
+
require 'extlib/module'
|
5
|
+
require 'extlib/nil'
|
6
|
+
require 'extlib/numeric'
|
7
|
+
require 'extlib/object'
|
8
|
+
require 'extlib/symbol'
|
9
|
+
require 'extlib/blank'
|
10
|
+
require "extlib/dictionary"
|
11
|
+
require 'usher'
|
12
|
+
require 'usher/interface/rack_interface'
|
13
|
+
require 'tilt'
|
14
|
+
|
15
|
+
$:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
16
|
+
|
17
|
+
require 'pancake/paths'
|
18
|
+
require 'pancake/hooks/on_inherit'
|
19
|
+
require 'pancake/hooks/inheritable_inner_classes'
|
20
|
+
require 'pancake/core_ext/class'
|
21
|
+
require 'pancake/core_ext/object'
|
22
|
+
require 'pancake/core_ext/symbol'
|
23
|
+
require 'pancake/configuration'
|
24
|
+
require 'pancake/bootloaders'
|
25
|
+
require 'pancake/mime_types'
|
26
|
+
require 'pancake/middleware'
|
27
|
+
require 'pancake/router'
|
28
|
+
require 'pancake/master'
|
29
|
+
require 'pancake/errors'
|
30
|
+
require 'pancake/stack/stack'
|
31
|
+
require 'pancake/stack/configuration'
|
32
|
+
require 'pancake/stack/router'
|
33
|
+
require 'pancake/stack/bootloader'
|
34
|
+
require 'pancake/stack/app'
|
35
|
+
require 'pancake/mixins/request_helper'
|
36
|
+
|
37
|
+
module Pancake
|
38
|
+
|
39
|
+
module Stacks
|
40
|
+
autoload :Short, "pancake/stacks/short"
|
41
|
+
end
|
42
|
+
|
43
|
+
module Mixins
|
44
|
+
autoload :Publish, "pancake/mixins/publish"
|
45
|
+
autoload :Render, "pancake/mixins/render"
|
46
|
+
autoload :StackHelper, "pancake/mixins/stack_helper"
|
47
|
+
end
|
48
|
+
end
|
@@ -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
|