gemirro 1.5.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +29 -0
  3. data/.rubocop.yml +6 -3
  4. data/Gemfile.lock +126 -0
  5. data/MANIFEST +6 -10
  6. data/README.md +1 -1
  7. data/bin/gemirro +7 -1
  8. data/gemirro.gemspec +7 -2
  9. data/lib/gemirro/cli/index.rb +12 -3
  10. data/lib/gemirro/cli/init.rb +6 -1
  11. data/lib/gemirro/cli/update.rb +6 -0
  12. data/lib/gemirro/configuration.rb +1 -1
  13. data/lib/gemirro/gems_fetcher.rb +5 -10
  14. data/lib/gemirro/indexer.rb +396 -89
  15. data/lib/gemirro/mirror_file.rb +1 -0
  16. data/lib/gemirro/server.rb +73 -166
  17. data/lib/gemirro/utils.rb +123 -68
  18. data/lib/gemirro/version.rb +1 -1
  19. data/lib/gemirro/versions_fetcher.rb +6 -2
  20. data/lib/gemirro.rb +0 -1
  21. data/spec/gemirro/server_spec.rb +76 -47
  22. data/template/config.rb +6 -0
  23. data/template/public/dist/css/gemirro.css +25 -1
  24. data/template/public/latest_specs.4.8 +0 -0
  25. data/template/public/prerelease_specs.4.8 +0 -0
  26. data/template/public/specs.4.8 +0 -0
  27. data/views/gem.erb +46 -37
  28. data/views/index.erb +41 -33
  29. data/views/layout.erb +4 -17
  30. data/views/not_found.erb +4 -4
  31. metadata +82 -16
  32. data/lib/gemirro/cache.rb +0 -115
  33. data/spec/gemirro/cache_spec.rb +0 -32
  34. data/template/public/dist/css/bootstrap.min.css +0 -7
  35. data/template/public/dist/fonts/glyphicons-halflings-regular.eot +0 -0
  36. data/template/public/dist/fonts/glyphicons-halflings-regular.svg +0 -288
  37. data/template/public/dist/fonts/glyphicons-halflings-regular.ttf +0 -0
  38. data/template/public/dist/fonts/glyphicons-halflings-regular.woff +0 -0
  39. data/template/public/dist/fonts/glyphicons-halflings-regular.woff2 +0 -0
  40. data/template/public/dist/js/bootstrap.min.js +0 -7
@@ -1,7 +1,6 @@
1
1
  require 'rack/test'
2
2
  require 'json'
3
3
  require 'parallel'
4
- require 'gemirro/cache'
5
4
  require 'gemirro/utils'
6
5
  require 'gemirro/mirror_directory'
7
6
  require 'gemirro/mirror_file'
@@ -37,11 +36,17 @@ module Gemirro
37
36
  Utils.instance_eval('@gems_orig_collection = nil')
38
37
  Utils.instance_eval('@gems_source_collection = nil')
39
38
  FakeFS::FileSystem.clone(Gemirro::Configuration.views_directory)
39
+ allow_any_instance_of(Indexer).to receive(:compress_indices)
40
+ allow_any_instance_of(Indexer).to receive(:compress_indicies)
41
+ allow_any_instance_of(Indexer).to receive(:rand).and_return('0')
42
+
43
+ source = Source.new('Rubygems', 'https://rubygems.org')
44
+ allow(Gemirro.configuration).to receive(:source).and_return(source)
40
45
  end
41
46
 
42
47
  context 'HTML render' do
43
48
  it 'should display index page' do
44
- allow(Logger).to receive(:new).twice.and_return(@fake_logger)
49
+ allow(Logger).to receive(:new).exactly(3).times.and_return(@fake_logger)
45
50
  allow(@fake_logger).to receive(:tap)
46
51
  .and_return(nil)
47
52
  .and_yield(@fake_logger)
@@ -67,54 +72,63 @@ module Gemirro
67
72
  ::Gem::Version.create('0.1.0'),
68
73
  'ruby']])
69
74
 
