public
Description: Phusion Passenger (mod_rails)
Homepage: http://www.modrails.com/
Clone URL: git://github.com/FooBarWidget/passenger.git
Click here to lend your support to: passenger and make a donation at www.pledgie.com !
Correctly support applications that do not specify a Rails version.
Hongli Lai (Phusion) (author)
Mon Mar 31 04:45:48 -0700 2008
commit  b77b49bbac8a356534b8f254322f297682598131
tree    ca143c004f4abecc646b51d9aa7e403efc5322c9
parent  12dae54d8f498d6f9a2772719ca18baaff79e75c
...
1
 
2
3
4
...
31
32
33
34
35
 
 
 
36
37
38
39
40
41
 
42
43
44
45
46
 
 
 
47
48
49
...
51
52
53
54
 
55
56
57
...
1
2
3
4
5
...
32
33
34
 
 
35
36
37
38
39
40
41
42
 
43
44
45
46
47
48
49
50
51
52
53
54
...
56
57
58
 
59
60
61
62
0
@@ -1,4 +1,5 @@
0
 require 'rubygems'
0
+require 'passenger/utils'
0
 module Passenger
0
 
0
 # Indicates that there is no Ruby on Rails version installed that satisfies
0
@@ -31,19 +32,23 @@ class Application
0
   # RequestHandler for a description of the owner pipe.
0
   attr_reader :owner_pipe
0
 
0
- # Return the Ruby on Rails version that the application requires.
0
- # Returns nil if the application has a vendored Rails.
0
+ # - Returns the Ruby on Rails version that the application requires.
0
+ # - Returns <tt>:vendor</tt> if the application has a vendored Rails.
0
+ # - Returns nil if the application doesn't specify a particular version.
0
   # Raises VersionNotFound if the required Rails version is not installed.
0
   def self.detect_framework_version(app_root)
0
     if File.directory?("#{app_root}/vendor/rails/railties")
0
       # NOTE: We must check for 'rails/railties' and not just 'rails'.
0
       # Typo's vendor directory contains an empty 'rails' directory.
0
- return nil
0
+ return :vendor
0
     end
0
     
0
     environment_rb = File.read("#{app_root}/config/environment.rb")
0
     environment_rb =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
0
     gem_version_spec = $1
0
+ if gem_version_spec.nil?
0
+ return nil
0
+ end
0
     
0
     found_version = Gem.cache.search('rails', gem_version_spec).map do |x|
0
       x.version.version
0
@@ -51,7 +56,7 @@ class Application
0
     if found_version.nil?
0
       # If this error was reported before, then the cache might be out of
0
       # date because the Rails version may have been installed now.
0
- # So we reload the cache and try again.
0
+ # So we reload the RubyGems cache and try again.
0
       Gem.refresh_all_caches!
0
       found_version = Gem.cache.search('rails', gem_version_spec).map do |x|
0
         x.version.version
...
68
69
70
 
 
71
72
73
...
68
69
70
71
72
73
74
75
0
@@ -68,6 +68,8 @@ class ApplicationSpawner < AbstractServer
0
   
0
   # An attribute, used internally. This should not be used outside Passenger.
0
   attr_accessor :time
0
+ # The application root of this spawner.
0
+ attr_reader :app_root
0
 
0
   # +app_root+ is the root directory of this application, i.e. the directory
0
   # that contains 'app/', 'public/', etc. If given an invalid directory,
...
59
60
61
62
63
64
65
66
 
 
 
 
 
 
 
 
 
 
 
 
67
68
69
 
 
 
 
70
 
71
72
73
74
75
 
76
77
78
79
 
80
81
 
 
 
 
 
 
82
83
84
...
95
96
97
 
 
 
 
 
98
99
100
 
 
 
 
 
 
 
 
101
102
103
...
59
60
61
 
62
 
 
 
63
64
65
66
67
68
69
70
71
72
73
74
75
 
 
76
77
78
79
80
81
82
83
84
85
 
86
87
88
89
90
91
92
 
93
94
95
96
97
98
99
100
101
...
112
113
114
115
116
117
118
119
120
 
 
121
122
123
124
125
126
127
128
129
130
131
0
@@ -59,26 +59,43 @@ class SpawnManager < AbstractServer
0
   # - FrameworkInitError: The Ruby on Rails framework that the application requires could not be loaded.
