gemirro 1.5.0 → 2.0.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 +4 -4
- data/.github/workflows/ruby.yml +29 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +6 -3
- data/Gemfile.lock +126 -0
- data/MANIFEST +3 -10
- data/README.md +1 -1
- data/bin/gemirro +7 -1
- data/gemirro.gemspec +7 -2
- data/lib/gemirro/cli/index.rb +14 -4
- data/lib/gemirro/cli/init.rb +1 -1
- data/lib/gemirro/cli/update.rb +6 -0
- data/lib/gemirro/cli.rb +3 -1
- data/lib/gemirro/configuration.rb +4 -12
- data/lib/gemirro/gems_fetcher.rb +7 -10
- data/lib/gemirro/indexer.rb +286 -178
- data/lib/gemirro/mirror_file.rb +1 -0
- data/lib/gemirro/server.rb +56 -181
- data/lib/gemirro/source.rb +2 -15
- data/lib/gemirro/utils.rb +130 -65
- data/lib/gemirro/version.rb +1 -1
- data/lib/gemirro/versions_fetcher.rb +9 -10
- data/lib/gemirro/versions_file.rb +26 -24
- data/lib/gemirro.rb +0 -1
- data/spec/gemirro/configuration_spec.rb +9 -2
- data/spec/gemirro/gems_fetcher_spec.rb +1 -1
- data/spec/gemirro/indexer_spec.rb +5 -5
- data/spec/gemirro/server_spec.rb +79 -73
- data/spec/gemirro/source_spec.rb +1 -10
- data/spec/gemirro/versions_fetcher_spec.rb +3 -4
- data/spec/gemirro/versions_file_spec.rb +8 -32
- data/template/config.rb +7 -1
- data/template/public/dist/css/gemirro.css +25 -1
- data/views/gem.erb +46 -37
- data/views/index.erb +41 -33
- data/views/layout.erb +4 -17
- data/views/not_found.erb +4 -4
- metadata +79 -16
- data/lib/gemirro/cache.rb +0 -115
- data/spec/gemirro/cache_spec.rb +0 -32
- data/template/public/dist/css/bootstrap.min.css +0 -7
- data/template/public/dist/fonts/glyphicons-halflings-regular.eot +0 -0
- data/template/public/dist/fonts/glyphicons-halflings-regular.svg +0 -288
- data/template/public/dist/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/template/public/dist/fonts/glyphicons-halflings-regular.woff +0 -0
- data/template/public/dist/fonts/glyphicons-halflings-regular.woff2 +0 -0
- data/template/public/dist/js/bootstrap.min.js +0 -7
data/lib/gemirro/indexer.rb
CHANGED
@@ -19,12 +19,14 @@ module Gemirro
|
|
19
19
|
# @return [Array]
|
20
20
|
#
|
21
21
|
class Indexer < ::Gem::Indexer
|
22
|
-
attr_accessor(
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
attr_accessor(
|
23
|
+
:files,
|
24
|
+
:quick_marshal_dir,
|
25
|
+
:directory,
|
26
|
+
:dest_directory,
|
27
|
+
:only_origin,
|
28
|
+
:updated_gems
|
29
|
+
)
|
28
30
|
|
29
31
|
##
|
30
32
|
# Create an indexer that will index the gems in +directory+.
|
@@ -33,48 +35,43 @@ module Gemirro
|
|
33
35
|
# @param [Hash] options Indexer options
|
34
36
|
# @return [Array]
|
35
37
|
##
|
36
|
-
def initialize(
|
38
|
+
def initialize(options = {})
|
37
39
|
require 'fileutils'
|
38
40
|
require 'tmpdir'
|
39
41
|
require 'zlib'
|
42
|
+
require 'builder/xchar'
|
43
|
+
require 'compact_index'
|
40
44
|
|
41
|
-
|
42
|
-
raise 'Gem::Indexer requires that the XML Builder ' \
|
43
|
-
'library be installed:' \
|
44
|
-
"\n\tgem install builder"
|
45
|
-
end
|
46
|
-
|
47
|
-
options = { build_modern: true }.merge options
|
45
|
+
options.merge!({ build_modern: false })
|
48
46
|
|
49
|
-
@
|
50
|
-
|
51
|
-
|
52
|
-
@directory = File.join(Dir.tmpdir,
|
53
|
-
"gem_generate_index_#{rand(1_000_000_000)}")
|
47
|
+
@dest_directory = Gemirro.configuration.destination
|
48
|
+
@directory =
|
49
|
+
File.join(Dir.tmpdir, "gem_generate_index_#{rand(1_000_000_000)}")
|
54
50
|
|
55
51
|
marshal_name = "Marshal.#{::Gem.marshal_version}"
|
56
52
|
|
57
|
-
@master_index =
|
58
|
-
|
53
|
+
@master_index =
|
54
|
+
File.join(@directory, 'yaml')
|
55
|
+
@marshal_index =
|
56
|
+
File.join(@directory, marshal_name)
|
59
57
|
|
60
|
-
@quick_dir = File.join
|
61
|
-
@quick_marshal_dir =
|
62
|
-
|
58
|
+
@quick_dir = File.join(@directory, 'quick')
|
59
|
+
@quick_marshal_dir =
|
60
|
+
File.join(@quick_dir, marshal_name)
|
61
|
+
@quick_marshal_dir_base =
|
62
|
+
File.join(@dest_directory, 'quick', marshal_name) # FIX: UGH
|
63
63
|
|
64
|
-
@quick_index =
|
65
|
-
|
64
|
+
@quick_index =
|
65
|
+
File.join(@quick_dir, 'index')
|
66
|
+
@latest_index =
|
67
|
+
File.join(@quick_dir, 'latest_index')
|
66
68
|
|
67
|
-
@specs_index = File.join @directory, "specs.#{::Gem.marshal_version}"
|
68
69
|
@latest_specs_index =
|
69
70
|
File.join(@directory, "latest_specs.#{::Gem.marshal_version}")
|
70
|
-
@prerelease_specs_index =
|
71
|
-
File.join(@directory, "prerelease_specs.#{::Gem.marshal_version}")
|
72
|
-
@dest_specs_index =
|
73
|
-
File.join(@dest_directory, "specs.#{::Gem.marshal_version}")
|
74
71
|
@dest_latest_specs_index =
|
75
72
|
File.join(@dest_directory, "latest_specs.#{::Gem.marshal_version}")
|
76
|
-
@
|
77
|
-
File.join(@dest_directory,
|
73
|
+
@infos_dir =
|
74
|
+
File.join(@dest_directory, 'info')
|
78
75
|
|
79
76
|
@files = []
|
80
77
|
end
|
@@ -82,16 +79,9 @@ module Gemirro
|
|
82
79
|
##
|
83
80
|
# Generate indices on the destination directory
|
84
81
|
#
|
85
|
-
def install_indices
|
86
|
-
install_indicies
|
87
|
-
end
|
88
|
-
|
89
|
-
##
|
90
|
-
# Generate indicies on the destination directory
|
91
|
-
#
|
92
82
|
# @return [Array]
|
93
83
|
#
|
94
|
-
def
|
84
|
+
def install_indices
|
95
85
|
Utils.logger
|
96
86
|
.debug("Downloading index into production dir #{@dest_directory}")
|
97
87
|
|
@@ -100,43 +90,34 @@ module Gemirro
|
|
100
90
|
|
101
91
|
if files.include?(@quick_marshal_dir) && !files.include?(@quick_dir)
|
102
92
|
files.delete @quick_marshal_dir
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
93
|
+
FileUtils.mkdir_p(File.dirname(@quick_marshal_dir_base), verbose: verbose)
|
94
|
+
if @quick_marshal_dir_base && File.exist?(@quick_marshal_dir_base)
|
95
|
+
FileUtils.rm_rf(@quick_marshal_dir_base, verbose: verbose)
|
96
|
+
end
|
97
|
+
FileUtils.mv(@quick_marshal_dir, @quick_marshal_dir_base, verbose: verbose, force: true)
|
108
98
|
end
|
109
99
|
|
110
100
|
files.each do |path|
|
111
101
|
file = path.sub(%r{^#{Regexp.escape @directory}/?}, '')
|
112
|
-
src_name = File.join(@directory, file)
|
113
|
-
dst_name = File.join(@dest_directory, file)
|
114
|
-
|
115
|
-
if ["#{@specs_index}.gz",
|
116
|
-
"#{@latest_specs_index}.gz",
|
117
|
-
"#{@prerelease_specs_index}.gz"].include?(path)
|
118
|
-
res = build_zlib_file(file, src_name, dst_name, true)
|
119
|
-
next unless res
|
120
|
-
else
|
121
|
-
source_content = download_from_source(file)
|
122
|
-
next if source_content.nil?
|
123
102
|
|
124
|
-
|
125
|
-
|
103
|
+
source_content = download_from_source(file)
|
104
|
+
next if source_content.nil?
|
105
|
+
|
106
|
+
MirrorFile.new(File.join(@dest_directory, file)).write(source_content)
|
126
107
|
|
127
108
|
FileUtils.rm_rf(path)
|
128
109
|
end
|
129
110
|
end
|
130
111
|
|
131
112
|
##
|
132
|
-
# Download file from source
|
113
|
+
# Download file from source (example: rubygems.org)
|
133
114
|
#
|
134
115
|
# @param [String] file File path
|
135
116
|
# @return [String]
|
136
117
|
#
|
137
118
|
def download_from_source(file)
|
138
119
|
source_host = Gemirro.configuration.source.host
|
139
|
-
Utils.logger.info("Download from source
|
120
|
+
Utils.logger.info("Download from source #{source_host}/#{file}")
|
140
121
|
resp = Http.get("#{source_host}/#{File.basename(file)}")
|
141
122
|
return unless resp.code == 200
|
142
123
|
|
@@ -149,29 +130,184 @@ module Gemirro
|
|
149
130
|
# @return [Array]
|
150
131
|
#
|
151
132
|
def build_indices
|
152
|
-
|
133
|
+
specs = *map_gems_to_specs(gem_file_list)
|
134
|
+
specs.select! { |s| s.instance_of?(::Gem::Specification) }
|
135
|
+
::Gem::Specification.dirs = []
|
136
|
+
::Gem::Specification.all = specs
|
137
|
+
|
138
|
+
build_marshal_gemspecs(specs)
|
139
|
+
|
140
|
+
build_compact_index_names
|
141
|
+
build_compact_index_infos(specs)
|
142
|
+
build_compact_index_versions(specs)
|
153
143
|
end
|
154
144
|
|
155
145
|
##
|
156
|
-
#
|
146
|
+
# Cache compact_index endpoint /names
|
147
|
+
# Report all gems with versions available. Does not require opening spec files.
|
157
148
|
#
|
158
|
-
# @return
|
149
|
+
# @return nil
|
159
150
|
#
|
160
|
-
def
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
151
|
+
def build_compact_index_names
|
152
|
+
Utils.logger.info('[1/1]: Caching /names')
|
153
|
+
FileUtils.rm_rf(Dir.glob(File.join(@dest_directory, 'names*.list')))
|
154
|
+
|
155
|
+
gem_name_list = Dir.glob('*.gem', base: File.join(@dest_directory, 'gems')).collect do |x|
|
156
|
+
x.sub(/-\d+(\.\d+)*(\.[a-zA-Z\d]+)*([-_a-zA-Z\d]+)?\.gem/, '')
|
157
|
+
end.uniq.sort!
|
158
|
+
|
159
|
+
Tempfile.create('names.list') do |f|
|
160
|
+
f.write CompactIndex.names(gem_name_list).to_s
|
161
|
+
f.rewind
|
162
|
+
FileUtils.cp(
|
163
|
+
f.path,
|
164
|
+
File.join(
|
165
|
+
@dest_directory,
|
166
|
+
"names.#{Digest::MD5.file(f.path).hexdigest}.#{Digest::SHA256.file(f.path).hexdigest}.list"
|
167
|
+
),
|
168
|
+
verbose: verbose
|
169
|
+
)
|
170
|
+
end
|
165
171
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
172
|
+
nil
|
173
|
+
end
|
174
|
+
|
175
|
+
##
|
176
|
+
# Cache compact_index endpoint /versions
|
177
|
+
#
|
178
|
+
# @param [Array] specs Gems list
|
179
|
+
# @param [Boolean] partial Is gem list an update or a full index
|
180
|
+
# @return nil
|
181
|
+
#
|
182
|
+
def build_compact_index_versions(specs, partial = false)
|
183
|
+
Utils.logger.info('[1/1]: Caching /versions')
|
184
|
+
|
185
|
+
cg =
|
186
|
+
specs
|
187
|
+
.sort_by(&:name)
|
188
|
+
.group_by(&:name)
|
189
|
+
.collect do |name, gem_versions|
|
190
|
+
gem_versions =
|
191
|
+
gem_versions.sort do |a, b|
|
192
|
+
a.version <=> b.version
|
193
|
+
end
|
194
|
+
|
195
|
+
info_file = Dir.glob(File.join(@infos_dir, "#{name}.*.*.list")).last
|
196
|
+
|
197
|
+
throw "Info file for #{name} not found" unless info_file
|
198
|
+
|
199
|
+
info_file_checksum = info_file.split('.', -4)[-3]
|
200
|
+
|
201
|
+
CompactIndex::Gem.new(
|
202
|
+
name,
|
203
|
+
gem_versions.collect do |y|
|
204
|
+
CompactIndex::GemVersion.new(
|
205
|
+
y.version.to_s,
|
206
|
+
y.platform,
|
207
|
+
nil,
|
208
|
+
info_file_checksum
|
209
|
+
)
|
210
|
+
end
|
211
|
+
)
|
212
|
+
end
|
213
|
+
|
214
|
+
Tempfile.create('versions.list') do |f|
|
215
|
+
previous_versions_file = Dir.glob(File.join(@dest_directory, 'versions.*.*.list')).last
|
216
|
+
|
217
|
+
if partial && previous_versions_file
|
218
|
+
versions_file = CompactIndex::VersionsFile.new(previous_versions_file)
|
219
|
+
else
|
220
|
+
versions_file = CompactIndex::VersionsFile.new(f.path)
|
221
|
+
f.write format('created_at: %s', Time.now.utc.iso8601)
|
222
|
+
f.write "\n---\n"
|
223
|
+
end
|
224
|
+
|
225
|
+
f.write CompactIndex.versions(versions_file, cg)
|
226
|
+
f.rewind
|
227
|
+
|
228
|
+
FileUtils.rm_rf(Dir.glob(File.join(@dest_directory, 'versions.*.*.list')))
|
229
|
+
|
230
|
+
FileUtils.cp(
|
231
|
+
f.path,
|
232
|
+
File.join(
|
233
|
+
@dest_directory,
|
234
|
+
"versions.#{Digest::MD5.file(f.path).hexdigest}.#{Digest::SHA256.file(f.path).hexdigest}.list"
|
235
|
+
),
|
236
|
+
verbose: verbose
|
237
|
+
)
|
238
|
+
end
|
239
|
+
|
240
|
+
nil
|
241
|
+
end
|
242
|
+
|
243
|
+
##
|
244
|
+
# Cache compact_index endpoint /info/[gemname]
|
245
|
+
#
|
246
|
+
# @param [Array] specs Gems list
|
247
|
+
# @param [Boolean] partial Is gem list an update or a full index
|
248
|
+
# @return nil
|
249
|
+
#
|
250
|
+
def build_compact_index_infos(specs, partial = false)
|
251
|
+
FileUtils.mkdir_p(@infos_dir, verbose: verbose)
|
252
|
+
|
253
|
+
if partial
|
254
|
+
specs.collect(&:name).uniq do |name|
|
255
|
+
FileUtils.rm_rf(Dir.glob(File.join(@infos_dir, "#{name}.*.*.list")))
|
256
|
+
end
|
170
257
|
else
|
171
|
-
|
172
|
-
build_modern_indicies if @build_modern
|
173
|
-
compress_indicies
|
258
|
+
FileUtils.rm_rf(Dir.glob(File.join(@infos_dir, '*.list')))
|
174
259
|
end
|
260
|
+
|
261
|
+
grouped_specs = specs.sort_by(&:name).group_by(&:name)
|
262
|
+
grouped_specs.each_with_index do |(name, gem_versions), index|
|
263
|
+
Utils.logger.info("[#{index + 1}/#{grouped_specs.size}]: Caching /info/#{name}")
|
264
|
+
|
265
|
+
gem_versions =
|
266
|
+
gem_versions.sort do |a, b|
|
267
|
+
a.version <=> b.version
|
268
|
+
end
|
269
|
+
|
270
|
+
versions =
|
271
|
+
Parallel.map(gem_versions, in_threads: Utils.configuration.update_thread_count) do |spec|
|
272
|
+
deps =
|
273
|
+
spec
|
274
|
+
.dependencies
|
275
|
+
.select { |d| d.type == :runtime }
|
276
|
+
.sort_by(&:name)
|
277
|
+
.collect do |dependency|
|
278
|
+
CompactIndex::Dependency.new(
|
279
|
+
dependency.name,
|
280
|
+
dependency.requirement.to_s
|
281
|
+
)
|
282
|
+
end
|
283
|
+
|
284
|
+
CompactIndex::GemVersion.new(
|
285
|
+
spec.version,
|
286
|
+
spec.platform,
|
287
|
+
Digest::SHA256.file(spec.loaded_from).hexdigest,
|
288
|
+
nil,
|
289
|
+
deps,
|
290
|
+
spec.required_ruby_version.to_s,
|
291
|
+
spec.required_rubygems_version.to_s
|
292
|
+
)
|
293
|
+
end
|
294
|
+
|
295
|
+
Tempfile.create("info_#{name}.list") do |f|
|
296
|
+
f.write CompactIndex.info(versions).to_s
|
297
|
+
f.rewind
|
298
|
+
|
299
|
+
FileUtils.cp(
|
300
|
+
f.path,
|
301
|
+
File.join(
|
302
|
+
@infos_dir,
|
303
|
+
"#{name}.#{Digest::MD5.file(f.path).hexdigest}.#{Digest::SHA256.file(f.path).hexdigest}.list"
|
304
|
+
),
|
305
|
+
verbose: verbose
|
306
|
+
)
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
nil
|
175
311
|
end
|
176
312
|
|
177
313
|
##
|
@@ -181,7 +317,9 @@ module Gemirro
|
|
181
317
|
# @return [Array]
|
182
318
|
#
|
183
319
|
def map_gems_to_specs(gems)
|
184
|
-
|
320
|
+
results = []
|
321
|
+
|
322
|
+
Parallel.each_with_index(gems, in_threads: Utils.configuration.update_thread_count) do |gemfile, index|
|
185
323
|
Utils.logger.info("[#{index + 1}/#{gems.size}]: Processing #{gemfile.split('/')[-1]}")
|
186
324
|
if File.empty?(gemfile)
|
187
325
|
Utils.logger.warn("Skipping zero-length gem: #{gemfile}")
|
@@ -190,12 +328,12 @@ module Gemirro
|
|
190
328
|
|
191
329
|
begin
|
192
330
|
begin
|
193
|
-
spec =
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
331
|
+
spec =
|
332
|
+
if ::Gem::Package.respond_to? :open
|
333
|
+
::Gem::Package.open(File.open(gemfile, 'rb'), 'r', &:metadata)
|
334
|
+
else
|
335
|
+
::Gem::Package.new(gemfile).spec
|
336
|
+
end
|
199
337
|
rescue NotImplementedError
|
200
338
|
next
|
201
339
|
end
|
@@ -213,19 +351,14 @@ module Gemirro
|
|
213
351
|
end
|
214
352
|
|
215
353
|
version = spec.version.version
|
216
|
-
unless version =~ /^\d
|
354
|
+
unless version =~ /^\d+(\.\d+)?(\.\d+)?.*/
|
217
355
|
msg = "Skipping gem #{spec.full_name} - invalid version #{version}"
|
218
356
|
Utils.logger.warn(msg)
|
219
357
|
next
|
220
358
|
end
|
221
359
|
|
222
|
-
|
223
|
-
|
224
|
-
spec.sanitize
|
225
|
-
else
|
226
|
-
abbreviate spec
|
227
|
-
sanitize spec
|
228
|
-
end
|
360
|
+
spec.abbreviate
|
361
|
+
spec.sanitize
|
229
362
|
|
230
363
|
spec
|
231
364
|
rescue SignalException
|
@@ -238,20 +371,49 @@ module Gemirro
|
|
238
371
|
"\t#{e.backtrace.join "\n\t"}"].join("\n")
|
239
372
|
Utils.logger.debug(msg)
|
240
373
|
end
|
241
|
-
|
374
|
+
|
375
|
+
results[index] = spec
|
376
|
+
end
|
377
|
+
|
378
|
+
# nils can result from insert by index
|
379
|
+
results.compact
|
242
380
|
end
|
243
381
|
|
382
|
+
##
|
383
|
+
# Handle `index --update`, detecting changed files and file lists.
|
384
|
+
#
|
385
|
+
# @return nil
|
386
|
+
#
|
244
387
|
def update_index
|
245
388
|
make_temp_directories
|
246
389
|
|
247
|
-
|
390
|
+
present_gemfiles = Dir.glob('*.gem', base: File.join(@dest_directory, 'gems'))
|
391
|
+
indexed_gemfiles = Dir.glob('*.gemspec.rz', base: @quick_marshal_dir_base).collect { |x| x.gsub(/spec.rz$/, '') }
|
392
|
+
|
393
|
+
@updated_gems = []
|
394
|
+
|
395
|
+
# detect files manually added to public/gems
|
396
|
+
@updated_gems += (present_gemfiles - indexed_gemfiles).collect { |x| File.join(@dest_directory, 'gems', x) }
|
397
|
+
# detect files manually deleted from public/gems
|
398
|
+
@updated_gems += (indexed_gemfiles - present_gemfiles).collect { |x| File.join(@dest_directory, 'gems', x) }
|
399
|
+
|
400
|
+
versions_mtime =
|
401
|
+
begin
|
402
|
+
File.stat(Dir.glob(File.join(@dest_directory, 'versions*.list')).last).mtime
|
403
|
+
rescue StandardError
|
404
|
+
Time.at(0)
|
405
|
+
end
|
248
406
|
newest_mtime = Time.at(0)
|
249
407
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
408
|
+
# files that have been replaced
|
409
|
+
@updated_gems +=
|
410
|
+
gem_file_list.select do |gem|
|
411
|
+
gem_mtime = File.stat(gem).mtime
|
412
|
+
newest_mtime = gem_mtime if gem_mtime > newest_mtime
|
413
|
+
gem_mtime > versions_mtime
|
414
|
+
end
|
415
|
+
|
416
|
+
@updated_gems.uniq!
|
255
417
|
|
256
418
|
if @updated_gems.empty?
|
257
419
|
Utils.logger.info('No new gems')
|
@@ -259,94 +421,40 @@ module Gemirro
|
|
259
421
|
end
|
260
422
|
|
261
423
|
specs = map_gems_to_specs(@updated_gems)
|
262
|
-
prerelease, released = specs.partition { |s| s.version.prerelease? }
|
263
424
|
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
::Gem.time('Updated indexes') do
|
273
|
-
update_specs_index(released, @dest_specs_index, @specs_index)
|
274
|
-
update_specs_index(released,
|
275
|
-
@dest_latest_specs_index,
|
276
|
-
@latest_specs_index)
|
277
|
-
update_specs_index(prerelease,
|
278
|
-
@dest_prerelease_specs_index,
|
279
|
-
@prerelease_specs_index)
|
280
|
-
end
|
281
|
-
|
282
|
-
if ::Gem::VERSION >= '2.5.0'
|
283
|
-
compress_indices
|
284
|
-
else
|
285
|
-
compress_indicies
|
286
|
-
end
|
287
|
-
|
288
|
-
Utils.logger.info("Updating production dir #{@dest_directory}") if verbose
|
289
|
-
files << @specs_index
|
290
|
-
files << "#{@specs_index}.gz"
|
291
|
-
files << @latest_specs_index
|
292
|
-
files << "#{@latest_specs_index}.gz"
|
293
|
-
files << @prerelease_specs_index
|
294
|
-
files << "#{@prerelease_specs_index}.gz"
|
295
|
-
|
296
|
-
files.each do |path|
|
297
|
-
file = path.sub(%r{^#{Regexp.escape @directory}/?}, '')
|
298
|
-
src_name = File.join(@directory, file)
|
299
|
-
dst_name = File.join(@dest_directory, file)
|
300
|
-
|
301
|
-
if ["#{@specs_index}.gz",
|
302
|
-
"#{@latest_specs_index}.gz",
|
303
|
-
"#{@prerelease_specs_index}.gz"].include?(path)
|
304
|
-
res = build_zlib_file(file, src_name, dst_name)
|
305
|
-
next unless res
|
306
|
-
else
|
307
|
-
FileUtils.mv(src_name,
|
308
|
-
dst_name,
|
309
|
-
verbose: verbose,
|
310
|
-
force: true)
|
425
|
+
# specs only includes latest discovered files.
|
426
|
+
# /info/[gemname] can not be rebuilt
|
427
|
+
# incrementally, so retrive specs for all versions of these gems.
|
428
|
+
gem_name_updates = specs.collect(&:name).uniq
|
429
|
+
u2 =
|
430
|
+
Dir.glob(File.join(File.join(@dest_directory, 'gems'), '*.gem')).select do |possibility|
|
431
|
+
gem_name_updates.any? { |updated| File.basename(possibility) =~ /^#{updated}-\d/ }
|
311
432
|
end
|
312
433
|
|
313
|
-
|
314
|
-
|
315
|
-
end
|
316
|
-
|
317
|
-
def build_zlib_file(file, src_name, dst_name, from_source = false)
|
318
|
-
content = Marshal.load(Zlib::GzipReader.open(src_name).read)
|
319
|
-
create_zlib_file("#{dst_name}.orig", content)
|
320
|
-
|
321
|
-
return false if @only_origin
|
322
|
-
|
323
|
-
if from_source
|
324
|
-
source_content = download_from_source(file)
|
325
|
-
source_content = Marshal.load(Zlib::GzipReader
|
326
|
-
.new(StringIO
|
327
|
-
.new(source_content)).read)
|
328
|
-
else
|
329
|
-
source_content = Marshal.load(Zlib::GzipReader.open(dst_name).read)
|
330
|
-
end
|
434
|
+
Utils.logger.info('Reloading for /info/[gemname]')
|
435
|
+
version_specs = map_gems_to_specs(u2)
|
331
436
|
|
332
|
-
|
437
|
+
::Gem::Specification.dirs = []
|
438
|
+
::Gem::Specification.all = *specs
|
439
|
+
build_marshal_gemspecs specs
|
333
440
|
|
334
|
-
|
335
|
-
|
441
|
+
build_compact_index_infos(version_specs, true)
|
442
|
+
build_compact_index_versions(specs, true)
|
443
|
+
build_compact_index_names
|
336
444
|
end
|
337
445
|
|
338
|
-
def
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
446
|
+
def download_source_versions
|
447
|
+
Tempfile.create(File.basename(Gemirro.configuration.versions_file)) do |f|
|
448
|
+
f.write(download_from_source('versions'))
|
449
|
+
f.close
|
450
|
+
|
451
|
+
FileUtils.rm(Gemirro.configuration.versions_file, verbose: verbose)
|
452
|
+
FileUtils.cp(
|
453
|
+
f.path,
|
454
|
+
Gemirro.configuration.versions_file,
|
455
|
+
verbose: verbose
|
456
|
+
)
|
343
457
|
end
|
344
|
-
|
345
|
-
FileUtils.mv(temp_file.path,
|
346
|
-
dst_name,
|
347
|
-
verbose: verbose,
|
348
|
-
force: true)
|
349
|
-
Utils.cache.flush_key(File.basename(dst_name))
|
350
458
|
end
|
351
459
|
|
352
460
|
def verbose
|