70
- MirrorFile.new('/var/www/gemirro/specs.4.8.gz.orig').write(marshal_dump)
71
- Struct.new('SuccessGzipReader', :read)
72
- gzip_reader = Struct::SuccessGzipReader.new(marshal_dump)
73
- MirrorDirectory.new('/var/www/gemirro')
74
- .add_directory('quick/Marshal.4.8')
75
- # rubocop:disable Metrics/LineLength
76
- MirrorFile.new('/var/www/gemirro/quick/Marshal.4.8/' \
77
- 'volay-0.1.0.gemspec.rz')
78
- .write("x\x9C\x8D\x94]\x8F\xD2@\x14\x86\x89Y\xBB\xB4|\xEC\x12\xD7h" \
79
- "\xD4h\xD3K\x13J\x01\x97\xC84n\x9A\xA8\xBBi\xE2\xC5\x06\xBB" \
80
- "{\xC3\x85)\xE5\x00\x13f:u:E\xD1\xC4\xDF\xE6\xB5\xBF\xCAiK" \
81
- "\x11\xE3GK\xEF\x98\xF7\xBC\xCFy\xCF\xC9\xCCQ=A\x0F\xAE\x80" \
82
- "\"\xF4>\x82\x00/p\xE0\v\xCC\xC2;\xC1\xDD\xA3\xFA\xF4\xA1k4" \
83
- "\x06\xA6e\xF6_(Hy\xEBa\xD55\xB4\r#\xFEV\xB1k\xDE\r\xEAdu" \
84
- "\xB7\xC0cY1U\xE4\xA1\x95\x8A\xD3C7A\xAA\x87)\xB4\x9C\x1FO" \
85
- "\xBE\xD7\xE4OA\xEA\x17\x16\x82k\xD4o\xBC\xD7\x99\xC2x\xEC" \
86
- "\xAD@\xBFe$\xA1\xA0\xC7\xDBX\x00\xD5\x05/\xBC\xEFg\xDE\x13" \
87
- "\xF8\x98`\x0E\x14B1U\xE4w\xEC\x1A\xC7\x17\xAF2\x85\xADd\xC4" \
88
- "\xBE96\x87\xF9\x1F\xEA\xDF%\x8A\x95\xE3T\x9E\xCC2\xF3i\x9B" \
89
- "\xA1\xB3\xCC\xFE\rD\x10\xCE!\f\xB6\x1A\xD2\x9C\xD0\xA7\xB2" \
90
- "\xBF\x13\x8A?\x13<\xEB\x06\x04\xA7b\xD4q\xF8\xAF&\x0E!\xDF" \
91
- ".~\xEF\xE3\xDC\xCC@\xD2Hl\#@M\x9E\x84BN\x00\x9D:\x11\a\x0E" \
92
- "\x04\xFC\x18.\xD1#g\x93\xCF\xEB\xC3\x81m\\\xC1\x97\xD9" \
93
- "\x9Af7\\\xE3l\xD7_\xBC\x02BX\"\xD23\xBB\xF9o\x83A\xB1\x12" \
94
- "\xBBe\xB7\xED\x93K\xFB\xB4\x82\xB6\x80\xA9K\xB1\x1E\x96" \
95
- "\x10\xEA\x03sP\xCD\xBFP\x16\xEE\x8D\x85\xBF\x86E\\\x96" \
96
- "\xC02G\xF9\b\xEC\x16:\x9D\xC3\x06\b\x8B\xD2\xA9\x95\x84" \
97
- "\xD9\x97\xED\xC3p\x89+\x81\xA9}\xAB`\xD9\x9D\xFF\x03\xF6" \
98
- "\xD2\xC2\xBF\xCD\xFD`\xDD\x15\x10\x97\xED\xA4.[\xAB\xC6(" \
99
- "\x94\x05B\xE3\xB1\xBC\xA5e\xF6\xC3\xAA\x11\n\xE5>A\x8CiD " \
100
- "`\x9B\xF2\x04\xE3\xCA\t\xC6\x87\by-f,`Q\xD9\x1E,sp^q\x0F" \
101
- "\x85\xD4r\x8Dg\x11\x06\xCE\xC1\xE4>\x9D\xF9\xC9\xFC\xE5" \
102
- "\xC8YR\x1F\x133`4\xBB\xF9R~\xEF:\x93\xE8\x93\\\x92\xBF\r" \
103
- "\xA3\t\xF8\x84l\xF5<\xBF\xBE\xF9\xE3Q\xD2?q,\x04\x84:\x0E" \
104
- "\xF5\xF4\x1D1\xF3\xBA\xE7+!\"\xD4\xEB-\xB1X%\xB3\x14\xD3" \
105
- "\xCB\xEDw\xEE\xBD\xFDk\xE99OSz\xF3\xEA\xFA]w7\xF5\xAF\xB5" \
106
- "\x9F+\xFEG\x96")
107
- # rubocop:enable Metrics/LineLength
75
+ MirrorFile.new('/var/www/gemirro/specs.4.8.gz.local').write(Marshal.dump({}))
76
+
108
77
 
