lib/mover/gems.rb in mover-0.3.5 vs lib/mover/gems.rb in mover-0.3.6

- old
+ new

@@ -1,42 +1,152 @@ unless defined?(Mover::Gems) - require 'rubygems' + require 'yaml' module Mover - class Gems - - VERSIONS = { - :active_wrapper => '=0.3.4', - :rake => '=0.8.7', - :rspec => '=1.3.1' - } - - TYPES = { - :gemspec => [], - :gemspec_dev => [ :active_wrapper, :rspec ], - :lib => [], - :rake => [ :rake, :rspec ], - :spec => [ :active_wrapper, :rspec ], - :spec_rake => [ :active_wrapper ] - } - + module Gems class <<self - def lockfile - file = File.expand_path('../../../gems', __FILE__) - unless File.exists?(file) - File.open(file, 'w') do |f| - Gem.loaded_specs.each do |key, value| - f.puts "#{key} #{value.version.version}" + attr_accessor :config + attr_reader :gemset, :gemsets, :versions + + class SimpleStruct + attr_reader :hash + + def initialize(hash) + @hash = hash + @hash.each do |key, value| + self.class.send(:define_method, key) { @hash[key] } + self.class.send(:define_method, "#{key}=") { |v| @hash[key] = v } + end + end + end + + Gems.config = SimpleStruct.new( + :gemsets => [ "#{File.expand_path('../../../', __FILE__)}/config/gemsets.yml" ], + :gemspec => "#{File.expand_path('../../../', __FILE__)}/config/gemspec.yml", + :warn => true + ) + + def activate(*gems) + begin + require 'rubygems' unless defined?(::Gem) + rescue LoadError + puts "rubygems library could not be required" if @config.warn + end + + self.gemset ||= gemset_from_loaded_specs + + gems.flatten.collect(&:to_sym).each do |name| + version = @versions[name] + vendor = File.expand_path("../../../vendor/#{name}/lib", __FILE__) + if File.exists?(vendor) + $:.unshift vendor + elsif defined?(gem) + gem name.to_s, version + else + puts "#{name} #{"(#{version})" if version} failed to activate" if @config.warn + end + end + end + + def dependencies + dependency_filter(@gemspec.dependencies, @gemset) + end + + def development_dependencies + dependency_filter(@gemspec.development_dependencies, @gemset) + end + + def gemset=(gemset) + if gemset + @gemset = gemset.to_sym + + @gemsets = @config.gemsets.reverse.collect { |config| + if config.is_a?(::String) + YAML::load(File.read(config)) rescue {} + elsif config.is_a?(::Hash) + config end + }.inject({}) do |hash, config| + deep_merge(hash, symbolize_keys(config)) end + + @versions = (@gemsets[gemspec.name.to_sym] || {}).inject({}) do |hash, (key, value)| + if !value.is_a?(::Hash) && value + hash[key] = value + elsif key == @gemset + (value || {}).each { |k, v| hash[k] = v } + end + hash + end + else + @gemset = nil + @gemsets = nil + @versions = nil end end - def require(type=nil) - (TYPES[type] || TYPES.values.flatten.compact).each do |name| - gem name.to_s, VERSIONS[name] + def gemset_names + ( + [ :default ] + + @gemsets[gemspec.name.to_sym].inject([]) { |array, (key, value)| + array.push(key) if value.is_a?(::Hash) || value.nil? + array + } + ).uniq + end + + def gemspec(reload=false) + if @gemspec && !reload + @gemspec + else + data = YAML::load(File.read(@config.gemspec)) rescue {} + @gemspec = SimpleStruct.new(data) + end + end + + private + + def deep_merge(first, second) + merger = lambda do |key, v1, v2| + Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 + end + first.merge(second, &merger) + end + + def dependency_filter(dependencies, match) + (dependencies || []).inject([]) { |array, value| + if value.is_a?(::Hash) + array += value[match.to_s] if value[match.to_s] + else + array << value + end + array + }.uniq.collect(&:to_sym) + end + + def gemset_from_loaded_specs + if defined?(Gem) + Gem.loaded_specs.each do |name, spec| + if name == gemspec.name + return :default + elsif name[0..gemspec.name.length] == "#{gemspec.name}-" + return name[gemspec.name.length+1..-1].to_sym + end + end + :default + else + :none + end + end + + def symbolize_keys(hash) + return {} unless hash.is_a?(::Hash) + hash.inject({}) do |options, (key, value)| + value = symbolize_keys(value) if value.is_a?(::Hash) + options[(key.to_sym rescue key) || key] = value + options end end end end end \ No newline at end of file