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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
|
require 'erb'
module Bundler
class Environment
attr_reader :root
def initialize(root, definition)
@root = root
@definition = definition
end
def index
@index ||= Index.build do |idx|
sources.each do |s|
idx.use s.local_specs
end
end
end
def requested_specs
@requested_specs ||= begin
groups = @definition.groups - Bundler.settings.without
groups.map! { |g| g.to_sym }
specs_for(groups)
end
end
def specs
@specs ||= resolve_locally || resolve_remotely
end
def dependencies
@definition.dependencies
end
def resolved_dependencies
@definition.resolved_dependencies
end
def lock
Bundler.ui.info("The bundle is already locked, relocking.") if locked?
sources.each { |s| s.lock if s.respond_to?(:lock) }
FileUtils.mkdir_p("#{root}/.bundle")
write_yml_lock
write_rb_lock
Bundler.ui.confirm("The bundle is now locked. Use `bundle show` to list the gems in the environment.")
end
private
def sources
@definition.sources
end
def resolve(type, index)
source_requirements = {}
resolved_dependencies.each do |dep|
next unless dep.source && dep.source.respond_to?(type)
source_requirements[dep.name] = dep.source.send(type)
end
# Run a resolve against the locally available gems
Resolver.resolve(resolved_dependencies, index, source_requirements)
end
def resolve_locally
resolve(:local_specs, index)
end
def resolve_remotely
raise NotImplementedError
end
def specs_for(groups)
deps = dependencies.select { |d| (d.groups & groups).any? }
specs.for(deps)
end
# ==== Locking
def locked?
File.exist?("#{root}/Gemfile.lock")
end
def write_rb_lock
begin
env_file = Bundler.default_gemfile.dirname.join(".bundle/environment.rb")
env_file.dirname.mkpath
File.open(env_file, 'w') do |f|
f.puts <<-RB
require "rubygems"
require "bundler/setup"
RB
end
rescue Errno::EACCES
Bundler.ui.warn "Cannot write .bundle/environment.rb file"
end
end
def gemfile_fingerprint
Digest::SHA1.hexdigest(File.read(Bundler.default_gemfile))
end
def specs_for_lock_file
requested_specs.map do |s|
hash = {
:name => s.name,
:load_paths => s.load_paths
}
if s.respond_to?(:relative_loaded_from) && s.relative_loaded_from
hash[:virtual_spec] = s.to_ruby
end
hash[:loaded_from] = s.loaded_from.to_s
hash
end
end
def load_paths
specs.map { |s| s.load_paths }.flatten
end
def write_yml_lock
File.open("#{root}/Gemfile.lock", 'w') do |f|
f.puts details
end
end
def details
output = ""
pinned_sources = dependencies.map {|d| d.source }
all_sources = @definition.sources.map {|s| s }
specified_sources = all_sources - pinned_sources
unless specified_sources.length == 1 && specified_sources.first.remotes.empty?
output << "sources:\n"
specified_sources.each do |source|
o = source.to_lock
output << " #{source.to_lock}\n" unless o.empty?
end
output << "\n"
end
unless @definition.dependencies.empty?
output << "dependencies:\n"
@definition.dependencies.sort_by {|d| d.name }.each do |dependency|
output << dependency.to_lock
end
output << "\n"
end
output << "specs:\n"
specs.sort_by {|s| s.name }.each do |spec|
output << spec.to_lock
end
output
end
def autorequires_for_groups(*groups)
groups.map! { |g| g.to_sym }
groups = groups.any? ? groups : (@definition.groups - Bundler.settings.without)
autorequires = Hash.new { |h,k| h[k] = [] }
ordered_deps = @definition.dependencies.find_all{|d| (d.groups & groups).any? }
ordered_deps.each do |dep|
dep.groups.each do |group|
# If there is no autorequire, then rescue from
# autorequiring the gems name
if dep.autorequire
dep.autorequire.each do |file|
autorequires[group] << [file, true]
end
else
autorequires[group] << [dep.name, false]
end
end
end
if groups.empty?
autorequires
else
groups.inject({}) { |h,g| h[g] = autorequires[g]; h }
end
end
end
end
|