mack 0.7.0.1 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/CHANGELOG +34 -0
  2. data/README +6 -13
  3. data/bin/env_handler.rb +10 -0
  4. data/bin/gem_load_path.rb +25 -0
  5. data/bin/mack +1 -0
  6. data/bin/mackery +22 -0
  7. data/bin/mackery-console +16 -0
  8. data/bin/mackery-server +41 -0
  9. data/lib/mack.rb +7 -1
  10. data/lib/mack/controller/controller.rb +5 -4
  11. data/lib/mack/controller/request.rb +19 -1
  12. data/lib/mack/errors/errors.rb +8 -8
  13. data/lib/mack/generators/controller_generator/controller_generator.rb +1 -1
  14. data/lib/mack/generators/mack_application_generator/templates/app/views/layouts/application.html.erb.template +1 -2
  15. data/lib/mack/generators/mack_application_generator/templates/config/app_config/default.yml.template +2 -0
  16. data/lib/mack/generators/mack_application_generator/templates/config/database.yml.template +6 -6
  17. data/lib/mack/generators/passenger_generator/passenger_generator.rb +2 -0
  18. data/lib/mack/generators/passenger_generator/templates/config.ru.template +5 -0
  19. data/lib/mack/generators/passenger_generator/templates/tmp/README.template +2 -0
  20. data/lib/mack/initialization/application.rb +39 -36
  21. data/lib/mack/initialization/boot_loader.rb +174 -0
  22. data/lib/mack/initialization/configuration.rb +83 -95
  23. data/lib/mack/initialization/console.rb +11 -0
  24. data/lib/mack/initialization/environment.rb +16 -0
  25. data/lib/mack/initialization/helpers.rb +26 -24
  26. data/lib/mack/initialization/logging.rb +81 -81
  27. data/lib/mack/initialization/plugins.rb +14 -11
  28. data/lib/mack/initialization/server/simple_server.rb +3 -3
  29. data/lib/mack/rendering/type/base.rb +1 -1
  30. data/lib/mack/rendering/type/layout.rb +1 -1
  31. data/lib/mack/rendering/type/partial.rb +1 -1
  32. data/lib/mack/rendering/type/public.rb +1 -1
  33. data/lib/mack/rendering/type/template.rb +1 -1
  34. data/lib/mack/runner.rb +2 -2
  35. data/lib/mack/runner_helpers/session.rb +3 -3
  36. data/lib/mack/sessions/cookie_session_store.rb +44 -0
  37. data/lib/mack/{controller → sessions}/session.rb +0 -0
  38. data/lib/mack/sessions/session_store_base.rb +62 -0
  39. data/lib/mack/sessions/test_session_store.rb +38 -0
  40. data/lib/mack/tasks/mack_server_tasks.rake +8 -21
  41. data/lib/mack/tasks/mack_tasks.rake +33 -6
  42. data/lib/mack/tasks/rake_rules.rake +8 -0
  43. data/lib/mack/tasks/test_tasks.rake +39 -15
  44. data/lib/mack/testing/helpers.rb +6 -39
  45. data/lib/mack/utils/content_length_handler.rb +45 -0
  46. data/lib/mack/utils/forgery_detector.rb +152 -0
  47. data/lib/mack/utils/gem_manager.rb +22 -1
  48. data/lib/mack/utils/paths.rb +154 -0
  49. data/lib/mack/utils/server.rb +8 -6
  50. data/lib/mack/version.rb +1 -1
  51. data/lib/mack/view_helpers/asset_helpers.rb +50 -0
  52. data/lib/mack/view_helpers/form_helpers.rb +52 -6
  53. data/lib/mack/view_helpers/link_helpers.rb +6 -3
  54. data/lib/mack_app.rb +12 -14
  55. data/lib/mack_core.rb +35 -14
  56. data/lib/mack_tasks.rb +35 -20
  57. metadata +23 -27
  58. data/lib/mack/tasks/cachetastic_tasks.rake +0 -58
@@ -45,17 +45,34 @@ module Mack
45
45
  end
46
46
  end
47
47
 
48
+ # Requires the gem and any libs that you've specified.
49
+ def do_task_requires
50
+ @required_gem_list.each do |g|
51
+ begin
52
+ if g.version?
53
+ gem(g.name, g.version)
54
+ else
55
+ gem(g.name)
56
+ end
57
+ g.tasks.each { |l| require l.to_s } if g.tasks?
58
+ rescue Exception => e
59
+ end
60
+ end
61
+ end
62
+
48
63
  private
49
64
  class GemObject # :nodoc:
50
65
  attr_accessor :name
51
66
  attr_accessor :version
