geminabox 0.11.0 → 0.11.1

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.

@@ -1,5 +1,5 @@
1
1
  # Gem in a Box – Really simple rubygem hosting
2
- [![Build Status](https://secure.travis-ci.org/cwninja/geminabox.png)](http://travis-ci.org/cwninja/geminabox)
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
4
 
5
5
  Geminabox lets you host your own gems, and push new gems to it just like with rubygems.org.
@@ -38,6 +38,12 @@ RubyGems supports generating indexes for the so called legacy versions (< 1.2),
38
38
 
39
39
  ## Client Usage
40
40
 
41
+ Since version 0.10, Geminabox supports the standard gemcutter push API:
42
+
43
+ gem push pkg/my-awesome-gem-1.0.gem --host HOST
44
+
45
+ You can also use the gem plugin:
46
+
41
47
  gem install geminabox
42
48
 
43
49
  gem inabox pkg/my-awesome-gem-1.0.gem
@@ -6,6 +6,8 @@ require 'rubygems/indexer'
6
6
  require 'rubygems/package'
7
7
  require 'hostess'
8
8
  require 'geminabox/version'
9
+ require 'geminabox/gem_store'
10
+ require 'geminabox/gem_store_error'
9
11
  require 'rss/atom'
10
12
  require 'tempfile'
11
13
 
@@ -36,6 +38,35 @@ class Geminabox < Sinatra::Base
36
38
  Gem.post_reset{ Gem::Specification.all = nil } if defined? Bundler and Gem.respond_to? :post_reset
37
39
  @post_reset_hook_applied = true
38
40
  end
41
+
42
+ def reindex(force_rebuild = false)
43
+ Geminabox.fixup_bundler_rubygems!
44
+ force_rebuild = true unless Geminabox.incremental_updates
45
+ if force_rebuild
46
+ indexer.generate_index
47
+ dependency_cache.flush
48
+ else
49
+ begin
50
+ require 'geminabox/indexer'
51
+ updated_gemspecs = Geminabox::Indexer.updated_gemspecs(indexer)
52
+ Geminabox::Indexer.patch_rubygems_update_index_pre_1_8_25(indexer)
53
+ indexer.update_index
54
+ updated_gemspecs.each { |gem| dependency_cache.flush_key(gem.name) }
55
+ rescue => e
56
+ puts "#{e.class}:#{e.message}"
57
+ puts e.backtrace.join("\n")
58
+ reindex(:force_rebuild)
59
+ end
60
+ end
61
+ end
62
+
63
+ def indexer
64
+ Gem::Indexer.new(Geminabox.data, :build_legacy => Geminabox.build_legacy)
65
+ end
66
+
67
+ def dependency_cache
68
+ @dependency_cache ||= Geminabox::DiskCache.new(File.join(Geminabox.data, "_cache"))
69
+ end
39
70
  end
40
71
 
41
72
  autoload :GemVersionCollection, "geminabox/gem_version_collection"
@@ -69,7 +100,7 @@ class Geminabox < Sinatra::Base
69
100
  end
70
101
 
71
102
  get '/reindex' do
72
- reindex(:force_rebuild)
103
+ self.class.reindex(:force_rebuild)
73
104
  redirect url("/")
74
105
  end
75
106
 
@@ -85,7 +116,7 @@ class Geminabox < Sinatra::Base
85
116
  error_response(403, 'Gem deletion is disabled - see https://github.com/cwninja/geminabox/issues/115')
86
117
  end
87
118
  File.delete file_path if File.exists? file_path
88
- reindex(:force_rebuild)
119
+ self.class.reindex(:force_rebuild)
89
120
  redirect url("/")
90
121
  end
91
122
 
@@ -110,10 +141,11 @@ class Geminabox < Sinatra::Base
110
141
  private
111
142
 
112
143
  def handle_incoming_gem(gem)
113
- prepare_data_folders
114
- error_response(400, "Cannot process gem") unless gem.valid?
115
- handle_replacement(gem) unless params[:overwrite] == "true"
116
- write_and_index(gem)
144
+ begin
145
+ GemStore.create(gem, params[:overwrite])
146
+ rescue GemStoreError => error
147
+ error_response error.code, error.reason
148
+ end
117
149
 
118
150
  if api_request?
119
151
  "Gem #{gem.name} received and indexed."
@@ -140,64 +172,6 @@ HTML
140
172
  halt [code, html]
141
173
  end
142
174
 
143
- def prepare_data_folders
144
- if File.exists? Geminabox.data
145
- error_response( 500, "Please ensure #{File.expand_path(Geminabox.data)} is a directory." ) unless File.directory? Geminabox.data
146
- error_response( 500, "Please ensure #{File.expand_path(Geminabox.data)} is writable by the geminabox web server." ) unless File.writable? Geminabox.data
147
- else
148
- begin
149
- FileUtils.mkdir_p(settings.data)
150
- rescue Errno::EACCES, Errno::ENOENT, RuntimeError => e
151
- error_response( 500, "Could not create #{File.expand_path(Geminabox.data)}.\n#{e}\n#{e.message}" )
152
- end
153
- end
154
-
155
- FileUtils.mkdir_p(File.join(settings.data, "gems"))
156
- end
157
-
158
- def handle_replacement(gem)
159
- if Geminabox.disallow_replace? and File.exist?(gem.dest_filename)
160
- existing_file_digest = Digest::SHA1.file(gem.dest_filename).hexdigest
161
-
162
- if existing_file_digest != gem.hexdigest
163
- error_response(409, "Updating an existing gem is not permitted.\nYou should either delete the existing version, or change your version number.")
164
- else
165
- error_response(200, "Ignoring upload, you uploaded the same thing previously.\nPlease use -o to ovewrite.")
166
- end
167
- end
168
- end
169
-
170
- def write_and_index(gem)
171
- tmpfile = gem.gem_data
172
- atomic_write(gem.dest_filename) do |f|
173
- while blk = tmpfile.read(65536)
174
- f << blk
175
- end
176
- end
177
- reindex
178
- end
179
-
180
- def reindex(force_rebuild = false)
181
- Geminabox.fixup_bundler_rubygems!
182
- force_rebuild = true unless settings.incremental_updates
183
- if force_rebuild
184
- indexer.generate_index
185
- dependency_cache.flush
186
- else
187
- begin
188
- require 'geminabox/indexer'
189
- updated_gemspecs = Geminabox::Indexer.updated_gemspecs(indexer)
190
- Geminabox::Indexer.patch_rubygems_update_index_pre_1_8_25(indexer)
191
- indexer.update_index
192
- updated_gemspecs.each { |gem| dependency_cache.flush_key(gem.name) }
193
- rescue => e
194
- puts "#{e.class}:#{e.message}"
195
- puts e.backtrace.join("\n")
196
- reindex(:force_rebuild)
197
- end
198
- end
199
- end
200
-
201
175
  def indexer
202
176
  Gem::Indexer.new(settings.data, :build_legacy => settings.build_legacy)
203
177
  end
@@ -229,17 +203,6 @@ HTML
229
203
  Set.new(gems.map{|gem| gem.name[0..0].downcase})
230
204
  end
231
205
 
232
- # based on http://as.rubyonrails.org/classes/File.html
233
- def atomic_write(file_name)
234
- temp_dir = File.join(settings.data, "_temp")
235
- FileUtils.mkdir_p(temp_dir)
236
- temp_file = Tempfile.new("." + File.basename(file_name), temp_dir)
237
- yield temp_file
238
- temp_file.close
239
- File.rename(temp_file.path, file_name)
240
- File.chmod(settings.gem_permissions, file_name)
241
- end
242
-
243
206
  helpers do
244
207
  def spec_for(gem_name, version)
245
208
  spec_file = File.join(settings.data, "quick", "Marshal.#{Gem.marshal_version}", "#{gem_name}-#{version}.gemspec.rz")
@@ -0,0 +1,97 @@
1
+
2
+
3
+ class GemStore
4
+ attr_accessor :gem, :overwrite
5
+
6
+ def self.create(gem, overwrite = false)
7
+ gem_store = new(gem, overwrite)
8
+ gem_store.save
9
+ end
10
+
11
+ def initialize(gem, overwrite = false)
12
+ @gem = gem
13
+ @overwrite = overwrite && overwrite == 'true'
14
+ end
15
+
16
+ def save
17
+ ensure_gem_valid
18
+ prepare_data_folders
19
+ check_replacement_status
20
+ write_and_index
21
+ end
22
+
23
+ def prepare_data_folders
24
+ ensure_existing_data_folder_compatible
25
+ begin
26
+ FileUtils.mkdir_p(File.join(Geminabox.data, "gems"))
27
+ rescue
28
+ raise GemStoreError.new(
29
+ 500,
30
+ "Could not create #{File.expand_path(Geminabox.data)}."
31
+ )
32
+ end
33
+ end
34
+
35
+ def check_replacement_status
36
+ if !overwrite and Geminabox.disallow_replace? and File.exist?(gem.dest_filename)
37
+ if existing_file_digest != gem.hexdigest
38
+ raise GemStoreError.new(409, "Updating an existing gem is not permitted.\nYou should either delete the existing version, or change your version number.")
39
+ else
40
+ raise GemStoreError.new(200, "Ignoring upload, you uploaded the same thing previously.\nPlease use -o to ovewrite.")
41
+ end
42
+ end
43
+ end
44
+
45
+ def ensure_gem_valid
46
+ raise GemStoreError.new(400, "Cannot process gem") unless gem.valid?
47
+ end
48
+
49
+ private
50
+ def ensure_existing_data_folder_compatible
51
+ if File.exists? Geminabox.data
52
+ ensure_data_folder_is_directory
53
+ ensure_data_folder_is_writable
54
+ end
55
+ end
56
+
57
+ def ensure_data_folder_is_directory
58
+ raise GemStoreError.new(
59
+ 500,
60
+ "Please ensure #{File.expand_path(Geminabox.data)} is a directory."
61
+ ) unless File.directory? Geminabox.data
62
+ end
63
+
64
+ def ensure_data_folder_is_writable
65
+ raise GemStoreError.new(
66
+ 500,
67
+ "Please ensure #{File.expand_path(Geminabox.data)} is writable by the geminabox web server."
68
+ ) unless File.writable? Geminabox.data
69
+ end
70
+
71
+ def existing_file_digest
72
+ Digest::SHA1.file(gem.dest_filename).hexdigest
73
+ end
74
+
75
+ def write_and_index
76
+ tmpfile = gem.gem_data
77
+ atomic_write(gem.dest_filename) do |f|
78
+ while blk = tmpfile.read(65536)
79
+ f << blk
80
+ end
81
+ end
82
+ Geminabox.reindex
83
+ end
84
+
85
+ # based on http://as.rubyonrails.org/classes/File.html
86
+ def atomic_write(file_name)
87
+ temp_dir = File.join(Geminabox.data, "_temp")
88
+ FileUtils.mkdir_p(temp_dir)
89
+ temp_file = Tempfile.new("." + File.basename(file_name), temp_dir)
90
+ temp_file.binmode
91
+ yield temp_file
92
+ temp_file.close
93
+ File.rename(temp_file.path, file_name)
94
+ File.chmod(Geminabox.gem_permissions, file_name)
95
+ end
96
+
97
+ end
@@ -0,0 +1,12 @@
1
+ require 'nesty'
2
+
3
+ class GemStoreError < StandardError
4
+ attr_reader :code, :reason
5
+
6
+ include Nesty::NestedError
7
+
8
+ def initialize(code, reason)
9
+ @code = code.to_s
10
+ @reason = reason
11
+ end
12
+ end
@@ -1 +1 @@
1
- GeminaboxVersion = '0.11.0' unless defined? GeminaboxVersion
1
+ GeminaboxVersion = '0.11.1' unless defined? GeminaboxVersion
metadata CHANGED
@@ -1,7 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geminabox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.11.1
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Tom Lea
@@ -9,25 +10,28 @@ authors:
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2013-08-07 00:00:00.000000000 Z
13
+ date: 2013-10-08 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: sinatra
16
17
  requirement: !ruby/object:Gem::Requirement
18
+ none: false
17
19
  requirements:
18
20
  - - ! '>='
19
21
  - !ruby/object:Gem::Version
20
- version: '0'
22
+ version: 1.2.7
21
23
  type: :runtime
22
24
  prerelease: false
23
25
  version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
24
27
  requirements:
25
28
  - - ! '>='
26
29
  - !ruby/object:Gem::Version
27
- version: '0'
30
+ version: 1.2.7
28
31
  - !ruby/object:Gem::Dependency
29
32
  name: builder
30
33
  requirement: !ruby/object:Gem::Requirement
34
+ none: false
31
35
  requirements:
32
36
  - - ! '>='
33
37
  - !ruby/object:Gem::Version
@@ -35,6 +39,7 @@ dependencies:
35
39
  type: :runtime
36
40
  prerelease: false
37
41
  version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
38
43
  requirements:
39
44
  - - ! '>='
40
45
  - !ruby/object:Gem::Version
@@ -42,6 +47,7 @@ dependencies:
42
47
  - !ruby/object:Gem::Dependency
43
48
  name: httpclient
44
49
  requirement: !ruby/object:Gem::Requirement
50
+ none: false
45
51
  requirements:
46
52
  - - ! '>='
47
53
  - !ruby/object:Gem::Version
@@ -49,13 +55,31 @@ dependencies:
49
55
  type: :runtime
50
56
  prerelease: false
51
57
  version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
52
59
  requirements:
53
60
  - - ! '>='
54
61
  - !ruby/object:Gem::Version
55
62
  version: 2.2.7
63
+ - !ruby/object:Gem::Dependency
64
+ name: nesty
65
+ requirement: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ type: :runtime
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
56
79
  - !ruby/object:Gem::Dependency
57
80
  name: rake
58
81
  requirement: !ruby/object:Gem::Requirement
82
+ none: false
59
83
  requirements:
60
84
  - - ! '>='
61
85
  - !ruby/object:Gem::Version
@@ -63,6 +87,7 @@ dependencies:
63
87
  type: :development
64
88
  prerelease: false
65
89
  version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
66
91
  requirements:
67
92
  - - ! '>='
68
93
  - !ruby/object:Gem::Version
@@ -70,6 +95,7 @@ dependencies:
70
95
  - !ruby/object:Gem::Dependency
71
96
  name: rack-test
72
97
  requirement: !ruby/object:Gem::Requirement
98
+ none: false
73
99
  requirements:
74
100
  - - ! '>='
75
101
  - !ruby/object:Gem::Version
@@ -77,6 +103,7 @@ dependencies:
77
103
  type: :development
78
104
  prerelease: false
79
105
  version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
80
107
  requirements:
81
108
  - - ! '>='
82
109
  - !ruby/object:Gem::Version
@@ -84,6 +111,7 @@ dependencies:
84
111
  - !ruby/object:Gem::Dependency
85
112
  name: minitest
86
113
  requirement: !ruby/object:Gem::Requirement
114
+ none: false
87
115
  requirements:
88
116
  - - ! '>='
89
117
  - !ruby/object:Gem::Version
@@ -91,6 +119,7 @@ dependencies:
91
119
  type: :development
92
120
  prerelease: false
93
121
  version_requirements: !ruby/object:Gem::Requirement
122
+ none: false
94
123
  requirements:
95
124
  - - ! '>='
96
125
  - !ruby/object:Gem::Version
@@ -98,6 +127,7 @@ dependencies:
98
127
  - !ruby/object:Gem::Dependency
99
128
  name: capybara
100
129
  requirement: !ruby/object:Gem::Requirement
130
+ none: false
101
131
  requirements:
102
132
  - - ! '>='
103
133
  - !ruby/object:Gem::Version
@@ -105,6 +135,7 @@ dependencies:
105
135
  type: :development
106
136
  prerelease: false
107
137
  version_requirements: !ruby/object:Gem::Requirement
138
+ none: false
108
139
  requirements:
109
140
  - - ! '>='
110
141
  - !ruby/object:Gem::Version
@@ -112,6 +143,7 @@ dependencies:
112
143
  - !ruby/object:Gem::Dependency
113
144
  name: capybara-mechanize
114
145
  requirement: !ruby/object:Gem::Requirement
146
+ none: false
115
147
  requirements:
116
148
  - - ! '>='
117
149
  - !ruby/object:Gem::Version
@@ -119,6 +151,7 @@ dependencies:
119
151
  type: :development
120
152
  prerelease: false
121
153
  version_requirements: !ruby/object:Gem::Requirement
154
+ none: false
122
155
  requirements:
123
156
  - - ! '>='
124
157
  - !ruby/object:Gem::Version
@@ -126,6 +159,7 @@ dependencies:
126
159
  - !ruby/object:Gem::Dependency
127
160
  name: pry
128
161
  requirement: !ruby/object:Gem::Requirement
162
+ none: false
129
163
  requirements:
130
164
  - - ! '>='
131
165
  - !ruby/object:Gem::Version
@@ -133,6 +167,7 @@ dependencies:
133
167
  type: :development
134
168
  prerelease: false
135
169
  version_requirements: !ruby/object:Gem::Requirement
170
+ none: false
136
171
  requirements:
137
172
  - - ! '>='
138
173
  - !ruby/object:Gem::Version
@@ -147,29 +182,30 @@ extra_rdoc_files:
147
182
  - README.markdown
148
183
  files:
149
184
  - README.markdown
150
- - lib/geminabox/disk_cache.rb
151
- - lib/geminabox/gem_version.rb
152
- - lib/geminabox/gem_version_collection.rb
185
+ - lib/rubygems_plugin.rb
186
+ - lib/hostess.rb
187
+ - lib/geminabox/version.rb
188
+ - lib/geminabox/gem_store_error.rb
153
189
  - lib/geminabox/incoming_gem.rb
190
+ - lib/geminabox/gem_version.rb
154
191
  - lib/geminabox/indexer.rb
155
- - lib/geminabox/version.rb
156
- - lib/geminabox.rb
157
- - lib/geminabox_client.rb
158
- - lib/hostess.rb
192
+ - lib/geminabox/gem_version_collection.rb
193
+ - lib/geminabox/disk_cache.rb
194
+ - lib/geminabox/gem_store.rb
159
195
  - lib/rubygems/commands/inabox_command.rb
160
- - lib/rubygems_plugin.rb
161
- - public/favicon.ico
162
- - public/jquery.js
163
- - public/master.css
196
+ - lib/geminabox_client.rb
197
+ - lib/geminabox.rb
164
198
  - public/master.js
199
+ - public/master.css
200
+ - public/jquery.js
201
+ - public/favicon.ico
165
202
  - views/atom.erb
166
203
  - views/gem.erb
167
- - views/index.erb
168
- - views/layout.erb
169
204
  - views/upload.erb
205
+ - views/layout.erb
206
+ - views/index.erb
170
207
  homepage: http://tomlea.co.uk/p/gem-in-a-box
171
208
  licenses: []
172
- metadata: {}
173
209
  post_install_message:
174
210
  rdoc_options:
175
211
  - --main
@@ -177,19 +213,21 @@ rdoc_options:
177
213
  require_paths:
178
214
  - lib
179
215
  required_ruby_version: !ruby/object:Gem::Requirement
216
+ none: false
180
217
  requirements:
181
218
  - - ! '>='
182
219
  - !ruby/object:Gem::Version
183
220
  version: '0'
184
221
  required_rubygems_version: !ruby/object:Gem::Requirement
222
+ none: false
185
223
  requirements:
186
224
  - - ! '>='
187
225
  - !ruby/object:Gem::Version
188
226
  version: '0'
189
227
  requirements: []
190
228
  rubyforge_project:
191
- rubygems_version: 2.0.3
229
+ rubygems_version: 1.8.25
192
230
  signing_key:
193
- specification_version: 4
231
+ specification_version: 3
194
232
  summary: Really simple rubygem hosting
195
233
  test_files: []
checksums.yaml DELETED
@@ -1,15 +0,0 @@
1
- ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- Y2QyZTI0YzVmMDBkZmRjNzAxOTcyNGU5Mzc1ZWE5MzQxZGYyMDUwMw==
5
- data.tar.gz: !binary |-
6
- YmFkNzRmNDAyMGI5NzMyMWI2OThjYTQyMGIyZGI0NDM4ZDY0YzQxNQ==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- Yjc5MTkzOWYxZDA2NWZlNWM2MDQxODQ0MWM3ODIyMWU3ZjY1ZTE1Y2VmMDNk
10
- OTAyNGU2ZTc0NTQwN2FiNWI4OGVkYjliYjM2MjNmMTNjOTI0MDE4OTcxYjY0
11
- NDc4MmM3NGI1MDU0MDBmYWZkNmQ2MTYxNGZmMzA3ODhlZTljOTE=
12
- data.tar.gz: !binary |-
13
- NDQ5YTkzZjIzMWFlZWQ2YjQ4MTE4MWRlODFiNThiNDcwOTM2YTUzYzkyY2Rh
14
- OWUxNzgxOTFiNjI1MGRhMmI1NzY5OWUyMDkyYjA0NzJmNTFjMWQ3ZWM1ZDY5
15
- NjZjYzA5OGU5ZTU5OWZhMTMxYWNkOGIwMTY0Yjk4Y2U4N2FlNmY=