middleman 2.0.4 → 2.0.5
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.
- data/CHANGELOG +8 -0
- data/lib/middleman.rb +7 -1
- data/lib/middleman/vendor/padrino-core-0.10.0/.document +5 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/.gitignore +22 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/LICENSE +20 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/README.rdoc +294 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/Rakefile +5 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/bin/padrino +9 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core.rb +119 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/application.rb +259 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/application/rendering.rb +228 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/application/routing.rb +821 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/application/showexceptions.rb +18 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/caller.rb +45 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/cli/adapter.rb +24 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/cli/base.rb +152 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/cli/console.rb +20 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/cli/rake.rb +24 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/cli/rake_tasks.rb +59 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/command.rb +27 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/images/404.png +0 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/images/500.png +0 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/loader.rb +182 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/cz.yml +30 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/da.yml +30 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/de.yml +30 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/en.yml +30 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/es.yml +30 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/fr.yml +30 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/hu.yml +30 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/it.yml +37 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/ja.yml +30 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/nl.yml +30 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/no.yml +31 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/pl.yml +30 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/pt_br.yml +37 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/ru.yml +30 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/tr.yml +30 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/uk.yml +30 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/zh_cn.yml +30 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/locale/zh_tw.yml +30 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/logger.rb +344 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/mounter.rb +192 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/reloader.rb +247 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/router.rb +79 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/server.rb +70 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/support_lite.rb +135 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/tasks.rb +23 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/lib/padrino-core/version.rb +15 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/padrino-core.gemspec +38 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/apps/.components +6 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/apps/.gitignore +7 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/apps/complex.rb +27 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/apps/simple.rb +33 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/a.rb +9 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/b.rb +4 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/c.rb +1 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/circular/e.rb +13 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/circular/f.rb +2 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/circular/g.rb +2 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/fixtures/dependencies/d.rb +4 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/helper.rb +101 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_application.rb +83 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_core.rb +79 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_dependencies.rb +44 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_filters.rb +266 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_logger.rb +91 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_mounter.rb +176 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_reloader_complex.rb +66 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_reloader_simple.rb +97 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_rendering.rb +437 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_router.rb +146 -0
- data/lib/middleman/vendor/padrino-core-0.10.0/test/test_routing.rb +1491 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/.document +5 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/.gitignore +21 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/LICENSE +20 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/README.rdoc +239 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/Rakefile +5 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers.rb +51 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/asset_tag_helpers.rb +288 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/form_builder/abstract_form_builder.rb +220 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/form_builder/standard_form_builder.rb +43 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/form_helpers.rb +446 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/format_helpers.rb +260 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/cz.yml +103 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/da.yml +91 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/de.yml +78 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/en.yml +103 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/es.yml +103 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/fr.yml +79 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/hu.yml +103 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/it.yml +85 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/ja.yml +103 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/nl.yml +78 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/no.yml +91 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/pl.yml +95 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/pt_br.yml +103 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/ru.yml +103 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/tr.yml +103 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/uk.yml +103 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/zh_cn.yml +103 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/locale/zh_tw.yml +103 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/number_helpers.rb +273 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/output_helpers.rb +128 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/output_helpers/abstract_handler.rb +103 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/output_helpers/erb_handler.rb +79 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/output_helpers/haml_handler.rb +64 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/output_helpers/slim_handler.rb +82 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/render_helpers.rb +40 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/tag_helpers.rb +59 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/lib/padrino-helpers/translation_helpers.rb +21 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/padrino-helpers.gemspec +27 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/app.rb +73 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/capture_concat.erb +14 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/capture_concat.haml +12 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/capture_concat.slim +13 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/content_for.erb +11 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/content_for.haml +9 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/content_for.slim +9 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/content_tag.erb +11 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/content_tag.haml +9 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/content_tag.slim +9 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/current_engine.erb +5 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/current_engine.haml +5 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/current_engine.slim +5 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/fields_for.erb +20 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/fields_for.haml +15 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/fields_for.slim +15 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/form_for.erb +56 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/form_for.haml +47 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/form_for.slim +47 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/form_tag.erb +56 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/form_tag.haml +45 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/form_tag.slim +45 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/link_to.erb +5 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/link_to.haml +4 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/link_to.slim +4 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/mail_to.erb +3 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/mail_to.haml +3 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/mail_to.slim +3 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/meta_tag.erb +3 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/meta_tag.haml +3 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/meta_tag.slim +3 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/partials/_erb.erb +1 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/partials/_haml.haml +1 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/partials/_slim.slim +1 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/simple_partial.erb +1 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/simple_partial.haml +1 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/markup_app/views/simple_partial.slim +1 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/app.rb +45 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/current_engine.haml +5 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/current_engines/_erb.erb +1 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/current_engines/_haml.haml +1 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/current_engines/_slim.slim +1 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/erb/test.erb +1 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/explicit_engine.haml +5 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/haml/test.haml +1 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/template/_user.haml +7 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/template/haml_template.haml +1 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/fixtures/render_app/views/template/some_template.haml +2 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/helper.rb +78 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_asset_tag_helpers.rb +320 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_form_builder.rb +998 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_form_helpers.rb +645 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_format_helpers.rb +227 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_number_helpers.rb +136 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_output_helpers.rb +133 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_render_helpers.rb +69 -0
- data/lib/middleman/vendor/padrino-helpers-0.10.0/test/test_tag_helpers.rb +100 -0
- data/lib/middleman/version.rb +1 -1
- data/middleman.gemspec +6 -2
- metadata +218 -67
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
module Padrino
|
|
2
|
+
##
|
|
3
|
+
# Represents a particular mounted padrino application
|
|
4
|
+
# Stores the name of the application (app folder name) and url mount path
|
|
5
|
+
#
|
|
6
|
+
# ==== Examples
|
|
7
|
+
#
|
|
8
|
+
# Mounter.new("blog_app", :app_class => "Blog").to("/blog")
|
|
9
|
+
# Mounter.new("blog_app", :app_file => "/path/to/blog/app.rb").to("/blog")
|
|
10
|
+
#
|
|
11
|
+
class Mounter
|
|
12
|
+
class MounterException < RuntimeError #:nodoc:
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
attr_accessor :name, :uri_root, :app_file, :app_class, :app_root, :app_obj, :app_host
|
|
16
|
+
|
|
17
|
+
def initialize(name, options={})
|
|
18
|
+
@name = name.to_s
|
|
19
|
+
@app_class = options[:app_class] || @name.camelize
|
|
20
|
+
@app_file = options[:app_file] || locate_app_file
|
|
21
|
+
@app_obj = options[:app_obj] || app_constant || locate_app_object
|
|
22
|
+
ensure_app_file! || ensure_app_object!
|
|
23
|
+
@app_root = options[:app_root] || File.dirname(@app_file)
|
|
24
|
+
@uri_root = "/"
|
|
25
|
+
Padrino::Reloader.exclude_constants << @app_class
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
##
|
|
29
|
+
# Registers the mounted application onto Padrino
|
|
30
|
+
#
|
|
31
|
+
# ==== Examples
|
|
32
|
+
#
|
|
33
|
+
# Mounter.new("blog_app").to("/blog")
|
|
34
|
+
#
|
|
35
|
+
def to(mount_url)
|
|
36
|
+
@uri_root = mount_url
|
|
37
|
+
Padrino.insert_mounted_app(self)
|
|
38
|
+
self
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
##
|
|
42
|
+
# Registers the mounted application onto Padrino for the given host
|
|
43
|
+
#
|
|
44
|
+
# ==== Examples
|
|
45
|
+
#
|
|
46
|
+
# Mounter.new("blog_app").to("/blog").host("blog.padrino.org")
|
|
47
|
+
# Mounter.new("blog_app").host("blog.padrino.org")
|
|
48
|
+
# Mounter.new("catch_all").host(/.*\.padrino.org/)
|
|
49
|
+
#
|
|
50
|
+
def host(mount_host)
|
|
51
|
+
@app_host = mount_host
|
|
52
|
+
Padrino.insert_mounted_app(self)
|
|
53
|
+
self
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
##
|
|
57
|
+
# Maps Padrino application onto a Padrino::Router
|
|
58
|
+
# For use in constructing a Rack application
|
|
59
|
+
#
|
|
60
|
+
# @app.map_onto(router)
|
|
61
|
+
#
|
|
62
|
+
def map_onto(router)
|
|
63
|
+
app_data, app_obj = self, @app_obj
|
|
64
|
+
app_obj.set :uri_root, app_data.uri_root
|
|
65
|
+
app_obj.set :app_name, app_data.name
|
|
66
|
+
app_obj.set :app_file, app_data.app_file unless ::File.exist?(app_obj.app_file)
|
|
67
|
+
app_obj.set :root, app_data.app_root unless app_data.app_root.blank?
|
|
68
|
+
app_obj.set :public, Padrino.root('public', app_data.uri_root) unless File.exists?(app_obj.public)
|
|
69
|
+
app_obj.set :static, File.exist?(app_obj.public) if app_obj.nil?
|
|
70
|
+
app_obj.setup_application! # We need to initialize here the app.
|
|
71
|
+
router.map(:to => app_obj, :path => app_data.uri_root, :host => app_data.app_host)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
###
|
|
75
|
+
# Returns the route objects for the mounted application
|
|
76
|
+
#
|
|
77
|
+
def routes
|
|
78
|
+
app_obj.routes
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
###
|
|
82
|
+
# Returns the basic route information for each named route
|
|
83
|
+
#
|
|
84
|
+
#
|
|
85
|
+
def named_routes
|
|
86
|
+
app_obj.routes.map { |route|
|
|
87
|
+
name_array = "(#{route.named.to_s.split("_").map { |piece| %Q[:#{piece}] }.join(", ")})"
|
|
88
|
+
request_method = route.conditions[:request_method][0]
|
|
89
|
+
full_path = File.join(uri_root, route.original_path)
|
|
90
|
+
next if route.named.blank? || request_method == 'HEAD'
|
|
91
|
+
OpenStruct.new(:verb => request_method, :identifier => route.named, :name => name_array, :path => full_path)
|
|
92
|
+
}.compact
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
##
|
|
96
|
+
# Makes two Mounters equal if they have the same name and uri_root
|
|
97
|
+
#
|
|
98
|
+
def ==(other)
|
|
99
|
+
other.is_a?(Mounter) && self.app_class == other.app_class && self.uri_root == other.uri_root
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
##
|
|
103
|
+
# Returns the class object for the app if defined, nil otherwise
|
|
104
|
+
#
|
|
105
|
+
def app_constant
|
|
106
|
+
klass = Object
|
|
107
|
+
for piece in app_class.split("::")
|
|
108
|
+
piece = piece.to_sym
|
|
109
|
+
if klass.const_defined?(piece)
|
|
110
|
+
klass = klass.const_get(piece)
|
|
111
|
+
else
|
|
112
|
+
return
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
klass
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
protected
|
|
119
|
+
##
|
|
120
|
+
# Locates and requires the file to load the app constant
|
|
121
|
+
#
|
|
122
|
+
def locate_app_object
|
|
123
|
+
@_app_object ||= begin
|
|
124
|
+
ensure_app_file!
|
|
125
|
+
Padrino.require_dependencies(app_file)
|
|
126
|
+
app_constant
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
##
|
|
131
|
+
# Returns the determined location of the mounted application main file
|
|
132
|
+
#
|
|
133
|
+
def locate_app_file
|
|
134
|
+
candidates = []
|
|
135
|
+
candidates << app_constant.app_file if app_constant.respond_to?(:app_file) && File.exist?(app_constant.app_file.to_s)
|
|
136
|
+
candidates << Padrino.first_caller if File.identical?(Padrino.first_caller.to_s, Padrino.called_from.to_s)
|
|
137
|
+
candidates << Padrino.mounted_root(name.downcase, "app.rb")
|
|
138
|
+
candidates << Padrino.root("app", "app.rb")
|
|
139
|
+
candidates.find { |candidate| File.exist?(candidate) }
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
###
|
|
143
|
+
# Raises an exception unless app_file is located properly
|
|
144
|
+
#
|
|
145
|
+
def ensure_app_file!
|
|
146
|
+
message = "Unable to locate source file for app '#{app_class}', try with :app_file => '/path/app.rb'"
|
|
147
|
+
raise MounterException, message unless @app_file
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
###
|
|
151
|
+
# Raises an exception unless app_obj is defined properly
|
|
152
|
+
#
|
|
153
|
+
def ensure_app_object!
|
|
154
|
+
message = "Unable to locate app for '#{app_class}', try with :app_class => 'MyAppClass'"
|
|
155
|
+
raise MounterException, message unless @app_obj
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
class << self
|
|
160
|
+
attr_writer :mounted_root # Set root directory where padrino searches mounted apps
|
|
161
|
+
|
|
162
|
+
##
|
|
163
|
+
# Returns the root to the mounted apps base directory
|
|
164
|
+
#
|
|
165
|
+
def mounted_root(*args)
|
|
166
|
+
Padrino.root(@mounted_root ||= "", *args)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
##
|
|
170
|
+
# Returns the mounted padrino applications (MountedApp objects)
|
|
171
|
+
#
|
|
172
|
+
def mounted_apps
|
|
173
|
+
@mounted_apps ||= []
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
##
|
|
177
|
+
# Inserts a Mounter object into the mounted applications (avoids duplicates)
|
|
178
|
+
#
|
|
179
|
+
def insert_mounted_app(mounter)
|
|
180
|
+
Padrino.mounted_apps.push(mounter) unless Padrino.mounted_apps.include?(mounter)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
##
|
|
184
|
+
# Mounts a new sub-application onto Padrino project
|
|
185
|
+
#
|
|
186
|
+
# Padrino.mount("blog_app").to("/blog")
|
|
187
|
+
#
|
|
188
|
+
def mount(name, options={})
|
|
189
|
+
Mounter.new(name, options)
|
|
190
|
+
end
|
|
191
|
+
end # Mounter
|
|
192
|
+
end # Padrino
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
require 'pathname'
|
|
2
|
+
|
|
3
|
+
module Padrino
|
|
4
|
+
##
|
|
5
|
+
# High performance source code reloader middleware
|
|
6
|
+
#
|
|
7
|
+
module Reloader
|
|
8
|
+
##
|
|
9
|
+
# This reloader is suited for use in a many environments because each file
|
|
10
|
+
# will only be checked once and only one system call to stat(2) is made.
|
|
11
|
+
#
|
|
12
|
+
# Please note that this will not reload files in the background, and does so
|
|
13
|
+
# only when explicitly invoked.
|
|
14
|
+
#
|
|
15
|
+
MTIMES = {}
|
|
16
|
+
LOADED_FILES = {}
|
|
17
|
+
LOADED_CLASSES = {}
|
|
18
|
+
|
|
19
|
+
class << self
|
|
20
|
+
##
|
|
21
|
+
# Specified folders can be excluded from the code reload detection process.
|
|
22
|
+
# Default excluded directories at Padrino.root are: test, spec, features, tmp, config, db and public
|
|
23
|
+
#
|
|
24
|
+
def exclude
|
|
25
|
+
@_exclude ||= %w(test spec tmp features config public db).map { |path| Padrino.root(path) }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
##
|
|
29
|
+
# Specified constants can be excluded from the code unloading process.
|
|
30
|
+
#
|
|
31
|
+
def exclude_constants
|
|
32
|
+
@_exclude_constants ||= []
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
##
|
|
36
|
+
# Specified constants can be configured to be reloaded on every request.
|
|
37
|
+
# Default included constants are: [none]
|
|
38
|
+
#
|
|
39
|
+
def include_constants
|
|
40
|
+
@_include_constants ||= []
|
|
41
|
+
end
|
|
42
|
+
##
|
|
43
|
+
# Reload all files with changes detected.
|
|
44
|
+
#
|
|
45
|
+
def reload!
|
|
46
|
+
# Detect changed files
|
|
47
|
+
rotation do |file, mtime|
|
|
48
|
+
# Retrive the last modified time
|
|
49
|
+
new_file = MTIMES[file].nil?
|
|
50
|
+
previous_mtime = MTIMES[file] ||= mtime
|
|
51
|
+
logger.devel "Detected a new file #{file}" if new_file
|
|
52
|
+
# We skip to next file if it is not new and not modified
|
|
53
|
+
next unless new_file || mtime > previous_mtime
|
|
54
|
+
# Now we can reload our file
|
|
55
|
+
apps = mounted_apps_of(file)
|
|
56
|
+
if apps.present?
|
|
57
|
+
apps.each { |app| app.app_obj.reload! }
|
|
58
|
+
else
|
|
59
|
+
safe_load(file, :force => new_file)
|
|
60
|
+
# Reload also apps
|
|
61
|
+
Padrino.mounted_apps.each do |app|
|
|
62
|
+
app.app_obj.reload! if app.app_obj.dependencies.include?(file)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
##
|
|
69
|
+
# Remove files and classes loaded with stat
|
|
70
|
+
#
|
|
71
|
+
def clear!
|
|
72
|
+
MTIMES.clear
|
|
73
|
+
LOADED_CLASSES.each do |file, klasses|
|
|
74
|
+
klasses.each { |klass| remove_constant(klass) }
|
|
75
|
+
LOADED_CLASSES.delete(file)
|
|
76
|
+
end
|
|
77
|
+
LOADED_FILES.each do |file, dependencies|
|
|
78
|
+
dependencies.each { |dependency| $LOADED_FEATURES.delete(dependency) }
|
|
79
|
+
$LOADED_FEATURES.delete(file)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
##
|
|
84
|
+
# Returns true if any file changes are detected and populates the MTIMES cache
|
|
85
|
+
#
|
|
86
|
+
def changed?
|
|
87
|
+
changed = false
|
|
88
|
+
rotation do |file, mtime|
|
|
89
|
+
new_file = MTIMES[file].nil?
|
|
90
|
+
previous_mtime = MTIMES[file] ||= mtime
|
|
91
|
+
changed = true if new_file || mtime > previous_mtime
|
|
92
|
+
end
|
|
93
|
+
changed
|
|
94
|
+
end
|
|
95
|
+
alias :run! :changed?
|
|
96
|
+
|
|
97
|
+
##
|
|
98
|
+
# We lock dependencies sets to prevent reloading of protected constants
|
|
99
|
+
#
|
|
100
|
+
def lock!
|
|
101
|
+
klasses = ObjectSpace.classes.map { |klass| klass.to_s.split("::")[0] }.uniq
|
|
102
|
+
klasses = klasses | Padrino.mounted_apps.map { |app| app.app_class }
|
|
103
|
+
Padrino::Reloader.exclude_constants.concat(klasses)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
##
|
|
107
|
+
# A safe Kernel::require which issues the necessary hooks depending on results
|
|
108
|
+
#
|
|
109
|
+
def safe_load(file, options={})
|
|
110
|
+
force, file = options[:force], figure_path(file)
|
|
111
|
+
|
|
112
|
+
# Check if file was changed or if force a reload
|
|
113
|
+
reload = MTIMES[file] && File.mtime(file) > MTIMES[file]
|
|
114
|
+
return if !force && !reload && MTIMES[file]
|
|
115
|
+
|
|
116
|
+
# Removes all classes declared in the specified file
|
|
117
|
+
if klasses = LOADED_CLASSES.delete(file)
|
|
118
|
+
klasses.each { |klass| remove_constant(klass) }
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Remove all loaded fatures with our file
|
|
122
|
+
if features = LOADED_FILES[file]
|
|
123
|
+
features.each { |feature| $LOADED_FEATURES.delete(feature) }
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Duplicate objects and loaded features before load file
|
|
127
|
+
klasses = ObjectSpace.classes.dup
|
|
128
|
+
files = $LOADED_FEATURES.dup
|
|
129
|
+
|
|
130
|
+
# Now we can reload dependencies of our file
|
|
131
|
+
if features = LOADED_FILES.delete(file)
|
|
132
|
+
features.each { |feature| safe_load(feature, :force => true) }
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# And finally load the specified file
|
|
136
|
+
begin
|
|
137
|
+
logger.devel "Loading #{file}" if !reload
|
|
138
|
+
logger.debug "Reloading #{file}" if reload
|
|
139
|
+
$LOADED_FEATURES.delete(file)
|
|
140
|
+
verbosity_was, $-v = $-v, nil
|
|
141
|
+
loaded = false
|
|
142
|
+
require(file)
|
|
143
|
+
loaded = true
|
|
144
|
+
MTIMES[file] = File.mtime(file)
|
|
145
|
+
rescue SyntaxError => e
|
|
146
|
+
logger.error "Cannot require #{file} because of syntax error: #{e.message}"
|
|
147
|
+
ensure
|
|
148
|
+
$-v = verbosity_was
|
|
149
|
+
new_constants = (ObjectSpace.classes - klasses).uniq
|
|
150
|
+
if loaded
|
|
151
|
+
# Store the file details
|
|
152
|
+
LOADED_CLASSES[file] = new_constants
|
|
153
|
+
LOADED_FILES[file] = ($LOADED_FEATURES - files - [file]).uniq
|
|
154
|
+
# Track only features in our Padrino.root
|
|
155
|
+
LOADED_FILES[file].delete_if { |feature| !in_root?(feature) }
|
|
156
|
+
else
|
|
157
|
+
logger.devel "Failed to load #{file}; removing partially defined constants"
|
|
158
|
+
new_constants.each { |klass| remove_constant(klass) }
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
##
|
|
165
|
+
# Returns true if the file is defined in our padrino root
|
|
166
|
+
#
|
|
167
|
+
def figure_path(file)
|
|
168
|
+
return file if Pathname.new(file).absolute?
|
|
169
|
+
$:.each do |path|
|
|
170
|
+
found = File.join(path, file)
|
|
171
|
+
return File.expand_path(found) if File.exist?(found)
|
|
172
|
+
end
|
|
173
|
+
file
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
##
|
|
177
|
+
# Removes the specified class and constant.
|
|
178
|
+
#
|
|
179
|
+
def remove_constant(const)
|
|
180
|
+
return if exclude_constants.compact.uniq.any? { |c| (const.to_s =~ %r{^#{Regexp.escape(c)}}) } &&
|
|
181
|
+
!include_constants.compact.uniq.any? { |c| (const.to_s =~ %r{^#{Regexp.escape(c)}}) }
|
|
182
|
+
begin
|
|
183
|
+
parts = const.to_s.split("::")
|
|
184
|
+
base = parts.size == 1 ? Object : parts[0..-2].join("::").constantize
|
|
185
|
+
object = parts[-1].to_s
|
|
186
|
+
base.send(:remove_const, object)
|
|
187
|
+
logger.devel "Removed constant: #{const}"
|
|
188
|
+
rescue NameError; end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
private
|
|
192
|
+
##
|
|
193
|
+
# Return the mounted_apps providing the app location
|
|
194
|
+
# Can be an array because in one app.rb we can define multiple Padrino::Appplications
|
|
195
|
+
#
|
|
196
|
+
def mounted_apps_of(file)
|
|
197
|
+
file = figure_path(file)
|
|
198
|
+
Padrino.mounted_apps.find_all { |app| File.identical?(file, app.app_file) }
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
##
|
|
202
|
+
# Returns true if file is in our Padrino.root
|
|
203
|
+
#
|
|
204
|
+
def in_root?(file)
|
|
205
|
+
# This is better but slow:
|
|
206
|
+
# Pathname.new(Padrino.root).find { |f| File.identical?(Padrino.root(f), figure_path(file)) }
|
|
207
|
+
figure_path(file) =~ %r{^#{Regexp.escape(Padrino.root)}}
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
##
|
|
211
|
+
# Searches Ruby files in your +Padrino.load_paths+ , Padrino::Application.load_paths
|
|
212
|
+
# and monitors them for any changes.
|
|
213
|
+
#
|
|
214
|
+
def rotation
|
|
215
|
+
files = Padrino.load_paths.map { |path| Dir["#{path}/**/*.rb"] }.flatten
|
|
216
|
+
files = files | Padrino.mounted_apps.map { |app| app.app_file }
|
|
217
|
+
files = files | Padrino.mounted_apps.map { |app| app.app_obj.dependencies }.flatten
|
|
218
|
+
files.uniq.map { |file|
|
|
219
|
+
file = File.expand_path(file)
|
|
220
|
+
next if Padrino::Reloader.exclude.any? { |base| file =~ %r{^#{Regexp.escape(base)}} } || !File.exist?(file)
|
|
221
|
+
yield(file, File.mtime(file))
|
|
222
|
+
}.compact
|
|
223
|
+
end
|
|
224
|
+
end # self
|
|
225
|
+
|
|
226
|
+
##
|
|
227
|
+
# This class acts as a Rack middleware to be added to the application stack. This middleware performs a
|
|
228
|
+
# check and reload for source files at the start of each request, but also respects a specified cool down time
|
|
229
|
+
# during which no further action will be taken.
|
|
230
|
+
#
|
|
231
|
+
class Rack
|
|
232
|
+
def initialize(app, cooldown=1)
|
|
233
|
+
@app = app
|
|
234
|
+
@cooldown = cooldown
|
|
235
|
+
@last = (Time.now - cooldown)
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def call(env)
|
|
239
|
+
if @cooldown && Time.now > @last + @cooldown
|
|
240
|
+
Thread.list.size > 1 ? Thread.exclusive { Padrino.reload! } : Padrino.reload!
|
|
241
|
+
@last = Time.now
|
|
242
|
+
end
|
|
243
|
+
@app.call(env)
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end # Reloader
|
|
247
|
+
end # Padrino
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
module Padrino
|
|
2
|
+
##
|
|
3
|
+
# This class is an extended version of Rack::URLMap
|
|
4
|
+
#
|
|
5
|
+
# Padrino::Router like Rack::URLMap dispatches in such a way that the
|
|
6
|
+
# longest paths are tried first, since they are most specific.
|
|
7
|
+
#
|
|
8
|
+
# Features:
|
|
9
|
+
#
|
|
10
|
+
# * Map a path to the specified App
|
|
11
|
+
# * Ignore server names (this solve issues with vhost and domain aliases)
|
|
12
|
+
# * Use hosts instead of server name for mappings (this help us with our vhost and doman aliases)
|
|
13
|
+
#
|
|
14
|
+
# ==== Options
|
|
15
|
+
#
|
|
16
|
+
# :to:: The class of application that you want mount
|
|
17
|
+
# :path:: Map the app to the given path
|
|
18
|
+
# :host:: Map the app to the given host
|
|
19
|
+
#
|
|
20
|
+
# ==== Examples
|
|
21
|
+
#
|
|
22
|
+
# routes = Padrino::Router.new do
|
|
23
|
+
# map(:path => "/", :to => PadrinoWeb, :host => "padrino.local")
|
|
24
|
+
# map(:path => "/", :to => Admin, :host => "admin.padrino.local")
|
|
25
|
+
# end
|
|
26
|
+
# run routes
|
|
27
|
+
#
|
|
28
|
+
# routes = Padrino::Router.new do
|
|
29
|
+
# map(:path => "/", :to => PadrinoWeb, :host => /*.padrino.local/)
|
|
30
|
+
# end
|
|
31
|
+
# run routes
|
|
32
|
+
#
|
|
33
|
+
class Router
|
|
34
|
+
def initialize(*mapping, &block)
|
|
35
|
+
@mapping = []
|
|
36
|
+
mapping.each { |m| map(m) }
|
|
37
|
+
instance_eval(&block) if block
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def sort!
|
|
41
|
+
@mapping = @mapping.sort_by { |h, p, m, a| -p.size }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def map(options={})
|
|
45
|
+
path = options[:path] || "/"
|
|
46
|
+
host = options[:host]
|
|
47
|
+
app = options[:to]
|
|
48
|
+
|
|
49
|
+
raise ArgumentError, "paths need to start with /" if path[0] != ?/
|
|
50
|
+
raise ArgumentError, "app is required" if app.nil?
|
|
51
|
+
|
|
52
|
+
path = path.chomp('/')
|
|
53
|
+
match = Regexp.new("^#{Regexp.quote(path).gsub('/', '/+')}(.*)", nil, 'n')
|
|
54
|
+
host = Regexp.new("^#{Regexp.quote(host)}$", true, 'n') unless host.nil? || host.is_a?(Regexp)
|
|
55
|
+
|
|
56
|
+
@mapping << [host, path, match, app]
|
|
57
|
+
sort!
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def call(env)
|
|
61
|
+
rPath = env["PATH_INFO"].to_s
|
|
62
|
+
script_name = env['SCRIPT_NAME']
|
|
63
|
+
hHost, sName, sPort = env.values_at('HTTP_HOST','SERVER_NAME','SERVER_PORT')
|
|
64
|
+
@mapping.each do |host, path, match, app|
|
|
65
|
+
next unless host.nil? || hHost =~ host
|
|
66
|
+
next unless rPath =~ match && rest = $1
|
|
67
|
+
next unless rest.empty? || rest[0] == ?/
|
|
68
|
+
|
|
69
|
+
rest = "/" if rest.empty?
|
|
70
|
+
|
|
71
|
+
return app.call(
|
|
72
|
+
env.merge(
|
|
73
|
+
'SCRIPT_NAME' => (script_name + path),
|
|
74
|
+
'PATH_INFO' => rest))
|
|
75
|
+
end
|
|
76
|
+
[404, {"Content-Type" => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{rPath}"]]
|
|
77
|
+
end
|
|
78
|
+
end # Router
|
|
79
|
+
end # Padrino
|