52
67
  attr_accessor :libs
68
+ attr_accessor :tasks
53
69
  attr_accessor :source
54
70
 
55
71
  def initialize(name, options = {})
56
72
  self.name = name
57
73
  self.version = options[:version]
58
74
  self.libs = [options[:libs]].flatten.compact
75
+ self.tasks = [options[:tasks], "#{name}_tasks"].flatten.compact
59
76
  self.source = options[:source]
60
77
  end
61
78
 
@@ -66,7 +83,7 @@ module Mack
66
83
  end
67
84
 
68
85
  def libs?
69
- !self.libs.empty?
86
+ self.libs.any?
70
87
  end
71
88
 
72
89
  def version?
@@ -77,6 +94,10 @@ module Mack
77
94
  !self.source.blank?
78
95
  end
79
96
 
97
+ def tasks?
98
+ self.tasks.any?
99
+ end
100
+
80
101
  end
81
102
 
82
103
  end # GemManager
@@ -0,0 +1,154 @@
1
+ module Mack
2
+ module Paths
3
+
4
+ # <MACK_PROJECT_ROOT>
5
+ def self.root(*files)
6
+ File.join(Mack.root, files)
7
+ end
8
+
9
+ # <MACK_PROJECT_ROOT>/public
10
+ def self.public(*files)
11
+ Mack::Paths.root("public", files)
12
+ end
13
+
14
+ # <MACK_PROJECT_ROOT>/public/images
15
+ def self.images(*files)
16
+ Mack::Paths.public("images", files)
17
+ end
18
+
19
+ # <MACK_PROJECT_ROOT>/public/javascripts
20
+ def self.javascripts(*files)
21
+ Mack::Paths.public("javascripts", files)
22
+ end
23
+
24
+ # <MACK_PROJECT_ROOT>/public/stylesheets
25
+ def self.stylesheets(*files)
26
+ Mack::Paths.public("stylesheets", files)
27
+ end
28
+
29
+ # <MACK_PROJECT_ROOT>/app
30
+ def self.app(*files)
31
+ Mack::Paths.root("app", files)
32
+ end
33
+
34
+ # <MACK_PROJECT_ROOT>/log
35
+ def self.log(*files)
36
+ Mack::Paths.root("log", files)
37
+ end
38
+
39
+ # <MACK_PROJECT_ROOT>/test
40
+ def self.test(*files)
41
+ Mack::Paths.root("test", files)
42
+ end
43
+
44
+ # <MACK_PROJECT_ROOT>/tmp
45
+ def self.tmp(*files)
46
+ Mack::Paths.root("tmp", files)
47
+ end
48
+
49
+ # <MACK_PROJECT_ROOT>/test/models
50
+ def self.model_tests(*files)
51
+ Mack::Paths.test("models", files)
52
+ end
53
+
54
+ # <MACK_PROJECT_ROOT>/test/controllers
55
+ def self.controller_tests(*files)
56
+ Mack::Paths.test("controllers", files)
57
+ end
58
+
59
+ def self.test_helpers(*files)
60
+ Mack::Paths.test("helpers", files)
61
+ end
62
+
63
+ # <MACK_PROJECT_ROOT>/test/helpers/controllers
64
+ def self.controller_helper_tests(*files)
65
+ Mack::Paths.test_helpers("controllers", files)
66
+ end
67
+
68
+ # <MACK_PROJECT_ROOT>/test/helpers/views
69
+ def self.view_helper_tests(*files)
70
+ Mack::Paths.test_helpers("views", files)
71
+ end
72
+
73
+ # <MACK_PROJECT_ROOT>/app/views
74
+ def self.views(*files)
75
+ Mack::Paths.app("views", files)
76
+ end
77
+
78
+ # <MACK_PROJECT_ROOT>/app/views/layouts
79
+ def self.layouts(*files)
80
+ Mack::Paths.views("layouts", files)
81
+ end
82
+
83
+ # <MACK_PROJECT_ROOT>/app/controllers
84
+ def self.controllers(*files)
85
+ Mack::Paths.app("controllers", files)
86
+ end
87
+
88
+ # <MACK_PROJECT_ROOT>/app/models
89
+ def self.models(*files)
90
+ Mack::Paths.app("models", files)
91
+ end
92
+
93
+ # <MACK_PROJECT_ROOT>/app/helpers
94
+ def self.helpers(*files)
95
+ Mack::Paths.app("helpers", files)
96
+ end
97
+
98
+ # <MACK_PROJECT_ROOT>/app/helpers/controllers
99
+ def self.controller_helpers(*files)
100
+ Mack::Paths.helpers("controllers", files)
101
+ end
102
+
103
+ # <MACK_PROJECT_ROOT>/app/helpers/views
104
+ def self.view_helpers(*files)
105
+ Mack::Paths.helpers("views", files)
106
+ end
107
+
108
+ # <MACK_PROJECT_ROOT>/lib
109
+ def self.lib(*files)
110
+ Mack::Paths.root("lib", files)
111
+ end
112
+
113
+ # <MACK_PROJECT_ROOT>/lib/tasks
114
+ def self.tasks(*files)
115
+ Mack::Paths.lib("tasks", files)
116
+ end
117
+
118
+ # <MACK_PROJECT_ROOT>/db
119
+ def self.db(*files)
120
+ Mack::Paths.root("db", files)
121
+ end
122
+
123
+ # <MACK_PROJECT_ROOT>/db/migrations
124
+ def self.migrations(*files)
125
+ Mack::Paths.db("migrations", files)
126
+ end
127
+
128
+ # <MACK_PROJECT_ROOT>/config
129
+ def self.config(*files)
130
+ Mack::Paths.root("config", files)
131
+ end
132
+
133
+ # <MACK_PROJECT_ROOT>/config/app_config
134
+ def self.app_config(*files)
135
+ Mack::Paths.config("app_config", files)
136
+ end
137
+
138
+ # <MACK_PROJECT_ROOT>/config/initializers
139
+ def self.initializers(*files)
140
+ Mack::Paths.config("initializers", files)
141
+ end
142
+
143
+ # <MACK_PROJECT_ROOT>/vendor
144
+ def self.vendor(*files)
145
+ Mack::Paths.root("vendor", files)
146
+ end
147
+
148
+ # <MACK_PROJECT_ROOT>/vendor/plugins
149
+ def self.plugins(*files)
150
+ Mack::Paths.vendor("plugins", files)
151
+ end
152
+
153
+ end # Paths
154
+ end # Mack
@@ -1,33 +1,35 @@
1
1
  module Mack
