gemirro 1.3.0 → 1.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f5ce407f251612fd3198509818414c754d97508355e1fc1a723a08448bfb369f
4
- data.tar.gz: 669d4d88aa1db6241b7e8861934d12893accde19fad6454d829a9e143569622b
3
+ metadata.gz: 1129e2117ef615eddf786284610e84808bd3e2ddd2ab21e8fafc972d9b5923e5
4
+ data.tar.gz: 2c6325d376cf3be31e8f447549697dfb9df6811da7e6aab17654059bf2a1cae6
5
5
  SHA512:
6
- metadata.gz: 3c49aa30264c21ca2fb840f5c4b2b6dd6058c5b587e94ff5ae4e94488a00d86f25e0a56de742c9ab8078a6350bb5f15d38119b69decfdd5088e0c8b0ff4dafa6
7
- data.tar.gz: 96e25a3b96ca072f6823b8583626b9dd502048e444423af8d50ffcc9040a139daa5aa36314ce914edef2123c335015a6f8f1f758b18a62339fcfe60d3c006afa
6
+ metadata.gz: 9550ed8196a872207d6db5809e97223f190aba44704c2886b469066f57ff7c5f4ab9ab50c11d8a43f010eef88a718fc7a5f736c3aebbf6fc2fd2a702d9c9b5f3
7
+ data.tar.gz: '0951b6fd87d27b0c830e25c1774e13fe88e322bcd8277facf4950726da931c4b1de2ee6ad0b8ba71742c9567615a57c742bbffcfb2c69a0a0ef81b67cc7bb8d6'
data/Gemfile CHANGED
@@ -3,3 +3,12 @@
3
3
  source 'https://rubygems.org/'
4
4
 
5
5
  gemspec
6
+
7
+ group :development, :test do
8
+ gem 'fakefs', '~> 2'
9
+ gem 'rack-test', '~> 1.1'
10
+ gem 'rake', '~> 13'
11
+ gem 'rspec', '~> 3.10'
12
+ gem 'rubocop', '~> 1'
13
+ gem 'simplecov', '~> 0.21'
14
+ end
data/MANIFEST CHANGED
@@ -1,6 +1,5 @@
1
1
  .gitignore
2
2
  .rubocop.yml
3
- .travis.yml
4
3
  Gemfile
5
4
  LICENSE
6
5
  MANIFEST
@@ -62,9 +61,8 @@ template/public/dist/fonts/glyphicons-halflings-regular.ttf
62
61
  template/public/dist/fonts/glyphicons-halflings-regular.woff
63
62
  template/public/dist/fonts/glyphicons-halflings-regular.woff2
64
63
  template/public/dist/js/bootstrap.min.js
65
- template/public/dist/js/jquery.min.js
66
64
  template/public/gems/.gitkeep
67
65
  views/gem.erb
68
66
  views/index.erb
69
67
  views/layout.erb
70
- views/not_found.erb
68
+ views/not_found.erb
data/README.md CHANGED
@@ -29,7 +29,7 @@ This is done by running the `gemirro init` command.
29
29
  $ gemirro init /srv/http/mirror.com/
