Attempt to deal with more cases of gems with native components.
This commit adds a rudimentary check for 'unbuilt' gems, so that we can abort the application load if there are any gems that have native components that have not yet been built. The rake task gems:build has now only builds 'unbuilt' gems as a result. The rake task gems:build:force has been added to deal with cases of incomplete builds, or any case where you need to force the build of all of your gems. Changes the gems:build task to get its gem list by parsing directory entries in vendor/gems, which sidesteps the chicken/egg issues involved with having a gem unpacked into vendor/gems without before its native bits are compiled. [#2266 state:committed] Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
This commit is contained in:
parent
acd5db300b
commit
599f2cfb4a
@ -156,6 +156,8 @@ def process
|
|||||||
|
|
||||||
add_support_load_paths
|
add_support_load_paths
|
||||||
|
|
||||||
|
check_for_unbuilt_gems
|
||||||
|
|
||||||
load_gems
|
load_gems
|
||||||
load_plugins
|
load_plugins
|
||||||
|
|
||||||
@ -308,6 +310,25 @@ def load_gems
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def check_for_unbuilt_gems
|
||||||
|
unbuilt_gems = @configuration.gems.select(&:frozen?).reject(&:built?)
|
||||||
|
if unbuilt_gems.size > 0
|
||||||
|
# don't print if the gems:build rake tasks are being run
|
||||||
|
unless $gems_build_rake_task
|
||||||
|
abort <<-end_error
|
||||||
|
The following gems have native components that need to be built
|
||||||
|
#{unbuilt_gems.map { |gem| "#{gem.name} #{gem.requirement}" } * "\n "}
|
||||||
|
|
||||||
|
You're running:
|
||||||
|
ruby #{Gem.ruby_version} at #{Gem.ruby}
|
||||||
|
rubygems #{Gem::RubyGemsVersion} at #{Gem.path * ', '}
|
||||||
|
|
||||||
|
Run `rake gems:build` to build the unbuilt gems.
|
||||||
|
end_error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def check_gem_dependencies
|
def check_gem_dependencies
|
||||||
unloaded_gems = @configuration.gems.reject { |g| g.loaded? }
|
unloaded_gems = @configuration.gems.reject { |g| g.loaded? }
|
||||||
if unloaded_gems.size > 0
|
if unloaded_gems.size > 0
|
||||||
|
@ -29,6 +29,15 @@ def self.add_frozen_gem_path
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.from_directory_name(directory_name)
|
||||||
|
directory_name_parts = File.basename(directory_name).split('-')
|
||||||
|
name = directory_name_parts[0..-2].join('-')
|
||||||
|
version = directory_name_parts.last
|
||||||
|
self.new(name, :version => version)
|
||||||
|
rescue ArgumentError => e
|
||||||
|
raise "Unable to determine gem name and version from '#{directory_name}'"
|
||||||
|
end
|
||||||
|
|
||||||
def initialize(name, options = {})
|
def initialize(name, options = {})
|
||||||
require 'rubygems' unless Object.const_defined?(:Gem)
|
require 'rubygems' unless Object.const_defined?(:Gem)
|
||||||
|
|
||||||
@ -101,8 +110,12 @@ def requirement
|
|||||||
end
|
end
|
||||||
|
|
||||||
def built?
|
def built?
|
||||||
# TODO: If Rubygems ever gives us a way to detect this, we should use it
|
return false unless frozen?
|
||||||
false
|
specification.extensions.each do |ext|
|
||||||
|
makefile = File.join(unpacked_gem_directory, File.dirname(ext), 'Makefile')
|
||||||
|
return false unless File.exists?(makefile)
|
||||||
|
end
|
||||||
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def framework_gem?
|
def framework_gem?
|
||||||
@ -155,9 +168,9 @@ def vendor_gem?
|
|||||||
specification && File.exists?(unpacked_gem_directory)
|
specification && File.exists?(unpacked_gem_directory)
|
||||||
end
|
end
|
||||||
|
|
||||||
def build
|
def build(options={})
|
||||||
require 'rails/gem_builder'
|
require 'rails/gem_builder'
|
||||||
unless built?
|
if options[:force] || !built?
|
||||||
return unless File.exists?(unpacked_specification_filename)
|
return unless File.exists?(unpacked_specification_filename)
|
||||||
spec = YAML::load_file(unpacked_specification_filename)
|
spec = YAML::load_file(unpacked_specification_filename)
|
||||||
Rails::GemBuilder.new(spec, unpacked_gem_directory).build_extensions
|
Rails::GemBuilder.new(spec, unpacked_gem_directory).build_extensions
|
||||||
|
@ -20,8 +20,16 @@ namespace :gems do
|
|||||||
desc "Build any native extensions for unpacked gems"
|
desc "Build any native extensions for unpacked gems"
|
||||||
task :build do
|
task :build do
|
||||||
$gems_build_rake_task = true
|
$gems_build_rake_task = true
|
||||||
Rake::Task['gems:unpack'].invoke
|
frozen_gems.each &:build
|
||||||
current_gems.each &:build
|
end
|
||||||
|
|
||||||
|
namespace :build do
|
||||||
|
desc "Force the build of all gems"
|
||||||
|
task :force do
|
||||||
|
$gems_build_rake_task = true
|
||||||
|
Rake::Task['gems:unpack'].invoke
|
||||||
|
current_gems.each { |gem| gem.build(:force => true) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "Installs all required gems."
|
desc "Installs all required gems."
|
||||||
@ -53,6 +61,12 @@ def current_gems
|
|||||||
gems
|
gems
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def frozen_gems
|
||||||
|
Dir[File.join(RAILS_ROOT, 'vendor', 'gems', '*-*')].map do |gem_dir|
|
||||||
|
Rails::GemDependency.from_directory_name(gem_dir)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def print_gem_status(gem, indent=1)
|
def print_gem_status(gem, indent=1)
|
||||||
code = case
|
code = case
|
||||||
when gem.framework_gem? then 'R'
|
when gem.framework_gem? then 'R'
|
||||||
|
@ -145,4 +145,25 @@ def test_gem_handle_missing_dependencies
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_gem_from_directory_name
|
||||||
|
dummy_gem = Rails::GemDependency.from_directory_name('dummy-gem-1.1')
|
||||||
|
assert_equal 'dummy-gem', dummy_gem.name
|
||||||
|
assert_equal '= 1.1', dummy_gem.version_requirements.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_gem_from_invalid_directory_name
|
||||||
|
assert_raises RuntimeError do
|
||||||
|
dummy_gem = Rails::GemDependency.from_directory_name('dummy-gem')
|
||||||
|
end
|
||||||
|
assert_raises RuntimeError do
|
||||||
|
dummy_gem = Rails::GemDependency.from_directory_name('dummy')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_gem_determines_build_status
|
||||||
|
assert_equal true, Rails::GemDependency.new("dummy-gem-a").built?
|
||||||
|
assert_equal true, Rails::GemDependency.new("dummy-gem-i").built?
|
||||||
|
assert_equal false, Rails::GemDependency.new("dummy-gem-j").built?
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
41
railties/test/vendor/gems/dummy-gem-i-1.0.0/.specification
vendored
Normal file
41
railties/test/vendor/gems/dummy-gem-i-1.0.0/.specification
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
--- !ruby/object:Gem::Specification
|
||||||
|
name: dummy-gem-i
|
||||||
|
version: !ruby/object:Gem::Version
|
||||||
|
version: 1.3.0
|
||||||
|
platform: ruby
|
||||||
|
authors:
|
||||||
|
- "Nobody"
|
||||||
|
date: 2008-10-03 00:00:00 -04:00
|
||||||
|
dependencies:
|
||||||
|
- !ruby/object:Gem::Dependency
|
||||||
|
name: dummy-gem-i
|
||||||
|
type: :runtime
|
||||||
|
version_requirement:
|
||||||
|
version_requirements: !ruby/object:Gem::Requirement
|
||||||
|
requirements:
|
||||||
|
- - ">="
|
||||||
|
- !ruby/object:Gem::Version
|
||||||
|
version: 1.0.0
|
||||||
|
version:
|
||||||
|
extensions:
|
||||||
|
- ext/dummy-gem-i/extconf.rb
|
||||||
|
files:
|
||||||
|
- lib
|
||||||
|
- lib/dummy-gem-i.rb
|
||||||
|
require_paths:
|
||||||
|
- lib
|
||||||
|
required_ruby_version: !ruby/object:Gem::Requirement
|
||||||
|
requirements:
|
||||||
|
- - ">="
|
||||||
|
- !ruby/object:Gem::Version
|
||||||
|
version: "0"
|
||||||
|
version:
|
||||||
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
||||||
|
requirements:
|
||||||
|
- - ">="
|
||||||
|
- !ruby/object:Gem::Version
|
||||||
|
version: "0"
|
||||||
|
version:
|
||||||
|
requirements: []
|
||||||
|
specification_version: 2
|
||||||
|
summary: Dummy Gem G
|
0
railties/test/vendor/gems/dummy-gem-i-1.0.0/ext/dummy-gem-i/Makefile
vendored
Normal file
0
railties/test/vendor/gems/dummy-gem-i-1.0.0/ext/dummy-gem-i/Makefile
vendored
Normal file
1
railties/test/vendor/gems/dummy-gem-i-1.0.0/lib/dummy-gem-i.rb
vendored
Normal file
1
railties/test/vendor/gems/dummy-gem-i-1.0.0/lib/dummy-gem-i.rb
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
DUMMY_GEM_I_VERSION="1.0.0"
|
41
railties/test/vendor/gems/dummy-gem-j-1.0.0/.specification
vendored
Normal file
41
railties/test/vendor/gems/dummy-gem-j-1.0.0/.specification
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
--- !ruby/object:Gem::Specification
|
||||||
|
name: dummy-gem-j
|
||||||
|
version: !ruby/object:Gem::Version
|
||||||
|
version: 1.3.0
|
||||||
|
platform: ruby
|
||||||
|
authors:
|
||||||
|
- "Nobody"
|
||||||
|
date: 2008-10-03 00:00:00 -04:00
|
||||||
|
dependencies:
|
||||||
|
- !ruby/object:Gem::Dependency
|
||||||
|
name: dummy-gem-j
|
||||||
|
type: :runtime
|
||||||
|
version_requirement:
|
||||||
|
version_requirements: !ruby/object:Gem::Requirement
|
||||||
|
requirements:
|
||||||
|
- - ">="
|
||||||
|
- !ruby/object:Gem::Version
|
||||||
|
version: 1.0.0
|
||||||
|
version:
|
||||||
|
extensions:
|
||||||
|
- ext/dummy-gem-j/extconf.rb
|
||||||
|
files:
|
||||||
|
- lib
|
||||||
|
- lib/dummy-gem-j.rb
|
||||||
|
require_paths:
|
||||||
|
- lib
|
||||||
|
required_ruby_version: !ruby/object:Gem::Requirement
|
||||||
|
requirements:
|
||||||
|
- - ">="
|
||||||
|
- !ruby/object:Gem::Version
|
||||||
|
version: "0"
|
||||||
|
version:
|
||||||
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
||||||
|
requirements:
|
||||||
|
- - ">="
|
||||||
|
- !ruby/object:Gem::Version
|
||||||
|
version: "0"
|
||||||
|
version:
|
||||||
|
requirements: []
|
||||||
|
specification_version: 2
|
||||||
|
summary: Dummy Gem G
|
1
railties/test/vendor/gems/dummy-gem-j-1.0.0/lib/dummy-gem-j.rb
vendored
Normal file
1
railties/test/vendor/gems/dummy-gem-j-1.0.0/lib/dummy-gem-j.rb
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
DUMMY_GEM_J_VERSION="1.0.0"
|
Loading…
Reference in New Issue
Block a user