2
2
  module Utils
3
-
3
+
4
4
  # Houses a registry of Rack runners that should be called before the Mack::Runner.
5
5
  class RunnersRegistry < Mack::Utils::RegistryList
6
6
  end
7
-
7
+
8
8
  module Server
9
-
9
+
10
10
  # This method wraps all the necessary components of the Rack system around
11
11
  # Mack::Runner. This can be used build your own server around the Mack framework.
12
12
  def self.build_app
13
13
  # Mack framework:
14
14
  app = Mack::Runner.new
15
-
15
+
16
16
  Mack::Utils::RunnersRegistry.registered_items.each do |runner|
17
17
  app = runner.new(app)
18
18
  end
19
-
19
+
20
20
  # Any urls listed will go straight to the public directly and will not be served up via the app:
21
21
  app = Rack::Static.new(app, :urls => ["/css", "/images", "/files", "/images", "/stylesheets", "/javascripts", "/media", "/favicon.ico"], :root => "public")
22
+ app = Mack::Utils::ContentLengthHandler.new(app)
22
23
  app = Rack::Lint.new(app) if app_config.mack.use_lint
23
24
  app = Rack::ShowStatus.new(app)
24
25
  app = Rack::ShowExceptions.new(app) if app_config.mack.show_exceptions
25
26
  app = Rack::Recursive.new(app)
27
+
26
28
  # This will reload any edited classes if the cache_classes config setting is set to true.
27
29
  app = Rack::Reloader.new(app, 1) unless app_config.mack.cache_classes
28
30
  app
29
31
  end
30
-
32
+
31
33
  end # Server
32
34
  end # Utils
33
35
  end # Mack
@@ -1,3 +1,3 @@
1
1
  module Mack
2
- VERSION = '0.7.0.1' unless const_defined?("VERSION")
2
+ VERSION = '0.7.1' unless const_defined?("VERSION")
3
3
  end