109
- allow(Zlib::GzipReader).to receive(:open)
110
- .once
111
- .with('/var/www/gemirro/specs.4.8.gz.orig')
112
- .and_return(gzip_reader)
78
+ allow(Zlib::GzipReader).to receive(:open).and_return(double(read: marshal_dump))
113
79
 
114
80
  get '/gem/volay'
81
+
82
+ expect(last_response.status).to eq(200)
83
+ expect(last_response).to be_ok
84
+ end
85
+
86
+ it 'responds to compact_index /names' do
87
+ MirrorFile.new('/var/www/gemirro/names.md5.sha256.list').write('---\n- volay\n')
88
+
89
+ get '/names'
90
+ expect(last_response.status).to eq(200)
91
+ expect(last_response).to be_ok
92
+ expect(last_response.body).to eq('---\n- volay\n')
93
+ expect(last_response.headers['etag']).to eq("md5")
94
+ expect(last_response.headers['repr-digest']).to eq('sha-256="sha256"')
95
+ end
96
+
97
+ it 'responds to compact_index /info/[gemname]' do
98
+ marshal_dump = Marshal.dump([['volay',
99
+ ::Gem::Version.create('0.1.0'),
100
+ 'ruby']])
101
+
102
+ MirrorFile.new('/var/www/gemirro/specs.4.8.gz.local').write(Marshal.dump({}))
103
+
104
+ allow(Zlib::GzipReader).to receive(:open).and_return(double(read: marshal_dump))
105
+
106
+
107
+ MirrorDirectory.new('/var/www/gemirro/info')
108
+ MirrorFile.new('/var/www/gemirro/info/volay.md5.sha256.list').write('---\n 0.1.0 |checksum:sha256\n')
109
+
110
+
111
+ get '/info/volay'
115
112
  expect(last_response.status).to eq(200)
116
113
  expect(last_response).to be_ok
114
+ expect(last_response.body).to eq('---\n 0.1.0 |checksum:sha256\n')
115
+ expect(last_response.headers['etag']).to eq("md5")
116
+ expect(last_response.headers['repr-digest']).to eq('sha-256="sha256"')
117
117
  end
118
+
119
+
120
+ it 'responds to compact_index /versions' do
121
+ MirrorFile.new('/var/www/gemirro/versions.md5.sha256.list').write('created_at: 2025-01-01T00:00:00Z\m---\nvolay 0.1.0\n')
122
+
123
+ get '/versions'
124
+ expect(last_response.status).to eq(200)
125
+ expect(last_response).to be_ok
126
+ expect(last_response.body).to eq('created_at: 2025-01-01T00:00:00Z\m---\nvolay 0.1.0\n')
127
+ expect(last_response.headers['etag']).to eq("md5")
128
+ expect(last_response.headers['repr-digest']).to eq('sha-256="sha256"')
129
+ end
130
+
131
+
118
132
  end
119
133
 
120
134
  context 'Download' do
@@ -150,8 +164,8 @@ module Gemirro
150
164
  allow(::Gem::SilentUI).to receive(:new).once.and_return(true)
151
165
 
152
166
  allow(Gemirro.configuration).to receive(:logger)
153
- .exactly(3).and_return(@fake_logger)
154
- allow(@fake_logger).to receive(:info).exactly(3)
167
+ .exactly(4).and_return(@fake_logger)
168
+ allow(@fake_logger).to receive(:info).exactly(4)
155
169
 
156
170
  get '/gems/gemirro-0.0.1.gem'
157
171
  expect(last_response).to_not be_ok
@@ -212,7 +226,7 @@ module Gemirro
212
226
  get '/api/v1/dependencies.json'
213
227
  expect(last_response.headers['Content-Type'])
214
228
  .to eq('application/json')
215
- expect(last_response.body).to eq('')
229
+ expect(last_response.body).to eq('[]')
216
230
  expect(last_response).to be_ok
217
231
  end
218
232
 
