gemirro 0.16.0 → 1.3.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 +5 -5
- data/.rubocop.yml +13 -6
- data/.travis.yml +1 -3
- data/Gemfile +2 -0
- data/README.md +1 -1
- data/bin/gemirro +1 -0
- data/gemirro.gemspec +12 -10
- data/lib/gemirro.rb +12 -12
- data/lib/gemirro/cache.rb +3 -0
- data/lib/gemirro/cli.rb +3 -3
- data/lib/gemirro/cli/index.rb +2 -0
- data/lib/gemirro/cli/init.rb +4 -0
- data/lib/gemirro/cli/list.rb +2 -0
- data/lib/gemirro/cli/server.rb +11 -10
- data/lib/gemirro/cli/update.rb +2 -0
- data/lib/gemirro/configuration.rb +16 -8
- data/lib/gemirro/gem.rb +7 -6
- data/lib/gemirro/gem_version.rb +2 -0
- data/lib/gemirro/gem_version_collection.rb +3 -2
- data/lib/gemirro/gems_fetcher.rb +10 -5
- data/lib/gemirro/http.rb +3 -3
- data/lib/gemirro/indexer.rb +16 -10
- data/lib/gemirro/mirror_directory.rb +2 -0
- data/lib/gemirro/mirror_file.rb +2 -0
- data/lib/gemirro/server.rb +13 -13
- data/lib/gemirro/source.rb +4 -2
- data/lib/gemirro/utils.rb +6 -1
- data/lib/gemirro/version.rb +3 -1
- data/lib/gemirro/versions_fetcher.rb +2 -0
- data/lib/gemirro/versions_file.rb +3 -1
- data/spec/gemirro/configuration_spec.rb +5 -4
- data/spec/gemirro/gems_fetcher_spec.rb +10 -8
- data/spec/gemirro/server_spec.rb +2 -2
- data/template/config.rb +4 -1
- metadata +34 -21
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: f5ce407f251612fd3198509818414c754d97508355e1fc1a723a08448bfb369f
|
|
4
|
+
data.tar.gz: 669d4d88aa1db6241b7e8861934d12893accde19fad6454d829a9e143569622b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3c49aa30264c21ca2fb840f5c4b2b6dd6058c5b587e94ff5ae4e94488a00d86f25e0a56de742c9ab8078a6350bb5f15d38119b69decfdd5088e0c8b0ff4dafa6
|
|
7
|
+
data.tar.gz: 96e25a3b96ca072f6823b8583626b9dd502048e444423af8d50ffcc9040a139daa5aa36314ce914edef2123c335015a6f8f1f758b18a62339fcfe60d3c006afa
|
data/.rubocop.yml
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
AllCops:
|
|
2
|
+
NewCops: enable
|
|
3
|
+
TargetRubyVersion: 2.5
|
|
2
4
|
Include:
|
|
3
5
|
- '**/Gemfile'
|
|
4
6
|
- lib/**/*.rb
|
|
@@ -7,16 +9,15 @@ AllCops:
|
|
|
7
9
|
Exclude:
|
|
8
10
|
- files/**/*
|
|
9
11
|
- templates/**/*
|
|
12
|
+
- spec/**/*
|
|
13
|
+
- vendor/**/*
|
|
14
|
+
|
|
10
15
|
Naming/FileName:
|
|
11
16
|
Exclude:
|
|
12
17
|
- Rakefile
|
|
13
|
-
|
|
18
|
+
Layout/MethodLength:
|
|
14
19
|
Enabled: false
|
|
15
|
-
|
|
16
|
-
Enabled: false
|
|
17
|
-
ClassLength:
|
|
18
|
-
Enabled: false
|
|
19
|
-
ParameterLists:
|
|
20
|
+
Layout/ClassLength:
|
|
20
21
|
Enabled: false
|
|
21
22
|
Metrics/CyclomaticComplexity:
|
|
22
23
|
Enabled: false
|
|
@@ -28,3 +29,9 @@ Metrics/BlockLength:
|
|
|
28
29
|
Enabled: false
|
|
29
30
|
Security/MarshalLoad:
|
|
30
31
|
Enabled: false
|
|
32
|
+
Style/ExpandPathArguments:
|
|
33
|
+
Enabled: false
|
|
34
|
+
Style/OptionalBooleanParameter:
|
|
35
|
+
Enabled: false
|
|
36
|
+
Lint/MissingSuper:
|
|
37
|
+
Enabled: false
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
data/bin/gemirro
CHANGED
data/gemirro.gemspec
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'date'
|
|
2
4
|
require File.expand_path('../lib/gemirro/version', __FILE__)
|
|
3
5
|
|
|
4
6
|
Gem::Specification.new do |s|
|
|
5
7
|
s.name = 'gemirro'
|
|
6
8
|
s.version = Gemirro::VERSION
|
|
7
|
-
s.date = Date.today.to_s
|
|
8
9
|
s.authors = ['Pierre Rambaud']
|
|
9
10
|
s.email = 'pierre.rambaud86@gmail.com'
|
|
10
11
|
s.license = 'GPL-3.0'
|
|
@@ -15,21 +16,22 @@ Gem::Specification.new do |s|
|
|
|
15
16
|
|
|
16
17
|
s.files = File.read(File.expand_path('../MANIFEST', __FILE__)).split("\n")
|
|
17
18
|
|
|
18
|
-
s.required_ruby_version = '>=
|
|
19
|
+
s.required_ruby_version = '>= 2.5'
|
|
19
20
|
|
|
21
|
+
s.add_dependency 'addressable', '~>2.5'
|
|
20
22
|
s.add_dependency 'builder', '~>3.2'
|
|
21
23
|
s.add_dependency 'confstruct', '~>1.0'
|
|
22
24
|
s.add_dependency 'erubis', '~>2.7'
|
|
23
25
|
s.add_dependency 'httpclient', '~>2.8'
|
|
24
|
-
s.add_dependency 'parallel', '~>1.
|
|
25
|
-
s.add_dependency 'sinatra', '~>2.0'
|
|
26
|
+
s.add_dependency 'parallel', '~>1.20'
|
|
27
|
+
s.add_dependency 'sinatra', '~>2.0.1'
|
|
26
28
|
s.add_dependency 'slop', '~>3.6'
|
|
27
29
|
s.add_dependency 'thin', '~>1.7'
|
|
28
30
|
|
|
29
|
-
s.add_development_dependency 'fakefs', '~>
|
|
30
|
-
s.add_development_dependency 'rack-test', '~>
|
|
31
|
-
s.add_development_dependency 'rake', '~>
|
|
32
|
-
s.add_development_dependency 'rspec', '~>3.
|
|
33
|
-
s.add_development_dependency 'rubocop', '~>
|
|
34
|
-
s.add_development_dependency 'simplecov', '~>0.
|
|
31
|
+
s.add_development_dependency 'fakefs', '~>1'
|
|
32
|
+
s.add_development_dependency 'rack-test', '~>1.1'
|
|
33
|
+
s.add_development_dependency 'rake', '~>13'
|
|
34
|
+
s.add_development_dependency 'rspec', '~>3.10'
|
|
35
|
+
s.add_development_dependency 'rubocop', '~>1'
|
|
36
|
+
s.add_development_dependency 'simplecov', '~>0.21'
|
|
35
37
|
end
|
data/lib/gemirro.rb
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require 'rubygems/indexer'
|
|
4
|
-
require 'slop'
|
|
5
|
-
require 'fileutils'
|
|
6
|
-
require 'digest/sha2'
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
7
3
|
require 'confstruct'
|
|
8
|
-
require '
|
|
4
|
+
require 'digest/sha2'
|
|
5
|
+
require 'fileutils'
|
|
9
6
|
require 'httpclient'
|
|
10
|
-
require 'logger'
|
|
11
|
-
require 'stringio'
|
|
12
7
|
require 'json'
|
|
8
|
+
require 'logger'
|
|
13
9
|
require 'parallel'
|
|
10
|
+
require 'rubygems'
|
|
11
|
+
require 'rubygems/indexer'
|
|
12
|
+
require 'rubygems/user_interaction'
|
|
13
|
+
require 'slop'
|
|
14
|
+
require 'stringio'
|
|
14
15
|
require 'tempfile'
|
|
16
|
+
require 'zlib'
|
|
15
17
|
|
|
16
|
-
unless $LOAD_PATH.include?(File.expand_path('../', __FILE__))
|
|
17
|
-
$LOAD_PATH.unshift(File.expand_path('../', __FILE__))
|
|
18
|
-
end
|
|
18
|
+
$LOAD_PATH.unshift(File.expand_path('../', __FILE__)) unless $LOAD_PATH.include?(File.expand_path('../', __FILE__))
|
|
19
19
|
|
|
20
20
|
require 'gemirro/version'
|
|
21
21
|
require 'gemirro/configuration'
|
data/lib/gemirro/cache.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Gemirro
|
|
2
4
|
##
|
|
3
5
|
# The Cache class contains all method to store marshal informations
|
|
@@ -102,6 +104,7 @@ module Gemirro
|
|
|
102
104
|
#
|
|
103
105
|
def write(key_hash, value)
|
|
104
106
|
return value if value.nil? || value.empty?
|
|
107
|
+
|
|
105
108
|
File.open(key_path(key_hash), 'wb') do |f|
|
|
106
109
|
Marshal.dump(value, f)
|
|
107
110
|
end
|
data/lib/gemirro/cli.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Gemirro
|
|
2
4
|
# CLI mode
|
|
3
5
|
module CLI
|
|
@@ -32,9 +34,7 @@ module Gemirro
|
|
|
32
34
|
config_file += '/config.rb' unless config_file.end_with?('.rb') ||
|
|
33
35
|
!File.directory?(config_file)
|
|
34
36
|
|
|
35
|
-
unless File.file?(config_file)
|
|
36
|
-
abort "The configuration file #{config_file} does not exist"
|
|
37
|
-
end
|
|
37
|
+
abort "The configuration file #{config_file} does not exist" unless File.file?(config_file)
|
|
38
38
|
|
|
39
39
|
require(config_file)
|
|
40
40
|
end
|
data/lib/gemirro/cli/index.rb
CHANGED
data/lib/gemirro/cli/init.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
Gemirro::CLI.options.command 'init' do
|
|
2
4
|
banner 'Usage: gemirro init [DIRECTORY] [OPTIONS]'
|
|
3
5
|
description 'Sets up a new mirror'
|
|
@@ -16,8 +18,10 @@ Gemirro::CLI.options.command 'init' do
|
|
|
16
18
|
else
|
|
17
19
|
Dir.glob("#{template}/**/*", File::FNM_DOTMATCH).each do |file|
|
|
18
20
|
next if ['.', '..'].include?(File.basename(file))
|
|
21
|
+
|
|
19
22
|
dest = File.join(directory, file.gsub(/^#{template}/, ''))
|
|
20
23
|
next if File.exist?(dest)
|
|
24
|
+
|
|
21
25
|
FileUtils.cp_r(file, dest)
|
|
22
26
|
end
|
|
23
27
|
end
|
data/lib/gemirro/cli/list.rb
CHANGED
data/lib/gemirro/cli/server.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
Gemirro::CLI.options.command 'server' do
|
|
2
4
|
banner 'Usage: gemirro server [OPTIONS]'
|
|
3
5
|
description 'Manage web server'
|
|
@@ -36,7 +38,7 @@ Gemirro::CLI.options.command 'server' do
|
|
|
36
38
|
end
|
|
37
39
|
|
|
38
40
|
# Copy stdout because we'll need to reopen it later on
|
|
39
|
-
@orig_stdout =
|
|
41
|
+
@orig_stdout = $stdout.clone
|
|
40
42
|
$PROGRAM_NAME = 'gemirro'
|
|
41
43
|
|
|
42
44
|
def create_pid
|
|
@@ -44,7 +46,7 @@ Gemirro::CLI.options.command 'server' do
|
|
|
44
46
|
f.write(Process.pid.to_s)
|
|
45
47
|
end
|
|
46
48
|
rescue Errno::EACCES
|
|
47
|
-
|
|
49
|
+
$stdout.reopen @orig_stdout
|
|
48
50
|
puts "Error: Can't write to #{@pid_file} - Permission denied"
|
|
49
51
|
exit!
|
|
50
52
|
end
|
|
@@ -63,20 +65,18 @@ Gemirro::CLI.options.command 'server' do
|
|
|
63
65
|
|
|
64
66
|
def start
|
|
65
67
|
puts 'Starting...'
|
|
66
|
-
if File.exist?(@pid_file)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
abort
|
|
70
|
-
end
|
|
68
|
+
if File.exist?(@pid_file) && running?(pid)
|
|
69
|
+
puts "Error: #{$PROGRAM_NAME} already running"
|
|
70
|
+
abort
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
-
Process.daemon
|
|
73
|
+
Process.daemon if Gemirro::Utils.configuration.server.daemonize
|
|
74
74
|
create_pid
|
|
75
|
-
|
|
75
|
+
$stdout.reopen @orig_stdout
|
|
76
76
|
puts "done! (PID is #{pid})\n"
|
|
77
77
|
Gemirro::Server.run!
|
|
78
78
|
destroy_pid
|
|
79
|
-
|
|
79
|
+
$stdout.reopen '/dev/null', 'a'
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
def stop
|
|
@@ -113,6 +113,7 @@ Gemirro::CLI.options.command 'server' do
|
|
|
113
113
|
|
|
114
114
|
def running?(process_id)
|
|
115
115
|
return false if process_id.nil?
|
|
116
|
+
|
|
116
117
|
Process.getpgid(process_id.to_i) != -1
|
|
117
118
|
rescue Errno::ESRCH
|
|
118
119
|
false
|
data/lib/gemirro/cli/update.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# Configuration
|
|
2
4
|
module Gemirro
|
|
3
5
|
##
|
|
@@ -7,7 +9,8 @@ module Gemirro
|
|
|
7
9
|
default_config = {
|
|
8
10
|
server: {
|
|
9
11
|
access_log: '/tmp/gemirro.access.log',
|
|
10
|
-
error_log: '/tmp/gemirro.access.log'
|
|
12
|
+
error_log: '/tmp/gemirro.access.log',
|
|
13
|
+
daemonize: true
|
|
11
14
|
},
|
|
12
15
|
|
|
13
16
|
update_on_fetch: true,
|
|
@@ -39,7 +42,7 @@ module Gemirro
|
|
|
39
42
|
# @return [Logger]
|
|
40
43
|
#
|
|
41
44
|
def logger
|
|
42
|
-
@logger ||= Logger.new(
|
|
45
|
+
@logger ||= Logger.new($stdout)
|
|
43
46
|
end
|
|
44
47
|
|
|
45
48
|
##
|
|
@@ -161,7 +164,7 @@ module Gemirro
|
|
|
161
164
|
# @return [Hash]
|
|
162
165
|
#
|
|
163
166
|
def ignored_gems
|
|
164
|
-
@ignored_gems ||= Hash.new { |hash, key| hash[key] =
|
|
167
|
+
@ignored_gems ||= Hash.new { |hash, key| hash[key] = {} }
|
|
165
168
|
end
|
|
166
169
|
|
|
167
170
|
##
|
|
@@ -170,9 +173,10 @@ module Gemirro
|
|
|
170
173
|
# @param [String] name
|
|
171
174
|
# @param [String] version
|
|
172
175
|
#
|
|
173
|
-
def ignore_gem(name, version)
|
|
174
|
-
ignored_gems[
|
|
175
|
-
ignored_gems[name]
|
|
176
|
+
def ignore_gem(name, version, platform)
|
|
177
|
+
ignored_gems[platform] ||= {}
|
|
178
|
+
ignored_gems[platform][name] ||= []
|
|
179
|
+
ignored_gems[platform][name] << version
|
|
176
180
|
end
|
|
177
181
|
|
|
178
182
|
##
|
|
@@ -182,8 +186,12 @@ module Gemirro
|
|
|
182
186
|
# @param [String] version
|
|
183
187
|
# @return [TrueClass|FalseClass]
|
|
184
188
|
#
|
|
185
|
-
def ignore_gem?(name, version)
|
|
186
|
-
ignored_gems[name]
|
|
189
|
+
def ignore_gem?(name, version, platform)
|
|
190
|
+
if ignored_gems[platform][name]
|
|
191
|
+
ignored_gems[platform][name].include?(version)
|
|
192
|
+
else
|
|
193
|
+
false
|
|
194
|
+
end
|
|
187
195
|
end
|
|
188
196
|
|
|
189
197
|
##
|
data/lib/gemirro/gem.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Gemirro
|
|
2
4
|
##
|
|
3
5
|
# The Gem class contains data about a Gem such as the name, requirement as
|
|
@@ -12,8 +14,9 @@ module Gemirro
|
|
|
12
14
|
# @return [Gem::Version]
|
|
13
15
|
#
|
|
14
16
|
class Gem
|
|
15
|
-
attr_reader :name, :requirement
|
|
16
|
-
attr_accessor :gemspec
|
|
17
|
+
attr_reader :name, :requirement
|
|
18
|
+
attr_accessor :gemspec, :platform
|
|
19
|
+
|
|
17
20
|
ONLY_LATEST = %i[latest newest].freeze
|
|
18
21
|
|
|
19
22
|
##
|
|
@@ -23,7 +26,7 @@ module Gemirro
|
|
|
23
26
|
# @return [Gem::Version]
|
|
24
27
|
#
|
|
25
28
|
def self.version_for(requirement)
|
|
26
|
-
::Gem::Version.new(requirement.requirements.
|
|
29
|
+
::Gem::Version.new(requirement.requirements.max.last.version)
|
|
27
30
|
end
|
|
28
31
|
|
|
29
32
|
##
|
|
@@ -33,9 +36,7 @@ module Gemirro
|
|
|
33
36
|
def initialize(name, requirement = nil, platform = 'ruby')
|
|
34
37
|
requirement ||= ::Gem::Requirement.default
|
|
35
38
|
|
|
36
|
-
if requirement.is_a?(String)
|
|
37
|
-
requirement = ::Gem::Requirement.new(requirement)
|
|
38
|
-
end
|
|
39
|
+
requirement = ::Gem::Requirement.new(requirement) if requirement.is_a?(String)
|
|
39
40
|
|
|
40
41
|
@name = name
|
|
41
42
|
@requirement = requirement
|
data/lib/gemirro/gem_version.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Gemirro
|
|
2
4
|
##
|
|
3
5
|
# The VersionCollection class contains a collection of ::Gem::Version
|
|
@@ -10,8 +12,7 @@ module Gemirro
|
|
|
10
12
|
class GemVersionCollection
|
|
11
13
|
include Enumerable
|
|
12
14
|
|
|
13
|
-
attr_reader :gems
|
|
14
|
-
attr_reader :grouped
|
|
15
|
+
attr_reader :gems, :grouped
|
|
15
16
|
|
|
16
17
|
##
|
|
17
18
|
# @param [Array] gems
|
data/lib/gemirro/gems_fetcher.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Gemirro
|
|
2
4
|
##
|
|
3
5
|
# The GemsFetcher class is responsible for downloading Gems from an external
|
|
@@ -25,7 +27,9 @@ module Gemirro
|
|
|
25
27
|
#
|
|
26
28
|
def fetch
|
|
27
29
|
@source.gems.each do |gem|
|
|
28
|
-
versions_for(gem).each do |
|
|
30
|
+
versions_for(gem).each do |versions|
|
|
31
|
+
gem.platform = versions[1] if versions
|
|
32
|
+
version = versions[0] if versions
|
|
29
33
|
if gem.gemspec?
|
|
30
34
|
gemfile = fetch_gemspec(gem, version)
|
|
31
35
|
if gemfile
|
|
@@ -55,7 +59,7 @@ module Gemirro
|
|
|
55
59
|
return [available.last] if gem.only_latest?
|
|
56
60
|
|
|
57
61
|
versions = available.select do |v|
|
|
58
|
-
gem.requirement.satisfied_by?(v)
|
|
62
|
+
gem.requirement.satisfied_by?(v[0])
|
|
59
63
|
end
|
|
60
64
|
|
|
61
65
|
versions = [available.last] if versions.empty?
|
|
@@ -103,12 +107,13 @@ module Gemirro
|
|
|
103
107
|
end
|
|
104
108
|
name = gem.name
|
|
105
109
|
|
|
106
|
-
if gem_exists?(filename) || ignore_gem?(name, version) ||
|
|
110
|
+
if gem_exists?(filename) || ignore_gem?(name, version, gem.platform) ||
|
|
111
|
+
!satisfied
|
|
107
112
|
Utils.logger.debug("Skipping #{filename}")
|
|
108
113
|
return
|
|
109
114
|
end
|
|
110
115
|
|
|
111
|
-
Utils.configuration.ignore_gem(gem.name, version)
|
|
116
|
+
Utils.configuration.ignore_gem(gem.name, version, gem.platform)
|
|
112
117
|
Utils.logger.info("Fetching #{filename}")
|
|
113
118
|
|
|
114
119
|
fetch_from_source(filename, gem, version)
|
|
@@ -131,7 +136,7 @@ module Gemirro
|
|
|
131
136
|
Utils.logger.error("Failed to retrieve #{filename}: #{e.message}")
|
|
132
137
|
Utils.logger.debug("Adding #{filename} to the list of ignored Gems")
|
|
133
138
|
|
|
134
|
-
Utils.configuration.ignore_gem(gem.name, version)
|
|
139
|
+
Utils.configuration.ignore_gem(gem.name, version, gem.platform)
|
|
135
140
|
end
|
|
136
141
|
|
|
137
142
|
data
|
data/lib/gemirro/http.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Gemirro
|
|
2
4
|
##
|
|
3
5
|
# The Http class is responsible for executing GET request
|
|
@@ -18,9 +20,7 @@ module Gemirro
|
|
|
18
20
|
def self.get(url)
|
|
19
21
|
response = client.get(url, follow_redirect: true)
|
|
20
22
|
|
|
21
|
-
unless HTTP::Status.successful?(response.status)
|
|
22
|
-
raise HTTPClient::BadResponseError, response.reason
|
|
23
|
-
end
|
|
23
|
+
raise HTTPClient::BadResponseError, response.reason unless HTTP::Status.successful?(response.status)
|
|
24
24
|
|
|
25
25
|
response
|
|
26
26
|
end
|
data/lib/gemirro/indexer.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Gemirro
|
|
2
4
|
##
|
|
3
5
|
# The Indexer class is responsible for downloading useful file directly
|
|
@@ -118,6 +120,7 @@ module Gemirro
|
|
|
118
120
|
else
|
|
119
121
|
source_content = download_from_source(file)
|
|
120
122
|
next if source_content.nil?
|
|
123
|
+
|
|
121
124
|
MirrorFile.new(dst_name).write(source_content)
|
|
122
125
|
end
|
|
123
126
|
|
|
@@ -136,6 +139,7 @@ module Gemirro
|
|
|
136
139
|
Utils.logger.info("Download from source: #{file}")
|
|
137
140
|
resp = Http.get("#{source_host}/#{File.basename(file)}")
|
|
138
141
|
return unless resp.code == 200
|
|
142
|
+
|
|
139
143
|
resp.body
|
|
140
144
|
end
|
|
141
145
|
|
|
@@ -155,7 +159,7 @@ module Gemirro
|
|
|
155
159
|
#
|
|
156
160
|
def build_indicies
|
|
157
161
|
specs = *map_gems_to_specs(gem_file_list)
|
|
158
|
-
specs.select! { |s| s.
|
|
162
|
+
specs.select! { |s| s.instance_of?(::Gem::Specification) }
|
|
159
163
|
::Gem::Specification.dirs = []
|
|
160
164
|
::Gem::Specification.all = specs
|
|
161
165
|
|
|
@@ -178,22 +182,23 @@ module Gemirro
|
|
|
178
182
|
#
|
|
179
183
|
def map_gems_to_specs(gems)
|
|
180
184
|
gems.map.with_index do |gemfile, index|
|
|
181
|
-
# rubocop:disable Metrics/LineLength
|
|
182
185
|
Utils.logger.info("[#{index + 1}/#{gems.size}]: Processing #{gemfile.split('/')[-1]}")
|
|
183
|
-
# rubocop:enable Metrics/LineLength
|
|
184
|
-
|
|
185
186
|
if File.size(gemfile).zero?
|
|
186
187
|
Utils.logger.warn("Skipping zero-length gem: #{gemfile}")
|
|
187
188
|
next
|
|
188
189
|
end
|
|
189
190
|
|
|
190
191
|
begin
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
192
|
+
begin
|
|
193
|
+
spec = if ::Gem::Package.respond_to? :open
|
|
194
|
+
::Gem::Package
|
|
195
|
+
.open(File.open(gemfile, 'rb'), 'r', &:metadata)
|
|
196
|
+
else
|
|
197
|
+
::Gem::Package.new(gemfile).spec
|
|
198
|
+
end
|
|
199
|
+
rescue NotImplementedError
|
|
200
|
+
next
|
|
201
|
+
end
|
|
197
202
|
|
|
198
203
|
spec.loaded_from = gemfile
|
|
199
204
|
|
|
@@ -325,6 +330,7 @@ module Gemirro
|
|
|
325
330
|
end
|
|
326
331
|
|
|
327
332
|
return false if source_content.nil?
|
|
333
|
+
|
|
328
334
|
new_content = source_content.concat(content).uniq
|
|
329
335
|
create_zlib_file(dst_name, new_content)
|
|
330
336
|
end
|
data/lib/gemirro/mirror_file.rb
CHANGED
data/lib/gemirro/server.rb
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'sinatra/base'
|
|
2
4
|
require 'thin'
|
|
3
5
|
require 'uri'
|
|
6
|
+
require 'addressable/uri'
|
|
4
7
|
|
|
5
8
|
module Gemirro
|
|
6
9
|
##
|
|
7
10
|
# Launch Sinatra server to easily download gems.
|
|
8
11
|
#
|
|
9
12
|
class Server < Sinatra::Base
|
|
10
|
-
# rubocop:disable
|
|
11
|
-
URI_REGEXP = /^(.*)-(\d+(?:\.\d+){1,4}.*?)(?:-(x86-(?:(?:mswin|mingw)(?:32|64)).*?|java))?\.(gem(?:spec\.rz)?)
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
# rubocop:disable Layout/LineLength
|
|
14
|
+
URI_REGEXP = /^(.*)-(\d+(?:\.\d+){1,4}.*?)(?:-(x86-(?:(?:mswin|mingw)(?:32|64)).*?|java))?\.(gem(?:spec\.rz)?)$/.freeze
|
|
15
|
+
# rubocop:enable Layout/LineLength
|
|
16
|
+
GEMSPEC_TYPE = 'gemspec.rz'
|
|
17
|
+
GEM_TYPE = 'gem'
|
|
14
18
|
|
|
15
19
|
access_logger = Logger.new(Utils.configuration.server.access_log).tap do |logger|
|
|
16
|
-
::Logger.class_eval { alias_method :write,
|
|
20
|
+
::Logger.class_eval { alias_method :write, :<< }
|
|
17
21
|
logger.level = ::Logger::INFO
|
|
18
22
|
end
|
|
19
|
-
# rubocop:enable Metrics/LineLength
|
|
20
23
|
|
|
21
24
|
error_logger = File.new(Utils.configuration.server.error_log, 'a+')
|
|
22
25
|
error_logger.sync = true
|
|
@@ -127,6 +130,7 @@ module Gemirro
|
|
|
127
130
|
#
|
|
128
131
|
def fetch_gem(resource)
|
|
129
132
|
return unless Utils.configuration.fetch_gem
|
|
133
|
+
|
|
130
134
|
name = File.basename(resource)
|
|
131
135
|
result = name.match(URI_REGEXP)
|
|
132
136
|
return unless result
|
|
@@ -138,10 +142,8 @@ module Gemirro
|
|
|
138
142
|
gem = Utils.stored_gem(gem_name, gem_version, gem_platform)
|
|
139
143
|
gem.gemspec = true if gem_type == GEMSPEC_TYPE
|
|
140
144
|
|
|
141
|
-
# rubocop:disable Metrics/LineLength
|
|
142
145
|
return if Utils.gems_fetcher.gem_exists?(gem.filename(gem_version)) && gem_type == GEM_TYPE
|
|
143
146
|
return if Utils.gems_fetcher.gemspec_exists?(gem.gemspec_filename(gem_version)) && gem_type == GEMSPEC_TYPE
|
|
144
|
-
# rubocop:enable Metrics/LineLength
|
|
145
147
|
|
|
146
148
|
Utils.logger
|
|
147
149
|
.info("Try to download #{gem_name} with version #{gem_version}")
|
|
@@ -167,7 +169,7 @@ module Gemirro
|
|
|
167
169
|
|
|
168
170
|
Utils.logger.info('Generating indexes')
|
|
169
171
|
indexer.update_index
|
|
170
|
-
indexer.updated_gems.
|
|
172
|
+
indexer.updated_gems.each do |gem|
|
|
171
173
|
Utils.cache.flush_key(File.basename(gem))
|
|
172
174
|
end
|
|
173
175
|
rescue SystemExit => e
|
|
@@ -215,9 +217,7 @@ module Gemirro
|
|
|
215
217
|
gem_collection = Parallel.map(gem_collection, in_threads: 4) do |gem|
|
|
216
218
|
[gem, spec_for(gem.name, gem.number, gem.platform)]
|
|
217
219
|
end
|
|
218
|
-
gem_collection.
|
|
219
|
-
spec.nil?
|
|
220
|
-
end
|
|
220
|
+
gem_collection.compact!
|
|
221
221
|
|
|
222
222
|
Parallel.map(gem_collection, in_threads: 4) do |gem, spec|
|
|
223
223
|
dependencies = spec.dependencies.select do |d|
|
|
@@ -280,7 +280,7 @@ module Gemirro
|
|
|
280
280
|
# @return [String]
|
|
281
281
|
#
|
|
282
282
|
def homepage(spec)
|
|
283
|
-
URI.parse(URI.escape(spec.homepage))
|
|
283
|
+
URI.parse(Addressable::URI.escape(spec.homepage))
|
|
284
284
|
end
|
|
285
285
|
end
|
|
286
286
|
end
|
data/lib/gemirro/source.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Gemirro
|
|
2
4
|
##
|
|
3
5
|
# The Source class is used for storing information about an external source
|
|
@@ -34,7 +36,7 @@ module Gemirro
|
|
|
34
36
|
"Fetching #{Configuration.versions_file} on #{@name} (#{@host})"
|
|
35
37
|
)
|
|
36
38
|
|
|
37
|
-
Http.get(host
|
|
39
|
+
Http.get("#{host}/#{Configuration.versions_file}").body
|
|
38
40
|
end
|
|
39
41
|
|
|
40
42
|
##
|
|
@@ -47,7 +49,7 @@ module Gemirro
|
|
|
47
49
|
"Fetching #{Configuration.prerelease_versions_file}" \
|
|
48
50
|
" on #{@name} (#{@host})"
|
|
49
51
|
)
|
|
50
|
-
Http.get(host
|
|
52
|
+
Http.get("#{host}/#{Configuration.prerelease_versions_file}").body
|
|
51
53
|
end
|
|
52
54
|
|
|
53
55
|
##
|
data/lib/gemirro/utils.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Gemirro
|
|
2
4
|
##
|
|
3
5
|
# The Utils class is responsible for executing specific traitments
|
|
@@ -16,6 +18,7 @@ module Gemirro
|
|
|
16
18
|
:gems_fetcher,
|
|
17
19
|
:gems_collection,
|
|
18
20
|
:stored_gems)
|
|
21
|
+
|
|
19
22
|
##
|
|
20
23
|
# Cache class to store marshal and data into files
|
|
21
24
|
#
|
|
@@ -44,6 +47,7 @@ module Gemirro
|
|
|
44
47
|
Parallel.map(file_paths, in_threads: 4) do |file_path|
|
|
45
48
|
next if data[:files].key?(file_path) &&
|
|
46
49
|
data[:files][file_path] == File.mtime(file_path)
|
|
50
|
+
|
|
47
51
|
has_file_changed = true
|
|
48
52
|
end
|
|
49
53
|
|
|
@@ -53,6 +57,7 @@ module Gemirro
|
|
|
53
57
|
gems = []
|
|
54
58
|
Parallel.map(file_paths, in_threads: 4) do |file_path|
|
|
55
59
|
next unless File.exist?(file_path)
|
|
60
|
+
|
|
56
61
|
gems.concat(Marshal.load(Zlib::GzipReader.open(file_path).read))
|
|
57
62
|
data[:files][file_path] = File.mtime(file_path)
|
|
58
63
|
end
|
|
@@ -75,7 +80,7 @@ module Gemirro
|
|
|
75
80
|
File.join(configuration.destination,
|
|
76
81
|
[specs_file_type,
|
|
77
82
|
marshal_version,
|
|
78
|
-
|
|
83
|
+
"gz#{orig ? '.orig' : ''}"].join('.'))
|
|
79
84
|
end
|
|
80
85
|
end
|
|
81
86
|
|
data/lib/gemirro/version.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Gemirro
|
|
2
4
|
##
|
|
3
5
|
# The VersionsFile class acts as a small Ruby wrapper around the RubyGems
|
|
@@ -65,7 +67,7 @@ module Gemirro
|
|
|
65
67
|
# @return [Array]
|
|
66
68
|
#
|
|
67
69
|
def versions_for(gem)
|
|
68
|
-
versions_hash[gem].map { |version| version[1] }
|
|
70
|
+
versions_hash[gem].map { |version| [version[1], version[2]] }
|
|
69
71
|
end
|
|
70
72
|
end
|
|
71
73
|
end
|
|
@@ -68,10 +68,11 @@ module Gemirro
|
|
|
68
68
|
|
|
69
69
|
it 'should return ignored gems' do
|
|
70
70
|
expect(@config.ignored_gems).to eq({})
|
|
71
|
-
expect(@config.ignore_gem?('rake', '1.0.0')).to be_falsy
|
|
72
|
-
expect(@config.ignore_gem('rake', '1.0.0')).to eq(['1.0.0'])
|
|
73
|
-
expect(@config.ignored_gems).to eq('rake' => ['1.0.0'])
|
|
74
|
-
expect(@config.ignore_gem?('rake', '1.0.0')).to be_truthy
|
|
71
|
+
expect(@config.ignore_gem?('rake', '1.0.0', 'ruby')).to be_falsy
|
|
72
|
+
expect(@config.ignore_gem('rake', '1.0.0', 'ruby')).to eq(['1.0.0'])
|
|
73
|
+
expect(@config.ignored_gems).to eq('ruby' => {'rake' => ['1.0.0']})
|
|
74
|
+
expect(@config.ignore_gem?('rake', '1.0.0', 'ruby')).to be_truthy
|
|
75
|
+
expect(@config.ignore_gem?('rake', '1.0.0', 'java')).to be_falsy
|
|
75
76
|
end
|
|
76
77
|
|
|
77
78
|
it 'should add and return source' do
|
|
@@ -34,9 +34,10 @@ module Gemirro
|
|
|
34
34
|
it 'should ignore gem' do
|
|
35
35
|
allow(Utils.logger).to receive(:info)
|
|
36
36
|
.once.with('Fetching gemirro-0.0.1.gem')
|
|
37
|
-
expect(@fetcher.ignore_gem?('gemirro', '0.0.1')).to be_falsy
|
|
38
|
-
Utils.configuration.ignore_gem('gemirro', '0.0.1')
|
|
39
|
-
expect(@fetcher.ignore_gem?('gemirro', '0.0.1')).to be_truthy
|
|
37
|
+
expect(@fetcher.ignore_gem?('gemirro', '0.0.1', 'ruby')).to be_falsy
|
|
38
|
+
Utils.configuration.ignore_gem('gemirro', '0.0.1', 'ruby')
|
|
39
|
+
expect(@fetcher.ignore_gem?('gemirro', '0.0.1', 'ruby')).to be_truthy
|
|
40
|
+
expect(@fetcher.ignore_gem?('gemirro', '0.0.1', 'java')).to be_falsy
|
|
40
41
|
end
|
|
41
42
|
|
|
42
43
|
it 'should log error when fetch gem failed' do
|
|
@@ -44,7 +45,7 @@ module Gemirro
|
|
|
44
45
|
.once.with('Fetching gemirro-0.0.1.gem')
|
|
45
46
|
gem = Gem.new('gemirro')
|
|
46
47
|
version = ::Gem::Version.new('0.0.1')
|
|
47
|
-
Utils.configuration.ignore_gem('gemirro', '0.0.1')
|
|
48
|
+
Utils.configuration.ignore_gem('gemirro', '0.0.1', 'ruby')
|
|
48
49
|
allow(@source).to receive(:fetch_gem)
|
|
49
50
|
.once.with('gemirro', version).and_raise(ArgumentError)
|
|
50
51
|
allow(Utils.logger).to receive(:error)
|
|
@@ -53,7 +54,7 @@ module Gemirro
|
|
|
53
54
|
.once.with(/Adding (.*) to the list of ignored Gems/)
|
|
54
55
|
|
|
55
56
|
expect(@fetcher.fetch_gem(gem, version)).to be_nil
|
|
56
|
-
expect(@fetcher.ignore_gem?('gemirro', '0.0.1')).to be_truthy
|
|
57
|
+
expect(@fetcher.ignore_gem?('gemirro', '0.0.1', 'ruby')).to be_truthy
|
|
57
58
|
end
|
|
58
59
|
|
|
59
60
|
it 'should fetch gem' do
|
|
@@ -125,9 +126,10 @@ module Gemirro
|
|
|
125
126
|
it 'should retrieve versions for specific gem' do
|
|
126
127
|
gem = Gem.new('gemirro', '0.0.2')
|
|
127
128
|
allow(@versions_file).to receive(:versions_for)
|
|
128
|
-
.once.with('gemirro')
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
.once.with('gemirro')
|
|
130
|
+
.and_return([[::Gem::Version.new('0.0.1'), 'ruby'],
|
|
131
|
+
[::Gem::Version.new('0.0.2'), 'ruby']])
|
|
132
|
+
expect(@fetcher.versions_for(gem)).to eq([[::Gem::Version.new('0.0.2'), 'ruby']])
|
|
131
133
|
end
|
|
132
134
|
|
|
133
135
|
it 'should fetch all gems and log debug if gem is not satisfied' do
|
data/spec/gemirro/server_spec.rb
CHANGED
|
@@ -125,7 +125,7 @@ module Gemirro
|
|
|
125
125
|
end
|
|
126
126
|
|
|
127
127
|
it 'should try to download gems.' do
|
|
128
|
-
source = Gemirro::Source.new('test', '
|
|
128
|
+
source = Gemirro::Source.new('test', 'https://rubygems.org')
|
|
129
129
|
|
|
130
130
|
versions_fetcher = Gemirro::VersionsFetcher.new(source)
|
|
131
131
|
allow(versions_fetcher).to receive(:fetch).once.and_return(true)
|
|
@@ -166,7 +166,7 @@ module Gemirro
|
|
|
166
166
|
end
|
|
167
167
|
|
|
168
168
|
it 'should catch exceptions' do
|
|
169
|
-
source = Gemirro::Source.new('test', '
|
|
169
|
+
source = Gemirro::Source.new('test', 'https://rubygems.org')
|
|
170
170
|
|
|
171
171
|
versions_fetcher = Gemirro::VersionsFetcher.new(source)
|
|
172
172
|
allow(versions_fetcher).to receive(:fetch).once.and_return(true)
|
data/template/config.rb
CHANGED
|
@@ -17,6 +17,9 @@ Gemirro.configuration.configure do
|
|
|
17
17
|
#
|
|
18
18
|
# server.host 'localhost'
|
|
19
19
|
# server.port '2000'
|
|
20
|
+
|
|
21
|
+
# If you don't want the server to run daemonized, uncomment the following
|
|
22
|
+
# server.daemonize false
|
|
20
23
|
server.access_log File.expand_path('../logs/access.log', __FILE__)
|
|
21
24
|
server.error_log File.expand_path('../logs/error.log', __FILE__)
|
|
22
25
|
|
|
@@ -32,7 +35,7 @@ Gemirro.configuration.configure do
|
|
|
32
35
|
# You must define a source which where gems will be downloaded.
|
|
33
36
|
# All gem in the block will be downloaded with the update command.
|
|
34
37
|
# Other gems will be downloaded with the server.
|
|
35
|
-
define_source 'rubygems', '
|
|
38
|
+
define_source 'rubygems', 'https://rubygems.org' do
|
|
36
39
|
gem 'rack', '>= 1.0.0'
|
|
37
40
|
end
|
|
38
41
|
end
|
metadata
CHANGED
|
@@ -1,15 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: gemirro
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 1.3.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:
|
|
11
|
+
date: 2021-03-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: addressable
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '2.5'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '2.5'
|
|
13
27
|
- !ruby/object:Gem::Dependency
|
|
14
28
|
name: builder
|
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -72,28 +86,28 @@ dependencies:
|
|
|
72
86
|
requirements:
|
|
73
87
|
- - "~>"
|
|
74
88
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '1.
|
|
89
|
+
version: '1.20'
|
|
76
90
|
type: :runtime
|
|
77
91
|
prerelease: false
|
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
93
|
requirements:
|
|
80
94
|
- - "~>"
|
|
81
95
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '1.
|
|
96
|
+
version: '1.20'
|
|
83
97
|
- !ruby/object:Gem::Dependency
|
|
84
98
|
name: sinatra
|
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
|
86
100
|
requirements:
|
|
87
101
|
- - "~>"
|
|
88
102
|
- !ruby/object:Gem::Version
|
|
89
|
-
version:
|
|
103
|
+
version: 2.0.1
|
|
90
104
|
type: :runtime
|
|
91
105
|
prerelease: false
|
|
92
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
107
|
requirements:
|
|
94
108
|
- - "~>"
|
|
95
109
|
- !ruby/object:Gem::Version
|
|
96
|
-
version:
|
|
110
|
+
version: 2.0.1
|
|
97
111
|
- !ruby/object:Gem::Dependency
|
|
98
112
|
name: slop
|
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -128,84 +142,84 @@ dependencies:
|
|
|
128
142
|
requirements:
|
|
129
143
|
- - "~>"
|
|
130
144
|
- !ruby/object:Gem::Version
|
|
131
|
-
version: '
|
|
145
|
+
version: '1'
|
|
132
146
|
type: :development
|
|
133
147
|
prerelease: false
|
|
134
148
|
version_requirements: !ruby/object:Gem::Requirement
|
|
135
149
|
requirements:
|
|
136
150
|
- - "~>"
|
|
137
151
|
- !ruby/object:Gem::Version
|
|
138
|
-
version: '
|
|
152
|
+
version: '1'
|
|
139
153
|
- !ruby/object:Gem::Dependency
|
|
140
154
|
name: rack-test
|
|
141
155
|
requirement: !ruby/object:Gem::Requirement
|
|
142
156
|
requirements:
|
|
143
157
|
- - "~>"
|
|
144
158
|
- !ruby/object:Gem::Version
|
|
145
|
-
version: '
|
|
159
|
+
version: '1.1'
|
|
146
160
|
type: :development
|
|
147
161
|
prerelease: false
|
|
148
162
|
version_requirements: !ruby/object:Gem::Requirement
|
|
149
163
|
requirements:
|
|
150
164
|
- - "~>"
|
|
151
165
|
- !ruby/object:Gem::Version
|
|
152
|
-
version: '
|
|
166
|
+
version: '1.1'
|
|
153
167
|
- !ruby/object:Gem::Dependency
|
|
154
168
|
name: rake
|
|
155
169
|
requirement: !ruby/object:Gem::Requirement
|
|
156
170
|
requirements:
|
|
157
171
|
- - "~>"
|
|
158
172
|
- !ruby/object:Gem::Version
|
|
159
|
-
version: '
|
|
173
|
+
version: '13'
|
|
160
174
|
type: :development
|
|
161
175
|
prerelease: false
|
|
162
176
|
version_requirements: !ruby/object:Gem::Requirement
|
|
163
177
|
requirements:
|
|
164
178
|
- - "~>"
|
|
165
179
|
- !ruby/object:Gem::Version
|
|
166
|
-
version: '
|
|
180
|
+
version: '13'
|
|
167
181
|
- !ruby/object:Gem::Dependency
|
|
168
182
|
name: rspec
|
|
169
183
|
requirement: !ruby/object:Gem::Requirement
|
|
170
184
|
requirements:
|
|
171
185
|
- - "~>"
|
|
172
186
|
- !ruby/object:Gem::Version
|
|
173
|
-
version: '3.
|
|
187
|
+
version: '3.10'
|
|
174
188
|
type: :development
|
|
175
189
|
prerelease: false
|
|
176
190
|
version_requirements: !ruby/object:Gem::Requirement
|
|
177
191
|
requirements:
|
|
178
192
|
- - "~>"
|
|
179
193
|
- !ruby/object:Gem::Version
|
|
180
|
-
version: '3.
|
|
194
|
+
version: '3.10'
|
|
181
195
|
- !ruby/object:Gem::Dependency
|
|
182
196
|
name: rubocop
|
|
183
197
|
requirement: !ruby/object:Gem::Requirement
|
|
184
198
|
requirements:
|
|
185
199
|
- - "~>"
|
|
186
200
|
- !ruby/object:Gem::Version
|
|
187
|
-
version: '
|
|
201
|
+
version: '1'
|
|
188
202
|
type: :development
|
|
189
203
|
prerelease: false
|
|
190
204
|
version_requirements: !ruby/object:Gem::Requirement
|
|
191
205
|
requirements:
|
|
192
206
|
- - "~>"
|
|
193
207
|
- !ruby/object:Gem::Version
|
|
194
|
-
version: '
|
|
208
|
+
version: '1'
|
|
195
209
|
- !ruby/object:Gem::Dependency
|
|
196
210
|
name: simplecov
|
|
197
211
|
requirement: !ruby/object:Gem::Requirement
|
|
198
212
|
requirements:
|
|
199
213
|
- - "~>"
|
|
200
214
|
- !ruby/object:Gem::Version
|
|
201
|
-
version: '0.
|
|
215
|
+
version: '0.21'
|
|
202
216
|
type: :development
|
|
203
217
|
prerelease: false
|
|
204
218
|
version_requirements: !ruby/object:Gem::Requirement
|
|
205
219
|
requirements:
|
|
206
220
|
- - "~>"
|
|
207
221
|
- !ruby/object:Gem::Version
|
|
208
|
-
version: '0.
|
|
222
|
+
version: '0.21'
|
|
209
223
|
description: Create your own gems mirror.
|
|
210
224
|
email: pierre.rambaud86@gmail.com
|
|
211
225
|
executables:
|
|
@@ -295,15 +309,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
295
309
|
requirements:
|
|
296
310
|
- - ">="
|
|
297
311
|
- !ruby/object:Gem::Version
|
|
298
|
-
version:
|
|
312
|
+
version: '2.5'
|
|
299
313
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
300
314
|
requirements:
|
|
301
315
|
- - ">="
|
|
302
316
|
- !ruby/object:Gem::Version
|
|
303
317
|
version: '0'
|
|
304
318
|
requirements: []
|
|
305
|
-
|
|
306
|
-
rubygems_version: 2.6.11
|
|
319
|
+
rubygems_version: 3.1.2
|
|
307
320
|
signing_key:
|
|
308
321
|
specification_version: 4
|
|
309
322
|
summary: Gem for easily creating your own gems mirror.
|