@@ -0,0 +1,50 @@
1
+ module Mack
2
+ class AssetHelpers # :nodoc:
3
+ include Singleton
4
+
5
+ #
6
+ # Set the asset hosts for this app. It supports the following format:
7
+ # - plain string: the string literal will be considered as the asset hosts (e.g. 'http://assets.foo.com')
8
+ # - formatted string: to support asset host distribution (e.g. 'http://asset%d.foo.com')
9
+ # - a proc object: to support custom asset hosts generation (e.g. Proc.new { |source| 'assets.foo.com' }
10
+ #
11
+ # The max number of distribution can be set from app_config's asset_hosts_max_distribution.
12
+ # The default value is 4
13
+ #
14
+ def asset_hosts=(host)
15
+ @hosts = host
16
+ end
17
+
18
+ #
19
+ # Return the max number of asset hosts distribution
20
+ #
21
+ def max_distribution
22
+ return app_config.asset_hosts_max_distribution.to_i || 4
23
+ end
24
+
25
+ #
26
+ # Return the asset hosts for this application.
27
+ #
28
+ def asset_hosts(source = '')
29
+ ret_val = ''
30
+
31
+ # if no explicit asset_host setting, then use the one defined in app_config (if exists)
32
+ host = @hosts || app_config.asset_hosts
33
+ host = '' if host.nil?
34
+
35
+ if host.kind_of?(Proc)
36
+ ret_val = host.call(source)
37
+ else
38
+ ret_val = sprintf(host, rand(max_distribution))
39
+ end
40
+ return ret_val
41
+ end
42
+
43
+ #
44
+ # Clear previously set configuration for asset hosts
45
+ #
46
+ def reset!
47
+ @hosts = nil
48
+ end
49
+ end
50
+ end
@@ -3,6 +3,19 @@ module Mack
3
3
  # A useful collection of helpers for forms.
4
4
  module FormHelpers
5
5
 
6
+ #
7
+ # Get the secret token to be added in an HTML form.
8
+ # This is to ensure that your form is valid.
9
+ #
10
+ # Only call this method if you generate the form manually.
11
+ # If you use the form() method to generate your form, then
12
+ # the authenticity token is already included in your form.
13
+ #
14
+ def form_authenticity_field
15
+ str = %{<input type="hidden" name="__authenticity_token" value="#{Mack::Utils::AuthenticityTokenDispenser.instance.dispense_token(request.session.id)}" />}
16
+ end
17
+
18
+
6
19
  # Examples:
7
20
  # <% form(users_create_url) do -%>
8
21
  # # form stuff here...
@@ -31,6 +44,7 @@ module Mack
31
44
  end
32
45
  concat("<form#{build_options(options)}>\n", block.binding)
33
46
  concat(meth, block.binding) unless meth.blank?
47
+ concat(form_authenticity_field, block.binding) if !app_config.mack.disable_forgery_detector
34
48
  yield
35
49
  concat("\n</form>", block.binding)
36
50
  # content_tag(:form, options, &block)
@@ -38,22 +52,54 @@ module Mack
38
52
 
39
53
  # Generates a button with a form around it and will set the request method to delete.
40
54
  def delete_button(url, value = "Delete", form_options = {}, button_options = {})
41
- if button_options[:confirm]
42
- button_options[:onclick] = "if (confirm('#{button_options[:confirm]}')) {submit();}; return false;"
43
- button_options.delete(:confirm)
44
- end
45
55
  t = "\n" << hidden_field(:_method, :value => :delete)
46
56
  t << "\n" << submit_button(value, button_options)
47
57
  t << "\n"
48
58
  content_tag(:form, {:action => url, :method => :post}.merge(form_options), t)
49
59
  end
50
60
 
51
- alias_deprecated_method :submit_tag, :submit_button, '0.7.0'
52
-
53
61
  # Examples:
54
62
  # <%= submit_button %> # => <input type="submit" value="Submit" />
55
63
  # <%= submit_button "Login" %> # => <input type="submit" value="Login" />
64
+ # You can disable the button after clicking it. In essence, this will work as follows:
65
+ # <%= submit_button "Login", :disable_with => "Please wait..." %>
66
+ # # => <input type="submit" value="Login" onclick="this.disabled=true;this.value='Please wait...';this.form.submit();" />
67
+ # Even though :disable_with will work on the onclick parameter, you can add your own onclick behaviour to the mix, as follows:
68
+ # <%= submit_button "Login", :disable_with => "Please wait...", :onclick => "alert('test')" %>
69
+ # # => <input type="submit" value="Login" onclick="this.disabled=true;this.value='Please wait...';alert('test');this.form.submit();" />
70
+ #
71
+ # Please note that if the form.submit() returns false the button's value will be restored to
72
+ # its initial value. This behaviour is acheived through the injection of a couple bits of JS
73
+ # into the onlick existing parameter. These bits are injected after the disabled value, and
74
+ # all existing onclick behaviour that you define in the :onlick option. The included JS bits
75
+ # are as follows:
76
+ # "result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit())",
77
+ # "if (result == false) { this.value = this.getAttribute('originalValue'); this.disabled = false }",
78
+ # "return result;"
56
79
  def submit_button(value = "Submit", options = {}, *original_args)