30
30
  ```
31
31
 
32
- Once created you can edit the main configuration file called `config.rb`.
32
+ Once created you can edit the main configuration file called [config.rb](https://github.com/PierreRambaud/gemirro/blob/master/template/config.rb).
33
33
  This configuration file specifies what source to mirror, destination directory, server host and port, etc.
34
34
 
35
35
  Once configured and if you add gem in the `define_source`, you can pull them by running the following command:
data/gemirro.gemspec CHANGED
@@ -18,20 +18,16 @@ Gem::Specification.new do |s|
18
18
 
19
19
  s.required_ruby_version = '>= 2.5'
20
20
 
21
- s.add_dependency 'addressable', '~>2.5'
21
+ s.add_dependency 'addressable', '~>2.8'
22
22
  s.add_dependency 'builder', '~>3.2'
23
- s.add_dependency 'confstruct', '~>1.0'
23
+ s.add_dependency 'confstruct', '~>1.1'
24
24
  s.add_dependency 'erubis', '~>2.7'
25
25
  s.add_dependency 'httpclient', '~>2.8'
26
- s.add_dependency 'parallel', '~>1.20'
27
- s.add_dependency 'sinatra', '~>2.0.1'
26
+ s.add_dependency 'parallel', '~>1.21'
27
+ s.add_dependency 'sinatra', '>=3.1', '<4.0'
28
28
  s.add_dependency 'slop', '~>3.6'
29
- s.add_dependency 'thin', '~>1.7'
29
+ s.add_dependency 'stringio', '~> 3.1'
30
+ s.add_dependency 'thin', '~>1.8'
30
31
 
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'
32
+ s.metadata['rubygems_mfa_required'] = 'true'
37
33
  end
@@ -42,9 +42,7 @@ Gemirro::CLI.options.command 'server' do
42
42
  $PROGRAM_NAME = 'gemirro'
43
43
 
44
44
  def create_pid
45
- File.open(@pid_file, 'w') do |f|
46
- f.write(Process.pid.to_s)
47
- end
45
+ File.write(@pid_file, Process.pid.to_s)
48
46
  rescue Errno::EACCES
49
47
  $stdout.reopen @orig_stdout
50
48
  puts "Error: Can't write to #{@pid_file} - Permission denied"
@@ -76,7 +74,7 @@ Gemirro::CLI.options.command 'server' do
76
74
  puts "done! (PID is #{pid})\n"
77
75
  Gemirro::Server.run!
78
76
  destroy_pid
79
- $stdout.reopen '/dev/null', 'a'
77
+ $stdout.reopen File::NULL, 'a'
80
78
  end
81
79
 
82
80
  def stop
data/lib/gemirro/http.rb CHANGED
@@ -29,7 +29,34 @@ module Gemirro
29
29
  # @return [HTTPClient]
30
30
  #
31
31
  def self.client
32
- @client ||= HTTPClient.new
32
+ client ||= HTTPClient.new
33
+ config = Utils.configuration
34
+ if defined?(config.upstream_user)
35
+ user = config.upstream_user
36
+ password = config.upstream_password
37
+ domain = config.upstream_domain
38
+ client.set_auth(domain, user, password)
39
+ end
40
+
41
+ if defined?(config.proxy)
42
+ proxy = config.proxy
43
+ client.proxy = (proxy)
44
+ end
45
+
46
+ # Use my own ca file for self signed cert
47
+ if defined?(config.rootca)
48
+ abort "The configuration file #{config.rootca} does not exist" unless File.file?(config.rootca)
49
+ client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_PEER
50
+ client.ssl_config.set_trust_ca(config.rootca)
51
+ elsif defined?(config.verify_mode)
52
+ client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE unless config.verify_mode
53
+ end
54
+
55
+ # Enforce base auth
56
+ if defined?(config.basic_auth) && config.basic_auth
57
+ client.www_auth.basic_auth.force_auth = (true)
58
+ end
59
+ @client = client
33
60
  end
34
61
  end
35
62
  end
@@ -40,8 +40,8 @@ module Gemirro
40
40
 
41
41
  unless defined?(Builder::XChar)
42
42
  raise 'Gem::Indexer requires that the XML Builder ' \
43
- 'library be installed:' \
44
- "\n\tgem install builder"
43
+ 'library be installed:' \
44
+ "\n\tgem install builder"
45
45
  end
46
46
 
47
47
  options = { build_modern: true }.merge options
@@ -183,7 +183,7 @@ module Gemirro
183
183
  def map_gems_to_specs(gems)
184
184
  gems.map.with_index do |gemfile, index|
185
185
  Utils.logger.info("[#{index + 1}/#{gems.size}]: Processing #{gemfile.split('/')[-1]}")
186
- if File.size(gemfile).zero?
186
+ if File.empty?(gemfile)
187
187
  Utils.logger.warn("Skipping zero-length gem: #{gemfile}")
188
188
  next
189
189
  end
@@ -220,6 +220,8 @@ module Gemirro
220
220
  gem_collection.compact!
221
221
 
222
222
  Parallel.map(gem_collection, in_threads: 4) do |gem, spec|
223
+ next if spec.nil?
224
+
223
225
  dependencies = spec.dependencies.select do |d|
224
226
  d.type == :runtime
225
227
  end
@@ -259,7 +261,14 @@ module Gemirro
259
261
 
260
262
  File.open(spec_file, 'r') do |uz_file|
261
263
  uz_file.binmode
262
- Marshal.load(::Gem.inflate(uz_file.read))
264
+ inflater = Zlib::Inflate.new
265
+ begin
266
+ inflate_data = inflater.inflate(uz_file.read)
267
+ ensure
268
+ inflater.finish
269
+ inflater.close
270
+ end
271
+ Marshal.load(inflate_data)
263
272
  end
264
273
  end
265
274
 
@@ -46,8 +46,8 @@ module Gemirro
46
46
  #
47
47
  def fetch_prerelease_versions
48
48
  Utils.logger.info(
49
- "Fetching #{Configuration.prerelease_versions_file}" \
50
- " on #{@name} (#{@host})"
49
+ "Fetching #{Configuration.prerelease_versions_file} " \
50
+ "on #{@name} (#{@host})"
51
51
  )
52
52
  Http.get("#{host}/#{Configuration.prerelease_versions_file}").body
53
53
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Gemirro Version
4
4
  module Gemirro
5
- VERSION = '1.3.0'
5
+ VERSION = '1.5.0'
6
6
  end
data/lib/gemirro.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'builder'
3
4
  require 'confstruct'
4
5
  require 'digest/sha2'
5
6
  require 'fileutils'
@@ -2,34 +2,93 @@ require 'spec_helper'
2
2
  require 'httpclient'
3
3
  require 'gemirro/http'
4
4
 
5
- # Http tests
6
5
  module Gemirro
7
- describe 'Http' do
8
- it 'should return http client' do
9
- expect(Http.client).to be_a(HTTPClient)
6
+ describe Http do
7
+ let(:config) { double('Configuration') }
8
+
9
+ before do
10
+ Http.instance_variable_set(:@client, nil)
11
+ allow(Utils).to receive(:configuration).and_return(config)
10
12
  end
11
13
 
12
- it 'should raise error when get request failed' do
13
- uri = 'http://github.com/PierreRambaud'
14
- Struct.new('HTTPError', :status, :reason)
15
- result = Struct::HTTPError.new(401, 'Unauthorized')
16
- allow(Http.client).to receive(:get)
17
- .once.with(uri, follow_redirect: true).and_return(result)
18
- expect { Http.get(uri) }
19
- .to raise_error HTTPClient::BadResponseError, 'Unauthorized'
14
+ describe '.client' do
15
+ it 'initializes a new HTTPClient' do
16
+ expect(Http.client).to be_a(HTTPClient)
17
+ end
18
+
19
+ context 'with proxy configuration' do
20
+ it 'sets proxy configuration' do
21
+ allow(config).to receive(:proxy).and_return('http://proxy.example.com:8080')
22
+
23
+ expect(Http.client.proxy.to_s).to eq('http://proxy.example.com:8080')
24
+ end
25
+ end
26
+
27
+ context 'with SSL configuration' do
28
+ context 'with invalid root CA path' do
29
+ before do
30
+ allow(config).to receive(:rootca).and_return('/nonexistent/ca.crt')
31
+ allow(File).to receive(:file?).with('/nonexistent/ca.crt').and_return(false)
32
+ end
33
+
34
+ it 'aborts with error message' do
35
+ expect { Http.client }.to raise_error(SystemExit)
36
+ end
37
+ end
38
+
39
+ context 'with verify_mode disabled' do
40
+ before do
41
+ allow(config).to receive(:verify_mode).and_return(false)
42
+ end
43
+
44
+ it 'sets SSL verify mode to VERIFY_NONE' do
45
+ expect(Http.client.ssl_config.verify_mode).to eq(OpenSSL::SSL::VERIFY_NONE)
46
+ end
47
+ end
48
+ end
49
+
50
+ context 'with basic auth forced' do
51
+ before do
52
+ allow(config).to receive(:basic_auth).and_return(true)
53
+ end
54
+
55
+ it 'forces basic authentication' do
56
+ expect(Http.client.www_auth.basic_auth.force_auth).to be true
57
+ end
58
+ end
20
59
  end
21
60
 
22
- it 'should execute get request' do
23
- uri = 'http://github.com/PierreRambaud'
24
- Struct.new('HTTPResponse', :status, :body)
25
- result = Struct::HTTPResponse.new(200, 'body content')
26
- allow(Http.client).to receive(:get)
27
- .once.with(uri, follow_redirect: true).and_return(result)
28
-
29
- response = Http.get(uri)
30
- expect(response).to be_a(Struct::HTTPResponse)
31
- expect(response.body).to eq('body content')
32
- expect(response.status).to eq(200)
61
+ describe '.get' do
62
+ let(:client) { instance_double(HTTPClient) }
63
+
64
+ before do
65
+ allow(Http).to receive(:client).and_return(client)
66
+ end
67
+
68
+ context 'with successful response' do
69
+ let(:response) { double('Response', status: 200, body: 'content') }
70
+
71
+ it 'returns response for successful request' do
72
+ allow(client).to receive(:get)
73
+ .with('http://example.com', follow_redirect: true)
74
+ .and_return(response)
75
+
76
+ expect(Http.get('http://example.com')).to eq(response)
77
+ end
78
+ end
79
+
80
+ context 'with error response' do
81
+ let(:response) { double('Response', status: 404, reason: 'Not Found') }
82
+
83
+ it 'raises BadResponseError for failed request' do
84
+ allow(client).to receive(:get)
85
+ .with('http://example.com', follow_redirect: true)
86
+ .and_return(response)
87
+
88
+ expect { Http.get('http://example.com') }
89
+ .to raise_error(HTTPClient::BadResponseError, 'Not Found')
90
+ end
91
+ end
33
92
  end
34
93
  end
35
- end
94
+ end
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'builder'
2
3
  require 'rubygems/indexer'
3
4
  require 'tempfile'
4
5
  require 'gemirro/source'
@@ -34,6 +35,8 @@ module Gemirro
34
35
  end
35
36
 
36
37
  it 'should install indices' do
38
+ allow(Gemirro.configuration).to receive(:destination).and_return('/tmp')
39
+
37
40
  dir = MirrorDirectory.new('/tmp')
38
41
  dir.add_directory('test')
39
42
  dir.add_directory('gem_generate_index/quick/Marshal.4.8')
data/template/config.rb CHANGED
@@ -32,6 +32,24 @@ Gemirro.configuration.configure do
32
32
  #
33
33
  # fetch_gem false
34
34
 
35
+ # If upstream repository requires authentication
36
+ # upstream_user 'username'
37
+ # upstream_password 'password'
38
+ # upstream_domain 'https://internal.com'
39
+
40
+ # Enforce the the base_auth
41
+ # basic_auth true
42
+
43
+ # Set the proxy server if behind the firewall
44
+ # proxy 'http://proxy.internal.com:80'
45
+
46
+ # Root CA cert location if additional root ca is added
47
+ # This will overwrite verfiy_mode. use PEER as default
48
+ # rootca '/etc/root_ca.crt'
49
+
50
+ # Not verify certificate in case the proxy has self-signed cert
51
+ # verify_mode false
52
+
35
53
  # You must define a source which where gems will be downloaded.
36
54
  # All gem in the block will be downloaded with the update command.
37
55
  # Other gems will be downloaded with the server.