Class: Rails::GemDependency
- Defined in:
- lib/rails/gem_dependency.rb
Constant Summary collapse
- @@framework_gems =
{}
Instance Attribute Summary collapse
-
#dep ⇒ Object
Returns the value of attribute dep.
-
#lib ⇒ Object
Returns the value of attribute lib.
-
#source ⇒ Object
Returns the value of attribute source.
Class Method Summary collapse
- .add_frozen_gem_path ⇒ Object
- .from_directory_name(directory_name, load_spec = true) ⇒ Object
- .unpacked_path ⇒ Object
Instance Method Summary collapse
- #==(other) ⇒ Object (also: #eql?)
- #add_load_paths ⇒ Object
- #build(options = {}) ⇒ Object
- #built? ⇒ Boolean
- #dependencies ⇒ Object
- #framework_gem? ⇒ Boolean
- #frozen? ⇒ Boolean
-
#initialize(name, options = {}) ⇒ GemDependency
constructor
A new instance of GemDependency.
- #install ⇒ Object
- #installed? ⇒ Boolean
- #load ⇒ Object
- #load_paths_added? ⇒ Boolean
- #loaded? ⇒ Boolean
- #refresh ⇒ Object
- #specification ⇒ Object
- #specification=(s) ⇒ Object
- #unpack(options = {}) ⇒ Object
- #vendor_gem? ⇒ Boolean
- #vendor_rails? ⇒ Boolean
- #write_specification(spec) ⇒ Object
Constructor Details
#initialize(name, options = {}) ⇒ GemDependency
Returns a new instance of GemDependency.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/rails/gem_dependency.rb', line 50 def initialize(name, = {}) require 'rubygems' unless Object.const_defined?(:Gem) if [:requirement] req = [:requirement] elsif [:version] req = Gem::Requirement.create([:version]) else req = Gem::Requirement.default end @lib = [:lib] @source = [:source] @loaded = @frozen = @load_paths_added = false super(name, req) end |
Instance Attribute Details
#dep ⇒ Object
Returns the value of attribute dep.
11 12 13 |
# File 'lib/rails/gem_dependency.rb', line 11 def dep @dep end |
#lib ⇒ Object
Returns the value of attribute lib.
11 12 13 |
# File 'lib/rails/gem_dependency.rb', line 11 def lib @lib end |
#source ⇒ Object
Returns the value of attribute source.
11 12 13 |
# File 'lib/rails/gem_dependency.rb', line 11 def source @source end |
Class Method Details
.add_frozen_gem_path ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/rails/gem_dependency.rb', line 19 def self.add_frozen_gem_path @@paths_loaded ||= begin source_index = Rails::VendorGemSourceIndex.new(Gem.source_index) Gem.clear_paths Gem.source_index = source_index # loaded before us - we can't change them, so mark them Gem.loaded_specs.each do |name, spec| @@framework_gems[name] = spec end true end end |
.from_directory_name(directory_name, load_spec = true) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/rails/gem_dependency.rb', line 32 def self.from_directory_name(directory_name, load_spec=true) directory_name_parts = File.basename(directory_name).split('-') version = directory_name_parts.find { |s| s.match(/^\d(\.\d|\.\w+)*$/) } name = directory_name_parts[0..directory_name_parts.index(version)-1].join('-') if version result = self.new(name, :version => version) spec_filename = File.join(directory_name, '.specification') if load_spec raise "Missing specification file in #{File.dirname(spec_filename)}. Perhaps you need to do a 'rake gems:refresh_specs'\?" unless File.exists?(spec_filename) spec = YAML::load_file(spec_filename) result.specification = spec end result rescue ArgumentError => e raise "Unable to determine gem name and version from '#{directory_name}'" end |
.unpacked_path ⇒ Object
13 14 15 |
# File 'lib/rails/gem_dependency.rb', line 13 def self.unpacked_path @unpacked_path ||= File.join(RAILS_ROOT, 'vendor', 'gems') end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
272 273 274 275 |
# File 'lib/rails/gem_dependency.rb', line 272 def ==(other) Gem::Dependency === other.class && self.name == other.name && self.requirement == other.requirement end |
#add_load_paths ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/rails/gem_dependency.rb', line 68 def add_load_paths self.class.add_frozen_gem_path return if @loaded || @load_paths_added if framework_gem? @load_paths_added = @loaded = @frozen = true return end begin dep = Gem::Dependency.new(name, requirement) spec = Gem.source_index.find { |_,s| s.satisfies_requirement?(dep) }.last spec.activate # a way that exists rescue gem self.name, self.requirement # < 1.8 unhappy way end @spec = Gem.loaded_specs[name] @frozen = @spec.loaded_from.include?(self.class.unpacked_path) if @spec @load_paths_added = true rescue Gem::LoadError end |
#build(options = {}) ⇒ Object
191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/rails/gem_dependency.rb', line 191 def build(={}) require 'rails/gem_builder' return if specification.nil? if [:force] || !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 dependencies.each { |dep| dep.build() } end |
#built? ⇒ Boolean
128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/rails/gem_dependency.rb', line 128 def built? return false unless frozen? if vendor_gem? specification.extensions.each do |ext| makefile = File.join(unpacked_gem_directory, File.dirname(ext), 'Makefile') return false unless File.exists?(makefile) end end true end |
#dependencies ⇒ Object
90 91 92 93 94 95 96 97 98 |
# File 'lib/rails/gem_dependency.rb', line 90 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.respond_to?(:requirement) ? dependency.requirement : dependency.version_requirements)) end end |
#framework_gem? ⇒ Boolean
141 142 143 |
# File 'lib/rails/gem_dependency.rb', line 141 def framework_gem? @@framework_gems.has_key?(name) end |
#frozen? ⇒ Boolean
145 146 147 |
# File 'lib/rails/gem_dependency.rb', line 145 def frozen? @frozen ||= vendor_rails? || vendor_gem? end |
#install ⇒ Object
203 204 205 206 207 208 209 |
# File 'lib/rails/gem_dependency.rb', line 203 def install unless installed? cmd = "#{gem_command} #{install_command.join(' ')}" puts cmd puts %x(#{cmd}) end end |
#installed? ⇒ Boolean
149 150 151 |
# File 'lib/rails/gem_dependency.rb', line 149 def installed? Gem.loaded_specs.keys.include?(name) end |
#load ⇒ Object
211 212 213 214 215 216 217 218 |
# File 'lib/rails/gem_dependency.rb', line 211 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 |
#load_paths_added? ⇒ Boolean
153 154 155 156 157 158 |
# File 'lib/rails/gem_dependency.rb', line 153 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 |
#loaded? ⇒ Boolean
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/rails/gem_dependency.rb', line 160 def loaded? @loaded ||= begin if vendor_rails? true elsif specification.nil? false else # check if the gem is loaded by inspecting $" # specification.files lists all the files contained in the gem gem_files = specification.files # select only the files contained in require_paths - typically in bin and lib require_paths_regexp = Regexp.new("^(#{specification.require_paths*'|'})/") gem_lib_files = gem_files.select { |f| require_paths_regexp.match(f) } # chop the leading directory off - a typical file might be in # lib/gem_name/file_name.rb, but it will be 'require'd as gem_name/file_name.rb gem_lib_files.map! { |f| f.split('/', 2)[1] } # if any of the files from the above list appear in $", the gem is assumed to # have been loaded !(gem_lib_files & $").empty? end end end |
#refresh ⇒ Object
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/rails/gem_dependency.rb', line 220 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 frozen? if installed_spec # we have a real copy # get a fresh spec - matches should only have one element # note that there is no reliable method to check that the loaded # 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_specification(real_spec) puts "Reloaded specification for #{name} from installed gems." else # the gem isn't installed locally - write out our current specs write_specification(specification) puts "Gem #{name} not loaded locally - writing out current spec." end else if framework_gem? puts "Gem directory for #{name} not found - check if it's loading before rails." else puts "Something bad is going on - gem directory not found for #{name}." end end end |
#specification ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/rails/gem_dependency.rb', line 100 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 |
#specification=(s) ⇒ Object
124 125 126 |
# File 'lib/rails/gem_dependency.rb', line 124 def specification=(s) @spec = s end |
#unpack(options = {}) ⇒ Object
250 251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/rails/gem_dependency.rb', line 250 def unpack(={}) 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 [:recursive] end |
#vendor_gem? ⇒ Boolean
187 188 189 |
# File 'lib/rails/gem_dependency.rb', line 187 def vendor_gem? specification && File.exists?(unpacked_gem_directory) end |
#vendor_rails? ⇒ Boolean
183 184 185 |
# File 'lib/rails/gem_dependency.rb', line 183 def vendor_rails? Gem.loaded_specs.has_key?(name) && Gem.loaded_specs[name].loaded_from.empty? end |
#write_specification(spec) ⇒ Object
263 264 265 266 267 268 269 270 |
# File 'lib/rails/gem_dependency.rb', line 263 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 |