0
   # - AppInitError: The application raised an exception or called exit() during startup.
0
   def spawn_application(app_root, lower_privilege = true, lowest_user = "nobody")
0
- options = {}
0
     framework_version = Application.detect_framework_version(app_root)
0
- if framework_version.nil?
0
- options[:vendor] = normalize_path("#{app_root}/vendor/rails")
0
- key = "vendor:#{options[:vendor]}"
0
+ if framework_version == :vendor
0
+ vendor_path = normalize_path("#{app_root}/vendor/rails")
0
+ key = "vendor:#{vendor_path}"
0
+ create_spawner = proc do
0
+ FrameworkSpawner.new(:vendor => vendor_path)
0
+ end
0
+ elsif framework_version.nil?
0
+ app_root = normalize_path(app_root)
0
+ key = "app:#{app_root}"
0
+ create_spawner = proc do
0
+ ApplicationSpawner.new(app_root, lower_privilege, lowest_user)
0
+ end
0
     else
0
- options[:version] = framework_version
0
- key = "version:#{options[:version]}"
0
+ key = "version:#{framework_version}"
0
+ create_spawner = proc do
0
+ FrameworkSpawner.new(:version => framework_version)
0
+ end
0
     end
0
+
0
     spawner = nil
0
     @lock.synchronize do
0
       spawner = @spawners[key]
0
       if !spawner
0
- spawner = FrameworkSpawner.new(options)
0
+ spawner = create_spawner.call
0
         spawner.start
0
         @spawners[key] = spawner
0
       end
0
     end
0
+
0
     spawner.time = Time.now
0
- return spawner.spawn_application(app_root, lower_privilege, lowest_user)
0
+ if spawner.is_a?(FrameworkSpawner)
0
+ return spawner.spawn_application(app_root, lower_privilege,
0
+ lowest_user)
0
+ else
0
+ return spawner.spawn_application(app_root)
0
+ end
0
   end
0
   
0
   # Remove the cached application instances at the given application root.
0
@@ -95,9 +112,20 @@ class SpawnManager < AbstractServer
0
   #
0
   # Raises AbstractServer::SpawnError if something went wrong.
0
   def reload(app_root = nil)
0
+ begin
0
+ app_root = normalize_path(app_root)
0
+ rescue ArgumentError
0
+ return
0
+ end
0
     @lock.synchronize do
0
- @spawners.each_value do |spawner|
0
- spawner.reload(app_root)
0
+ @spawners.keys.each do |key|
0
+ spawner = @spawners[key]
0
+ if spawner.respond_to?(:reload)
0
+ spawner.reload(app_root)
0
+ elsif spawner.respond_to?(:app_root) && spawner.app_root == app_root
0
+ spawner.stop
0
+ @spawners.delete(key)
0
+ end
0
       end
0
     end
0
   end
...
8
9
10
11
 
12
 
 
 
 
 
13
14
15
...
8
9
10
 
11
12
13
14
15
16
17
18
19
20
0
@@ -8,8 +8,13 @@ describe Application do
0
     rails_version.should =~ /^2\.0\.(\d+)$/
0
   end
0
   
0
- it "should correctly detect vendor Rails" do
0
+ it "should return :vendor if an application uses a vendored Rails" do
0
     rails_version = Application.detect_framework_version('stub/minimal-railsapp')
0
+ rails_version.should == :vendor
0
+ end
0
+
0
+ it "should return nil if an application does not specify its Rails version" do
0
+ rails_version = Application.detect_framework_version('stub/railsapp-without-version-spec')
0
     rails_version.should be_nil
0
   end
0
   
...
44
45
46
47
 
48
49
50
...
44
45
46
 
47
48
49
50
0
@@ -44,7 +44,7 @@ describe FrameworkSpawner do
0
   
0
   def spawn_application(app_root)
0
     version = Application.detect_framework_version(app_root)
0
- if version.nil?
0
+ if version == :vendor
0
       options = { :vendor => "#{@app_root}/vendor/rails" }
0
     else
0
       options = { :version => version }

Comments

    No one has commented yet.