gemirro 0.11.0 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of gemirro might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/MANIFEST +2 -1
- data/README.md +1 -0
- data/gemirro.gemspec +2 -0
- data/lib/gemirro/cache.rb +113 -0
- data/lib/gemirro/cli/server.rb +5 -2
- data/lib/gemirro/cli.rb +1 -0
- data/lib/gemirro/gem.rb +3 -1
- data/lib/gemirro/gem_version.rb +4 -2
- data/lib/gemirro/gem_version_collection.rb +2 -0
- data/lib/gemirro/gems_fetcher.rb +4 -10
- data/lib/gemirro/indexer.rb +19 -4
- data/lib/gemirro/server.rb +90 -42
- data/lib/gemirro/source.rb +22 -0
- data/lib/gemirro/version.rb +1 -1
- data/lib/gemirro/versions_fetcher.rb +18 -4
- data/lib/gemirro.rb +2 -0
- data/spec/gemirro/gems_fetcher_spec.rb +2 -1
- data/spec/gemirro/indexer_spec.rb +2 -1
- data/spec/gemirro/server_spec.rb +2 -0
- data/spec/gemirro/source_spec.rb +10 -0
- data/spec/gemirro/versions_fetcher_spec.rb +5 -3
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8982c03b3986ec30f9cb52186836ff37b677a369
|
4
|
+
data.tar.gz: 4983fc83b1bf255c6b74da5a66482ac868ae66c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 379c27532e2525d86ee0590b9b42697672a1e44c517574d6ded98bfc52fd7699192df09cab8158c19a8edacd325a430e946f980ddc18d483b72352ebd4840252
|
7
|
+
data.tar.gz: 0ff72c9c524b607df1a98dd2f1662522ef8c5d2fa743a0247241ba7a65b30c3f1049915345157ad05a2ede29ff6d6d9bdad33ab29f74a8703b2e637586293fb4
|
data/MANIFEST
CHANGED
@@ -9,6 +9,7 @@ Rakefile
|
|
9
9
|
bin/gemirro
|
10
10
|
gemirro.gemspec
|
11
11
|
lib/gemirro.rb
|
12
|
+
lib/gemirro/cache.rb
|
12
13
|
lib/gemirro/cli.rb
|
13
14
|
lib/gemirro/cli/index.rb
|
14
15
|
lib/gemirro/cli/init.rb
|
@@ -63,4 +64,4 @@ template/public/gems/.gitkeep
|
|
63
64
|
views/gem.erb
|
64
65
|
views/index.erb
|
65
66
|
views/layout.erb
|
66
|
-
views/not_found.erb
|
67
|
+
views/not_found.erb
|
data/README.md
CHANGED
data/gemirro.gemspec
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
+
require 'date'
|
2
3
|
require File.expand_path('../lib/gemirro/version', __FILE__)
|
3
4
|
|
4
5
|
Gem::Specification.new do |s|
|
@@ -23,6 +24,7 @@ Gem::Specification.new do |s|
|
|
23
24
|
s.add_dependency 'builder', '~>3.2'
|
24
25
|
s.add_dependency 'sinatra', '~>1.4'
|
25
26
|
s.add_dependency 'thin', '~>1.6'
|
27
|
+
s.add_dependency 'pmap', '~>1.0'
|
26
28
|
|
27
29
|
s.add_development_dependency 'rake', '~>10.4'
|
28
30
|
s.add_development_dependency 'rack-test', '~>0.6'
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Gemirro
|
3
|
+
##
|
4
|
+
# The Cache class contains all method to store marshal informations
|
5
|
+
# into files.
|
6
|
+
#
|
7
|
+
# @!attribute [r] root_path
|
8
|
+
# @return [String]
|
9
|
+
#
|
10
|
+
class Cache
|
11
|
+
attr_reader :root_path
|
12
|
+
|
13
|
+
##
|
14
|
+
# Initialize cache root path
|
15
|
+
#
|
16
|
+
# @param [String] path
|
17
|
+
#
|
18
|
+
def initialize(path)
|
19
|
+
@root_path = path
|
20
|
+
create_root_path
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# Create root path
|
25
|
+
#
|
26
|
+
def create_root_path
|
27
|
+
FileUtils.mkdir_p(@root_path)
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Flush cache directory
|
32
|
+
#
|
33
|
+
def flush
|
34
|
+
FileUtils.rm_rf(@root_path)
|
35
|
+
create_root_path
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Flush key
|
40
|
+
#
|
41
|
+
# @param [String] key
|
42
|
+
#
|
43
|
+
def flush_key(key)
|
44
|
+
path = key_path(key2hash(key))
|
45
|
+
FileUtils.rm_f(path)
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Cache data
|
50
|
+
#
|
51
|
+
# @param [String] key
|
52
|
+
#
|
53
|
+
# @return [Mixed]
|
54
|
+
#
|
55
|
+
def cache(key)
|
56
|
+
key_hash = key2hash(key)
|
57
|
+
read(key_hash) || (write(key_hash, yield) if block_given?)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
##
|
63
|
+
# Convert key to hash
|
64
|
+
#
|
65
|
+
# @param [String] key
|
66
|
+
#
|
67
|
+
# @return [String]
|
68
|
+
#
|
69
|
+
def key2hash(key)
|
70
|
+
Digest::MD5.hexdigest(key)
|
71
|
+
end
|
72
|
+
|
73
|
+
##
|
74
|
+
# Path from key hash
|
75
|
+
#
|
76
|
+
# @param [String] key_hash
|
77
|
+
#
|
78
|
+
# @return [String]
|
79
|
+
#
|
80
|
+
def key_path(key_hash)
|
81
|
+
File.join(@root_path, key_hash)
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Read cache
|
86
|
+
#
|
87
|
+
# @param [String] key_hash
|
88
|
+
#
|
89
|
+
# @return [Mixed]
|
90
|
+
#
|
91
|
+
def read(key_hash)
|
92
|
+
path = key_path(key_hash)
|
93
|
+
Marshal.load(File.open(path)) if File.exist?(path)
|
94
|
+
end
|
95
|
+
|
96
|
+
##
|
97
|
+
# write cache
|
98
|
+
#
|
99
|
+
# @param [String] key_hash
|
100
|
+
# @param [Mixed] value
|
101
|
+
#
|
102
|
+
# @return [Mixed]
|
103
|
+
#
|
104
|
+
def write(key_hash, value)
|
105
|
+
return value if value.nil? || value.empty?
|
106
|
+
File.open(key_path(key_hash), 'wb') do |f|
|
107
|
+
Marshal.dump(value, f)
|
108
|
+
end
|
109
|
+
|
110
|
+
value
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
data/lib/gemirro/cli/server.rb
CHANGED
@@ -28,7 +28,9 @@ Gemirro::CLI.options.command 'server' do
|
|
28
28
|
abort
|
29
29
|
end
|
30
30
|
|
31
|
-
@pid_file = File.join(config.destination,
|
31
|
+
@pid_file = File.expand_path(File.join(config.destination,
|
32
|
+
'..',
|
33
|
+
'gemirro.pid'))
|
32
34
|
require 'gemirro/server'
|
33
35
|
end
|
34
36
|
|
@@ -56,7 +58,6 @@ Gemirro::CLI.options.command 'server' do
|
|
56
58
|
end
|
57
59
|
rescue Errno::ENOENT
|
58
60
|
puts "Error: PID File not found #{@pid_file}"
|
59
|
-
exit!
|
60
61
|
end
|
61
62
|
|
62
63
|
def start
|
@@ -79,6 +80,8 @@ Gemirro::CLI.options.command 'server' do
|
|
79
80
|
|
80
81
|
def stop
|
81
82
|
process_pid = pid
|
83
|
+
return if process_pid.nil?
|
84
|
+
|
82
85
|
begin
|
83
86
|
Process.kill('TERM', process_pid)
|
84
87
|
Timeout.timeout(30) { sleep 0.1 while running?(process_pid) }
|
data/lib/gemirro/cli.rb
CHANGED
@@ -30,6 +30,7 @@ module Gemirro
|
|
30
30
|
def self.load_configuration(config_file)
|
31
31
|
config_file ||= Configuration.default_configuration_file
|
32
32
|
config_file = File.expand_path(config_file, Dir.pwd)
|
33
|
+
config_file += '/config.rb' unless config_file.end_with?('config.rb')
|
33
34
|
|
34
35
|
unless File.file?(config_file)
|
35
36
|
abort "The configuration file #{config_file} does not exist"
|
data/lib/gemirro/gem.rb
CHANGED
@@ -9,9 +9,11 @@ module Gemirro
|
|
9
9
|
# @return [String]
|
10
10
|
# @!attribute [r] requirement
|
11
11
|
# @return [Gem::Requirement]
|
12
|
+
# @!attribute [r] version
|
13
|
+
# @return [Gem::Version]
|
12
14
|
#
|
13
15
|
class Gem
|
14
|
-
attr_reader :name, :requirement, :platform
|
16
|
+
attr_reader :name, :requirement, :platform, :version
|
15
17
|
attr_accessor :gemspec
|
16
18
|
|
17
19
|
##
|
data/lib/gemirro/gem_version.rb
CHANGED
@@ -11,10 +11,12 @@ module Gemirro
|
|
11
11
|
# @return [Integer]
|
12
12
|
# @!attribute [r] platform
|
13
13
|
# @return [String]
|
14
|
+
# @!attribute [r] version
|
15
|
+
# @return [Gem::Version]
|
14
16
|
#
|
15
17
|
class GemVersion
|
16
18
|
include Comparable
|
17
|
-
attr_reader :name, :number, :platform
|
19
|
+
attr_reader :name, :number, :platform, :version
|
18
20
|
|
19
21
|
##
|
20
22
|
# @param [String] name
|
@@ -42,7 +44,7 @@ module Gemirro
|
|
42
44
|
# @return [Gem::Version]
|
43
45
|
#
|
44
46
|
def version
|
45
|
-
::Gem::Version.create(number)
|
47
|
+
@version ||= ::Gem::Version.create(number)
|
46
48
|
end
|
47
49
|
|
48
50
|
##
|
data/lib/gemirro/gems_fetcher.rb
CHANGED
@@ -48,15 +48,9 @@ module Gemirro
|
|
48
48
|
# @return [Array]
|
49
49
|
#
|
50
50
|
def versions_for(gem)
|
51
|
-
available
|
52
|
-
versions
|
53
|
-
|
54
|
-
|
55
|
-
# Get rid of invalid versions. Due to Gem::Version having a custom ==
|
56
|
-
# method, which treats "3.4" the same as "3.4.0" we'll have to compare
|
57
|
-
# the versions as String instances.
|
58
|
-
versions = versions.select do |version|
|
59
|
-
available_names.include?(version.to_s)
|
51
|
+
available = @versions_file.versions_for(gem.name)
|
52
|
+
versions = available.select do |v|
|
53
|
+
gem.requirement.satisfied_by?(v)
|
60
54
|
end
|
61
55
|
|
62
56
|
versions = [available.last] if versions.empty?
|
@@ -115,7 +109,7 @@ module Gemirro
|
|
115
109
|
# @return [String]
|
116
110
|
#
|
117
111
|
def fetch_from_source(gem, version, gemspec = false)
|
118
|
-
data
|
112
|
+
data = nil
|
119
113
|
begin
|
120
114
|
data = @source.fetch_gem(gem.name, version) unless gemspec
|
121
115
|
data = @source.fetch_gemspec(gem.name, version) if gemspec
|
data/lib/gemirro/indexer.rb
CHANGED
@@ -15,13 +15,17 @@ module Gemirro
|
|
15
15
|
# @return [String]
|
16
16
|
# @!attribute [r] only_origin
|
17
17
|
# @return [Boolean]
|
18
|
+
# @!attribute [r] updated_gems
|
19
|
+
# @return [Array]
|
18
20
|
#
|
19
21
|
class Indexer < ::Gem::Indexer
|
20
22
|
attr_accessor(:files,
|
21
23
|
:quick_marshal_dir,
|
22
24
|
:directory,
|
23
25
|
:dest_directory,
|
24
|
-
:only_origin
|
26
|
+
:only_origin,
|
27
|
+
:updated_gems)
|
28
|
+
attr_reader :cache
|
25
29
|
|
26
30
|
##
|
27
31
|
# Create an indexer that will index the gems in +directory+.
|
@@ -202,18 +206,18 @@ module Gemirro
|
|
202
206
|
specs_mtime = File.stat(@dest_specs_index).mtime
|
203
207
|
newest_mtime = Time.at(0)
|
204
208
|
|
205
|
-
updated_gems = gem_file_list.select do |gem|
|
209
|
+
@updated_gems = gem_file_list.select do |gem|
|
206
210
|
gem_mtime = File.stat(gem).mtime
|
207
211
|
newest_mtime = gem_mtime if gem_mtime > newest_mtime
|
208
212
|
gem_mtime > specs_mtime
|
209
213
|
end
|
210
214
|
|
211
|
-
if updated_gems.empty?
|
215
|
+
if @updated_gems.empty?
|
212
216
|
logger.info('No new gems')
|
213
217
|
terminate_interaction(0)
|
214
218
|
end
|
215
219
|
|
216
|
-
specs = map_gems_to_specs(updated_gems)
|
220
|
+
specs = map_gems_to_specs(@updated_gems)
|
217
221
|
prerelease, released = specs.partition { |s| s.version.prerelease? }
|
218
222
|
|
219
223
|
::Gem::Specification.dirs = []
|
@@ -292,6 +296,17 @@ module Gemirro
|
|
292
296
|
dst_name,
|
293
297
|
verbose: verbose,
|
294
298
|
force: true)
|
299
|
+
cache.flush_key(File.basename(dst_name))
|
300
|
+
end
|
301
|
+
|
302
|
+
##
|
303
|
+
# Cache class to store marshal and data into files
|
304
|
+
#
|
305
|
+
# @return [Gemirro::Cache]
|
306
|
+
#
|
307
|
+
def cache
|
308
|
+
@cache ||= Gemirro::Cache
|
309
|
+
.new(File.join(Gemirro.configuration.destination, '.cache'))
|
295
310
|
end
|
296
311
|
|
297
312
|
def verbose
|
data/lib/gemirro/server.rb
CHANGED
@@ -12,7 +12,17 @@ module Gemirro
|
|
12
12
|
# @return [Gemirro::GemsFetcher]
|
13
13
|
#
|
14
14
|
class Server < Sinatra::Base
|
15
|
+
# rubocop:disable Metrics/LineLength
|
16
|
+
URI_REGEXP = /^(.*)-(\d+(?:\.\d+){1,4}.*?)(?:-x86-(?:(?:mswin|mingw)(?:32|64)).*?)?\.(gem(?:spec\.rz)?)$/
|
17
|
+
GEMSPEC_TYPE = 'gemspec.rz'
|
18
|
+
GEM_TYPE = 'gem'
|
19
|
+
# rubocop:enable Metrics/LineLength
|
20
|
+
|
15
21
|
attr_accessor :versions_fetcher, :gems_fetcher
|
22
|
+
attr_reader(:gems_orig_collection,
|
23
|
+
:gems_source_collection,
|
24
|
+
:stored_gems,
|
25
|
+
:cache)
|
16
26
|
|
17
27
|
# rubocop:disable Metrics/LineLength
|
18
28
|
access_logger = Logger.new(Gemirro.configuration.server.access_log).tap do |logger|
|
@@ -120,6 +130,16 @@ module Gemirro
|
|
120
130
|
send_file(resource)
|
121
131
|
end
|
122
132
|
|
133
|
+
##
|
134
|
+
# Cache class to store marshal and data into files
|
135
|
+
#
|
136
|
+
# @return [Gemirro::Cache]
|
137
|
+
#
|
138
|
+
def cache
|
139
|
+
@cache ||= Gemirro::Cache
|
140
|
+
.new(File.join(configuration.destination, '.cache'))
|
141
|
+
end
|
142
|
+
|
123
143
|
##
|
124
144
|
# Try to fetch gem and download its if it's possible, and
|
125
145
|
# build and install indicies.
|
@@ -129,22 +149,19 @@ module Gemirro
|
|
129
149
|
#
|
130
150
|
def fetch_gem(resource)
|
131
151
|
name = File.basename(resource)
|
132
|
-
|
133
|
-
regexp = /^(.*)-(\d+(?:\.\d+){2,4}.*?)(?:-x86-(?:(?:mswin|mingw)(?:32|64)).*?)?\.(gem(?:spec\.rz)?)$/
|
134
|
-
# rubocop:enable Metrics/LineLength
|
135
|
-
result = name.match(regexp)
|
152
|
+
result = name.match(URI_REGEXP)
|
136
153
|
return unless result
|
137
154
|
|
138
155
|
gem_name, gem_version, gem_type = result.captures
|
139
156
|
return unless gem_name && gem_version
|
140
157
|
|
141
158
|
begin
|
142
|
-
gem =
|
143
|
-
gem.gemspec = true if gem_type ==
|
159
|
+
gem = stored_gem(gem_name, gem_version)
|
160
|
+
gem.gemspec = true if gem_type == GEMSPEC_TYPE
|
144
161
|
|
145
162
|
# rubocop:disable Metrics/LineLength
|
146
|
-
return if gems_fetcher.gem_exists?(gem.filename(gem_version)) && gem_type ==
|
147
|
-
return if gems_fetcher.gemspec_exists?(gem.gemspec_filename(gem_version)) && gem_type ==
|
163
|
+
return if gems_fetcher.gem_exists?(gem.filename(gem_version)) && gem_type == GEM_TYPE
|
164
|
+
return if gems_fetcher.gemspec_exists?(gem.gemspec_filename(gem_version)) && gem_type == GEMSPEC_TYPE
|
148
165
|
# rubocop:enable Metrics/LineLength
|
149
166
|
|
150
167
|
logger.info("Try to download #{gem_name} with version #{gem_version}")
|
@@ -164,12 +181,15 @@ module Gemirro
|
|
164
181
|
# @return [Indexer]
|
165
182
|
#
|
166
183
|
def update_indexes
|
167
|
-
indexer
|
184
|
+
indexer = Gemirro::Indexer.new(configuration.destination)
|
168
185
|
indexer.only_origin = true
|
169
186
|
indexer.ui = ::Gem::SilentUI.new
|
170
187
|
|
171
188
|
configuration.logger.info('Generating indexes')
|
172
189
|
indexer.update_index
|
190
|
+
indexer.updated_gems.peach do |gem|
|
191
|
+
cache.flush_key(gem.name)
|
192
|
+
end
|
173
193
|
rescue SystemExit => e
|
174
194
|
configuration.logger.info(e.message)
|
175
195
|
end
|
@@ -221,15 +241,23 @@ module Gemirro
|
|
221
241
|
# @return [Gemirro::GemVersionCollection]
|
222
242
|
#
|
223
243
|
def gems_collection(orig = true)
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
244
|
+
return @gems_orig_collection if orig && !@gems_orig_collection.nil?
|
245
|
+
return @gems_source_collection if !orig && !@gems_source_collection.nil?
|
246
|
+
|
247
|
+
gems = []
|
248
|
+
specs_files_paths(orig).pmap do |specs_file_path|
|
249
|
+
cache.cache(File.basename(specs_file_path)) do
|
250
|
+
# rubocop:disable Metrics/LineLength
|
251
|
+
gems.concat(Marshal.load(Zlib::GzipReader.open(specs_file_path).read)) if File.exist?(specs_file_path)
|
252
|
+
# rubocop:enable Metrics/LineLength
|
229
253
|
end
|
230
|
-
end
|
254
|
+
end
|
255
|
+
|
256
|
+
collection = GemVersionCollection.new(gems)
|
257
|
+
@gems_source_collection = collection unless orig
|
258
|
+
@gems_orig_collection = collection if orig
|
231
259
|
|
232
|
-
|
260
|
+
collection
|
233
261
|
end
|
234
262
|
|
235
263
|
##
|
@@ -238,9 +266,11 @@ module Gemirro
|
|
238
266
|
# @return [Array]
|
239
267
|
#
|
240
268
|
def query_gems_list
|
241
|
-
|
269
|
+
gems_collection(false) # load collection
|
270
|
+
gems = query_gems.pmap do |query_gem|
|
242
271
|
gem_dependencies(query_gem)
|
243
272
|
end
|
273
|
+
gems.flatten!
|
244
274
|
gems = gems.select do |g|
|
245
275
|
!g.empty?
|
246
276
|
end
|
@@ -254,33 +284,35 @@ module Gemirro
|
|
254
284
|
# @return [Array]
|
255
285
|
#
|
256
286
|
def gem_dependencies(gem_name)
|
257
|
-
|
258
|
-
|
259
|
-
|
287
|
+
cache.cache(gem_name) do
|
288
|
+
gems = gems_collection(false)
|
289
|
+
gem_collection = gems.find_by_name(gem_name)
|
260
290
|
|
261
|
-
|
262
|
-
[gem, spec_for(gem.name, gem.number, gem.platform)]
|
263
|
-
end
|
291
|
+
return '' if gem_collection.nil?
|
264
292
|
|
265
|
-
|
266
|
-
|
267
|
-
end
|
268
|
-
|
269
|
-
gem_collection.map do |gem, spec|
|
270
|
-
dependencies = spec.dependencies.select do |d|
|
271
|
-
d.type == :runtime
|
293
|
+
gem_collection = gem_collection.pmap do |gem|
|
294
|
+
[gem, spec_for(gem.name, gem.number, gem.platform)]
|
272
295
|
end
|
273
|
-
|
274
|
-
|
275
|
-
[d.name.is_a?(Array) ? d.name.first : d.name, d.requirement.to_s]
|
296
|
+
gem_collection.reject! do |_, spec|
|
297
|
+
spec.nil?
|
276
298
|
end
|
277
299
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
300
|
+
gem_collection.pmap do |gem, spec|
|
301
|
+
dependencies = spec.dependencies.select do |d|
|
302
|
+
d.type == :runtime
|
303
|
+
end
|
304
|
+
|
305
|
+
dependencies = dependencies.pmap do |d|
|
306
|
+
[d.name.is_a?(Array) ? d.name.first : d.name, d.requirement.to_s]
|
307
|
+
end
|
308
|
+
|
309
|
+
{
|
310
|
+
name: gem.name,
|
311
|
+
number: gem.number,
|
312
|
+
platform: gem.platform,
|
313
|
+
dependencies: dependencies
|
314
|
+
}
|
315
|
+
end
|
284
316
|
end
|
285
317
|
end
|
286
318
|
|
@@ -292,7 +324,7 @@ module Gemirro
|
|
292
324
|
#
|
293
325
|
def specs_files_paths(orig = true)
|
294
326
|
marshal_version = Gemirro::Configuration.marshal_version
|
295
|
-
specs_file_types.
|
327
|
+
specs_file_types.pmap do |specs_file_type|
|
296
328
|
File.join(settings.public_folder,
|
297
329
|
[specs_file_type,
|
298
330
|
marshal_version,
|
@@ -310,6 +342,23 @@ module Gemirro
|
|
310
342
|
[:specs, :prerelease_specs]
|
311
343
|
end
|
312
344
|
|
345
|
+
##
|
346
|
+
# Try to cache gem classes
|
347
|
+
#
|
348
|
+
# @param [String] gem_name Gem name
|
349
|
+
# @return [Gem]
|
350
|
+
#
|
351
|
+
def stored_gem(gem_name, gem_version, platform = 'ruby')
|
352
|
+
@stored_gems ||= {}
|
353
|
+
# rubocop:disable Metrics/LineLength
|
354
|
+
@stored_gems[gem_name] = {} unless @stored_gems.key?(gem_name)
|
355
|
+
@stored_gems[gem_name][gem_version] = {} unless @stored_gems[gem_name].key?(gem_version)
|
356
|
+
@stored_gems[gem_name][gem_version][platform] ||= Gem.new(gem_name, gem_version, platform) unless @stored_gems[gem_name][gem_version].key?(platform)
|
357
|
+
# rubocop:enable Metrics/LineLength
|
358
|
+
|
359
|
+
@stored_gems[gem_name][gem_version][platform]
|
360
|
+
end
|
361
|
+
|
313
362
|
helpers do
|
314
363
|
##
|
315
364
|
# Return gem specification from gemname and version
|
@@ -319,13 +368,12 @@ module Gemirro
|
|
319
368
|
# @return [::Gem::Specification]
|
320
369
|
#
|
321
370
|
def spec_for(gemname, version, platform = 'ruby')
|
322
|
-
gem =
|
371
|
+
gem = stored_gem(gemname, version.to_s, platform)
|
323
372
|
gemspec_path = File.join('quick',
|
324
373
|
Gemirro::Configuration.marshal_identifier,
|
325
374
|
gem.gemspec_filename)
|
326
375
|
spec_file = File.join(settings.public_folder,
|
327
376
|
gemspec_path)
|
328
|
-
|
329
377
|
fetch_gem(gemspec_path) unless File.exist?(spec_file)
|
330
378
|
File.open(spec_file, 'r') do |uz_file|
|
331
379
|
uz_file.binmode
|
data/lib/gemirro/source.rb
CHANGED
@@ -25,12 +25,24 @@ module Gemirro
|
|
25
25
|
@gems = gems
|
26
26
|
end
|
27
27
|
|
28
|
+
##
|
29
|
+
# @see Gemirro::Configuration#logger
|
30
|
+
# @return [Logger]
|
31
|
+
#
|
32
|
+
def logger
|
33
|
+
Gemirro.configuration.logger
|
34
|
+
end
|
35
|
+
|
28
36
|
##
|
29
37
|
# Fetches a list of all the available Gems and their versions.
|
30
38
|
#
|
31
39
|
# @return [String]
|
32
40
|
#
|
33
41
|
def fetch_versions
|
42
|
+
logger.info(
|
43
|
+
"Fetching #{Configuration.versions_file} on #{@name} (#{@host})"
|
44
|
+
)
|
45
|
+
|
34
46
|
Http.get(host + '/' + Configuration.versions_file).body
|
35
47
|
end
|
36
48
|
|
@@ -40,6 +52,10 @@ module Gemirro
|
|
40
52
|
# @return [String]
|
41
53
|
#
|
42
54
|
def fetch_prerelease_versions
|
55
|
+
logger.info(
|
56
|
+
"Fetching #{Configuration.prerelease_versions_file}" \
|
57
|
+
" on #{@name} (#{@host})"
|
58
|
+
)
|
43
59
|
Http.get(host + '/' + Configuration.prerelease_versions_file).body
|
44
60
|
end
|
45
61
|
|
@@ -51,6 +67,9 @@ module Gemirro
|
|
51
67
|
# @return [String]
|
52
68
|
#
|
53
69
|
def fetch_gem(name, version)
|
70
|
+
logger.info(
|
71
|
+
"Fetching gem #{name}, #{version} on #{@name} (#{@host})"
|
72
|
+
)
|
54
73
|
Http.get(host + "/gems/#{name}-#{version}.gem").body
|
55
74
|
end
|
56
75
|
|
@@ -62,6 +81,9 @@ module Gemirro
|
|
62
81
|
# @return [String]
|
63
82
|
#
|
64
83
|
def fetch_gemspec(name, version)
|
84
|
+
logger.info(
|
85
|
+
"Fetching gemspec #{name}, #{version} on #{@name} (#{@host})"
|
86
|
+
)
|
65
87
|
marshal = Gemirro::Configuration.marshal_identifier
|
66
88
|
Http.get(host + "/quick/#{marshal}/#{name}-#{version}.gemspec.rz").body
|
67
89
|
end
|
data/lib/gemirro/version.rb
CHANGED
@@ -21,11 +21,25 @@ module Gemirro
|
|
21
21
|
# @return [Gemirro::VersionsFile]
|
22
22
|
#
|
23
23
|
def fetch
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
VersionsFile.load(read_file(Configuration.versions_file),
|
25
|
+
read_file(Configuration.prerelease_versions_file, true))
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Read file if exists otherwise download its from source
|
30
|
+
#
|
31
|
+
# @param [String] file name
|
32
|
+
# @param [TrueClass|FalseClass] prerelease Is prerelease or not
|
33
|
+
#
|
34
|
+
def read_file(file, prerelease = false)
|
35
|
+
destination = Gemirro.configuration.destination
|
36
|
+
file_dst = File.join(destination, file)
|
37
|
+
unless File.exist?(file_dst)
|
38
|
+
File.write(file_dst, @source.fetch_versions) unless prerelease
|
39
|
+
File.write(file_dst, @source.fetch_prerelease_versions) if prerelease
|
40
|
+
end
|
27
41
|
|
28
|
-
|
42
|
+
File.read(file_dst)
|
29
43
|
end
|
30
44
|
end
|
31
45
|
end
|
data/lib/gemirro.rb
CHANGED
@@ -11,6 +11,7 @@ require 'httpclient'
|
|
11
11
|
require 'logger'
|
12
12
|
require 'stringio'
|
13
13
|
require 'json'
|
14
|
+
require 'pmap'
|
14
15
|
require 'tempfile'
|
15
16
|
|
16
17
|
unless $LOAD_PATH.include?(File.expand_path('../', __FILE__))
|
@@ -19,6 +20,7 @@ end
|
|
19
20
|
|
20
21
|
require 'gemirro/version'
|
21
22
|
require 'gemirro/configuration'
|
23
|
+
require 'gemirro/cache'
|
22
24
|
require 'gemirro/gem'
|
23
25
|
require 'gemirro/gem_version'
|
24
26
|
require 'gemirro/gem_version_collection'
|
@@ -109,7 +109,8 @@ module Gemirro
|
|
109
109
|
it 'should retrieve versions for specific gem' do
|
110
110
|
gem = Gem.new('gemirro', '0.0.2')
|
111
111
|
allow(@versions_file).to receive(:versions_for)
|
112
|
-
.once.with('gemirro').and_return(['0.0.1',
|
112
|
+
.once.with('gemirro').and_return([::Gem::Version.new('0.0.1'),
|
113
|
+
::Gem::Version.new('0.0.2')])
|
113
114
|
expect(@fetcher.versions_for(gem)).to eq([::Gem::Version.new('0.0.2')])
|
114
115
|
end
|
115
116
|
|
@@ -52,7 +52,8 @@ module Gemirro
|
|
52
52
|
'/tmp/gem_generate_index/specs.4.8.gz',
|
53
53
|
'/tmp/gem_generate_index/something.4.8.gz'
|
54
54
|
]
|
55
|
-
|
55
|
+
allow(FileUtils).to receive(:mkdir_p).and_return(true)
|
56
|
+
allow(FileUtils).to receive(:rm_f).and_return(true)
|
56
57
|
allow(FileUtils).to receive(:mkdir_p)
|
57
58
|
.once.with('/tmp/test/quick', verbose: true)
|
58
59
|
allow(FileUtils).to receive(:rm_rf)
|
data/spec/gemirro/server_spec.rb
CHANGED
data/spec/gemirro/source_spec.rb
CHANGED
@@ -8,6 +8,7 @@ module Gemirro
|
|
8
8
|
describe 'Source' do
|
9
9
|
before(:each) do
|
10
10
|
@source = Source.new('RubyGems', 'https://rubygems.org')
|
11
|
+
allow(@source.logger).to receive(:info)
|
11
12
|
end
|
12
13
|
|
13
14
|
it 'should be initialized' do
|
@@ -25,6 +26,15 @@ module Gemirro
|
|
25
26
|
expect(@source.fetch_versions).to be_truthy
|
26
27
|
end
|
27
28
|
|
29
|
+
it 'should fetch prereleases versions' do
|
30
|
+
Struct.new('FetchPrereleaseVersions', :body)
|
31
|
+
result = Struct::FetchPrereleaseVersions.new(true)
|
32
|
+
allow(Http).to receive(:get).once.with(
|
33
|
+
"https://rubygems.org/#{Configuration.prerelease_versions_file}"
|
34
|
+
).and_return(result)
|
35
|
+
expect(@source.fetch_prerelease_versions).to be_truthy
|
36
|
+
end
|
37
|
+
|
28
38
|
it 'should fetch gem' do
|
29
39
|
Struct.new('FetchGem', :body)
|
30
40
|
result = Struct::FetchGem.new(true)
|
@@ -5,6 +5,8 @@ require 'gemirro/versions_fetcher'
|
|
5
5
|
# VersionsFetcher tests
|
6
6
|
module Gemirro
|
7
7
|
describe 'VersionsFetcher' do
|
8
|
+
include FakeFS::SpecHelpers
|
9
|
+
|
8
10
|
before(:each) do
|
9
11
|
@source = Source.new('RubyGems', 'https://rubygems.org')
|
10
12
|
@fetcher = VersionsFetcher.new(@source)
|
@@ -15,11 +17,11 @@ module Gemirro
|
|
15
17
|
end
|
16
18
|
|
17
19
|
it 'should fetch versions' do
|
18
|
-
allow(Gemirro.configuration.logger).to receive(:info)
|
19
|
-
.once.with("Updating #{@source.name} (#{@source.host})")
|
20
20
|
allow(@source).to receive(:fetch_versions).once.and_return([])
|
21
21
|
allow(@source).to receive(:fetch_prerelease_versions).once.and_return([])
|
22
|
-
allow(VersionsFile).to receive(:load).with(
|
22
|
+
allow(VersionsFile).to receive(:load).with('nothing', 'nothing')
|
23
|
+
allow(File).to receive(:write).twice
|
24
|
+
allow(File).to receive(:read).twice.and_return('nothing')
|
23
25
|
expect(@fetcher.fetch).to be_nil
|
24
26
|
end
|
25
27
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gemirro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pierre Rambaud
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-11-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: slop
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '1.6'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pmap
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.0'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: rake
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -196,6 +210,7 @@ files:
|
|
196
210
|
- bin/gemirro
|
197
211
|
- gemirro.gemspec
|
198
212
|
- lib/gemirro.rb
|
213
|
+
- lib/gemirro/cache.rb
|
199
214
|
- lib/gemirro/cli.rb
|
200
215
|
- lib/gemirro/cli/index.rb
|
201
216
|
- lib/gemirro/cli/init.rb
|