Skip to content
This repository
Newer
Older
100644 246 lines (202 sloc) 7.092 kb
d19c5779 »
2010-02-05 Locked environment checks for Gemfile changes
1 require "digest/sha1"
8835be62 »
2010-02-04 Print an error if the Gemfile changed after the lock
2
c0f8641c »
2010-02-03 Persist spec groups to the lockfile
3 module Bundler
4 class Runtime < Environment
f7bfddea »
2010-02-10 Actually disable system gems in .bundle/environment.rb
5 include SharedHelpers
6
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
7 def setup(*groups)
8 # Has to happen first
2d052427 »
2010-02-05 Handle rubygems executable wrappers better
9 clean_load_path
10
11 specs = specs_for(*groups)
12
6d369092 »
2010-02-05 Cripple rubygems with a smarter #gem
13 cripple_rubygems(specs)
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
14
15 # Activate the specs
6d369092 »
2010-02-05 Cripple rubygems with a smarter #gem
16 specs.each do |spec|
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
17 Gem.loaded_specs[spec.name] = spec
18 $LOAD_PATH.unshift(*spec.load_paths)
19 end
20 self
21 end
22
23 def require(*groups)
ca6cc3b8 »
2010-02-03 Merge branch 'master' of git://github.com/carlhuda/bundler into carlhuda
24 groups = [:default] if groups.empty?
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
25 autorequires = autorequires_for_groups(*groups)
26 groups.each do |group|
27 (autorequires[group] || []).each do |path|
28 Kernel.require(path)
c0f8641c »
2010-02-03 Persist spec groups to the lockfile
29 end
30 end
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
31 end
32
33 def dependencies
6c5a67dc »
2010-02-08 Dump full details into Gemfile.lock
34 @definition.dependencies
35 end
36
37 def actual_dependencies
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
38 @definition.actual_dependencies
39 end
40
4ebd4da3 »
2010-02-03 Fix a bug with git repos and bundle lock breaking the install
41 def lock
42 Bundler.ui.info("The bundle is already locked, relocking.") if locked?
43 sources.each { |s| s.lock if s.respond_to?(:lock) }
44 FileUtils.mkdir_p("#{root}/.bundle")
45 write_yml_lock
46 write_rb_lock
47 Bundler.ui.info("The bundle is now locked. Use `bundle show` to list the gems in the environment.")
48 end
49
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
50 def locked?
89994a02 »
2010-02-06 Locked checks should always include both Gemfile.lock and the environ…
51 File.exist?("#{root}/Gemfile.lock") || File.exist?("#{root}/.bundle/environment.rb")
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
52 end
c0f8641c »
2010-02-03 Persist spec groups to the lockfile
53
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
54 def dependencies_for(*groups)
55 if groups.empty?
56 dependencies
57 else
58 dependencies.select { |d| (groups & d.groups).any? }
c0f8641c »
2010-02-03 Persist spec groups to the lockfile
59 end
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
60 end
c0f8641c »
2010-02-03 Persist spec groups to the lockfile
61
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
62 def specs_for(*groups)
742816c8 »
2010-02-10 Lets try to actually fix .bundle/environment.rb this time.
63 groups.map! { |g| g.to_sym }
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
64 if groups.empty?
65 specs
66 else
67 Resolver.resolve(dependencies_for(*groups), index)
c0f8641c »
2010-02-03 Persist spec groups to the lockfile
68 end
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
69 end
70
71 def specs
72 @specs ||= begin
73 source_requirements = {}
6c5a67dc »
2010-02-08 Dump full details into Gemfile.lock
74 actual_dependencies.each do |dep|
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
75 next unless dep.source && dep.source.respond_to?(:local_specs)
76 source_requirements[dep.name] = dep.source.local_specs
c0f8641c »
2010-02-03 Persist spec groups to the lockfile
77 end
78
742816c8 »
2010-02-10 Lets try to actually fix .bundle/environment.rb this time.
79 group_specs(Resolver.resolve(@definition.actual_dependencies, index, source_requirements))
c0f8641c »
2010-02-03 Persist spec groups to the lockfile
80 end
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
81 end
82
83 alias gems specs
84
85 def index
86 @definition.local_index
87 end
88
89 def pack
90 pack_path = "#{root}/vendor/cache/"
91 FileUtils.mkdir_p(pack_path)
92
93 Bundler.ui.info "Copying .gem files into vendor/cache"
94 specs.each do |spec|
95 next unless spec.source.is_a?(Source::SystemGems) || spec.source.is_a?(Source::Rubygems)
96 possibilities = Gem.path.map { |p| "#{p}/cache/#{spec.full_name}.gem" }
97 cached_path = possibilities.find { |p| File.exist? p }
98 Bundler.ui.info " * #{File.basename(cached_path)}"
99 next if File.expand_path(File.dirname(cached_path)) == File.expand_path(pack_path)
100 FileUtils.cp(cached_path, pack_path)
c0f8641c »
2010-02-03 Persist spec groups to the lockfile
101 end
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
102 end
c0f8641c »
2010-02-03 Persist spec groups to the lockfile
103
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
104 private
c0f8641c »
2010-02-03 Persist spec groups to the lockfile
105
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
106 def sources
107 @definition.sources
108 end
c0f8641c »
2010-02-03 Persist spec groups to the lockfile
109
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
110 def load_paths
111 specs.map { |s| s.load_paths }.flatten
112 end
113
2d052427 »
2010-02-05 Handle rubygems executable wrappers better
114 def write_rb_lock
f7bfddea »
2010-02-10 Actually disable system gems in .bundle/environment.rb
115 shared_helpers = File.read(File.expand_path("../shared_helpers.rb", __FILE__))
2d052427 »
2010-02-05 Handle rubygems executable wrappers better
116 template = File.read(File.expand_path("../templates/environment.erb", __FILE__))
117 erb = ERB.new(template, nil, '-')
118 File.open("#{root}/.bundle/environment.rb", 'w') do |f|
119 f.puts erb.result(binding)
120 end
121 end
122
123 def write_yml_lock
124 yml = details.to_yaml
125 File.open("#{root}/Gemfile.lock", 'w') do |f|
126 f.puts yml
127 end
128 end
129
130 def details
131 details = {}
132 details["hash"] = gemfile_fingerprint
133 details["sources"] = sources.map { |s| { s.class.name.split("::").last => s.options} }
134
135 details["specs"] = specs.map do |s|
136 options = {"version" => s.version.to_s}
137 options["source"] = sources.index(s.source) if sources.include?(s.source)
138 { s.name => options }
139 end
140
6c5a67dc »
2010-02-08 Dump full details into Gemfile.lock
141 details["dependencies"] = @definition.dependencies.inject({}) do |h,d|
142 h.merge!({d.name => {"version" => d.version_requirements.to_s,
143 "group" => d.groups,
144 "require" => d.autorequire}})
145 end
2d052427 »
2010-02-05 Handle rubygems executable wrappers better
146 details
147 end
148
149 def gemfile_fingerprint
150 Digest::SHA1.hexdigest(File.read("#{root}/Gemfile"))
151 end
152
742816c8 »
2010-02-10 Lets try to actually fix .bundle/environment.rb this time.
153 def specs_for_lock_file
154 specs.map do |spec|
155 dep = @definition.dependencies.find { |d| d.name == spec.name }
156 hash = {}
157 hash[:name] = spec.name
158 hash[:version] = spec.version.to_s
159 hash[:groups] = spec.groups
160 hash[:load_paths] = spec.load_paths
161 hash
162 end
163 end
164
2d052427 »
2010-02-05 Handle rubygems executable wrappers better
165 def autorequires_for_groups(*groups)
742816c8 »
2010-02-10 Lets try to actually fix .bundle/environment.rb this time.
166 groups.map! { |g| g.to_sym }
2d052427 »
2010-02-05 Handle rubygems executable wrappers better
167 autorequires = Hash.new { |h,k| h[k] = [] }
168 @definition.dependencies.each do |dep|
169 dep.groups.each do |group|
170 autorequires[group].concat dep.autorequire
171 end
172 end
173
174 if groups.empty?
175 autorequires
176 else
177 groups.inject({}) { |h,g| h[g] = autorequires[g]; h }
178 end
179 end
180
181 def cripple_rubygems(specs)
182 reverse_rubygems_kernel_mixin
183
184 executables = specs.map { |s| s.executables }.flatten
6d369092 »
2010-02-05 Cripple rubygems with a smarter #gem
185
742816c8 »
2010-02-10 Lets try to actually fix .bundle/environment.rb this time.
186 # TODO: This is duplicated a bit too much in environment.erb.
187 # Let's figure out how to improve that.
6d369092 »
2010-02-05 Cripple rubygems with a smarter #gem
188 ::Kernel.send(:define_method, :gem) do |dep, *reqs|
2d052427 »
2010-02-05 Handle rubygems executable wrappers better
189 if executables.include? File.basename(caller.first.split(':').first)
190 return
191 end
6d369092 »
2010-02-05 Cripple rubygems with a smarter #gem
192 opts = reqs.last.is_a?(Hash) ? reqs.pop : {}
193
194 unless dep.respond_to?(:name) && dep.respond_to?(:version_requirements)
195 dep = Gem::Dependency.new(dep, reqs)
c0f8641c »
2010-02-03 Persist spec groups to the lockfile
196 end
6d369092 »
2010-02-05 Cripple rubygems with a smarter #gem
197
198 spec = specs.find { |s| s.name == dep.name }
199
200 if spec.nil?
201 e = Gem::LoadError.new "#{dep} is not part of the bundle. Add it to Gemfile."
202 e.name = dep.name
203 e.version_requirement = dep.version_requirements
204 raise e
205 elsif dep !~ spec
206 e = Gem::LoadError.new "can't activate #{dep}, already activated #{spec.full_name}. " \
207 "Make sure all dependencies are added to Gemfile."
208 e.name = dep.name
209 e.version_requirement = dep.version_requirements
210 raise e
211 end
212
213 true
c0f8641c »
2010-02-03 Persist spec groups to the lockfile
214 end
215
2d052427 »
2010-02-05 Handle rubygems executable wrappers better
216 # === Following hacks are to improve on the generated bin wrappers ===
c0f8641c »
2010-02-03 Persist spec groups to the lockfile
217
2d052427 »
2010-02-05 Handle rubygems executable wrappers better
218 # Yeah, talk about a hack
219 source_index_class = (class << Gem::SourceIndex ; self ; end)
220 source_index_class.send(:define_method, :from_gems_in) do |*args|
221 source_index = Gem::SourceIndex.new
222 source_index.add_specs *specs
223 source_index
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
224 end
225
2d052427 »
2010-02-05 Handle rubygems executable wrappers better
226 # OMG more hacks
227 gem_class = (class << Gem ; self ; end)
228 gem_class.send(:define_method, :bin_path) do |name, *args|
229 exec_name, *reqs = args
c0f8641c »
2010-02-03 Persist spec groups to the lockfile
230
2d052427 »
2010-02-05 Handle rubygems executable wrappers better
231 spec = nil
d19c5779 »
2010-02-05 Locked environment checks for Gemfile changes
232
2d052427 »
2010-02-05 Handle rubygems executable wrappers better
233 if exec_name
234 spec = specs.find { |s| s.executables.include?(exec_name) }
235 spec or raise Gem::Exception, "can't find executable #{exec_name}"
236 else
237 spec = specs.find { |s| s.name == name }
238 exec_name = spec.default_executable or raise Gem::Exception, "no default executable for #{spec.full_name}"
ca6cc3b8 »
2010-02-03 Merge branch 'master' of git://github.com/carlhuda/bundler into carlhuda
239 end
240
2d052427 »
2010-02-05 Handle rubygems executable wrappers better
241 File.join(spec.full_gem_path, spec.bindir, exec_name)
c0f8641c »
2010-02-03 Persist spec groups to the lockfile
242 end
e993e6f8 »
2010-02-03 Persist spec groups to the lockfile
243 end
c0f8641c »
2010-02-03 Persist spec groups to the lockfile
244 end
ca6cc3b8 »
2010-02-03 Merge branch 'master' of git://github.com/carlhuda/bundler into carlhuda
245 end
Something went wrong with that request. Please try again.