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 CHANGED
@@ -1,12 +1,13 @@
1
1
  # Gem in a Box – Really simple rubygem hosting
2
- ##
2
+ ##
3
3
 
4
- Geminabox let's you host your own gems, and push new gems to it just like with rubygems.org.
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 it left up to either the web server, or the Rack stack.
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 verions (< 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 yout config.ru file:
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
 
@@ -1 +1 @@
1
- GeminaboxVersion = '0.6.1' unless defined? GeminaboxVersion
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
- disk_cache.cache(params[:gems]) do
54
- query_gems = params[:gems].split(',')
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
- File.open(dest_filename, "wb") do |f|
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")
@@ -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 < 400
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 "http://fonts.googleapis.com/css?family=Droid+Sans+Mono";
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
@@ -1,3 +1,6 @@
1
+ <p>
2
+ <small>Choose a gem file to upload ...</small>
3
+ </p>
1
4
  <%= @error %>
2
5
  <form method="POST" enctype="multipart/form-data">
3
6
  <input type="file" name="file">
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
- hash: 5
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
- date: 2012-03-17 00:00:00 Z
19
- dependencies:
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
- - !ruby/object:Gem::Dependency
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
- hash: 3
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
- requirement: &id003 !ruby/object:Gem::Requirement
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
- hash: 3
57
- segments:
58
- - 0
59
- version: "0"
60
- version_requirements: *id003
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
- - !ruby/object:Gem::Dependency
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
- requirement: &id004 !ruby/object:Gem::Requirement
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
- hash: 3
71
- segments:
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
- requirement: &id005 !ruby/object:Gem::Requirement
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
- hash: 3
85
- segments:
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
- requirement: &id006 !ruby/object:Gem::Requirement
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
- hash: 3
99
- segments:
100
- - 0
101
- version: "0"
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
- hash: 3
146
- segments:
149
+ requirements:
150
+ - - ! '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ segments:
147
154
  - 0
148
- version: "0"
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
- hash: 3
155
- segments:
158
+ requirements:
159
+ - - ! '>='
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ segments:
156
163
  - 0
157
- version: "0"
164
+ hash: 4127424449105456213
158
165
  requirements: []
159
-
160
166
  rubyforge_project:
161
- rubygems_version: 1.8.13
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
-