geminabox 0.6.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of geminabox might be problematic. Click here for more details.
- data/README.markdown +5 -4
- data/lib/geminabox/version.rb +1 -1
- data/lib/geminabox.rb +25 -6
- data/lib/geminabox_client.rb +2 -1
- data/public/master.css +8 -2
- data/views/gem.erb +37 -0
- data/views/index.erb +14 -1
- data/views/layout.erb +0 -8
- data/views/upload.erb +3 -0
- metadata +111 -106
data/README.markdown
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
# Gem in a Box – Really simple rubygem hosting
|
2
|
-
##
|
2
|
+
##
|
3
3
|
|
4
|
-
Geminabox
|
4
|
+
Geminabox lets you host your own gems, and push new gems to it just like with rubygems.org.
|
5
5
|
The bundler dependencies API is supported out of the box.
|
6
|
-
Authentication
|
6
|
+
Authentication is left up to either the web server, or the Rack stack.
|
7
7
|
For basic auth, try [Rack::Auth](http://rack.rubyforge.org/doc/Rack/Auth/Basic.html).
|
8
8
|
|
9
9
|
|
10
|
+
[![Build Status](https://secure.travis-ci.org/cwninja/geminabox.png)](http://travis-ci.org/cwninja/geminabox)
|
10
11
|
|
11
12
|
|
12
13
|
![screen shot](http://pics.tomlea.co.uk/bbbba6/geminabox.png)
|
@@ -30,7 +31,7 @@ And finally, hook up the config.ru as you normally would ([passenger][passenger]
|
|
30
31
|
|
31
32
|
## Legacy RubyGems index
|
32
33
|
|
33
|
-
RubyGems supports generating indexes for the so called legacy
|
34
|
+
RubyGems supports generating indexes for the so called legacy versions (< 1.2), and since it is very rare to use such versions nowadays, it can be disabled, thus improving indexing times for large repositories. If it's safe for your application, you can disable support for these legacy versions by adding the following configuration to your config.ru file:
|
34
35
|
|
35
36
|
Geminabox.build_legacy = false
|
36
37
|
|
data/lib/geminabox/version.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
GeminaboxVersion = '0.
|
1
|
+
GeminaboxVersion = '0.7.0' unless defined? GeminaboxVersion
|
data/lib/geminabox.rb
CHANGED
@@ -7,6 +7,7 @@ require 'rubygems/indexer'
|
|
7
7
|
require 'hostess'
|
8
8
|
require 'geminabox/version'
|
9
9
|
require 'rss/atom'
|
10
|
+
require 'tempfile'
|
10
11
|
|
11
12
|
class Geminabox < Sinatra::Base
|
12
13
|
enable :static, :methodoverride
|
@@ -50,8 +51,9 @@ class Geminabox < Sinatra::Base
|
|
50
51
|
end
|
51
52
|
|
52
53
|
get '/api/v1/dependencies' do
|
53
|
-
|
54
|
-
|
54
|
+
query_gems = params[:gems].split(',').sort
|
55
|
+
cache_key = query_gems.join(',')
|
56
|
+
disk_cache.cache(cache_key) do
|
55
57
|
deps = load_gems.gems.select {|gem| query_gems.include?(gem.name) }.map do |gem|
|
56
58
|
spec = spec_for(gem.name, gem.number)
|
57
59
|
{
|
@@ -74,6 +76,13 @@ class Geminabox < Sinatra::Base
|
|
74
76
|
redirect url("/")
|
75
77
|
end
|
76
78
|
|
79
|
+
get '/gems/:gemname' do
|
80
|
+
gems = Hash[load_gems.by_name]
|
81
|
+
@gem = gems[params[:gemname]]
|
82
|
+
halt 404 unless @gem
|
83
|
+
erb :gem
|
84
|
+
end
|
85
|
+
|
77
86
|
delete '/gems/*.gem' do
|
78
87
|
File.delete file_path if File.exists? file_path
|
79
88
|
reindex(:force_rebuild)
|
@@ -82,8 +91,8 @@ class Geminabox < Sinatra::Base
|
|
82
91
|
|
83
92
|
post '/upload' do
|
84
93
|
if File.exists? Geminabox.data
|
85
|
-
error_response( 500, "Please ensure #{File.expand_path(Geminabox.data)} is writable by the geminabox web server." ) unless File.writable? Geminabox.data
|
86
94
|
error_response( 500, "Please ensure #{File.expand_path(Geminabox.data)} is a directory." ) unless File.directory? Geminabox.data
|
95
|
+
error_response( 500, "Please ensure #{File.expand_path(Geminabox.data)} is writable by the geminabox web server." ) unless File.writable? Geminabox.data
|
87
96
|
else
|
88
97
|
begin
|
89
98
|
FileUtils.mkdir_p(settings.data)
|
@@ -114,14 +123,14 @@ class Geminabox < Sinatra::Base
|
|
114
123
|
error_response(200, "Ignoring upload, you uploaded the same thing previously.")
|
115
124
|
end
|
116
125
|
end
|
117
|
-
|
118
|
-
|
126
|
+
|
127
|
+
atomic_write(dest_filename) do |f|
|
119
128
|
while blk = tmpfile.read(65536)
|
120
129
|
f << blk
|
121
130
|
end
|
122
131
|
end
|
123
132
|
reindex
|
124
|
-
|
133
|
+
|
125
134
|
if api_request?
|
126
135
|
"Gem #{gem_name} received and indexed."
|
127
136
|
else
|
@@ -193,6 +202,16 @@ HTML
|
|
193
202
|
Set.new(gems.map{|gem| gem.name[0..0].downcase})
|
194
203
|
end
|
195
204
|
|
205
|
+
# based on http://as.rubyonrails.org/classes/File.html
|
206
|
+
def atomic_write(file_name)
|
207
|
+
temp_dir = File.join(settings.data, "_temp")
|
208
|
+
FileUtils.mkdir_p(temp_dir)
|
209
|
+
temp_file = Tempfile.new("." + File.basename(file_name), temp_dir)
|
210
|
+
yield temp_file
|
211
|
+
temp_file.close
|
212
|
+
File.rename(temp_file.path, file_name)
|
213
|
+
end
|
214
|
+
|
196
215
|
helpers do
|
197
216
|
def spec_for(gem_name, version)
|
198
217
|
spec_file = File.join(settings.data, "quick", "Marshal.#{Gem.marshal_version}", "#{gem_name}-#{version}.gemspec.rz")
|
data/lib/geminabox_client.rb
CHANGED
@@ -10,6 +10,7 @@ class GeminaboxClient
|
|
10
10
|
@http_client.set_auth(url_for(:upload), @username, @password) if @username or @password
|
11
11
|
@http_client.www_auth.basic_auth.challenge(url_for(:upload)) # Workaround: https://github.com/nahi/httpclient/issues/63
|
12
12
|
@http_client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
13
|
+
@http_client.send_timeout = 600
|
13
14
|
end
|
14
15
|
|
15
16
|
def extract_username_and_password_from_url!(url)
|
@@ -27,7 +28,7 @@ class GeminaboxClient
|
|
27
28
|
def push(gemfile)
|
28
29
|
response = http_client.post(url_for(:upload), {'file' => File.open(gemfile, "rb")}, {'Accept' => 'text/plain'})
|
29
30
|
|
30
|
-
if response.status <
|
31
|
+
if response.status < 300
|
31
32
|
response.body
|
32
33
|
else
|
33
34
|
raise GeminaboxClient::Error, "Error (#{response.code} received)\n\n#{response.body}"
|
data/public/master.css
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
@import "
|
1
|
+
@import "https://fonts.googleapis.com/css?family=Droid+Sans+Mono";
|
2
2
|
|
3
3
|
|
4
4
|
body {
|
@@ -24,6 +24,12 @@ a:hover {
|
|
24
24
|
color: #00f;
|
25
25
|
}
|
26
26
|
|
27
|
+
a#more_link {
|
28
|
+
font-size: 0.7em;
|
29
|
+
line-height: 1.2;
|
30
|
+
vertical-align: bottom;
|
31
|
+
}
|
32
|
+
|
27
33
|
form {
|
28
34
|
margin: 0;
|
29
35
|
}
|
@@ -146,4 +152,4 @@ ul.gemlist li:hover a.download {
|
|
146
152
|
|
147
153
|
.gem-version small.platform {
|
148
154
|
padding: 0 0 0 15px;
|
149
|
-
}
|
155
|
+
}
|
data/views/gem.erb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
<p>
|
2
|
+
<a href="/">Back to Gem Index</a>
|
3
|
+
</p>
|
4
|
+
|
5
|
+
<ul class="gemlist">
|
6
|
+
<% @gem.by_name do |name, versions| %>
|
7
|
+
<li class="gem-version">
|
8
|
+
<h2><%= name %> (<%= versions.count == 1 ? versions.first.number : "#{versions.oldest.number} - #{versions.newest.number}" %>)</h2>
|
9
|
+
<% versions.each.reverse_each do |version| %>
|
10
|
+
<p>
|
11
|
+
<code>gem install <%= version.name %> <%= "--prerelease" if version.number.to_s.match(/[a-z]/i) %> -v "<%= version.number %>"</code>
|
12
|
+
<% unless version.platform =~ /^ruby/i %>
|
13
|
+
<small class="platform"><%= version.platform %></small>
|
14
|
+
<% end %>
|
15
|
+
</p>
|
16
|
+
<form class="delete-form" method="post" action="<%= url("/gems/#{version.gemfile_name}.gem") %>">
|
17
|
+
<a class="download" href="<%= url("/gems/#{version.gemfile_name}.gem") %>">download</a>
|
18
|
+
<input type="hidden" name="_method" value="DELETE" />
|
19
|
+
<button type="submit">delete</button>
|
20
|
+
</form>
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<div class="details">
|
24
|
+
<p>
|
25
|
+
<% if spec = spec_for(name, versions.newest.number) %>
|
26
|
+
<%= spec.description %>
|
27
|
+
<br/>
|
28
|
+
<span class="author">– <%= spec.authors.map do |author|
|
29
|
+
"<a href='#{spec.homepage}'>#{author}</a>"
|
30
|
+
end.join(', ') %></span>
|
31
|
+
<% end %>
|
32
|
+
</p>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
</li>
|
36
|
+
<% end %>
|
37
|
+
</ul>
|
data/views/index.erb
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
<p>
|
2
|
+
<small>If you did not need any credentials to get to this page</small>
|
3
|
+
<pre><code>gem sources -a <%= url "/" %></code></pre>
|
4
|
+
<small>If you needed some credentials to get to this page</small>
|
5
|
+
<pre><code>gem sources -a <%= url.to_s.gsub('://','://username:password@') %></code></pre>
|
6
|
+
<small>and then ...</small>
|
7
|
+
<pre><code>gem install geminabox<br />gem inabox [gemfile]</code></pre>
|
8
|
+
</p>
|
9
|
+
|
1
10
|
<% if @gems.any? %>
|
2
11
|
<a href="<%= url("/upload") %>">Upload Another Gem</a>
|
3
12
|
|
@@ -8,7 +17,7 @@
|
|
8
17
|
<% @gems.by_name do |name, versions| %>
|
9
18
|
<li <%= %{id="jump_#{name[0..0].downcase}"} if @index_gems.delete(name[0..0].downcase) %> class="gem-version">
|
10
19
|
<h2><%= name %> (<%= versions.count == 1 ? versions.first.number : "#{versions.oldest.number} - #{versions.newest.number}" %>)</h2>
|
11
|
-
<% versions.each do |version| %>
|
20
|
+
<% versions.each.reverse_each.first(5).each do |version| %>
|
12
21
|
<p>
|
13
22
|
<code>gem install <%= version.name %> <%= "--prerelease" if version.number.to_s.match(/[a-z]/i) %> -v "<%= version.number %>"</code>
|
14
23
|
<% unless version.platform =~ /^ruby/i %>
|
@@ -22,6 +31,10 @@
|
|
22
31
|
</form>
|
23
32
|
<% end %>
|
24
33
|
|
34
|
+
<% if versions.count > 5 %>
|
35
|
+
<a href="<%= url("/gems/#{name}") %>" id="more_link">Older versions...</a>
|
36
|
+
<% end %>
|
37
|
+
|
25
38
|
<div class="details">
|
26
39
|
<p>
|
27
40
|
<% if spec = spec_for(name, versions.newest.number) %>
|
data/views/layout.erb
CHANGED
@@ -8,14 +8,6 @@
|
|
8
8
|
<body>
|
9
9
|
<div id="content">
|
10
10
|
<h1>Gem in a Box</h1>
|
11
|
-
<p>
|
12
|
-
<small>If you did not need any credentials to get to this page</small>
|
13
|
-
<pre><code>gem sources -a <%= url "/" %></code></pre>
|
14
|
-
<small>If you needed some credentials to get to this page</small>
|
15
|
-
<pre><code>gem sources -a <%= url.to_s.gsub('://','://username:password@') %></code></pre>
|
16
|
-
<small>and then ...</small>
|
17
|
-
<pre><code>gem install geminabox<br />gem inabox [gemfile]</code></pre>
|
18
|
-
</p>
|
19
11
|
<%= yield %>
|
20
12
|
</div>
|
21
13
|
<script type="text/javascript" src="<%= url "/jquery.js" %>"></script>
|
data/views/upload.erb
CHANGED
metadata
CHANGED
@@ -1,115 +1,122 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: geminabox
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.7.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 6
|
9
|
-
- 1
|
10
|
-
version: 0.6.1
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Tom Lea
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
21
|
-
prerelease: false
|
22
|
-
type: :runtime
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
-
none: false
|
25
|
-
requirements:
|
26
|
-
- - ">="
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
hash: 3
|
29
|
-
segments:
|
30
|
-
- 0
|
31
|
-
version: "0"
|
32
|
-
version_requirements: *id001
|
12
|
+
date: 2012-08-22 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
33
15
|
name: sinatra
|
34
|
-
|
35
|
-
prerelease: false
|
36
|
-
type: :runtime
|
37
|
-
requirement: &id002 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70182476864760 !ruby/object:Gem::Requirement
|
38
17
|
none: false
|
39
|
-
requirements:
|
40
|
-
- -
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
|
43
|
-
segments:
|
44
|
-
- 0
|
45
|
-
version: "0"
|
46
|
-
version_requirements: *id002
|
47
|
-
name: builder
|
48
|
-
- !ruby/object:Gem::Dependency
|
49
|
-
prerelease: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
50
22
|
type: :runtime
|
51
|
-
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70182476864760
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: builder
|
27
|
+
requirement: &70182476863120 !ruby/object:Gem::Requirement
|
52
28
|
none: false
|
53
|
-
requirements:
|
54
|
-
- -
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70182476863120
|
36
|
+
- !ruby/object:Gem::Dependency
|
61
37
|
name: httpclient
|
62
|
-
|
38
|
+
requirement: &70182476861740 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
63
45
|
prerelease: false
|
46
|
+
version_requirements: *70182476861740
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
requirement: &70182476861160 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
64
55
|
type: :development
|
65
|
-
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70182476861160
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rack-test
|
60
|
+
requirement: &70182476859960 !ruby/object:Gem::Requirement
|
66
61
|
none: false
|
67
|
-
requirements:
|
68
|
-
- -
|
69
|
-
- !ruby/object:Gem::Version
|
70
|
-
|
71
|
-
|
72
|
-
- 0
|
73
|
-
version: "0"
|
74
|
-
version_requirements: *id004
|
75
|
-
name: rake
|
76
|
-
- !ruby/object:Gem::Dependency
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
77
67
|
prerelease: false
|
68
|
+
version_requirements: *70182476859960
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest
|
71
|
+
requirement: &70182476858640 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
78
77
|
type: :development
|
79
|
-
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70182476858640
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: capybara
|
82
|
+
requirement: &70182480431960 !ruby/object:Gem::Requirement
|
80
83
|
none: false
|
81
|
-
requirements:
|
82
|
-
- -
|
83
|
-
- !ruby/object:Gem::Version
|
84
|
-
|
85
|
-
|
86
|
-
- 0
|
87
|
-
version: "0"
|
88
|
-
version_requirements: *id005
|
89
|
-
name: rack-test
|
90
|
-
- !ruby/object:Gem::Dependency
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :development
|
91
89
|
prerelease: false
|
90
|
+
version_requirements: *70182480431960
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: capybara-mechanize
|
93
|
+
requirement: &70182480428020 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
92
99
|
type: :development
|
93
|
-
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *70182480428020
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: pry
|
104
|
+
requirement: &70182480424560 !ruby/object:Gem::Requirement
|
94
105
|
none: false
|
95
|
-
requirements:
|
96
|
-
- -
|
97
|
-
- !ruby/object:Gem::Version
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
version_requirements: *id006
|
103
|
-
name: minitest
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: *70182480424560
|
104
113
|
description: A sinatra based gem hosting app, with client side gem push style functionality.
|
105
114
|
email: contrib@tomlea.co.uk
|
106
115
|
executables: []
|
107
|
-
|
108
116
|
extensions: []
|
109
|
-
|
110
|
-
extra_rdoc_files:
|
117
|
+
extra_rdoc_files:
|
111
118
|
- README.markdown
|
112
|
-
files:
|
119
|
+
files:
|
113
120
|
- README.markdown
|
114
121
|
- lib/geminabox/disk_cache.rb
|
115
122
|
- lib/geminabox/gem_version.rb
|
@@ -125,42 +132,40 @@ files:
|
|
125
132
|
- public/master.css
|
126
133
|
- public/master.js
|
127
134
|
- views/atom.erb
|
135
|
+
- views/gem.erb
|
128
136
|
- views/index.erb
|
129
137
|
- views/layout.erb
|
130
138
|
- views/upload.erb
|
131
139
|
homepage: http://tomlea.co.uk/p/gem-in-a-box
|
132
140
|
licenses: []
|
133
|
-
|
134
141
|
post_install_message:
|
135
|
-
rdoc_options:
|
142
|
+
rdoc_options:
|
136
143
|
- --main
|
137
144
|
- README.markdown
|
138
|
-
require_paths:
|
145
|
+
require_paths:
|
139
146
|
- lib
|
140
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
147
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
148
|
none: false
|
142
|
-
requirements:
|
143
|
-
- -
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
|
146
|
-
segments:
|
149
|
+
requirements:
|
150
|
+
- - ! '>='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
segments:
|
147
154
|
- 0
|
148
|
-
|
149
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
155
|
+
hash: 4127424449105456213
|
156
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
157
|
none: false
|
151
|
-
requirements:
|
152
|
-
- -
|
153
|
-
- !ruby/object:Gem::Version
|
154
|
-
|
155
|
-
segments:
|
158
|
+
requirements:
|
159
|
+
- - ! '>='
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '0'
|
162
|
+
segments:
|
156
163
|
- 0
|
157
|
-
|
164
|
+
hash: 4127424449105456213
|
158
165
|
requirements: []
|
159
|
-
|
160
166
|
rubyforge_project:
|
161
|
-
rubygems_version: 1.8.
|
167
|
+
rubygems_version: 1.8.15
|
162
168
|
signing_key:
|
163
169
|
specification_version: 3
|
164
170
|
summary: Really simple rubygem hosting
|
165
171
|
test_files: []
|
166
|
-
|