aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/lib/action_controller/polymorphic_routes.rb7
-rw-r--r--actionpack/lib/action_controller/resources.rb7
-rw-r--r--actionpack/lib/action_controller/vendor/rack-1.0/rack.rb1
-rw-r--r--actionpack/lib/action_controller/vendor/rack-1.0/rack/chunked.rb49
-rw-r--r--actionpack/lib/action_controller/vendor/rack-1.0/rack/file.rb2
-rw-r--r--actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb4
-rw-r--r--actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb3
-rw-r--r--actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb5
-rw-r--r--actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb4
-rw-r--r--actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb4
-rw-r--r--actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb3
-rw-r--r--actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb3
-rw-r--r--actionpack/lib/action_controller/vendor/rack-1.0/rack/lint.rb54
-rw-r--r--actionpack/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb6
-rw-r--r--actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb2
-rw-r--r--actionpack/lib/action_view/base.rb18
-rw-r--r--actionpack/lib/action_view/renderable.rb26
-rw-r--r--actionpack/test/controller/polymorphic_routes_test.rb85
-rw-r--r--actionpack/test/controller/request/multipart_params_parsing_test.rb2
-rw-r--r--actionpack/test/controller/resources_test.rb8
-rwxr-xr-xactiverecord/lib/active_record/base.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb55
-rw-r--r--activerecord/lib/active_record/validations.rb2
-rw-r--r--activerecord/test/cases/migration_test.rb26
-rw-r--r--activerecord/test/cases/transactions_test.rb15
-rw-r--r--activesupport/lib/active_support/core_ext/hash/conversions.rb5
-rw-r--r--activesupport/test/core_ext/hash_ext_test.rb9
-rw-r--r--railties/environments/boot.rb1
-rw-r--r--railties/lib/initializer.rb4
-rw-r--r--railties/lib/rails/gem_dependency.rb223
-rw-r--r--railties/lib/tasks/gems.rake78
-rw-r--r--railties/test/boot_test.rb2
-rw-r--r--railties/test/gem_dependency_test.rb17
-rw-r--r--railties/test/vendor/gems/dummy-gem-g-1.0.0/.specification2
34 files changed, 475 insertions, 263 deletions
diff --git a/actionpack/lib/action_controller/polymorphic_routes.rb b/actionpack/lib/action_controller/polymorphic_routes.rb
index 924d1aa6bd..d9b614c237 100644
--- a/actionpack/lib/action_controller/polymorphic_routes.rb
+++ b/actionpack/lib/action_controller/polymorphic_routes.rb
@@ -163,7 +163,8 @@ module ActionController
if parent.is_a?(Symbol) || parent.is_a?(String)
string << "#{parent}_"
else
- string << "#{RecordIdentifier.__send__("singular_class_name", parent)}_"
+ string << "#{RecordIdentifier.__send__("plural_class_name", parent)}".singularize
+ string << "_"
end
end
end
@@ -171,7 +172,9 @@ module ActionController
if record.is_a?(Symbol) || record.is_a?(String)
route << "#{record}_"
else
- route << "#{RecordIdentifier.__send__("#{inflection}_class_name", record)}_"
+ route << "#{RecordIdentifier.__send__("plural_class_name", record)}"
+ route = route.singularize if inflection == :singular
+ route << "_"
end
action_prefix(options) + namespace + route + routing_type(options).to_s
diff --git a/actionpack/lib/action_controller/resources.rb b/actionpack/lib/action_controller/resources.rb
index 0a89c4b3d5..5f71a105c8 100644
--- a/actionpack/lib/action_controller/resources.rb
+++ b/actionpack/lib/action_controller/resources.rb
@@ -670,12 +670,7 @@ module ActionController
when "show", "edit"; default_options.merge(add_conditions_for(resource.conditions, method || :get)).merge(resource.requirements(require_id))
when "update"; default_options.merge(add_conditions_for(resource.conditions, method || :put)).merge(resource.requirements(require_id))
when "destroy"; default_options.merge(add_conditions_for(resource.conditions, method || :delete)).merge(resource.requirements(require_id))
- else
- if method.nil? || resource.member_methods.nil? || resource.member_methods[method.to_sym].nil?
- default_options.merge(add_conditions_for(resource.conditions, method)).merge(resource.requirements)
- else
- resource.member_methods[method.to_sym].include?(action) ? default_options.merge(add_conditions_for(resource.conditions, method)).merge(resource.requirements(require_id)) : default_options.merge(add_conditions_for(resource.conditions, method)).merge(resource.requirements)
- end
+ else default_options.merge(add_conditions_for(resource.conditions, method)).merge(resource.requirements)
end
end
end
diff --git a/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb b/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb
index e3e20ed2a3..7fab1a7931 100644
--- a/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb
+++ b/actionpack/lib/action_controller/vendor/rack-1.0/rack.rb
@@ -28,6 +28,7 @@ module Rack
autoload :Builder, "rack/builder"
autoload :Cascade, "rack/cascade"
+ autoload :Chunked, "rack/chunked"
autoload :CommonLogger, "rack/commonlogger"
autoload :ConditionalGet, "rack/conditionalget"
autoload :ContentLength, "rack/content_length"
diff --git a/actionpack/lib/action_controller/vendor/rack-1.0/rack/chunked.rb b/actionpack/lib/action_controller/vendor/rack-1.0/rack/chunked.rb
new file mode 100644
index 0000000000..280d89dd65
--- /dev/null
+++ b/actionpack/lib/action_controller/vendor/rack-1.0/rack/chunked.rb
@@ -0,0 +1,49 @@
+require 'rack/utils'
+
+module Rack
+
+ # Middleware that applies chunked transfer encoding to response bodies
+ # when the response does not include a Content-Length header.
+ class Chunked
+ include Rack::Utils
+
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ status, headers, body = @app.call(env)
+ headers = HeaderHash.new(headers)
+
+ if env['HTTP_VERSION'] == 'HTTP/1.0' ||
+ STATUS_WITH_NO_ENTITY_BODY.include?(status) ||
+ headers['Content-Length'] ||
+ headers['Transfer-Encoding']
+ [status, headers.to_hash, body]
+ else
+ dup.chunk(status, headers, body)
+ end
+ end
+
+ def chunk(status, headers, body)
+ @body = body
+ headers.delete('Content-Length')
+ headers['Transfer-Encoding'] = 'chunked'
+ [status, headers.to_hash, self]
+ end
+
+ def each
+ term = "\r\n"
+ @body.each do |chunk|
+ size = bytesize(chunk)
+ next if size == 0
+ yield [size.to_s(16), term, chunk, term].join
+ end
+ yield ["0", term, "", term].join
+ end
+
+ def close
+ @body.close if @body.respond_to?(:close)
+ end
+ end
+end
diff --git a/actionpack/lib/action_controller/vendor/rack-1.0/rack/file.rb b/actionpack/lib/action_controller/vendor/rack-1.0/rack/file.rb
index 7869227a36..fe62bd6b86 100644
--- a/actionpack/lib/action_controller/vendor/rack-1.0/rack/file.rb
+++ b/actionpack/lib/action_controller/vendor/rack-1.0/rack/file.rb
@@ -60,7 +60,7 @@ module Rack
body = self
else
body = [F.read(@path)]
- size = body.first.size
+ size = Utils.bytesize(body.first)
end
[200, {
diff --git a/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb b/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb
index f2c976cf46..e38156c7f0 100644
--- a/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb
+++ b/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb
@@ -1,3 +1,5 @@
+require 'rack/content_length'
+
module Rack
module Handler
class CGI
@@ -6,6 +8,8 @@ module Rack
end
def self.serve(app)
+ app = ContentLength.new(app)
+
env = ENV.to_hash
env.delete "HTTP_CONTENT_LENGTH"
diff --git a/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb b/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb
index f03e1615c9..6324c7d274 100644
--- a/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb
+++ b/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb
@@ -1,5 +1,6 @@
require 'fcgi'
require 'socket'
+require 'rack/content_length'
module Rack
module Handler
@@ -29,6 +30,8 @@ module Rack
end
def self.serve(request, app)
+ app = Rack::ContentLength.new(app)
+
env = request.env
env.delete "HTTP_CONTENT_LENGTH"
diff --git a/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb b/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb
index dfc79c204b..c65ba3ec8e 100644
--- a/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb
+++ b/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb
@@ -1,5 +1,6 @@
require 'lsapi'
-#require 'cgi'
+require 'rack/content_length'
+
module Rack
module Handler
class LSWS
@@ -9,6 +10,8 @@ module Rack
end
end
def self.serve(app)
+ app = Rack::ContentLength.new(app)
+
env = ENV.to_hash
env.delete "HTTP_CONTENT_LENGTH"
env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
diff --git a/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb b/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb
index 178a1a8fe4..f0c0d58330 100644
--- a/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb
+++ b/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb
@@ -1,5 +1,7 @@
require 'mongrel'
require 'stringio'
+require 'rack/content_length'
+require 'rack/chunked'
module Rack
module Handler
@@ -33,7 +35,7 @@ module Rack
end
def initialize(app)
- @app = app
+ @app = Rack::Chunked.new(Rack::ContentLength.new(app))
end
def process(request, response)
diff --git a/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb b/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb
index fd18a8359b..9495c66374 100644
--- a/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb
+++ b/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb
@@ -1,5 +1,7 @@
require 'scgi'
require 'stringio'
+require 'rack/content_length'
+require 'rack/chunked'
module Rack
module Handler
@@ -14,7 +16,7 @@ module Rack
end
def initialize(settings = {})
- @app = settings[:app]
+ @app = Rack::Chunked.new(Rack::ContentLength.new(settings[:app]))
@log = Object.new
def @log.info(*args); end
def @log.error(*args); end
diff --git a/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb b/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb
index 7ad088b36a..3d4fedff75 100644
--- a/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb
+++ b/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb
@@ -1,9 +1,12 @@
require "thin"
+require "rack/content_length"
+require "rack/chunked"
module Rack
module Handler
class Thin
def self.run(app, options={})
+ app = Rack::Chunked.new(Rack::ContentLength.new(app))
server = ::Thin::Server.new(options[:Host] || '0.0.0.0',
options[:Port] || 8080,
app)
diff --git a/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb b/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb
index 138aae0ee9..829e7d6bf8 100644
--- a/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb
+++ b/actionpack/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb
@@ -1,5 +1,6 @@
require 'webrick'
require 'stringio'
+require 'rack/content_length'
module Rack
module Handler
@@ -14,7 +15,7 @@ module Rack
def initialize(server, app)
super server
- @app = app
+ @app = Rack::ContentLength.new(app)
end
def service(req, res)
diff --git a/actionpack/lib/action_controller/vendor/rack-1.0/rack/lint.rb b/actionpack/lib/action_controller/vendor/rack-1.0/rack/lint.rb
index ec4dac96f8..44a33ce36e 100644
--- a/actionpack/lib/action_controller/vendor/rack-1.0/rack/lint.rb
+++ b/actionpack/lib/action_controller/vendor/rack-1.0/rack/lint.rb
@@ -374,59 +374,43 @@ module Rack
## === The Content-Length
def check_content_length(status, headers, env)
- chunked_response = false
- headers.each { |key, value|
- if key.downcase == 'transfer-encoding'
- chunked_response = value.downcase != 'identity'
- end
- }
-
headers.each { |key, value|
if key.downcase == 'content-length'
- ## There must be a <tt>Content-Length</tt>, except when the
- ## +Status+ is 1xx, 204 or 304, in which case there must be none
- ## given.
+ ## There must not be a <tt>Content-Length</tt> header when the
+ ## +Status+ is 1xx, 204 or 304.
assert("Content-Length header found in #{status} response, not allowed") {
not Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.include? status.to_i
}
- assert('Content-Length header should not be used if body is chunked') {
- not chunked_response
- }
-
bytes = 0
string_body = true
- @body.each { |part|
- unless part.kind_of?(String)
- string_body = false
- break
- end
+ if @body.respond_to?(:to_ary)
+ @body.each { |part|
+ unless part.kind_of?(String)
+ string_body = false
+ break
+ end
- bytes += Rack::Utils.bytesize(part)
- }
-
- if env["REQUEST_METHOD"] == "HEAD"
- assert("Response body was given for HEAD request, but should be empty") {
- bytes == 0
+ bytes += Rack::Utils.bytesize(part)
}
- else
- if string_body
- assert("Content-Length header was #{value}, but should be #{bytes}") {
- value == bytes.to_s
+
+ if env["REQUEST_METHOD"] == "HEAD"
+ assert("Response body was given for HEAD request, but should be empty") {
+ bytes == 0
}
+ else
+ if string_body
+ assert("Content-Length header was #{value}, but should be #{bytes}") {
+ value == bytes.to_s
+ }
+ end
end
end
return
end
}
-
- if [ String, Array ].include?(@body.class) && !chunked_response
- assert('No Content-Length header found') {
- Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.include? status.to_i
- }
- end
end
## === The Body
diff --git a/actionpack/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb b/actionpack/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb
index eb1457a850..0ff32df181 100644
--- a/actionpack/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb
+++ b/actionpack/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb
@@ -12,7 +12,11 @@ module Rack
# first, since they are most specific.
class URLMap
- def initialize(map)
+ def initialize(map = {})
+ remap(map)
+ end
+
+ def remap(map)
@mapping = map.map { |location, app|
if location =~ %r{\Ahttps?://(.*?)(/.*)}
host, location = $1, $2
diff --git a/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb b/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb
index e86d4ccdcd..0a61bce707 100644
--- a/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb
+++ b/actionpack/lib/action_controller/vendor/rack-1.0/rack/utils.rb
@@ -372,7 +372,7 @@ module Rack
data = body
end
- Utils.normalize_params(params, name, data)
+ Utils.normalize_params(params, name, data) unless data.nil?
break if buf.empty? || content_length == -1
}
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index fe6053e574..e19acc5c29 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -221,10 +221,12 @@ module ActionView #:nodoc:
def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil)#:nodoc:
@assigns = assigns_for_first_render
@assigns_added = nil
- @_render_stack = []
@controller = controller
@helpers = ProxyModule.new(self)
self.view_paths = view_paths
+
+ @_first_render = nil
+ @_current_render = nil
end
attr_reader :view_paths
@@ -286,7 +288,19 @@ module ActionView #:nodoc:
# Access the current template being rendered.
# Returns a ActionView::Template object.
def template
- @_render_stack.last
+ @_current_render
+ end
+
+ def template=(template) #:nodoc:
+ @_first_render ||= template
+ @_current_render = template
+ end
+
+ def with_template(current_template)
+ last_template, self.template = template, current_template
+ yield
+ ensure
+ self.template = last_template
end
private
diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb
index 41080ed629..ff7bc7d9de 100644
--- a/actionpack/lib/action_view/renderable.rb
+++ b/actionpack/lib/action_view/renderable.rb
@@ -27,23 +27,19 @@ module ActionView
def render(view, local_assigns = {})
compile(local_assigns)
- stack = view.instance_variable_get(:@_render_stack)
- stack.push(self)
-
- view.send(:_evaluate_assigns_and_ivars)
- view.send(:_set_controller_content_type, mime_type) if respond_to?(:mime_type)
-
- result = view.send(method_name(local_assigns), local_assigns) do |*names|
- ivar = :@_proc_for_layout
- if !view.instance_variable_defined?(:"@content_for_#{names.first}") && view.instance_variable_defined?(ivar) && (proc = view.instance_variable_get(ivar))
- view.capture(*names, &proc)
- elsif view.instance_variable_defined?(ivar = :"@content_for_#{names.first || :layout}")
- view.instance_variable_get(ivar)
+ view.with_template self do
+ view.send(:_evaluate_assigns_and_ivars)
+ view.send(:_set_controller_content_type, mime_type) if respond_to?(:mime_type)
+
+ view.send(method_name(local_assigns), local_assigns) do |*names|
+ ivar = :@_proc_for_layout
+ if !view.instance_variable_defined?(:"@content_for_#{names.first}") && view.instance_variable_defined?(ivar) && (proc = view.instance_variable_get(ivar))
+ view.capture(*names, &proc)
+ elsif view.instance_variable_defined?(ivar = :"@content_for_#{names.first || :layout}")
+ view.instance_variable_get(ivar)
+ end
end
end
-
- stack.pop
- result
end
def method_name(local_assigns)
diff --git a/actionpack/test/controller/polymorphic_routes_test.rb b/actionpack/test/controller/polymorphic_routes_test.rb
index 53295522ae..146d703619 100644
--- a/actionpack/test/controller/polymorphic_routes_test.rb
+++ b/actionpack/test/controller/polymorphic_routes_test.rb
@@ -18,6 +18,20 @@ class Tag < Article
def response_id; 1 end
end
+class Tax
+ attr_reader :id
+ def save; @id = 1 end
+ def new_record?; @id.nil? end
+ def name
+ model = self.class.name.downcase
+ @id.nil? ? "new #{model}" : "#{model} ##{@id}"
+ end
+end
+
+class Fax < Tax
+ def store_id; 1 end
+end
+
# TODO: test nested models
class Response::Nested < Response; end
@@ -27,6 +41,8 @@ class PolymorphicRoutesTest < ActiveSupport::TestCase
def setup
@article = Article.new
@response = Response.new
+ @tax = Tax.new
+ @fax = Fax.new
end
def test_with_record
@@ -205,4 +221,73 @@ class PolymorphicRoutesTest < ActiveSupport::TestCase
polymorphic_url(path)
end
end
+
+ # Tests for names where .plural.singular doesn't round-trip
+ def test_with_irregular_plural_record
+ @tax.save
+ expects(:taxis_url).with(@tax)
+ polymorphic_url(@tax)
+ end
+
+ def test_with_irregular_plural_new_record
+ expects(:taxes_url).with()
+ @tax.expects(:new_record?).returns(true)
+ polymorphic_url(@tax)
+ end
+
+ def test_with_irregular_plural_record_and_action
+ expects(:new_taxis_url).with()
+ @tax.expects(:new_record?).never
+ polymorphic_url(@tax, :action => 'new')
+ end
+
+ def test_irregular_plural_url_helper_prefixed_with_new
+ expects(:new_taxis_url).with()
+ new_polymorphic_url(@tax)
+ end
+
+ def test_irregular_plural_url_helper_prefixed_with_edit
+ @tax.save
+ expects(:edit_taxis_url).with(@tax)
+ edit_polymorphic_url(@tax)
+ end
+
+ def test_with_nested_irregular_plurals
+ @fax.save
+ expects(:taxis_faxis_url).with(@tax, @fax)
+ polymorphic_url([@tax, @fax])
+ end
+
+ def test_with_nested_unsaved_irregular_plurals
+ expects(:taxis_faxes_url).with(@tax)
+ polymorphic_url([@tax, @fax])
+ end
+
+ def test_new_with_irregular_plural_array_and_namespace
+ expects(:new_admin_taxis_url).with()
+ polymorphic_url([:admin, @tax], :action => 'new')
+ end
+
+ def test_unsaved_with_irregular_plural_array_and_namespace
+ expects(:admin_taxes_url).with()
+ polymorphic_url([:admin, @tax])
+ end
+
+ def test_nesting_with_irregular_plurals_and_array_ending_in_singleton_resource
+ expects(:taxis_faxis_url).with(@tax)
+ polymorphic_url([@tax, :faxis])
+ end
+
+ def test_with_array_containing_single_irregular_plural_object
+ @tax.save
+ expects(:taxis_url).with(@tax)
+ polymorphic_url([nil, @tax])
+ end
+
+ def test_with_array_containing_single_name_irregular_plural
+ @tax.save
+ expects(:taxes_url)
+ polymorphic_url([:taxes])
+ end
+
end
diff --git a/actionpack/test/controller/request/multipart_params_parsing_test.rb b/actionpack/test/controller/request/multipart_params_parsing_test.rb
index 054519d0d2..b812072ef4 100644
--- a/actionpack/test/controller/request/multipart_params_parsing_test.rb
+++ b/actionpack/test/controller/request/multipart_params_parsing_test.rb
@@ -103,7 +103,7 @@ class MultipartParamsParsingTest < ActionController::IntegrationTest
test "does not create tempfile if no file has been selected" do
params = parse_multipart('none')
- assert_equal %w(files submit-name), params.keys.sort
+ assert_equal %w(submit-name), params.keys.sort
assert_equal 'Larry', params['submit-name']
assert_equal nil, params['files']
end
diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb
index 35f943737f..91066ea893 100644
--- a/actionpack/test/controller/resources_test.rb
+++ b/actionpack/test/controller/resources_test.rb
@@ -209,14 +209,6 @@ class ResourcesTest < ActionController::TestCase
end
end
- def test_with_member_action_and_requirement
- expected_options = {:controller => 'messages', :action => 'mark', :id => '1.1.1'}
-
- with_restful_routing(:messages, :requirements => {:id => /[0-9]\.[0-9]\.[0-9]/}, :member => { :mark => :get }) do
- assert_recognizes(expected_options, :path => 'messages/1.1.1/mark', :method => :get)
- end
- end
-
def test_member_when_override_paths_for_default_restful_actions_with
[:put, :post].each do |method|
with_restful_routing :messages, :member => { :mark => method }, :path_names => {:new => 'nuevo'} do
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index a5459d09da..2a5385119d 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -1344,7 +1344,7 @@ module ActiveRecord #:nodoc:
subclasses.each { |klass| klass.reset_inheritable_attributes; klass.reset_column_information }
end
- def self_and_descendents_from_active_record#nodoc:
+ def self_and_descendants_from_active_record#nodoc:
klass = self
classes = [klass]
while klass != klass.base_class
@@ -1364,7 +1364,7 @@ module ActiveRecord #:nodoc:
# module now.
# Specify +options+ with additional translating options.
def human_attribute_name(attribute_key_name, options = {})
- defaults = self_and_descendents_from_active_record.map do |klass|
+ defaults = self_and_descendants_from_active_record.map do |klass|
:"#{klass.name.underscore}.#{attribute_key_name}"
end
defaults << options[:default] if options[:default]
@@ -1379,7 +1379,7 @@ module ActiveRecord #:nodoc:
# Default scope of the translation is activerecord.models
# Specify +options+ with additional translating options.
def human_name(options = {})
- defaults = self_and_descendents_from_active_record.map do |klass|
+ defaults = self_and_descendants_from_active_record.map do |klass|
:"#{klass.name.underscore}"
end
defaults << self.name.humanize
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index 6077ddcdb6..afd6472db8 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -72,6 +72,18 @@ module ActiveRecord
#
# * <tt>:database</tt> - Path to the database file.
class SQLiteAdapter < AbstractAdapter
+ class Version
+ include Comparable
+
+ def initialize(version_string)
+ @version = version_string.split('.').map(&:to_i)
+ end
+
+ def <=>(version_string)
+ @version <=> version_string.split('.').map(&:to_i)
+ end
+ end
+
def initialize(connection, logger, config)
super(connection, logger)
@config = config
@@ -81,6 +93,10 @@ module ActiveRecord
'SQLite'
end
+ def supports_ddl_transactions?
+ sqlite_version >= '2.0.0'
+ end
+
def supports_migrations? #:nodoc:
true
end
@@ -88,6 +104,10 @@ module ActiveRecord
def requires_reloading?
true
end
+
+ def supports_add_column?
+ sqlite_version >= '3.1.6'
+ end
def disconnect!
super
@@ -169,7 +189,6 @@ module ActiveRecord
catch_schema_changes { @connection.rollback }
end
-
# SELECT ... FOR UPDATE is redundant since the table is locked.
def add_lock!(sql, options) #:nodoc:
sql
@@ -218,14 +237,20 @@ module ActiveRecord
execute "ALTER TABLE #{name} RENAME TO #{new_name}"
end
+ # See: http://www.sqlite.org/lang_altertable.html
+ # SQLite has an additional restriction on the ALTER TABLE statement
+ def valid_alter_table_options( type, options)
+ type.to_sym != :primary_key
+ end
+
def add_column(table_name, column_name, type, options = {}) #:nodoc:
- if @connection.respond_to?(:transaction_active?) && @connection.transaction_active?
- raise StatementInvalid, 'Cannot add columns to a SQLite database while inside a transaction'
+ if supports_add_column? && valid_alter_table_options( type, options )
+ super(table_name, column_name, type, options)
+ else
+ alter_table(table_name) do |definition|
+ definition.column(column_name, type, options)
+ end
end
-
- super(table_name, column_name, type, options)
- # See last paragraph on http://www.sqlite.org/lang_altertable.html
- execute "VACUUM"
end
def remove_column(table_name, *column_names) #:nodoc:
@@ -385,7 +410,7 @@ module ActiveRecord
end
def sqlite_version
- @sqlite_version ||= select_value('select sqlite_version(*)')
+ @sqlite_version ||= SQLiteAdapter::Version.new(select_value('select sqlite_version(*)'))
end
def default_primary_key_type
@@ -398,23 +423,9 @@ module ActiveRecord
end
class SQLite2Adapter < SQLiteAdapter # :nodoc:
- def supports_count_distinct? #:nodoc:
- false
- end
-
def rename_table(name, new_name)
move_table(name, new_name)
end
-
- def add_column(table_name, column_name, type, options = {}) #:nodoc:
- if @connection.respond_to?(:transaction_active?) && @connection.transaction_active?
- raise StatementInvalid, 'Cannot add columns to a SQLite database while inside a transaction'
- end
-
- alter_table(table_name) do |definition|
- definition.column(column_name, type, options)
- end
- end
end
class DeprecatedSQLiteAdapter < SQLite2Adapter # :nodoc:
diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb
index e2b596446f..d2d12b80c9 100644
--- a/activerecord/lib/active_record/validations.rb
+++ b/activerecord/lib/active_record/validations.rb
@@ -89,7 +89,7 @@ module ActiveRecord
message, options[:default] = options[:default], message if options[:default].is_a?(Symbol)
- defaults = @base.class.self_and_descendents_from_active_record.map do |klass|
+ defaults = @base.class.self_and_descendants_from_active_record.map do |klass|
[ :"models.#{klass.name.underscore}.attributes.#{attribute}.#{message}",
:"models.#{klass.name.underscore}.#{message}" ]
end
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index 50d039ec77..16861f21b1 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -93,6 +93,30 @@ if ActiveRecord::Base.connection.supports_migrations?
end
end
+ def testing_table_with_only_foo_attribute
+ Person.connection.create_table :testings, :id => false do |t|
+ t.column :foo, :string
+ end
+
+ yield Person.connection
+ ensure
+ Person.connection.drop_table :testings rescue nil
+ end
+ protected :testing_table_with_only_foo_attribute
+
+ def test_create_table_without_id
+ testing_table_with_only_foo_attribute do |connection|
+ assert_equal connection.columns(:testings).size, 1
+ end
+ end
+
+ def test_add_column_with_primary_key_attribute
+ testing_table_with_only_foo_attribute do |connection|
+ assert_nothing_raised { connection.add_column :testings, :id, :primary_key }
+ assert_equal connection.columns(:testings).size, 2
+ end
+ end
+
def test_create_table_adds_id
Person.connection.create_table :testings do |t|
t.column :foo, :string
@@ -928,7 +952,7 @@ if ActiveRecord::Base.connection.supports_migrations?
assert_equal(0, ActiveRecord::Migrator.current_version)
end
- if current_adapter?(:PostgreSQLAdapter)
+ if ActiveRecord::Base.connection.supports_ddl_transactions?
def test_migrator_one_up_with_exception_and_rollback
assert !Person.column_methods_hash.include?(:last_name)
diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb
index f9ae5115fc..f6533b5396 100644
--- a/activerecord/test/cases/transactions_test.rb
+++ b/activerecord/test/cases/transactions_test.rb
@@ -349,7 +349,7 @@ class TransactionTest < ActiveRecord::TestCase
end
end
- def test_sqlite_add_column_in_transaction_raises_statement_invalid
+ def test_sqlite_add_column_in_transaction
return true unless current_adapter?(:SQLite3Adapter, :SQLiteAdapter)
# Test first if column creation/deletion works correctly when no
@@ -368,10 +368,15 @@ class TransactionTest < ActiveRecord::TestCase
assert !Topic.column_names.include?('stuff')
end
- # Test now inside a transaction: add_column should raise a StatementInvalid
- Topic.transaction do
- assert_raise(ActiveRecord::StatementInvalid) { Topic.connection.add_column('topics', 'stuff', :string) }
- raise ActiveRecord::Rollback
+ if Topic.connection.supports_ddl_transactions?
+ assert_nothing_raised do
+ Topic.transaction { Topic.connection.add_column('topics', 'stuff', :string) }
+ end
+ else
+ Topic.transaction do
+ assert_raise(ActiveRecord::StatementInvalid) { Topic.connection.add_column('topics', 'stuff', :string) }
+ raise ActiveRecord::Rollback
+ end
end
end
diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb
index 991a5a6a89..10435975c5 100644
--- a/activesupport/lib/active_support/core_ext/hash/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb
@@ -24,11 +24,12 @@ module ActiveSupport #:nodoc:
"Bignum" => "integer",
"BigDecimal" => "decimal",
"Float" => "float",
+ "TrueClass" => "boolean",
+ "FalseClass" => "boolean",
"Date" => "date",
"DateTime" => "datetime",
"Time" => "datetime",
- "TrueClass" => "boolean",
- "FalseClass" => "boolean"
+ "ActiveSupport::TimeWithZone" => "datetime"
} unless defined?(XML_TYPE_NAMES)
XML_FORMATTING = {
diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb
index 482ae57830..0edac72fe7 100644
--- a/activesupport/test/core_ext/hash_ext_test.rb
+++ b/activesupport/test/core_ext/hash_ext_test.rb
@@ -497,6 +497,15 @@ class HashToXmlTest < Test::Unit::TestCase
assert xml.include?(%(<addresses type="array"><address><streets type="array"><street><name>))
end
+ def test_timezoned_attributes
+ xml = {
+ :created_at => Time.utc(1999,2,2),
+ :local_created_at => Time.utc(1999,2,2).in_time_zone('Eastern Time (US & Canada)')
+ }.to_xml(@xml_options)
+ assert_match %r{<created-at type=\"datetime\">1999-02-02T00:00:00Z</created-at>}, xml
+ assert_match %r{<local-created-at type=\"datetime\">1999-02-01T19:00:00-05:00</local-created-at>}, xml
+ end
+
def test_single_record_from_xml
topic_xml = <<-EOT
<topic>
diff --git a/railties/environments/boot.rb b/railties/environments/boot.rb
index 0a516880ca..0ad0f787f8 100644
--- a/railties/environments/boot.rb
+++ b/railties/environments/boot.rb
@@ -44,6 +44,7 @@ module Rails
def load_initializer
require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
Rails::Initializer.run(:install_gem_spec_stubs)
+ Rails::GemDependency.add_frozen_gem_path
end
end
diff --git a/railties/lib/initializer.rb b/railties/lib/initializer.rb
index edea4e513a..a04405a7c2 100644
--- a/railties/lib/initializer.rb
+++ b/railties/lib/initializer.rb
@@ -301,7 +301,9 @@ module Rails
end
def load_gems
- @configuration.gems.each { |gem| gem.load }
+ unless $gems_build_rake_task
+ @configuration.gems.each { |gem| gem.load }
+ end
end
def check_gem_dependencies
diff --git a/railties/lib/rails/gem_dependency.rb b/railties/lib/rails/gem_dependency.rb
index 2dd659032f..3062a77104 100644
--- a/railties/lib/rails/gem_dependency.rb
+++ b/railties/lib/rails/gem_dependency.rb
@@ -7,8 +7,8 @@ module Gem
end
module Rails
- class GemDependency
- attr_accessor :lib, :source
+ class GemDependency < Gem::Dependency
+ attr_accessor :lib, :source, :dep
def self.unpacked_path
@unpacked_path ||= File.join(RAILS_ROOT, 'vendor', 'gems')
@@ -29,18 +29,6 @@ module Rails
end
end
- def framework_gem?
- @@framework_gems.has_key?(name)
- end
-
- def vendor_rails?
- Gem.loaded_specs.has_key?(name) && Gem.loaded_specs[name].loaded_from.empty?
- end
-
- def vendor_gem?
- Gem.loaded_specs.has_key?(name) && Gem.loaded_specs[name].loaded_from.include?(self.class.unpacked_path)
- end
-
def initialize(name, options = {})
require 'rubygems' unless Object.const_defined?(:Gem)
@@ -52,10 +40,11 @@ module Rails
req = Gem::Requirement.default
end
- @dep = Gem::Dependency.new(name, req)
@lib = options[:lib]
@source = options[:source]
@loaded = @frozen = @load_paths_added = false
+
+ super(name, req)
end
def add_load_paths
@@ -65,52 +54,74 @@ module Rails
@load_paths_added = @loaded = @frozen = true
return
end
- gem @dep
+ gem self
@spec = Gem.loaded_specs[name]
@frozen = @spec.loaded_from.include?(self.class.unpacked_path) if @spec
@load_paths_added = true
rescue Gem::LoadError
end
- def dependencies(options = {})
- return [] if framework_gem? || specification.nil?
-
- all_dependencies = specification.dependencies.map do |dependency|
+ def dependencies
+ return [] if framework_gem?
+ return [] unless installed?
+ specification.dependencies.reject do |dependency|
+ dependency.type == :development
+ end.map do |dependency|
GemDependency.new(dependency.name, :requirement => dependency.version_requirements)
end
+ end
- all_dependencies += all_dependencies.map { |d| d.dependencies(options) }.flatten if options[:flatten]
- all_dependencies.uniq
+ def specification
+ # code repeated from Gem.activate. Find a matching spec, or the currently loaded version.
+ # error out if loaded version and requested version are incompatible.
+ @spec ||= begin
+ matches = Gem.source_index.search(self)
+ matches << @@framework_gems[name] if framework_gem?
+ if Gem.loaded_specs[name] then
+ # This gem is already loaded. If the currently loaded gem is not in the
+ # list of candidate gems, then we have a version conflict.
+ existing_spec = Gem.loaded_specs[name]
+ unless matches.any? { |spec| spec.version == existing_spec.version } then
+ raise Gem::Exception,
+ "can't activate #{@dep}, already activated #{existing_spec.full_name}"
+ end
+ # we're stuck with it, so change to match
+ version_requirements = Gem::Requirement.create("=#{existing_spec.version}")
+ existing_spec
+ else
+ # new load
+ matches.last
+ end
+ end
end
- def gem_dir(base_directory)
- File.join(base_directory, specification.full_name)
+ def requirement
+ r = version_requirements
+ (r == Gem::Requirement.default) ? nil : r
end
- def spec_filename(base_directory)
- File.join(gem_dir(base_directory), '.specification')
+ def built?
+ # TODO: If Rubygems ever gives us a way to detect this, we should use it
+ false
end
- def load
- return if @loaded || @load_paths_added == false
- require(@lib || name) unless @lib == false
- @loaded = true
- rescue LoadError
- puts $!.to_s
- $!.backtrace.each { |b| puts b }
+ def framework_gem?
+ @@framework_gems.has_key?(name)
end
- def name
- @dep.name.to_s
+ def frozen?
+ @frozen ||= vendor_rails? || vendor_gem?
end
- def requirement
- r = @dep.version_requirements
- (r == Gem::Requirement.default) ? nil : r
+ def installed?
+ Gem.loaded_specs.keys.include?(name)
end
- def frozen?
- @frozen ||= vendor_rails? || vendor_gem?
+ def load_paths_added?
+ # always try to add load paths - even if a gem is loaded, it may not
+ # be a compatible version (ie random_gem 0.4 is loaded and a later spec
+ # needs >= 0.5 - gem 'random_gem' will catch this and error out)
+ @load_paths_added
end
def loaded?
@@ -136,48 +147,49 @@ module Rails
end
end
- def load_paths_added?
- # always try to add load paths - even if a gem is loaded, it may not
- # be a compatible version (ie random_gem 0.4 is loaded and a later spec
- # needs >= 0.5 - gem 'random_gem' will catch this and error out)
- @load_paths_added
+ def vendor_rails?
+ Gem.loaded_specs.has_key?(name) && Gem.loaded_specs[name].loaded_from.empty?
end
- def install
- cmd = "#{gem_command} #{install_command.join(' ')}"
- puts cmd
- puts %x(#{cmd})
+ def vendor_gem?
+ specification && File.exists?(unpacked_gem_directory)
end
- def unpack_to(directory)
- return if specification.nil? || File.directory?(gem_dir(directory)) || framework_gem?
-
- FileUtils.mkdir_p directory
- Dir.chdir directory do
- Gem::GemRunner.new.run(unpack_command)
+ def build
+ require 'rails/gem_builder'
+ unless built?
+ return unless File.exists?(unpacked_specification_filename)
+ spec = YAML::load_file(unpacked_specification_filename)
+ Rails::GemBuilder.new(spec, unpacked_gem_directory).build_extensions
+ puts "Built gem: '#{unpacked_gem_directory}'"
end
-
- # Gem.activate changes the spec - get the original
- real_spec = Gem::Specification.load(specification.loaded_from)
- write_spec(directory, real_spec)
-
+ dependencies.each { |dep| dep.build }
end
- def write_spec(directory, spec)
- # copy the gem's specification into GEMDIR/.specification so that
- # we can access information about the gem on deployment systems
- # without having the gem installed
- File.open(spec_filename(directory), 'w') do |file|
- file.puts spec.to_yaml
+ def install
+ unless installed?
+ cmd = "#{gem_command} #{install_command.join(' ')}"
+ puts cmd
+ puts %x(#{cmd})
end
end
- def refresh_spec(directory)
+ def load
+ return if @loaded || @load_paths_added == false
+ require(@lib || name) unless @lib == false
+ @loaded = true
+ rescue LoadError
+ puts $!.to_s
+ $!.backtrace.each { |b| puts b }
+ end
+
+ def refresh
+ Rails::VendorGemSourceIndex.silence_spec_warnings = true
real_gems = Gem.source_index.installed_source_index
exact_dep = Gem::Dependency.new(name, "= #{specification.version}")
matches = real_gems.search(exact_dep)
installed_spec = matches.first
- if File.exist?(File.dirname(spec_filename(directory)))
+ if frozen?
if installed_spec
# we have a real copy
# get a fresh spec - matches should only have one element
@@ -185,11 +197,11 @@ module Rails
# spec is the same as the copy from real_gems - Gem.activate changes
# some of the fields
real_spec = Gem::Specification.load(matches.first.loaded_from)
- write_spec(directory, real_spec)
+ write_specification(real_spec)
puts "Reloaded specification for #{name} from installed gems."
else
# the gem isn't installed locally - write out our current specs
- write_spec(directory, specification)
+ write_specification(specification)
puts "Gem #{name} not loaded locally - writing out current spec."
end
else
@@ -201,42 +213,44 @@ module Rails
end
end
- def ==(other)
- self.name == other.name && self.requirement == other.requirement
+ def unpack(options={})
+ unless frozen? || framework_gem?
+ FileUtils.mkdir_p unpack_base
+ Dir.chdir unpack_base do
+ Gem::GemRunner.new.run(unpack_command)
+ end
+ # Gem.activate changes the spec - get the original
+ real_spec = Gem::Specification.load(specification.loaded_from)
+ write_specification(real_spec)
+ end
+ dependencies.each { |dep| dep.unpack } if options[:recursive]
end
- alias_method :"eql?", :"=="
- def hash
- @dep.hash
+ def write_specification(spec)
+ # copy the gem's specification into GEMDIR/.specification so that
+ # we can access information about the gem on deployment systems
+ # without having the gem installed
+ File.open(unpacked_specification_filename, 'w') do |file|
+ file.puts spec.to_yaml
+ end
end
- def specification
- # code repeated from Gem.activate. Find a matching spec, or the currently loaded version.
- # error out if loaded version and requested version are incompatible.
- @spec ||= begin
- matches = Gem.source_index.search(@dep)
- matches << @@framework_gems[name] if framework_gem?
- if Gem.loaded_specs[name] then
- # This gem is already loaded. If the currently loaded gem is not in the
- # list of candidate gems, then we have a version conflict.
- existing_spec = Gem.loaded_specs[name]
- unless matches.any? { |spec| spec.version == existing_spec.version } then
- raise Gem::Exception,
- "can't activate #{@dep}, already activated #{existing_spec.full_name}"
- end
- # we're stuck with it, so change to match
- @dep.version_requirements = Gem::Requirement.create("=#{existing_spec.version}")
- existing_spec
- else
- # new load
- matches.last
- end
- end
+ def ==(other)
+ self.name == other.name && self.requirement == other.requirement
end
+ alias_method :"eql?", :"=="
private
+
def gem_command
- RUBY_PLATFORM =~ /win32/ ? 'gem.bat' : 'gem'
+ case RUBY_PLATFORM
+ when /win32/
+ 'gem.bat'
+ when /java/
+ 'jruby -S gem'
+ else
+ 'gem'
+ end
end
def install_command
@@ -251,5 +265,18 @@ module Rails
cmd << "--version" << "= "+specification.version.to_s if requirement
cmd
end
+
+ def unpack_base
+ Rails::GemDependency.unpacked_path
+ end
+
+ def unpacked_gem_directory
+ File.join(unpack_base, specification.full_name)
+ end
+
+ def unpacked_specification_filename
+ File.join(unpacked_gem_directory, '.specification')
+ end
+
end
end
diff --git a/railties/lib/tasks/gems.rake b/railties/lib/tasks/gems.rake
index 0932ba73b5..ed07bf2016 100644
--- a/railties/lib/tasks/gems.rake
+++ b/railties/lib/tasks/gems.rake
@@ -9,71 +9,57 @@ task :gems => 'gems:base' do
puts "R = Framework (loaded before rails starts)"
end
-def print_gem_status(gem, indent=1)
- code = gem.loaded? ? (gem.frozen? ? (gem.framework_gem? ? "R" : "F") : "I") : " "
- puts " "*(indent-1)+" - [#{code}] #{gem.name} #{gem.requirement.to_s}"
- gem.dependencies.each { |g| print_gem_status(g, indent+1)} if gem.loaded?
-end
-
namespace :gems do
task :base do
$gems_rake_task = true
+ require 'rubygems'
+ require 'rubygems/gem_runner'
Rake::Task[:environment].invoke
end
desc "Build any native extensions for unpacked gems"
task :build do
- $gems_rake_task = true
- require 'rails/gem_builder'
- Dir[File.join(Rails::GemDependency.unpacked_path, '*')].each do |gem_dir|
- spec_file = File.join(gem_dir, '.specification')
- next unless File.exists?(spec_file)
- specification = YAML::load_file(spec_file)
- next unless ENV['GEM'].blank? || ENV['GEM'] == specification.name
- Rails::GemBuilder.new(specification, gem_dir).build_extensions
- puts "Built gem: '#{gem_dir}'"
- end
+ $gems_build_rake_task = true
+ Rake::Task['gems:unpack'].invoke
+ current_gems.each &:build
end
- desc "Installs all required gems for this application."
+ desc "Installs all required gems."
task :install => :base do
- require 'rubygems'
- require 'rubygems/gem_runner'
- Rails.configuration.gems.each { |gem| gem.install unless gem.loaded? }
+ current_gems.each &:install
end
- desc "Unpacks the specified gem into vendor/gems."
- task :unpack => :base do
- require 'rubygems'
- require 'rubygems/gem_runner'
- Rails.configuration.gems.each do |gem|
- next unless ENV['GEM'].blank? || ENV['GEM'] == gem.name
- gem.unpack_to(Rails::GemDependency.unpacked_path)
- end
+ desc "Unpacks all required gems into vendor/gems."
+ task :unpack => :install do
+ current_gems.each &:unpack
end
namespace :unpack do
- desc "Unpacks the specified gems and its dependencies into vendor/gems"
- task :dependencies => :unpack do
- require 'rubygems'
- require 'rubygems/gem_runner'
- Rails.configuration.gems.each do |gem|
- next unless ENV['GEM'].blank? || ENV['GEM'] == gem.name
- gem.dependencies(:flatten => true).each do |dependency|
- dependency.unpack_to(Rails::GemDependency.unpacked_path)
- end
- end
+ desc "Unpacks all required gems and their dependencies into vendor/gems."
+ task :dependencies => :install do
+ current_gems.each { |gem| gem.unpack(:recursive => true) }
end
end
desc "Regenerate gem specifications in correct format."
task :refresh_specs => :base do
- require 'rubygems'
- require 'rubygems/gem_runner'
- Rails::VendorGemSourceIndex.silence_spec_warnings = true
- Rails.configuration.gems.each do |gem|
- next unless gem.frozen? && (ENV['GEM'].blank? || ENV['GEM'] == gem.name)
- gem.refresh_spec(Rails::GemDependency.unpacked_path) if gem.loaded?
- end
+ current_gems.each &:refresh
+ end
+end
+
+def current_gems
+ gems = Rails.configuration.gems
+ gems = gems.select { |gem| gem.name == ENV['GEM'] } unless ENV['GEM'].blank?
+ gems
+end
+
+def print_gem_status(gem, indent=1)
+ code = case
+ when gem.framework_gem? then 'R'
+ when gem.frozen? then 'F'
+ when gem.installed? then 'I'
+ else ' '
end
-end \ No newline at end of file
+ puts " "*(indent-1)+" - [#{code}] #{gem.name} #{gem.requirement.to_s}"
+ gem.dependencies.each { |g| print_gem_status(g, indent+1) }
+end
diff --git a/railties/test/boot_test.rb b/railties/test/boot_test.rb
index 16776af098..08fcc82e6f 100644
--- a/railties/test/boot_test.rb
+++ b/railties/test/boot_test.rb
@@ -62,6 +62,8 @@ class VendorBootTest < Test::Unit::TestCase
def test_load_initializer_requires_from_vendor_rails
boot = VendorBoot.new
boot.expects(:require).with("#{RAILS_ROOT}/vendor/rails/railties/lib/initializer")
+ Rails::Initializer.expects(:run).with(:install_gem_spec_stubs)
+ Rails::GemDependency.expects(:add_frozen_gem_path)
boot.load_initializer
end
end
diff --git a/railties/test/gem_dependency_test.rb b/railties/test/gem_dependency_test.rb
index 8b761c48b2..189ad02b76 100644
--- a/railties/test/gem_dependency_test.rb
+++ b/railties/test/gem_dependency_test.rb
@@ -46,31 +46,34 @@ class GemDependencyTest < Test::Unit::TestCase
end
def test_gem_adds_load_paths
- @gem.expects(:gem).with(Gem::Dependency.new(@gem.name, nil))
+ @gem.expects(:gem).with(@gem)
@gem.add_load_paths
end
def test_gem_with_version_adds_load_paths
- @gem_with_version.expects(:gem).with(Gem::Dependency.new(@gem_with_version.name, @gem_with_version.requirement.to_s))
+ @gem_with_version.expects(:gem).with(@gem_with_version)
@gem_with_version.add_load_paths
+ assert @gem_with_version.load_paths_added?
end
def test_gem_loading
- @gem.expects(:gem).with(Gem::Dependency.new(@gem.name, nil))
+ @gem.expects(:gem).with(@gem)
@gem.expects(:require).with(@gem.name)
@gem.add_load_paths
@gem.load
+ assert @gem.loaded?
end
def test_gem_with_lib_loading
- @gem_with_lib.expects(:gem).with(Gem::Dependency.new(@gem_with_lib.name, nil))
+ @gem_with_lib.expects(:gem).with(@gem_with_lib)
@gem_with_lib.expects(:require).with(@gem_with_lib.lib)
@gem_with_lib.add_load_paths
@gem_with_lib.load
+ assert @gem_with_lib.loaded?
end
def test_gem_without_lib_loading
- @gem_without_load.expects(:gem).with(Gem::Dependency.new(@gem_without_load.name, nil))
+ @gem_without_load.expects(:gem).with(@gem_without_load)
@gem_without_load.expects(:require).with(@gem_without_load.lib).never
@gem_without_load.add_load_paths
@gem_without_load.load
@@ -132,8 +135,8 @@ class GemDependencyTest < Test::Unit::TestCase
dummy_gem = Rails::GemDependency.new "dummy-gem-g"
dummy_gem.add_load_paths
dummy_gem.load
- assert dummy_gem.loaded?
- assert_equal 2, dummy_gem.dependencies(:flatten => true).size
+ assert_equal 1, dummy_gem.dependencies.size
+ assert_equal 1, dummy_gem.dependencies.first.dependencies.size
assert_nothing_raised do
dummy_gem.dependencies.each do |g|
g.dependencies
diff --git a/railties/test/vendor/gems/dummy-gem-g-1.0.0/.specification b/railties/test/vendor/gems/dummy-gem-g-1.0.0/.specification
index 5483048c1c..27e29912a6 100644
--- a/railties/test/vendor/gems/dummy-gem-g-1.0.0/.specification
+++ b/railties/test/vendor/gems/dummy-gem-g-1.0.0/.specification
@@ -9,7 +9,7 @@ date: 2008-10-03 00:00:00 -04:00
dependencies:
- !ruby/object:Gem::Dependency
name: dummy-gem-f
- type: :development
+ type: :runtime
version_requirement:
version_requirements: !ruby/object:Gem::Requirement
requirements: