gemirro 1.6.0 → 3.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 +1 -1
- data/.gitignore +2 -0
- data/.rubocop.yml +3 -1
- data/Gemfile +2 -1
- data/Gemfile.lock +73 -61
- data/MANIFEST +0 -3
- data/bin/gemirro +1 -8
- data/gemirro.gemspec +4 -6
- data/lib/gemirro/cli/index.rb +48 -27
- data/lib/gemirro/cli/init.rb +48 -29
- data/lib/gemirro/cli/list.rb +37 -17
- data/lib/gemirro/cli/server.rb +173 -114
- data/lib/gemirro/cli/update.rb +42 -17
- data/lib/gemirro/cli.rb +64 -21
- data/lib/gemirro/configuration.rb +26 -20
- data/lib/gemirro/gem_version.rb +1 -0
- data/lib/gemirro/gem_version_collection.rb +4 -4
- data/lib/gemirro/gems_fetcher.rb +9 -9
- data/lib/gemirro/http.rb +115 -41
- data/lib/gemirro/indexer.rb +33 -232
- data/lib/gemirro/mirror_file.rb +3 -10
- data/lib/gemirro/server.rb +12 -43
- data/lib/gemirro/source.rb +2 -15
- data/lib/gemirro/utils.rb +22 -12
- data/lib/gemirro/version.rb +1 -1
- data/lib/gemirro/versions_fetcher.rb +7 -12
- data/lib/gemirro/versions_file.rb +26 -24
- data/lib/gemirro.rb +3 -7
- data/spec/gemirro/cli_spec.rb +49 -15
- data/spec/gemirro/configuration_spec.rb +9 -2
- data/spec/gemirro/gems_fetcher_spec.rb +2 -2
- data/spec/gemirro/http_spec.rb +58 -54
- data/spec/gemirro/indexer_spec.rb +5 -5
- data/spec/gemirro/server_spec.rb +30 -52
- data/spec/gemirro/source_spec.rb +2 -10
- data/spec/gemirro/versions_fetcher_spec.rb +3 -4
- data/spec/gemirro/versions_file_spec.rb +8 -32
- data/template/config.rb +1 -1
- metadata +29 -69
- data/template/public/latest_specs.4.8 +0 -0
- data/template/public/prerelease_specs.4.8 +0 -0
- data/template/public/specs.4.8 +0 -0
data/lib/gemirro/cli/server.rb
CHANGED
|
@@ -1,119 +1,178 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
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
|
-
|
|
3
|
+
require 'timeout'
|
|
4
|
+
|
|
5
|
+
module Gemirro
|
|
6
|
+
module CLI
|
|
7
|
+
# `gemirro server` command
|
|
8
|
+
module ServerCommand
|
|
9
|
+
##
|
|
10
|
+
# @param [Array] argv
|
|
11
|
+
#
|
|
12
|
+
def self.run(argv)
|
|
13
|
+
options = {}
|
|
14
|
+
option_parser(options).parse!(argv)
|
|
15
|
+
|
|
16
|
+
config = load_configuration(options)
|
|
17
|
+
pid_file = pid_file_for(config)
|
|
18
|
+
|
|
19
|
+
start(pid_file) if options[:start]
|
|
20
|
+
stop(pid_file) if options[:stop]
|
|
21
|
+
restart(pid_file) if options[:restart]
|
|
22
|
+
status(pid_file) if options[:status]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
##
|
|
26
|
+
# @param [Hash] options
|
|
27
|
+
# @return [Gemirro::Configuration]
|
|
28
|
+
#
|
|
29
|
+
def self.load_configuration(options)
|
|
30
|
+
Gemirro::CLI.load_configuration(options[:config])
|
|
31
|
+
config = Gemirro.configuration
|
|
32
|
+
config.logger_level = options[:log_level] if options[:log_level]
|
|
33
|
+
Gemirro::CLI.ensure_destination!(config)
|
|
34
|
+
require 'gemirro/server'
|
|
35
|
+
|
|
36
|
+
config
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
##
|
|
40
|
+
# @param [Gemirro::Configuration] config
|
|
41
|
+
# @return [String]
|
|
42
|
+
#
|
|
43
|
+
def self.pid_file_for(config)
|
|
44
|
+
File.expand_path(File.join(config.destination, '..', 'gemirro.pid'))
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
##
|
|
48
|
+
# @param [String] pid_file
|
|
49
|
+
# @param [IO] orig_stdout
|
|
50
|
+
#
|
|
51
|
+
def self.create_pid(pid_file, orig_stdout)
|
|
52
|
+
File.write(pid_file, Process.pid.to_s)
|
|
53
|
+
rescue Errno::EACCES
|
|
54
|
+
$stdout.reopen orig_stdout
|
|
55
|
+
puts "Error: Can't write to #{pid_file} - Permission denied"
|
|
56
|
+
exit!
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
##
|
|
60
|
+
# @param [String] pid_file
|
|
61
|
+
#
|
|
62
|
+
def self.destroy_pid(pid_file)
|
|
63
|
+
File.delete(pid_file) if File.exist?(pid_file) && pid(pid_file) == Process.pid
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
##
|
|
67
|
+
# @param [String] pid_file
|
|
68
|
+
# @return [Integer]
|
|
69
|
+
#
|
|
70
|
+
def self.pid(pid_file)
|
|
71
|
+
File.open(pid_file, 'r') do |f|
|
|
72
|
+
return f.gets.to_i
|
|
73
|
+
end
|
|
74
|
+
rescue Errno::ENOENT
|
|
75
|
+
puts "Error: PID File not found #{pid_file}"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
##
|
|
79
|
+
# @param [String] pid_file
|
|
80
|
+
#
|
|
81
|
+
def self.start(pid_file)
|
|
82
|
+
puts 'Starting...'
|
|
83
|
+
if File.exist?(pid_file) && running?(pid(pid_file))
|
|
84
|
+
puts "Error: #{$PROGRAM_NAME} already running"
|
|
85
|
+
abort
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Copy stdout because we'll need to reopen it later on
|
|
89
|
+
orig_stdout = $stdout.clone
|
|
90
|
+
|
|
91
|
+
Process.daemon if Gemirro::Utils.configuration.server.daemonize
|
|
92
|
+
create_pid(pid_file, orig_stdout)
|
|
93
|
+
$stdout.reopen orig_stdout
|
|
94
|
+
puts "done! (PID is #{pid(pid_file)})\n"
|
|
95
|
+
Gemirro::Server.run!
|
|
96
|
+
destroy_pid(pid_file)
|
|
97
|
+
$stdout.reopen File::NULL, 'a'
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
##
|
|
101
|
+
# @param [String] pid_file
|
|
102
|
+
#
|
|
103
|
+
def self.stop(pid_file)
|
|
104
|
+
process_pid = pid(pid_file)
|
|
105
|
+
return if process_pid.nil?
|
|
106
|
+
|
|
107
|
+
begin
|
|
108
|
+
Process.kill('TERM', process_pid)
|
|
109
|
+
Timeout.timeout(30) { sleep 0.1 while running?(process_pid) }
|
|
110
|
+
rescue Errno::ESRCH
|
|
111
|
+
puts "Error: Couldn't find process with PID #{process_pid}"
|
|
112
|
+
exit!
|
|
113
|
+
rescue Timeout::Error
|
|
114
|
+
puts 'timeout while sending TERM signal, sending KILL signal now... '
|
|
115
|
+
Process.kill('KILL', process_pid)
|
|
116
|
+
destroy_pid(pid_file)
|
|
117
|
+
end
|
|
118
|
+
puts 'done!'
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
##
|
|
122
|
+
# @param [String] pid_file
|
|
123
|
+
#
|
|
124
|
+
def self.restart(pid_file)
|
|
125
|
+
stop(pid_file)
|
|
126
|
+
start(pid_file)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
##
|
|
130
|
+
# @param [String] pid_file
|
|
131
|
+
#
|
|
132
|
+
def self.status(pid_file)
|
|
133
|
+
if running?(pid(pid_file))
|
|
134
|
+
puts "#{$PROGRAM_NAME} is running"
|
|
135
|
+
else
|
|
136
|
+
puts "#{$PROGRAM_NAME} is not running"
|
|
137
|
+
abort
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
##
|
|
142
|
+
# @param [Integer] process_id
|
|
143
|
+
# @return [TrueClass|FalseClass]
|
|
144
|
+
#
|
|
145
|
+
def self.running?(process_id)
|
|
146
|
+
return false if process_id.nil?
|
|
147
|
+
|
|
148
|
+
Process.getpgid(process_id.to_i) != -1
|
|
149
|
+
rescue Errno::ESRCH
|
|
150
|
+
false
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
##
|
|
154
|
+
# @param [Hash] options
|
|
155
|
+
# @return [OptionParser]
|
|
156
|
+
#
|
|
157
|
+
def self.option_parser(options)
|
|
158
|
+
OptionParser.new do |opts|
|
|
159
|
+
opts.banner = 'Usage: gemirro server [OPTIONS]'
|
|
160
|
+
opts.separator ''
|
|
161
|
+
opts.separator 'Options:'
|
|
162
|
+
opts.separator ''
|
|
163
|
+
|
|
164
|
+
opts.on('--start', 'Run web server') { options[:start] = true }
|
|
165
|
+
opts.on('--stop', 'Stop web server') { options[:stop] = true }
|
|
166
|
+
opts.on('--restart', 'Restart web server') { options[:restart] = true }
|
|
167
|
+
opts.on('--status', 'Status of web server') { options[:status] = true }
|
|
168
|
+
opts.on('-c', '--config CONFIG', 'Path to the configuration file') { |v| options[:config] = v }
|
|
169
|
+
opts.on('-l', '--log_level LEVEL', 'Set logger level') { |v| options[:log_level] = v }
|
|
170
|
+
opts.on('-h', '--help', 'Display this help message.') do
|
|
171
|
+
puts opts
|
|
172
|
+
exit
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
69
176
|
end
|
|
70
|
-
|
|
71
|
-
Process.daemon if Gemirro::Utils.configuration.server.daemonize
|
|
72
|
-
create_pid
|
|
73
|
-
$stdout.reopen @orig_stdout
|
|
74
|
-
puts "done! (PID is #{pid})\n"
|
|
75
|
-
Gemirro::Server.run!
|
|
76
|
-
destroy_pid
|
|
77
|
-
$stdout.reopen File::NULL, 'a'
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def stop
|
|
81
|
-
process_pid = pid
|
|
82
|
-
return if process_pid.nil?
|
|
83
|
-
|
|
84
|
-
begin
|
|
85
|
-
Process.kill('TERM', process_pid)
|
|
86
|
-
Timeout.timeout(30) { sleep 0.1 while running?(process_pid) }
|
|
87
|
-
rescue Errno::ESRCH
|
|
88
|
-
puts "Error: Couldn't find process with PID #{process_pid}"
|
|
89
|
-
exit!
|
|
90
|
-
rescue Timeout::Error
|
|
91
|
-
puts 'timeout while sending TERM signal, sending KILL signal now... '
|
|
92
|
-
Process.kill('KILL', process_pid)
|
|
93
|
-
destroy_pid
|
|
94
|
-
end
|
|
95
|
-
puts 'done!'
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def restart
|
|
99
|
-
stop
|
|
100
|
-
start
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def status
|
|
104
|
-
if running?(pid)
|
|
105
|
-
puts "#{$PROGRAM_NAME} is running"
|
|
106
|
-
else
|
|
107
|
-
puts "#{$PROGRAM_NAME} is not running"
|
|
108
|
-
abort
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
def running?(process_id)
|
|
113
|
-
return false if process_id.nil?
|
|
114
|
-
|
|
115
|
-
Process.getpgid(process_id.to_i) != -1
|
|
116
|
-
rescue Errno::ESRCH
|
|
117
|
-
false
|
|
118
177
|
end
|
|
119
178
|
end
|
data/lib/gemirro/cli/update.rb
CHANGED
|
@@ -1,27 +1,52 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
Gemirro
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
module Gemirro
|
|
4
|
+
module CLI
|
|
5
|
+
# `gemirro update` command
|
|
6
|
+
module UpdateCommand
|
|
7
|
+
##
|
|
8
|
+
# @param [Array] argv
|
|
9
|
+
#
|
|
10
|
+
def self.run(argv)
|
|
11
|
+
options = {}
|
|
12
|
+
option_parser(options).parse!(argv)
|
|
7
13
|
|
|
8
|
-
|
|
9
|
-
|
|
14
|
+
Gemirro::CLI.load_configuration(options[:config])
|
|
15
|
+
config = Gemirro.configuration
|
|
16
|
+
config.logger_level = options[:log_level] if options[:log_level]
|
|
10
17
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
18
|
+
source = config.source
|
|
19
|
+
versions = Gemirro::VersionsFetcher.new(source).fetch
|
|
20
|
+
gems = Gemirro::GemsFetcher.new(source, versions)
|
|
14
21
|
|
|
15
|
-
|
|
16
|
-
versions = Gemirro::VersionsFetcher.new(source).fetch
|
|
17
|
-
gems = Gemirro::GemsFetcher.new(source, versions)
|
|
22
|
+
gems.fetch
|
|
18
23
|
|
|
19
|
-
|
|
24
|
+
source.gems.each do |gem|
|
|
25
|
+
gem.gemspec = true
|
|
26
|
+
end
|
|
20
27
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
28
|
+
gems.fetch
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
# @param [Hash] options
|
|
33
|
+
# @return [OptionParser]
|
|
34
|
+
#
|
|
35
|
+
def self.option_parser(options)
|
|
36
|
+
OptionParser.new do |opts|
|
|
37
|
+
opts.banner = 'Usage: gemirro update [OPTIONS]'
|
|
38
|
+
opts.separator ''
|
|
39
|
+
opts.separator 'Options:'
|
|
40
|
+
opts.separator ''
|
|
24
41
|
|
|
25
|
-
|
|
42
|
+
opts.on('-c', '--config CONFIG', 'Path to the configuration file') { |v| options[:config] = v }
|
|
43
|
+
opts.on('-l', '--log_level LEVEL', 'Set logger level') { |v| options[:log_level] = v }
|
|
44
|
+
opts.on('-h', '--help', 'Display this help message.') do
|
|
45
|
+
puts opts
|
|
46
|
+
exit
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
26
51
|
end
|
|
27
52
|
end
|
data/lib/gemirro/cli.rb
CHANGED
|
@@ -1,24 +1,67 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require File.expand_path('../version', __FILE__)
|
|
4
|
+
|
|
3
5
|
module Gemirro
|
|
4
6
|
# CLI mode
|
|
5
7
|
module CLI
|
|
6
8
|
##
|
|
7
|
-
#
|
|
9
|
+
# Names of the commands available, in the order they're listed by
|
|
10
|
+
# `--help`, together with a short description.
|
|
8
11
|
#
|
|
9
12
|
# @return [Hash]
|
|
10
13
|
#
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
COMMANDS = {
|
|
15
|
+
'index' => 'Retrieve specs list from source.',
|
|
16
|
+
'init' => 'Sets up a new mirror',
|
|
17
|
+
'list' => 'List available gems.',
|
|
18
|
+
'server' => 'Manage web server',
|
|
19
|
+
'update' => 'Updates the list of Gems'
|
|
15
20
|
}.freeze
|
|
16
21
|
|
|
17
22
|
##
|
|
18
|
-
#
|
|
23
|
+
# Entry point, called from `bin/gemirro`.
|
|
24
|
+
#
|
|
25
|
+
# @param [Array] argv
|
|
19
26
|
#
|
|
20
|
-
def self.
|
|
21
|
-
|
|
27
|
+
def self.run(argv = ARGV)
|
|
28
|
+
$PROGRAM_NAME = 'gemirro'
|
|
29
|
+
command = argv.first
|
|
30
|
+
case command
|
|
31
|
+
when '-v', '--version'
|
|
32
|
+
puts version_information
|
|
33
|
+
when '-h', '--help', nil
|
|
34
|
+
puts usage
|
|
35
|
+
when *COMMANDS.keys
|
|
36
|
+
argv.shift
|
|
37
|
+
require "gemirro/cli/#{command}"
|
|
38
|
+
const_get("#{command.capitalize}Command").run(argv)
|
|
39
|
+
else
|
|
40
|
+
puts "Unknown command: #{command}"
|
|
41
|
+
puts usage
|
|
42
|
+
exit 1
|
|
43
|
+
end
|
|
44
|
+
rescue OptionParser::ParseError => e
|
|
45
|
+
puts e.message
|
|
46
|
+
exit 1
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
##
|
|
50
|
+
# Returns a String containing the top level usage/help banner.
|
|
51
|
+
#
|
|
52
|
+
# @return [String]
|
|
53
|
+
#
|
|
54
|
+
def self.usage
|
|
55
|
+
lines = ['Usage: gemirro [COMMAND] [OPTIONS]', '', 'Options:', '']
|
|
56
|
+
lines << ' -v, --version Shows the current version'
|
|
57
|
+
lines << ' -h, --help Display this help message.'
|
|
58
|
+
lines << '' << 'Available commands:' << ''
|
|
59
|
+
COMMANDS.each do |name, description|
|
|
60
|
+
lines << " #{name.ljust(9)}#{description}"
|
|
61
|
+
end
|
|
62
|
+
lines << '' << 'See `<command> --help` for more information on a specific command.'
|
|
63
|
+
|
|
64
|
+
lines.join("\n")
|
|
22
65
|
end
|
|
23
66
|
|
|
24
67
|
##
|
|
@@ -40,25 +83,25 @@ module Gemirro
|
|
|
40
83
|
end
|
|
41
84
|
|
|
42
85
|
##
|
|
43
|
-
#
|
|
86
|
+
# Returns a String containing some platform/version related information.
|
|
44
87
|
#
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
on :v, :version, 'Shows the current version' do
|
|
50
|
-
puts CLI.version_information
|
|
51
|
-
end
|
|
52
|
-
end
|
|
88
|
+
# @return [String]
|
|
89
|
+
#
|
|
90
|
+
def self.version_information
|
|
91
|
+
"gemirro v#{Gemirro::VERSION} on #{RUBY_DESCRIPTION}"
|
|
53
92
|
end
|
|
54
93
|
|
|
55
94
|
##
|
|
56
|
-
#
|
|
95
|
+
# Aborts with an error if the configured destination directory
|
|
96
|
+
# doesn't exist yet.
|
|
57
97
|
#
|
|
58
|
-
# @
|
|
98
|
+
# @param [Gemirro::Configuration] config
|
|
59
99
|
#
|
|
60
|
-
def self.
|
|
61
|
-
|
|
100
|
+
def self.ensure_destination!(config)
|
|
101
|
+
return if File.directory?(config.destination)
|
|
102
|
+
|
|
103
|
+
config.logger.error("The directory #{config.destination} does not exist")
|
|
104
|
+
abort
|
|
62
105
|
end
|
|
63
106
|
end
|
|
64
107
|
end
|
|
@@ -99,18 +99,10 @@ module Gemirro
|
|
|
99
99
|
#
|
|
100
100
|
# @return [String]
|
|
101
101
|
#
|
|
102
|
-
def
|
|
103
|
-
|
|
104
|
-
end
|
|
102
|
+
def versions_file
|
|
103
|
+
return unless @source
|
|
105
104
|
|
|
106
|
-
|
|
107
|
-
# Returns the name of the file that contains an index
|
|
108
|
-
# of all the prerelease versions.
|
|
109
|
-
#
|
|
110
|
-
# @return [String]
|
|
111
|
-
#
|
|
112
|
-
def self.prerelease_versions_file
|
|
113
|
-
"prerelease_specs.#{marshal_version}.gz"
|
|
105
|
+
File.expand_path("#{URI.parse(@source.host).host.gsub('.', '_')}_versions", destination.to_s)
|
|
114
106
|
end
|
|
115
107
|
|
|
116
108
|
##
|
|
@@ -174,9 +166,11 @@ module Gemirro
|
|
|
174
166
|
# @param [String] version
|
|
175
167
|
#
|
|
176
168
|
def ignore_gem(name, version, platform)
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
169
|
+
ignored_gems_mutex.synchronize do
|
|
170
|
+
ignored_gems[platform] ||= {}
|
|
171
|
+
ignored_gems[platform][name] ||= []
|
|
172
|
+
ignored_gems[platform][name] << version
|
|
173
|
+
end
|
|
180
174
|
end
|
|
181
175
|
|
|
182
176
|
##
|
|
@@ -187,13 +181,25 @@ module Gemirro
|
|
|
187
181
|
# @return [TrueClass|FalseClass]
|
|
188
182
|
#
|
|
189
183
|
def ignore_gem?(name, version, platform)
|
|
190
|
-
|
|
191
|
-
ignored_gems[platform][name]
|
|
192
|
-
|
|
193
|
-
|
|
184
|
+
ignored_gems_mutex.synchronize do
|
|
185
|
+
if ignored_gems[platform][name]
|
|
186
|
+
ignored_gems[platform][name].include?(version)
|
|
187
|
+
else
|
|
188
|
+
false
|
|
189
|
+
end
|
|
194
190
|
end
|
|
195
191
|
end
|
|
196
192
|
|
|
193
|
+
##
|
|
194
|
+
# Guards {#ignored_gems} against concurrent mutation, since gems can
|
|
195
|
+
# be fetched from multiple threads at once (see {GemsFetcher#fetch}).
|
|
196
|
+
#
|
|
197
|
+
# @return [Mutex]
|
|
198
|
+
#
|
|
199
|
+
def ignored_gems_mutex
|
|
200
|
+
@ignored_gems_mutex ||= Mutex.new
|
|
201
|
+
end
|
|
202
|
+
|
|
197
203
|
##
|
|
198
204
|
# Define the source to mirror.
|
|
199
205
|
#
|
|
@@ -201,9 +207,9 @@ module Gemirro
|
|
|
201
207
|
# @param [String] url
|
|
202
208
|
# @param [Proc] block
|
|
203
209
|
#
|
|
204
|
-
def define_source(name, url, &
|
|
210
|
+
def define_source(name, url, &)
|
|
205
211
|
source = Source.new(name, url)
|
|
206
|
-
source.instance_eval(&
|
|
212
|
+
source.instance_eval(&)
|
|
207
213
|
|
|
208
214
|
@source = source
|
|
209
215
|
end
|
data/lib/gemirro/gem_version.rb
CHANGED
|
@@ -59,8 +59,8 @@ module Gemirro
|
|
|
59
59
|
##
|
|
60
60
|
# Each method
|
|
61
61
|
#
|
|
62
|
-
def each(&
|
|
63
|
-
@gems.each(&
|
|
62
|
+
def each(&)
|
|
63
|
+
@gems.each(&)
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
##
|
|
@@ -69,7 +69,7 @@ module Gemirro
|
|
|
69
69
|
# @param [Proc] block
|
|
70
70
|
# @return [Array]
|
|
71
71
|
#
|
|
72
|
-
def by_name(&
|
|
72
|
+
def by_name(&)
|
|
73
73
|
if @grouped.nil?
|
|
74
74
|
@grouped = @gems.group_by(&:name).map do |name, collection|
|
|
75
75
|
[name, GemVersionCollection.new(collection)]
|
|
@@ -85,7 +85,7 @@ module Gemirro
|
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
if block_given?
|
|
88
|
-
@grouped.each(&
|
|
88
|
+
@grouped.each(&)
|
|
89
89
|
else
|
|
90
90
|
@grouped
|
|
91
91
|
end
|
data/lib/gemirro/gems_fetcher.rb
CHANGED
|
@@ -23,10 +23,12 @@ module Gemirro
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
##
|
|
26
|
-
# Fetches the Gems
|
|
26
|
+
# Fetches the Gems, in parallel across
|
|
27
|
+
# `Gemirro.configuration.update_thread_count` threads since each Gem is
|
|
28
|
+
# an independent network round-trip.
|
|
27
29
|
#
|
|
28
30
|
def fetch
|
|
29
|
-
@source.gems.
|
|
31
|
+
Parallel.each(@source.gems, in_threads: Utils.configuration.update_thread_count) do |gem|
|
|
30
32
|
versions_for(gem).each do |versions|
|
|
31
33
|
gem.platform = versions[1] if versions
|
|
32
34
|
version = versions[0] if versions
|
|
@@ -55,6 +57,8 @@ module Gemirro
|
|
|
55
57
|
# @return [Array]
|
|
56
58
|
#
|
|
57
59
|
def versions_for(gem)
|
|
60
|
+
return [] unless @versions_file
|
|
61
|
+
|
|
58
62
|
available = @versions_file.versions_for(gem.name)
|
|
59
63
|
return [available.last] if gem.only_latest?
|
|
60
64
|
|
|
@@ -76,11 +80,7 @@ module Gemirro
|
|
|
76
80
|
#
|
|
77
81
|
def fetch_gemspec(gem, version)
|
|
78
82
|
filename = gem.gemspec_filename(version)
|
|
79
|
-
satisfied =
|
|
80
|
-
true
|
|
81
|
-
else
|
|
82
|
-
gem.requirement.satisfied_by?(version)
|
|
83
|
-
end
|
|
83
|
+
satisfied = gem.only_latest? || gem.requirement.satisfied_by?(version)
|
|
84
84
|
|
|
85
85
|
if gemspec_exists?(filename) || !satisfied
|
|
86
86
|
Utils.logger.debug("Skipping #{filename}")
|
|
@@ -160,8 +160,8 @@ module Gemirro
|
|
|
160
160
|
##
|
|
161
161
|
# @see Gemirro::Configuration#ignore_gem?
|
|
162
162
|
#
|
|
163
|
-
def ignore_gem?(*
|
|
164
|
-
Utils.configuration.ignore_gem?(*
|
|
163
|
+
def ignore_gem?(*)
|
|
164
|
+
Utils.configuration.ignore_gem?(*)
|
|
165
165
|
end
|
|
166
166
|
end
|
|
167
167
|
end
|