80
+ if options[:confirm]
81
+ onclick = "if (confirm('#{options.delete(:confirm)}')) {submit();}; return false;"
82
+ onclick << ";#{options.delete(:onclick)}" if options.has_key?(:onclick)
83
+ options[:onclick] = onclick
84
+ end
85
+ # processing the disable with option, which will be embebed in the onclick parameter.
86
+ if disable_with = options.delete(:disable_with)
87
+ disable_with = "this.innerHTML='#{disable_with}'"
88
+
89
+ # Making sure that we keep the content of the onclick option, should it exist.
90
+ disable_with << ";#{options.delete(:onclick)}" if options.has_key?(:onclick)
91
+
92
+ # Setting the onlick option.
93
+ options[:onclick] = [
94
+ "this.setAttribute('originalValue', this.innerHTML)",
95
+ "this.disabled=true",
96
+ disable_with,
97
+ "result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit())",
98
+ "if (result == false) { this.innerHTML = this.getAttribute('originalValue'); this.disabled = false }",
99
+ "return result;",
100
+ ].join(";")
101
+ end
102
+
57
103
  # non_content_tag(:input, {:type => :submit, :value => value}.merge(options))
58
104
  content_tag(:button, {:type => :submit}.merge(options), value)
59
105
  end
@@ -129,7 +129,8 @@ module Mack
129
129
  link = ""
130
130
  files.each do |name|
131
131
  file_name = !name.to_s.end_with?(".js") ? "#{name}.js" : "#{name}"
132
- link += "<javascript src=\"#{get_resource_root}/javascripts/#{file_name}?#{Time.now.to_i}\" type=\"#{options[:type]}\" />\n"
132
+ resource = "/javascripts/#{file_name}"
133
+ link += "<javascript src=\"#{get_resource_root(resource)}#{resource}?#{Time.now.to_i}\" type=\"#{options[:type]}\" />\n"
133
134
  end
134
135
  return link
135
136
  end
@@ -153,16 +154,18 @@ module Mack
153
154
  link = ""
154
155
  files.each do |name|
155
156
  file_name = !name.to_s.end_with?(".css") ? "#{name}.css" : "#{name}"
156
- link += "<link href=\"#{get_resource_root}/stylesheets/#{file_name}\" media=\"#{options[:media]}\" rel=\"#{options[:rel]}\" type=\"#{options[:type]}\" />\n"
157
+ resource = "/stylesheets/#{file_name}"
158
+ link += "<link href=\"#{get_resource_root(resource)}#{resource}\" media=\"#{options[:media]}\" rel=\"#{options[:rel]}\" type=\"#{options[:type]}\" />\n"
157
159
  end
158
160
 
159
161
  return link
160
162
  end
161
163
 
162
164
  private
163
- def get_resource_root
165
+ def get_resource_root(resource)
164
166
  path = ""
165
167
  path = "#{app_config.mack.distributed_site_domain}" if app_config.mack.distributed_site_domain
168
+ path = Mack::AssetHelpers.instance.asset_hosts(resource) if path.empty?
166
169
  return path
167
170
  end
168
171
 
@@ -1,20 +1,18 @@
1
- require 'ruby-debug'
2
-
3
1
  fl = File.join(File.dirname(__FILE__), "mack")
2
+ require File.join(fl, "initialization", "application.rb")
3
+ require File.join(fl, "initialization", "helpers.rb")
4
+ require File.join(fl, "initialization", "plugins.rb")
4
5
 
5
- require File.join(fl, "initialization", "configuration.rb")
6
+ boot_load(:start_mack_application, :configuration, :print_hello_banner, :lib, :routes, :app_files, :helpers, :runner) do
7
+ Mack::Environment.load
8
+ Mack.logger.debug "Initialization of Mack Application Environment finished."
9
+ end
6
10
 
7
- unless Mack::Configuration.initialized_application
8
-
9
- Mack.logger.debug "Starting application in #{Mack.env} mode."
11
+ boot_load(:print_hello_banner, :configuration) do
12
+ Mack.reset_logger!
10
13
  Mack.logger.debug "Mack root: #{Mack.root}"
11
14
  Mack.logger.debug "Mack version: #{Mack::VERSION}"
15
+ Mack.logger.debug "Starting application in #{Mack.env} mode."
16
+ end
12
17
 
13
- require File.join(fl, "initialization", "application.rb")
14
-
15
- require File.join(fl, "initialization", "helpers.rb")
16
-
17
- Mack::Configuration.initialized_application = true if Mack::Configuration.initialized_application.nil?
18
-
19
- Mack.logger.debug "Initialization of Mack Application Environment finished."
20
- end
18
+ Mack::BootLoader.run(:start_mack_application)