/
gems.rb
154 lines (133 loc) · 4.53 KB
/
gems.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
unless defined?(GemTemplate::Gems)
require 'yaml'
module GemTemplate
module Gems
class <<self
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 { |g| g.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 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
end