@@ -261,6 +275,21 @@ module Gemirro
261
275
  "\x9F+\xFEG\x96")
262
276
  # rubocop:enable Metrics/LineLength
263
277
 
278
+ MirrorFile.new('/var/www/gemirro/api/v1/dependencies/volay.md5.sha.list')
279
+ .write(Marshal.dump([
280
+ {
281
+ name: 'volay',
282
+ number: "0.1.0",
283
+ platform: 'ruby',
284
+ dependencies: [
285
+ {
286
+ name: 'json',
287
+ requirement: '~> 2.1'
288
+ }
289
+ ]
290
+ }
291
+ ]))
292
+
264
293
  gem = Gemirro::GemVersion.new('volay', '0.1.0', 'ruby')
265
294
  collection = Gemirro::GemVersionCollection.new([gem])
266
295
  allow(Utils).to receive(:gems_collection)
data/template/config.rb CHANGED
@@ -23,6 +23,12 @@ Gemirro.configuration.configure do
23
23
  server.access_log File.expand_path('../logs/access.log', __FILE__)
24
24
  server.error_log File.expand_path('../logs/error.log', __FILE__)
25
25
 
26
+ # Number of parallel processes while indexing. Too many will kill
27
+ # your indexing process prematurely.
28
+ #
29
+ # update_threads Etc.nprocessors - 1
30
+ # update_threads 4
31
+
26
32
  # If you don't want to generate indexes after each fetched gem.
27
33
  #
28
34
  # update_on_fetch false
