geminabox 0.12.4 → 0.13.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.

checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- MTBmZWQxYjM3NjFlODM4NmQ0N2ViMjY1MjU0ZjRiMWE4ODcyMjFmYw==
5
- data.tar.gz: !binary |-
6
- NTcwNGQ5YjkxMDNkMGMzOWNmMThjNTJlNmVlNDg0MjE0MGEzNTdkMg==
2
+ SHA1:
3
+ metadata.gz: d0d8d2b7b2d895ef9b0017f0e6b48132fa3e6a16
4
+ data.tar.gz: f333f2cf2dbf72221cc0fd281f8b720def07d2a0
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- YWQyZjU1NWM4M2FmY2U1NDgzMzU5MTgzYWI1ZTVjYzc0ZWVjNTM4MTkyMzRk
10
- NTc3NjM4N2VkNTljODAwZjk5MDQ5MTdiZjU1ZGMyNTg0ZjMzNTQ3Y2FkMjJk
11
- YjE2NTI2Y2NiNzY5NWUyNzdlNGJiMTBlOWU1MDBiYzJjZDg3MzU=
12
- data.tar.gz: !binary |-
13
- NTUwM2EwZGVjYzc2ZTI3YjExMjI2ODI3ODZlMjc2YzIzOWUyM2IxMmIyYmMy
14
- MDdkMTNmY2E5ZmRkYzNiM2YyMjliMWViYjM2NWFlMWFmMzY5NWFmOTFiY2Uz
15
- ZDc1ZmU4NWY3MjM1NTY3MDg1MTcyYWM5NDY5YjgzOWM3MmZkODA=
6
+ metadata.gz: 9146b95e001840793b881bc3cb72dfc5103019251aa71ae1b0f5d3bd93fb59553ae2cc61478deaee5aa6615197c33149e99cc69cfac5c8c944b15b766af4accc
7
+ data.tar.gz: 1dc6216ac61f994bb72ce106c3717b03e8a5599330d1c9050683f2628277cbb3daa5d3038b1170e208013510133d8da2421c7bc6f9d2905cb1c1209505eda1fc
@@ -1,11 +1,12 @@
1
1
  # Gem in a Box – Really simple rubygem hosting
