gel 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/exe/gel +13 -0
- data/lib/gel.rb +22 -0
- data/lib/gel/catalog.rb +153 -0
- data/lib/gel/catalog/common.rb +82 -0
- data/lib/gel/catalog/compact_index.rb +152 -0
- data/lib/gel/catalog/dependency_index.rb +125 -0
- data/lib/gel/catalog/legacy_index.rb +157 -0
- data/lib/gel/catalog/marshal_hacks.rb +16 -0
- data/lib/gel/command.rb +86 -0
- data/lib/gel/command/config.rb +11 -0
- data/lib/gel/command/env.rb +7 -0
- data/lib/gel/command/exec.rb +66 -0
- data/lib/gel/command/help.rb +7 -0
- data/lib/gel/command/install.rb +7 -0
- data/lib/gel/command/install_gem.rb +16 -0
- data/lib/gel/command/lock.rb +34 -0
- data/lib/gel/command/ruby.rb +10 -0
- data/lib/gel/command/shell_setup.rb +25 -0
- data/lib/gel/command/stub.rb +12 -0
- data/lib/gel/command/update.rb +11 -0
- data/lib/gel/compatibility.rb +4 -0
- data/lib/gel/compatibility/bundler.rb +54 -0
- data/lib/gel/compatibility/bundler/cli.rb +6 -0
- data/lib/gel/compatibility/bundler/friendly_errors.rb +3 -0
- data/lib/gel/compatibility/bundler/setup.rb +4 -0
- data/lib/gel/compatibility/rubygems.rb +192 -0
- data/lib/gel/compatibility/rubygems/command.rb +4 -0
- data/lib/gel/compatibility/rubygems/dependency_installer.rb +0 -0
- data/lib/gel/compatibility/rubygems/gem_runner.rb +6 -0
- data/lib/gel/config.rb +80 -0
- data/lib/gel/db.rb +294 -0
- data/lib/gel/direct_gem.rb +29 -0
- data/lib/gel/environment.rb +592 -0
- data/lib/gel/error.rb +104 -0
- data/lib/gel/gemfile_parser.rb +144 -0
- data/lib/gel/gemspec_parser.rb +95 -0
- data/lib/gel/git_catalog.rb +38 -0
- data/lib/gel/git_depot.rb +119 -0
- data/lib/gel/httpool.rb +148 -0
- data/lib/gel/installer.rb +251 -0
- data/lib/gel/lock_loader.rb +164 -0
- data/lib/gel/lock_parser.rb +64 -0
- data/lib/gel/locked_store.rb +126 -0
- data/lib/gel/multi_store.rb +96 -0
- data/lib/gel/package.rb +156 -0
- data/lib/gel/package/inspector.rb +23 -0
- data/lib/gel/package/installer.rb +267 -0
- data/lib/gel/path_catalog.rb +44 -0
- data/lib/gel/pinboard.rb +140 -0
- data/lib/gel/pub_grub/preference_strategy.rb +82 -0
- data/lib/gel/pub_grub/source.rb +153 -0
- data/lib/gel/runtime.rb +27 -0
- data/lib/gel/store.rb +205 -0
- data/lib/gel/store_catalog.rb +31 -0
- data/lib/gel/store_gem.rb +80 -0
- data/lib/gel/stub_set.rb +51 -0
- data/lib/gel/support/gem_platform.rb +225 -0
- data/lib/gel/support/gem_requirement.rb +264 -0
- data/lib/gel/support/gem_version.rb +398 -0
- data/lib/gel/support/tar.rb +13 -0
- data/lib/gel/support/tar/tar_header.rb +229 -0
- data/lib/gel/support/tar/tar_reader.rb +123 -0
- data/lib/gel/support/tar/tar_reader/entry.rb +154 -0
- data/lib/gel/support/tar/tar_writer.rb +339 -0
- data/lib/gel/tail_file.rb +205 -0
- data/lib/gel/version.rb +5 -0
- data/lib/gel/work_pool.rb +143 -0
- data/man/man1/gel-exec.1 +16 -0
- data/man/man1/gel-install.1 +16 -0
- data/man/man1/gel.1 +30 -0
- metadata +131 -0
data/lib/gel/httpool.rb
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "monitor"
|
4
|
+
require "net/http"
|
5
|
+
|
6
|
+
class Gel::Httpool
|
7
|
+
include MonitorMixin
|
8
|
+
|
9
|
+
require "logger"
|
10
|
+
Logger = ::Logger.new($stderr)
|
11
|
+
Logger.level = $DEBUG ? ::Logger::DEBUG : ::Logger::WARN
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
super()
|
15
|
+
|
16
|
+
@pool = {}
|
17
|
+
@cond = new_cond
|
18
|
+
|
19
|
+
if block_given?
|
20
|
+
begin
|
21
|
+
yield self
|
22
|
+
ensure
|
23
|
+
close
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def request(uri, request = Net::HTTP::Get.new(uri))
|
29
|
+
with_connection(uri) do |http|
|
30
|
+
logger.debug { "GET #{uri}" }
|
31
|
+
|
32
|
+
if uri.user
|
33
|
+
request.basic_auth(uri.user, uri.password || "")
|
34
|
+
end
|
35
|
+
|
36
|
+
t = Time.now
|
37
|
+
response = http.request(request)
|
38
|
+
logger.debug { "HTTP #{response.code} (#{response.message}) #{uri} [#{Time.now - t}s]" }
|
39
|
+
response
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def close
|
44
|
+
https = nil
|
45
|
+
|
46
|
+
synchronize do
|
47
|
+
https = @pool.values.flatten
|
48
|
+
@pool = nil
|
49
|
+
@cond.broadcast
|
50
|
+
end
|
51
|
+
|
52
|
+
https.each(&:finish)
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def ident_for(uri)
|
58
|
+
"#{uri.scheme}://#{uri.host}:#{uri.port}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def logger
|
62
|
+
Logger
|
63
|
+
end
|
64
|
+
|
65
|
+
def connect(ident, uri)
|
66
|
+
logger.debug { "Connect #{ident}" }
|
67
|
+
t = Time.now
|
68
|
+
http = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https")
|
69
|
+
logger.debug { " Connected #{ident} [#{Time.now - t}s]" }
|
70
|
+
|
71
|
+
http
|
72
|
+
end
|
73
|
+
|
74
|
+
def queue_new_connection(ident, uri)
|
75
|
+
Thread.new do
|
76
|
+
begin
|
77
|
+
http = connect(ident, uri)
|
78
|
+
|
79
|
+
synchronize do
|
80
|
+
unless Thread.current[:discard]
|
81
|
+
Thread.current[:result] = http
|
82
|
+
http = nil
|
83
|
+
@cond.broadcast
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
if http
|
88
|
+
checkin ident, http
|
89
|
+
end
|
90
|
+
rescue StandardError => exception
|
91
|
+
synchronize do
|
92
|
+
unless Thread.current[:discard]
|
93
|
+
Thread.current[:error] = exception
|
94
|
+
http = nil
|
95
|
+
@cond.broadcast
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def checkin(ident, http)
|
103
|
+
synchronize do
|
104
|
+
if @pool
|
105
|
+
@pool[ident].push http
|
106
|
+
http = nil
|
107
|
+
@cond.broadcast
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
if http
|
112
|
+
http.finish
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def checkout(ident, uri)
|
117
|
+
synchronize do
|
118
|
+
@pool[ident] ||= []
|
119
|
+
|
120
|
+
return @pool[ident].pop unless @pool[ident].empty?
|
121
|
+
|
122
|
+
thread = queue_new_connection(ident, uri)
|
123
|
+
|
124
|
+
@cond.wait_while { !thread[:result] && @pool[ident].empty? }
|
125
|
+
|
126
|
+
if thread[:result]
|
127
|
+
thread[:result]
|
128
|
+
elsif thread[:error]
|
129
|
+
raise thread[:error]
|
130
|
+
else
|
131
|
+
thread[:discard] = true
|
132
|
+
@pool[ident].pop
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def with_connection(uri)
|
138
|
+
ident = ident_for(uri)
|
139
|
+
http = checkout(ident, uri)
|
140
|
+
|
141
|
+
yield http
|
142
|
+
|
143
|
+
ensure
|
144
|
+
if http
|
145
|
+
checkin ident, http
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,251 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "monitor"
|
4
|
+
require "net/http"
|
5
|
+
|
6
|
+
require_relative "work_pool"
|
7
|
+
require_relative "git_depot"
|
8
|
+
require_relative "package"
|
9
|
+
require_relative "package/installer"
|
10
|
+
|
11
|
+
class Gel::Installer
|
12
|
+
DOWNLOAD_CONCURRENCY = 6
|
13
|
+
COMPILE_CONCURRENCY = 4
|
14
|
+
|
15
|
+
include MonitorMixin
|
16
|
+
|
17
|
+
attr_reader :store
|
18
|
+
|
19
|
+
def initialize(store)
|
20
|
+
super()
|
21
|
+
|
22
|
+
@trace = nil
|
23
|
+
|
24
|
+
@messages = Queue.new
|
25
|
+
|
26
|
+
@store = store
|
27
|
+
@dependencies = Hash.new { |h, k| h[k] = [] }
|
28
|
+
@weights = Hash.new(1)
|
29
|
+
@pending = Hash.new(0)
|
30
|
+
|
31
|
+
@download_pool = Gel::WorkPool.new(DOWNLOAD_CONCURRENCY, monitor: self, name: "gel-download", collect_errors: true)
|
32
|
+
@compile_pool = Gel::WorkPool.new(COMPILE_CONCURRENCY, monitor: self, name: "gel-compile", collect_errors: true)
|
33
|
+
|
34
|
+
@download_pool.queue_order = -> ((_, name)) { -@weights[name] }
|
35
|
+
@compile_pool.queue_order = -> ((_, name)) { -@weights[name] }
|
36
|
+
|
37
|
+
@git_depot = Gel::GitDepot.new(store)
|
38
|
+
|
39
|
+
@compile_waiting = []
|
40
|
+
end
|
41
|
+
|
42
|
+
def known_dependencies(deps)
|
43
|
+
deps = deps.dup
|
44
|
+
|
45
|
+
synchronize do
|
46
|
+
@dependencies.update(deps) { |k, l, r| deps[k] = r - l; l | r }
|
47
|
+
return if deps.values.all?(&:empty?)
|
48
|
+
|
49
|
+
deps.each do |dependent, dependencies|
|
50
|
+
dependencies.each do |dependency|
|
51
|
+
add_weight dependency, @weights[dependent]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Every time we learn about a new dependency, we reorder the
|
56
|
+
# queues to ensure the most depended-on gems are processed first.
|
57
|
+
# This ensures we can start compiling extension gems as soon as
|
58
|
+
# possible.
|
59
|
+
@download_pool.reorder_queue!
|
60
|
+
@compile_pool.reorder_queue!
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def install_gem(catalogs, name, version)
|
65
|
+
synchronize do
|
66
|
+
raise "catalogs is nil" if catalogs.nil?
|
67
|
+
@pending[name] += 1
|
68
|
+
@download_pool.queue(name) do
|
69
|
+
work_download([catalogs, name, version])
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def load_git_gem(remote, revision, name)
|
75
|
+
synchronize do
|
76
|
+
@pending[name] += 1
|
77
|
+
@download_pool.queue(name) do
|
78
|
+
work_git(remote, revision, name)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def work_git(remote, revision, name)
|
84
|
+
@git_depot.checkout(remote, revision)
|
85
|
+
|
86
|
+
@messages << "Using #{name} (git)\n"
|
87
|
+
@pending[name] -= 1
|
88
|
+
end
|
89
|
+
|
90
|
+
def download_gem(catalogs, name, version)
|
91
|
+
catalogs.each do |catalog|
|
92
|
+
if fpath = catalog.cached_gem(name, version)
|
93
|
+
return fpath
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
catalogs.each do |catalog|
|
98
|
+
begin
|
99
|
+
return catalog.download_gem(name, version)
|
100
|
+
rescue Net::HTTPExceptions
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
raise "Unable to locate #{name} #{version} in: #{catalogs.join ", "}"
|
105
|
+
end
|
106
|
+
|
107
|
+
def work_download((catalogs, name, version))
|
108
|
+
fpath = download_gem(catalogs, name, version)
|
109
|
+
|
110
|
+
installer = Gel::Package::Installer.new(store)
|
111
|
+
g = Gel::Package.extract(fpath, installer)
|
112
|
+
known_dependencies g.spec.name => g.spec.runtime_dependencies.keys
|
113
|
+
if g.needs_compile?
|
114
|
+
synchronize do
|
115
|
+
add_weight name, 1000
|
116
|
+
|
117
|
+
@compile_pool.queue(g.spec.name) do
|
118
|
+
work_compile(g)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
else
|
122
|
+
work_install(g)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def work_compile(g)
|
127
|
+
synchronize do
|
128
|
+
unless compile_ready?(g.spec.name)
|
129
|
+
@compile_waiting << g
|
130
|
+
return
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
g.compile
|
135
|
+
work_install(g)
|
136
|
+
end
|
137
|
+
|
138
|
+
def work_install(g)
|
139
|
+
@messages << "Installing #{g.spec.name} (#{g.spec.version})\n"
|
140
|
+
g.install
|
141
|
+
@pending[g.spec.name] -= 1
|
142
|
+
|
143
|
+
synchronize do
|
144
|
+
compile_recheck, @compile_waiting = @compile_waiting, []
|
145
|
+
|
146
|
+
compile_recheck.each do |g|
|
147
|
+
@compile_pool.queue(g.spec.name) do
|
148
|
+
work_compile(g)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def wait(output = nil)
|
155
|
+
clear = ""
|
156
|
+
tty = output && output.isatty
|
157
|
+
|
158
|
+
pools = { "Downloading" => @download_pool, "Compiling" => @compile_pool }
|
159
|
+
|
160
|
+
return if pools.values.all?(&:idle?)
|
161
|
+
|
162
|
+
update_status = lambda do
|
163
|
+
synchronize do
|
164
|
+
if output
|
165
|
+
output.write clear
|
166
|
+
output.write @messages.pop until @messages.empty?
|
167
|
+
|
168
|
+
if tty
|
169
|
+
messages = pools.map { |label, pool| pool_status(label, pool, label == "Compiling" ? @compile_waiting.size : 0) }.compact
|
170
|
+
if messages.empty?
|
171
|
+
msgline = ""
|
172
|
+
else
|
173
|
+
msgline = "[" + messages.join("; ") + "]"
|
174
|
+
end
|
175
|
+
clear = "\r" + " " * msgline.size + "\r"
|
176
|
+
output.write msgline
|
177
|
+
end
|
178
|
+
else
|
179
|
+
@messages.pop until @messages.empty?
|
180
|
+
end
|
181
|
+
pools.values.all?(&:idle?) && @compile_waiting.empty?
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
pools.values.map do |pool|
|
186
|
+
Thread.new do
|
187
|
+
Thread.current.abort_on_exception = true
|
188
|
+
|
189
|
+
pool.wait(&update_status)
|
190
|
+
pools.values.each(&:tick!)
|
191
|
+
pool.stop
|
192
|
+
end
|
193
|
+
end.each(&:join)
|
194
|
+
|
195
|
+
errors = @download_pool.errors + @compile_pool.errors
|
196
|
+
|
197
|
+
if errors.empty?
|
198
|
+
if output
|
199
|
+
output.write "Installed #{@download_pool.count} gems\n"
|
200
|
+
end
|
201
|
+
else
|
202
|
+
if output
|
203
|
+
output.write "Installed #{@download_pool.count - errors.size} of #{@download_pool.count} gems\n\nErrors encountered with #{errors.size} gems:\n\n"
|
204
|
+
errors.each do |(_, name), exception|
|
205
|
+
output.write "#{name}\n #{exception}\n\n"
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
if errors.first
|
210
|
+
raise errors.first.last
|
211
|
+
else
|
212
|
+
raise "Errors encountered while installing gems"
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
private
|
218
|
+
|
219
|
+
def compile_ready?(name)
|
220
|
+
@dependencies[name].all? do |dep|
|
221
|
+
if @pending[dep] == 0
|
222
|
+
compile_ready?(dep)
|
223
|
+
elsif @download_pool.errors.any? { |(_, failed_name), ex| failed_name == dep }
|
224
|
+
raise "Depends on #{dep.inspect}, which failed to download"
|
225
|
+
elsif @compile_pool.errors.any? { |(_, failed_name), ex| failed_name == dep }
|
226
|
+
raise "Depends on #{dep.inspect}, which failed to compile"
|
227
|
+
else
|
228
|
+
false
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def pool_status(label, pool, extra_queue = 0)
|
234
|
+
st = pool.status
|
235
|
+
queue = st[:queued] + extra_queue
|
236
|
+
|
237
|
+
return if st[:active].empty? && queue.zero?
|
238
|
+
|
239
|
+
msg = +"#{label}:"
|
240
|
+
msg << " #{st[:active].join(" ")}" unless st[:active].empty?
|
241
|
+
msg << " +#{queue}" unless queue.zero?
|
242
|
+
msg
|
243
|
+
end
|
244
|
+
|
245
|
+
def add_weight(name, weight)
|
246
|
+
@weights[name] += weight
|
247
|
+
@dependencies[name].each do |dependency|
|
248
|
+
add_weight dependency, weight
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Gel::LockLoader
|
4
|
+
attr_reader :filename
|
5
|
+
attr_reader :gemfile
|
6
|
+
|
7
|
+
def initialize(filename, gemfile = nil)
|
8
|
+
@filename = filename
|
9
|
+
@gemfile = gemfile
|
10
|
+
end
|
11
|
+
|
12
|
+
def lock_content
|
13
|
+
@lock_content ||= Gel::LockParser.new.parse(File.read(filename))
|
14
|
+
end
|
15
|
+
|
16
|
+
def each_gem
|
17
|
+
lock_content.each do |(section, body)|
|
18
|
+
case section
|
19
|
+
when "GEM", "PATH", "GIT"
|
20
|
+
specs = body["specs"]
|
21
|
+
specs.each do |gem_spec, dep_specs|
|
22
|
+
gem_spec =~ /\A(.+) \(([^-]+)(?:-(.+))?\)\z/
|
23
|
+
name, version, platform = $1, $2, $3
|
24
|
+
|
25
|
+
if dep_specs
|
26
|
+
deps = dep_specs.map do |spec|
|
27
|
+
spec =~ /\A(.+?)(?: \((.+)\))?\z/
|
28
|
+
[$1, $2 ? $2.split(", ") : []]
|
29
|
+
end
|
30
|
+
else
|
31
|
+
deps = []
|
32
|
+
end
|
33
|
+
|
34
|
+
sym =
|
35
|
+
case section
|
36
|
+
when "GEM"; :gem
|
37
|
+
when "PATH"; :path
|
38
|
+
when "GIT"; :git
|
39
|
+
end
|
40
|
+
yield sym, body, name, version, platform, deps
|
41
|
+
end
|
42
|
+
when "PLATFORMS", "DEPENDENCIES"
|
43
|
+
when "BUNDLED WITH"
|
44
|
+
else
|
45
|
+
warn "Unknown lockfile section #{section.inspect}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def bundler_version
|
51
|
+
_, (version,) = lock_content.assoc("BUNDLED WITH")
|
52
|
+
version
|
53
|
+
end
|
54
|
+
|
55
|
+
def gem_names
|
56
|
+
names = []
|
57
|
+
each_gem do |section, body, name, version, platform, deps|
|
58
|
+
names << name
|
59
|
+
end
|
60
|
+
names
|
61
|
+
end
|
62
|
+
|
63
|
+
def activate(env, base_store, install: false, output: nil)
|
64
|
+
locked_store = Gel::LockedStore.new(base_store)
|
65
|
+
|
66
|
+
locks = {}
|
67
|
+
|
68
|
+
if install
|
69
|
+
require_relative "installer"
|
70
|
+
installer = Gel::Installer.new(base_store)
|
71
|
+
end
|
72
|
+
|
73
|
+
filtered_gems = Hash.new(nil)
|
74
|
+
top_gems = []
|
75
|
+
if gemfile && env
|
76
|
+
gemfile.gems.each do |name, *|
|
77
|
+
filtered_gems[name] = false
|
78
|
+
end
|
79
|
+
env.filtered_gems(gemfile.gems).each do |name, *|
|
80
|
+
top_gems << name
|
81
|
+
filtered_gems[name] = true
|
82
|
+
end
|
83
|
+
elsif pair = lock_content.assoc("DEPENDENCIES")
|
84
|
+
_, list = pair
|
85
|
+
top_gems = list.map { |name| name.split(" ", 2)[0].chomp("!") }
|
86
|
+
top_gems.each do |name|
|
87
|
+
filtered_gems[name] = true
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
gems = {}
|
92
|
+
each_gem do |section, body, name, version, platform, deps|
|
93
|
+
next if env && !env.platform?(platform)
|
94
|
+
|
95
|
+
gems[name] = [section, body, version, platform, deps]
|
96
|
+
|
97
|
+
installer.known_dependencies name => deps.map(&:first) if installer
|
98
|
+
end
|
99
|
+
|
100
|
+
walk = lambda do |name|
|
101
|
+
filtered_gems[name] = true
|
102
|
+
next unless gems[name]
|
103
|
+
gems[name].last.map(&:first).each do |dep_name|
|
104
|
+
walk[dep_name] unless filtered_gems[dep_name]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
top_gems.each(&walk)
|
109
|
+
|
110
|
+
require_relative "git_depot"
|
111
|
+
require_relative "work_pool"
|
112
|
+
|
113
|
+
Gel::WorkPool.new(8) do |work_pool|
|
114
|
+
git_depot = Gel::GitDepot.new(base_store)
|
115
|
+
|
116
|
+
gems.each do |name, (section, body, version, platform, _deps)|
|
117
|
+
next unless filtered_gems[name]
|
118
|
+
|
119
|
+
if section == :gem
|
120
|
+
if installer && !base_store.gem?(name, version, platform)
|
121
|
+
require_relative "catalog"
|
122
|
+
catalogs = body["remote"].map { |r| Gel::Catalog.new(r, work_pool: work_pool) }
|
123
|
+
installer.install_gem(catalogs, name, platform ? "#{version}-#{platform}" : version)
|
124
|
+
end
|
125
|
+
|
126
|
+
locks[name] = version
|
127
|
+
else
|
128
|
+
if section == :git
|
129
|
+
remote = body["remote"].first
|
130
|
+
revision = body["revision"].first
|
131
|
+
|
132
|
+
dir = git_depot.git_path(remote, revision)
|
133
|
+
if installer && !Dir.exist?(dir)
|
134
|
+
installer.load_git_gem(remote, revision, name)
|
135
|
+
|
136
|
+
locks[name] = -> { Gel::DirectGem.new(dir, name, version) }
|
137
|
+
next
|
138
|
+
end
|
139
|
+
else
|
140
|
+
dir = File.expand_path(body["remote"].first, File.dirname(filename))
|
141
|
+
end
|
142
|
+
|
143
|
+
locks[name] = Gel::DirectGem.new(dir, name, version)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
installer.wait(output) if installer
|
148
|
+
|
149
|
+
locks.each do |name, locked|
|
150
|
+
locks[name] = locked.call if locked.is_a?(Proc)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
locked_store.lock(locks)
|
155
|
+
|
156
|
+
if env
|
157
|
+
env.open(locked_store)
|
158
|
+
|
159
|
+
env.gems_from_lock(locks)
|
160
|
+
end
|
161
|
+
|
162
|
+
locked_store
|
163
|
+
end
|
164
|
+
end
|