@@ -1 +1,25 @@
1
- .pull-none {float:none;}
1
+ body { max-width: 620px; margin: 0 auto; padding: 0; font-family: sans-serif; }
2
+
3
+ dl { display: grid; grid-template-columns: 1fr min-content; }
4
+
5
+ dt { grid-column: 1; margin: 0; padding: 8px 0; border-bottom: 1px solid #e2e2e2; }
6
+ dd { grid-column: 2; margin: 0; padding: 8px 0; border-bottom: 1px solid #e2e2e2; }
7
+
8
+ dd.full { grid-column: 1/2; border-bottom: 0; }
9
+ dd.description, dd.authors, dd.dependencies { grid-column: 1/2; border-bottom: 0; }
10
+
11
+
12
+ a, a:visited, a:active, a:hover { color: #007bff; }
13
+ .btn { color: #fff; background: #007bff; padding: 5px; border-radius: 4px; text-decoration: none; }
14
+ .btn:visited, .btn:active, .btn:hover { color: #fff; }
15
+
16
+
17
+ ul { list-style-type: none; margin: 0; padding: 0 0 0 1em; }
18
+
19
+
20
+ @media (prefers-color-scheme: dark) {
21
+ html, body { background: #16161d; color: #fff; }
22
+ a, a:visited, a:active, a:hover { color: lightskyblue; }
23
+ .btn { color: #16161d; background: lightskyblue; padding: 5px; border-radius: 4px; text-decoration: none; }
24
+ .btn:visited, .btn:active, .btn:hover { color: #16161d; }
25
+ }
Binary file
Binary file
data/views/gem.erb CHANGED
@@ -1,58 +1,67 @@
1
- <div class="col-lg-12">
2
- <div class="col-lg-3 center-block pull-none text-center">
1
+
3
2
  <a class="btn btn-default" href="<%= url '/'%>">Back to Gem Index</a>
4
3
  </div>
5
4
  </div>
6
5
 
7
- <div class="col-lg-12">
6
+
7
+ <article>
8
8
  <% gem.by_name do |name, versions| %>
9
- <div class="col-lg-6 center-block pull-none">
10
- <div class="panel panel-info">
11
- <div class="panel-heading">
12
- <a href="<%= url("gem/#{name}") %>">
13
- <h2 class="panel-title"><%= escape(name) %> <span class="badge pull-right"><%= escape(versions.newest.number) %></span></h2>
14
- </a>
15
- </div>
16
- <div class="panel-body">
17
- <% newest_gem = versions.newest %>
18
- <% if spec = spec_for(name, newest_gem.number, newest_gem.platform) %>
19
- <p><%= escape(spec.description) %></p>
9
+ <dl>
10
+ <dt>
11
+ <h2><%= Rack::Utils.escape_html(name) %></h2>
12
+ </dt>
13
+ <dd>
14
+ <h2><%= Rack::Utils.escape_html(versions.newest.number) %></h2>
15
+ </dd>
16
+ <% newest_gem = versions.newest %>
17
+ <% spec = Gemirro::Utils.spec_for(name, newest_gem.number, newest_gem.platform) %>
18
+ <% if spec %>
19
+ <dd class="description">
20
+ <%= Rack::Utils.escape_html(spec.description) %>
21
+ </dd>
20
22
 
23
+ <% if spec.dependencies.size > 0 %>
24
+ <dd class="dependencies">
21
25
  <h3>Dependencies</h3>
22
- <ul class="list-group">
26
+ <ul>
23
27
  <% spec.dependencies.each do |dependency| %>
24
28
  <li class="list-group-item">
25
- <a href="<%= url("gem/#{dependency.name}") %>"><%= escape([dependency.name, dependency.requirement].join(' ')) %></a>
29
+ <a href="<%= url("gem/#{dependency.name}") %>"><%= Rack::Utils.escape_html([dependency.name, dependency.requirement].join(' ')) %></a>
26
30
  </li>
27
31
  <% end %>
28
32
  </ul>
33
+ </dd>
34
+ <% end %>
29
35
 
36
+ <% if spec.authors.size > 0 %>
37
+ <dd class="authors">
30
38
  <h3>Authors</h3>
31
- <ul class="list-group">
39
+ <ul>
32
40
  <% spec.authors.each do |author| %>
33
41
  <li class="list-group-item">
34
- <a href="<%= homepage(spec) %>"><%= escape(author) %></a>
42
+ <a href="<%= URI.parse(Addressable::URI.escape(spec.homepage)) %>"><%= Rack::Utils.escape_html(author) %></a>
35
43
  </li>
36
44
  <% end %>
37
45
  </ul>
38
- <% end %>
39
- </div>
46
+ </dd>
47
+ <% end %>
48
+ <% end %>
40
49
 
41
- <ul class="list-group">
42
- <% versions.each.reverse_each do |version| %>
43
- <li class="list-group-item clearfix">
44
- <p class="pull-left">
45
- <code>gem install <%= escape(version.name) %> -v "<%= escape(version.number) %>"</code>
46
- <% unless version.platform =~ /^ruby/i %>
47
- <small class="platform"><%= escape(version.platform) %></small>
48
- <% end %>
49
- </p>
50
- <div class="pull-right">
51
- <a class="btn btn-primary btn-sm" href="<%= url("/gems/#{version.gemfile_name}.gem") %>">Download</a>
52
- </div>
53
- </li>
54
- <% end %>
55
- </ul>
56
- </div>
50
+ <% versions.each.reverse_each do |version| %>
51
+ <dt>
52
+ <code>
53
+ gem install
54
+ <%= Rack::Utils.escape_html(version.name) %>
55
+ --version "<%= Rack::Utils.escape_html(version.number) %>"
56
+ <% unless version.platform =~ /^ruby/i %>
57
+ --platform <%= Rack::Utils.escape_html(version.platform) %>
58
+ <% end %>
59
+ </code>
60
+ </dt>
61
+ <dd>
62
+ <a class="btn" href="<%= url("/gems/#{version.gemfile_name}.gem") %>">Download</a>
63
+ </dd>
64
+ <% end %>
65
+ </dl>
57
66
  <% end %>
58
- </div>
67
+ </article>
data/views/index.erb CHANGED
@@ -1,38 +1,46 @@
1
1
 
2
- <div class="col-lg-12">
3
- <div class="col-lg-3 center-block pull-none">
4
- <pre class="bg-info"><code>gem sources -a <%= url("/") %></code></pre>
5
- </div>
6
- </div>
2
+ <code>gem sources -a <%= url("/") %></code>
7
3
 
8
- <div class="col-lg-12">
9
- <% if gems.any? %>
10
- <div class="col-lg-6 center-block pull-none">
11
- <% gems.by_name do |name, versions| %>
12
- <div class="panel panel-info">
13
- <div class="panel-heading">
14
- <a href="<%= url("gem/#{name}") %>">
15
- <h2 class="panel-title"><%= escape(name) %> <span class="badge pull-right"><%= escape(versions.newest.number) %></span></h2>
16
- </a>
17
- </div>
4
+ <% if gems.any? %>
5
+ <article>
6
+ <% gems.by_name do |name, versions| %>
7
+ <dl>
8
+ <dt>
9
+ <a href="<%= url("gem/#{name}") %>">
10
+ <h2><%= Rack::Utils.escape_html(name) %></h2>
11
+ </a>
12
+ </dt>
13
+ <dd>
14
+ <h2><%= Rack::Utils.escape_html(versions.newest.number) %></h2>
15
+ </dd>
16
+
17
+ <% spec = Gemirro::Utils.spec_for(name, versions.newest.number, versions.newest.platform) %>
18
+ <% if spec.is_a?(::Gem::Specification) %>
19
+ <dd class="description">
20
+ <%= Rack::Utils.escape_html(spec.description) %>
21
+ </dd>
22
+ <% end %>
18
23
 
19
- <div class="panel-body">
20
- <% spec = spec_for(name, versions.newest.number) %>
21
- <% if spec.is_a?(::Gem::Specification) %>
22
- <%= escape(spec.description) %>
23
- <% end %>
24
-
25
- <% versions.reverse_each.first(5).each do |version| %>
26
- <p>
27
- <code>gem install <%= escape(version.name) %> <%= "--prerelease" if version.number.to_s.match(/[a-z]/i) %> -v "<%= escape(version.number) %>"</code>
24
+ <% versions.reverse_each.first(5).each do |version| %>
25
+ <dt class="version">
26
+ <code>
27
+ gem install
28
+ <%= Rack::Utils.escape_html(version.name) %>
29
+ <%= "--prerelease" if version.number.to_s.match(/[a-z]/i) %>
30
+ --version "<%= Rack::Utils.escape_html(version.number) %>"
28
31
  <% unless version.platform =~ /^ruby/i %>
29
- <small class="platform"><%= escape(version.platform) %></small>
32
+ --platform <%= Rack::Utils.escape_html(version.platform) %></small>
30
33
  <% end %>
31
- </p>
32
- <% end %>
33
- </div>
34
- </div>
35
- <% end %>
36
- </div>
37
- <% end %>
38
- </div>
34
+ </code>
35
+ </dt>
36
+ <dd>
37
+ <a class="btn btn-primary btn-sm" href="<%= url("/gems/#{version.gemfile_name}.gem") %>">Download</a>
38
+ </dd>
39
+ <% end %>
40
+ <% if versions.size > 5 %>
41
+ <dd class="full"><a href="<%= url("gem/#{name}") %>"><%= "And %d More..." % [versions.size - 5] %></a></dd>
42
+ <% end %>
43
+ </dl>
44
+ <% end %>
45
+ </article>
46
+ <% end %>
data/views/layout.erb CHANGED
@@ -2,31 +2,18 @@
2
2
  <html>
3
3
  <head>
4
4
  <meta charset="utf-8">
5
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
7
6
  <meta name="description" content="Ruby gems mirror">
8
7
  <meta name="author" content="Pierre Rambaud">
9
8
 
10
9
  <title>Gemirro - a simple ruby gems mirror</title>
11
10
 
12
- <link href="/dist/css/bootstrap.min.css" media="screen" rel="stylesheet" type="text/css" />
13
11
  <link href="/dist/css/gemirro.css" media="screen" rel="stylesheet" type="text/css" />
14
-
15
12
  </head>
16
13
  <body>
17
- <div class="container-fluid">
18
- <div class="row">
19
- <div class="col-lg-12 text-center">
20
- <h1>Gemirro</h1>
21
- </div>
22
- </div>
23
- <div class="row">
24
- <div class="col-lg-12">
25
- <%= yield %>
26
- </div>
27
- </div>
28
- </div>
29
- <script src="/dist/js/jquery-3.2.1.slim.min.js" type="text/javascript"></script>
30
- <script src="/dist/js/bootstrap.bundle.min.js" type="text/javascript"></script>
14
+ <header>
15
+ <h1>Gemirro</h1>
16
+ </header>
17
+ <%= yield %>
31
18
  </body>
32
19
  </html>
data/views/not_found.erb CHANGED
@@ -1,4 +1,4 @@
1
- <div class="center-block text-center">
2
- <h1>Page not found.</h1>
3
- <a class="btn btn-default" href="<%= url('/') %>">Back to <%= url('/') %> →</a>
4
- </div>
1
+
2
+ <h1>Page not found.</h1>
3
+
4
+ <a class="btn" href="<%= url('/') %>">Back to <%= url('/') %> →</a>
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: 1.5.0
4
+ version: 1.6.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: 2025-01-20 00:00:00.000000000 Z
11
+ date: 2025-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: compact_index
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.15'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.15'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: confstruct
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +94,48 @@ dependencies:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
96
  version: '2.8'
97
+ - !ruby/object:Gem::Dependency
98
+ name: logger
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">"
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">"
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: mutex_m
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">"
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">"
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: ostruct
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">"
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">"
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
83
139
  - !ruby/object:Gem::Dependency
84
140
  name: parallel
85
141
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +150,20 @@ dependencies:
94
150
  - - "~>"
95
151
  - !ruby/object:Gem::Version
96
152
  version: '1.21'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rubygems-generate_index
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">"
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">"
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
97
167
  - !ruby/object:Gem::Dependency
98
168
  name: sinatra
99
169
  requirement: !ruby/object:Gem::Requirement
@@ -132,16 +202,16 @@ dependencies:
132
202
  name: stringio
133
203
  requirement: !ruby/object:Gem::Requirement
134
204
  requirements:
135
- - - "~>"
205
+ - - ">"
136
206
  - !ruby/object:Gem::Version
137
- version: '3.1'
207
+ version: '0'
138
208
  type: :runtime
139
209
  prerelease: false
140
210
  version_requirements: !ruby/object:Gem::Requirement
141
211
  requirements:
142
- - - "~>"
212
+ - - ">"
143
213
  - !ruby/object:Gem::Version
144
- version: '3.1'
214
+ version: '0'
145
215
  - !ruby/object:Gem::Dependency
146
216
  name: thin
147
217
  requirement: !ruby/object:Gem::Requirement
@@ -163,9 +233,11 @@ executables:
163
233
  extensions: []
164
234
  extra_rdoc_files: []
165
235
  files:
236
+ - ".github/workflows/ruby.yml"
166
237
  - ".gitignore"
167
238
  - ".rubocop.yml"
168
239
  - Gemfile
240
+ - Gemfile.lock
169
241
  - LICENSE
170
242
  - MANIFEST
171
243
  - README.md
@@ -173,7 +245,6 @@ files:
173
245
  - bin/gemirro
174
246
  - gemirro.gemspec
175
247
  - lib/gemirro.rb
176
- - lib/gemirro/cache.rb
177
248
  - lib/gemirro/cli.rb
178
249
  - lib/gemirro/cli/index.rb
179
250
  - lib/gemirro/cli/init.rb
@@ -197,7 +268,6 @@ files:
197
268
  - lib/gemirro/versions_file.rb
198
269
  - spec/fixtures/gems/gemirro-0.0.1.gem
199
270
  - spec/fixtures/quick/gemirro-0.0.1.gemspec.rz
200
- - spec/gemirro/cache_spec.rb
201
271
  - spec/gemirro/cli_spec.rb
202
272
  - spec/gemirro/configuration_spec.rb
203
273
  - spec/gemirro/gem_spec.rb
@@ -218,15 +288,11 @@ files:
218
288
  - task/rubocop.rake
219
289
  - template/config.rb
220
290
  - template/logs/.gitkeep
221
- - template/public/dist/css/bootstrap.min.css
222
291
  - template/public/dist/css/gemirro.css
223
- - template/public/dist/fonts/glyphicons-halflings-regular.eot
224
- - template/public/dist/fonts/glyphicons-halflings-regular.svg
225
- - template/public/dist/fonts/glyphicons-halflings-regular.ttf
226
- - template/public/dist/fonts/glyphicons-halflings-regular.woff
227
- - template/public/dist/fonts/glyphicons-halflings-regular.woff2
228
- - template/public/dist/js/bootstrap.min.js
229
292
  - template/public/gems/.gitkeep
293
+ - template/public/latest_specs.4.8
294
+ - template/public/prerelease_specs.4.8
295
+ - template/public/specs.4.8
230
296
  - views/gem.erb
231
297
  - views/index.erb
232
298
  - views/layout.erb
@@ -244,7 +310,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
244
310
  requirements:
245
311
  - - ">="
246
312
  - !ruby/object:Gem::Version
247
- version: '2.5'
313
+ version: '3.0'
248
314
  required_rubygems_version: !ruby/object:Gem::Requirement
249
315
  requirements:
250
316
  - - ">="