2
2
  [![Build Status](https://secure.travis-ci.org/geminabox/geminabox.png)](http://travis-ci.org/geminabox/geminabox)
3
3
  [![Gem Version](https://badge.fury.io/rb/geminabox.png)](http://badge.fury.io/rb/geminabox)
4
+ [![Code Climate](https://codeclimate.com/github/geminabox/geminabox/badges/gpa.svg)](https://codeclimate.com/github/geminabox/geminabox)
4
5
 
5
6
  Geminabox lets you host your own gems, and push new gems to it just like with rubygems.org.
6
7
  The bundler dependencies API is supported out of the box.
7
8
  Authentication is left up to either the web server, or the Rack stack.
8
- For basic auth, try [Rack::Auth](http://rack.rubyforge.org/doc/Rack/Auth/Basic.html).
9
+ For basic auth, try [Rack::Auth](http://www.rubydoc.info/github/rack/rack/Rack/Auth/Basic).
9
10
 
10
11
  ![screen shot](http://pics.tomlea.co.uk/bbbba6/geminabox.png)
11
12
 
@@ -48,6 +49,10 @@ Or in config.ru (before the run command), set:
48
49
 
49
50
  Geminabox.rubygems_proxy = true
50
51
 
52
+ If you want Geminabox to carry on providing gems when rubygems.org is unavailable, add this to config.ru:
53
+
54
+ Geminabox.allow_remote_failure = true
55
+
51
56
  ## HTTP adapter
52
57
 
53
58
  Geminabox uses the HTTPClient gem to manage its connections to remote resources.
@@ -8,9 +8,13 @@ require 'rubygems/package'
8
8
  require 'rss/atom'
9
9
  require 'tempfile'
10
10
  require 'json'
11
+ require 'tilt/erb'
11
12
 
12
13
  module Geminabox
13
14
 
15
+ class Error < StandardError ; end
16
+ class AlreadyLocked < Error ; end
17
+
14
18
  require_relative 'geminabox/version'
15
19
  require_relative 'geminabox/proxy'
16
20
  require_relative 'geminabox/http_adapter'
@@ -43,7 +47,10 @@ module Geminabox
43
47
  :allow_delete,
44
48
  :rubygems_proxy,
45
49
  :http_adapter,
46
- :allow_remote_failure
50
+ :lockfile,
51
+ :retry_interval,
52
+ :allow_remote_failure,
53
+ :ruby_gems_url
47
54
  )
48
55
 
49
56
  def set_defaults(defaults)
@@ -73,7 +80,10 @@ module Geminabox
73
80
  rubygems_proxy: (ENV['RUBYGEMS_PROXY'] == 'true'),
74
81
  allow_delete: true,
75
82
  http_adapter: HttpClientAdapter.new,
76
- allow_remote_failure: false
83
+ lockfile: '/tmp/geminabox.lockfile',
84
+ retry_interval: 60,
85
+ allow_remote_failure: false,
86
+ ruby_gems_url: 'https://rubygems.org/'
77
87
  )
78
88
 
79
89
  end
@@ -1,7 +1,7 @@
1
1
  module Geminabox
2
2
 
3
3
  class IncomingGem
4
- def initialize(gem_data, root_path = Geminabox.settings.data)
4
+ def initialize(gem_data, root_path = Geminabox.data)
5
5
  unless gem_data.respond_to? :read
6
6
  raise ArgumentError, "Expected an instance of IO"
7
7
  end
@@ -21,7 +21,7 @@ module Geminabox::Indexer
21
21
  end
22
22
 
23
23
  def self.updated_gemspecs(indexer)
24
- specs_mtime = File.stat(indexer.dest_specs_index).mtime
24
+ specs_mtime = File.stat(indexer.dest_specs_index).mtime rescue Time.at(0)
25
25
  newest_mtime = Time.at 0
26
26
 
27
27
  updated_gems = indexer.gem_file_list.select do |gem|
@@ -59,7 +59,7 @@ module Geminabox
59
59
  file = File.expand_path(File.join(Server.data, *request.path_info))
60
60
 
61
61
  unless File.exists?(file)
62
- ruby_gems_url = 'http://production.cf.rubygems.org'
62
+ ruby_gems_url = Geminabox.ruby_gems_url
63
63
  path = File.join(ruby_gems_url, *request.path_info)
64
64
  content = Geminabox.http_adapter.get_content(path)
65
65
  GemStore.create(IncomingGem.new(StringIO.new(content)))
@@ -16,7 +16,10 @@ module Geminabox
16
16
  :allow_replace,
17
17
  :gem_permissions,
18
18
  :allow_delete,
19
- :rubygems_proxy
19
+ :lockfile,
20
+ :retry_interval,
21
+ :rubygems_proxy,
22
+ :ruby_gems_url
20
23
  )
21
24
 
22
25
  if Server.rubygems_proxy
@@ -53,12 +56,15 @@ module Geminabox
53
56
  Geminabox::Indexer.patch_rubygems_update_index_pre_1_8_25(indexer)
54
57
  indexer.update_index
55
58
  updated_gemspecs.each { |gem| dependency_cache.flush_key(gem.name) }
59
+ rescue Errno::ENOENT
60
+ reindex(:force_rebuild)
56
61
  rescue => e
57
62
  puts "#{e.class}:#{e.message}"
58
63
  puts e.backtrace.join("\n")
59
64
  reindex(:force_rebuild)
60
65
  end
61
66
  end
67
+ rescue Gem::SystemExitException
62
68
  end
63
69
 
64
70
  def indexer
@@ -100,8 +106,10 @@ module Geminabox
100
106
  end
101
107
 
102
108
  get '/reindex' do
103
- self.class.reindex(:force_rebuild)
104
- redirect url("/")
109
+ serialize_update do
110
+ self.class.reindex(:force_rebuild)
111
+ redirect url("/")
112
+ end
105
113
  end
106
114
 
107
115
  get '/gems/:gemname' do
@@ -115,22 +123,31 @@ module Geminabox
115
123
  unless self.class.allow_delete?
116
124
  error_response(403, 'Gem deletion is disabled - see https://github.com/cwninja/geminabox/issues/115')
117
125
  end
118
- File.delete file_path if File.exists? file_path
119
- self.class.reindex(:force_rebuild)
120
- redirect url("/")
126
+
127
+ serialize_update do
128
+ File.delete file_path if File.exists? file_path
129
+ self.class.reindex(:force_rebuild)
130
+ redirect url("/")
131
+ end
132
+
121
133
  end
122
134
 
123
135
  post '/upload' do
124
- unless params[:file] && params[:file][:filename] && (tmpfile = params[:file][:tempfile])
136
+ if params[:file] && params[:file][:filename] && (tmpfile = params[:file][:tempfile])
137
+ serialize_update do
138
+ handle_incoming_gem(Geminabox::IncomingGem.new(tmpfile))
139
+ end
140
+ else
125
141
  @error = "No file selected"
126
142
  halt [400, erb(:upload)]
127
143
  end
128
- handle_incoming_gem(Geminabox::IncomingGem.new(tmpfile))
129
144
  end
130
145
 
131
146
  post '/api/v1/gems' do
132
147
  begin
133
- handle_incoming_gem(Geminabox::IncomingGem.new(request.body))
148
+ serialize_update do
149
+ handle_incoming_gem(Geminabox::IncomingGem.new(request.body))
150
+ end
134
151
  rescue Object => o
135
152
  File.open "/tmp/debug.txt", "a" do |io|
136
153
  io.puts o, o.backtrace
@@ -140,6 +157,24 @@ module Geminabox
140
157
 
141
158
  private
142
159
 
160
+ def serialize_update(&block)
161
+ with_lock(&block)
162
+ rescue AlreadyLocked
163
+ halt 503, { 'Retry-After' => settings.retry_interval }, 'Repository lock is held by another process'
164
+ end
165
+
166
+ def with_lock
167
+ file_class.open(settings.lockfile, File::RDWR | File::CREAT) do |f|
168
+ raise AlreadyLocked unless f.flock(File::LOCK_EX | File::LOCK_NB)
169
+ yield
170
+ end
171
+ end
172
+
173
+ # This method provides a test hook, as stubbing File is painful...
174
+ def file_class
175
+ File
176
+ end
177
+
143
178
  def handle_incoming_gem(gem)
144
179
  begin
145
180
  GemStore.create(gem, params[:overwrite])
@@ -155,7 +190,7 @@ module Geminabox
155
190
  end
156
191
 
157
192
  def api_request?
158
- request.accept.first != "text/html"
193
+ request.accept.first.to_s != "text/html"
159
194
  end
160
195
 
161
196
  def error_response(code, message)
@@ -1,3 +1,3 @@
1
1
  module Geminabox
2
- VERSION = '0.12.4' unless defined? VERSION
2
+ VERSION = '0.13.0' unless defined? VERSION
3
3
  end
@@ -4,6 +4,7 @@
4
4
  <title>Gem in a Box</title>
5
5
  <link href="<%= url '/atom.xml' %>" rel="self" />
6
6
  <link href="<%= url '/' %>" />
7
+ <author><name>Gem in a Box</name></author>
7
8
  <id><%= url '/atom.xml' %></id>
8
9
  <% @gems.by_name do |name, versions| %>
9
10
  <% newest_gem = versions.newest %>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geminabox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.4
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Lea
@@ -10,104 +10,76 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-03-19 00:00:00.000000000 Z
13
+ date: 2016-02-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: sinatra
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  requirements:
19
- - - ! '>='
19
+ - - ">="
20
20
  - !ruby/object:Gem::Version
21
21
  version: 1.2.7
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
- - - ! '>='
26
+ - - ">="
27
27
  - !ruby/object:Gem::Version
28
28
  version: 1.2.7
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: builder
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
- - - ! '>='
33
+ - - ">="
34
34
  - !ruby/object:Gem::Version
35
35
  version: '0'
36
36
  type: :runtime
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
- - - ! '>='
40
+ - - ">="
41
41
  - !ruby/object:Gem::Version
42
42
  version: '0'
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: httpclient
45
45
  requirement: !ruby/object:Gem::Requirement
46
46
  requirements:
47
- - - ! '>='
47
+ - - ">="
48
48
  - !ruby/object:Gem::Version
49
49
  version: 2.2.7
50
50
  type: :runtime
51
51
  prerelease: false
52
52
  version_requirements: !ruby/object:Gem::Requirement
53
53
  requirements:
54
- - - ! '>='
54
+ - - ">="
55
55
  - !ruby/object:Gem::Version
56
56
  version: 2.2.7
57
57
  - !ruby/object:Gem::Dependency
58
58
  name: nesty
59
59
  requirement: !ruby/object:Gem::Requirement
60
60
  requirements:
61
- - - ! '>='
61
+ - - ">="
62
62
  - !ruby/object:Gem::Version
63
63
  version: '0'
64
64
  type: :runtime
65
65
  prerelease: false
66
66
  version_requirements: !ruby/object:Gem::Requirement
67
67
  requirements:
68
- - - ! '>='
68
+ - - ">="
69
69
  - !ruby/object:Gem::Version
70
70
  version: '0'
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: faraday
73
73
  requirement: !ruby/object:Gem::Requirement
74
74
  requirements:
75
- - - ! '>='
75
+ - - ">="
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
78
  type: :runtime
79
79
  prerelease: false
80
80
  version_requirements: !ruby/object:Gem::Requirement
81
81
  requirements:
82
- - - ! '>='
83
- - !ruby/object:Gem::Version
84
- version: '0'
85
- - !ruby/object:Gem::Dependency
86
- name: rake
87
- requirement: !ruby/object:Gem::Requirement
88
- requirements:
89
- - - ! '>='
90
- - !ruby/object:Gem::Version
91
- version: '0'
92
- type: :development
93
- prerelease: false
94
- version_requirements: !ruby/object:Gem::Requirement
95
- requirements:
96
- - - ! '>='
97
- - !ruby/object:Gem::Version
98
- version: '0'
99
- - !ruby/object:Gem::Dependency
100
- name: pry
101
- requirement: !ruby/object:Gem::Requirement
102
- requirements:
103
- - - ! '>='
104
- - !ruby/object:Gem::Version
105
- version: '0'
106
- type: :development
107
- prerelease: false
108
- version_requirements: !ruby/object:Gem::Requirement
109
- requirements:
110
- - - ! '>='
82
+ - - ">="
111
83
  - !ruby/object:Gem::Version
112
84
  version: '0'
113
85
  description: A sinatra based gem hosting app, with client side gem push style functionality.
@@ -122,63 +94,63 @@ extra_rdoc_files:
122
94
  files:
123
95
  - MIT-LICENSE
124
96
  - README.markdown
125
- - lib/rubygems_plugin.rb
126
- - lib/geminabox/version.rb
97
+ - lib/geminabox.rb
98
+ - lib/geminabox/disk_cache.rb
99
+ - lib/geminabox/gem_list_merge.rb
100
+ - lib/geminabox/gem_store.rb
127
101
  - lib/geminabox/gem_store_error.rb
128
- - lib/geminabox/incoming_gem.rb
129
102
  - lib/geminabox/gem_version.rb
103
+ - lib/geminabox/gem_version_collection.rb
130
104
  - lib/geminabox/hostess.rb
105
+ - lib/geminabox/http_adapter.rb
106
+ - lib/geminabox/http_adapter/http_client_adapter.rb
107
+ - lib/geminabox/http_adapter/template_faraday_adapter.rb
108
+ - lib/geminabox/http_adapter_config_error.rb
109
+ - lib/geminabox/incoming_gem.rb
131
110
  - lib/geminabox/indexer.rb
132
- - lib/geminabox/gem_list_merge.rb
133
- - lib/geminabox/rubygems_dependency.rb
134
111
  - lib/geminabox/proxy.rb
112
+ - lib/geminabox/proxy/copier.rb
135
113
  - lib/geminabox/proxy/file_handler.rb
136
114
  - lib/geminabox/proxy/hostess.rb
137
- - lib/geminabox/proxy/copier.rb
138
115
  - lib/geminabox/proxy/splicer.rb
139
- - lib/geminabox/gem_version_collection.rb
140
- - lib/geminabox/http_adapter/http_client_adapter.rb
141
- - lib/geminabox/http_adapter/template_faraday_adapter.rb
116
+ - lib/geminabox/rubygems_dependency.rb
142
117
  - lib/geminabox/server.rb
143
- - lib/geminabox/disk_cache.rb
144
- - lib/geminabox/http_adapter.rb
145
- - lib/geminabox/http_adapter_config_error.rb
146
- - lib/geminabox/gem_store.rb
147
- - lib/rubygems/commands/inabox_command.rb
118
+ - lib/geminabox/version.rb
148
119
  - lib/geminabox_client.rb
149
- - lib/geminabox.rb
150
- - public/master.js
151
- - public/master.css
152
- - public/jquery.js
120
+ - lib/rubygems/commands/inabox_command.rb
121
+ - lib/rubygems_plugin.rb
153
122
  - public/favicon.ico
123
+ - public/jquery.js
124
+ - public/master.css
125
+ - public/master.js
154
126
  - views/atom.erb
155
127
  - views/gem.erb
156
- - views/upload.erb
157
- - views/layout.erb
158
128
  - views/index.erb
129
+ - views/layout.erb
130
+ - views/upload.erb
159
131
  homepage: http://tomlea.co.uk/p/gem-in-a-box
160
132
  licenses:
161
133
  - MIT-LICENSE
162
134
  metadata: {}
163
135
  post_install_message:
164
136
  rdoc_options:
165
- - --main
137
+ - "--main"
166
138
  - README.markdown
167
139
  require_paths:
168
140
  - lib
169
141
  required_ruby_version: !ruby/object:Gem::Requirement
170
142
  requirements:
171
- - - ! '>='
143
+ - - ">="
172
144
  - !ruby/object:Gem::Version
173
145
  version: '0'
174
146
  required_rubygems_version: !ruby/object:Gem::Requirement
175
147
  requirements:
176
- - - ! '>='
148
+ - - ">="
177
149
  - !ruby/object:Gem::Version
178
150
  version: '0'
179
151
  requirements: []
180
152
  rubyforge_project:
181
- rubygems_version: 2.1.10
153
+ rubygems_version: 2.5.1
182
154
  signing_key:
183
155
  specification_version: 4
184
156
  summary: Really simple rubygem hosting