stickler 0.1.1 → 2.0.0a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/HISTORY.rdoc +5 -2
- data/Rakefile +31 -0
- data/examples/config.ru +9 -0
- data/examples/gemcutter_repo.ru +19 -0
- data/examples/index_repo.ru +15 -0
- data/examples/local_repo.ru +14 -0
- data/examples/mirror_repo.ru +16 -0
- data/examples/not_found.ru +8 -0
- data/lib/stickler/error.rb +3 -0
- data/lib/stickler/middleware/compression.rb +30 -0
- data/lib/stickler/middleware/gemcutter.rb +62 -0
- data/lib/stickler/middleware/helpers.rb +84 -0
- data/lib/stickler/middleware/index.rb +137 -0
- data/lib/stickler/middleware/local.rb +38 -0
- data/lib/stickler/middleware/mirror.rb +60 -0
- data/lib/stickler/middleware/not_found.rb +62 -0
- data/lib/stickler/middleware.rb +4 -0
- data/lib/stickler/repository/api.rb +167 -0
- data/lib/stickler/repository/index.rb +97 -0
- data/lib/stickler/repository/local.rb +251 -0
- data/lib/stickler/repository/mirror.rb +48 -0
- data/lib/stickler/repository/null.rb +58 -0
- data/lib/stickler/repository/remote.rb +235 -0
- data/lib/stickler/repository.rb +7 -499
- data/lib/stickler/spec_lite.rb +60 -14
- data/lib/stickler/version.rb +6 -6
- data/lib/stickler/web.rb +19 -0
- data/spec/data/gems/bar-1.0.0.gem +0 -0
- data/spec/data/gems/foo-1.0.0.gem +0 -0
- data/spec/data/specifications/bar-1.0.0.gemspec +31 -0
- data/spec/data/specifications/foo-1.0.0.gemspec +31 -0
- data/spec/middleware/common_gem_server_helpers.rb +67 -0
- data/spec/middleware/index_spec.rb +26 -0
- data/spec/middleware/legacy_gem_server_behavior.rb +33 -0
- data/spec/middleware/local_spec.rb +25 -0
- data/spec/middleware/modern_gem_server_behavior.rb +20 -0
- data/spec/middleware/not_found_spec.rb +25 -0
- data/spec/repository/api_behavior.rb +162 -0
- data/spec/repository/api_spec.rb +38 -0
- data/spec/repository/index_spec.rb +32 -0
- data/spec/repository/local_spec.rb +36 -0
- data/spec/repository/null_spec.rb +17 -0
- data/spec/repository/remote_spec.rb +49 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +15 -3
- data/spec/spec_lite_spec.rb +62 -0
- data/stickler.gemspec +60 -0
- data/views/index.erb +19 -0
- data/views/layout.erb +39 -0
- metadata +93 -63
- data/COPYING +0 -339
- data/bin/stickler +0 -58
- data/data/stickler.yml +0 -14
- data/gemspec.rb +0 -62
- data/lib/stickler/cli.rb +0 -302
- data/lib/stickler/configuration.rb +0 -74
- data/lib/stickler/console.rb +0 -72
- data/lib/stickler/paths.rb +0 -62
- data/lib/stickler/source.rb +0 -75
- data/lib/stickler/source_group.rb +0 -365
- data/lib/stickler.rb +0 -19
- data/spec/configuration_spec.rb +0 -68
- data/spec/paths_spec.rb +0 -25
- data/spec/repository_spec.rb +0 -55
- data/spec/version_spec.rb +0 -17
- data/tasks/announce.rake +0 -39
- data/tasks/config.rb +0 -107
- data/tasks/distribution.rake +0 -45
- data/tasks/documentation.rake +0 -31
- data/tasks/rspec.rake +0 -29
- data/tasks/rubyforge.rake +0 -51
- data/tasks/utils.rb +0 -80
@@ -0,0 +1,235 @@
|
|
1
|
+
require 'resourceful'
|
2
|
+
require 'stickler/repository'
|
3
|
+
require 'stickler/repository/api'
|
4
|
+
require 'stringio'
|
5
|
+
|
6
|
+
module ::Stickler::Repository
|
7
|
+
#
|
8
|
+
# A Repository::Api implementation that retrieves all is data from an HTTP
|
9
|
+
# based remote location. It utilizes the Modern gem server api and the gem
|
10
|
+
# cutter api (push/yank/unyank). The legacy gem server api is not utilized.
|
11
|
+
#
|
12
|
+
class Remote
|
13
|
+
# the http client
|
14
|
+
attr_reader :http
|
15
|
+
|
16
|
+
def initialize( repo_uri )
|
17
|
+
@uri = Addressable::URI.parse( ensure_http( ensure_trailing_slash( repo_uri ) ) )
|
18
|
+
@http = Resourceful::HttpAccessor.new( :cache_manager => Resourceful::InMemoryCacheManager.new )
|
19
|
+
# :logger => Resourceful::StdOutLogger.new )
|
20
|
+
@specs_list = nil
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# See Api#uri
|
25
|
+
def uri
|
26
|
+
@uri
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# See Api#gems_uri
|
31
|
+
#
|
32
|
+
def gems_uri
|
33
|
+
@gems_uri ||= self.uri.join( "gems/" )
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# See Api#uri_from_gem
|
38
|
+
#
|
39
|
+
def uri_for_gem( spec )
|
40
|
+
return nil unless remote_gem_file_exist?( spec )
|
41
|
+
return self.gems_uri.join( spec.file_name )
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# The array of specs from upstream
|
46
|
+
#
|
47
|
+
def specs_list
|
48
|
+
Marshal.load( download_specs_list )
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# See Api#search_for
|
53
|
+
#
|
54
|
+
def search_for( spec )
|
55
|
+
found = []
|
56
|
+
specs_list.each do |name, version, platform|
|
57
|
+
up_spec = Stickler::SpecLite.new( name, version, platform )
|
58
|
+
found << up_spec if spec =~ up_spec
|
59
|
+
end
|
60
|
+
return found
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# See Api#get
|
65
|
+
#
|
66
|
+
def get( spec )
|
67
|
+
return download_gem( spec ) if remote_gem_file_exist?( spec )
|
68
|
+
return nil
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# See Api#push
|
73
|
+
#
|
74
|
+
def push( path )
|
75
|
+
spec = speclite_from_gem_file( path )
|
76
|
+
raise Stickler::Repository::Error, "gem #{spec.full_name} already exists in remote repository" if remote_gem_file_exist?( spec )
|
77
|
+
begin
|
78
|
+
resp = push_resource.post( IO.read( path ) )
|
79
|
+
rescue Resourceful::UnsuccessfulHttpRequestError => e
|
80
|
+
msg = "Failure pushing #{path} to remote repository : response code => #{e.http_response.code}, response message => '#{e.http_response.body}'"
|
81
|
+
raise Stickler::Repository::Error, msg
|
82
|
+
end
|
83
|
+
return spec
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
# See Api#yank
|
88
|
+
#
|
89
|
+
def yank( spec )
|
90
|
+
return nil unless remote_gem_file_exist?( spec )
|
91
|
+
begin
|
92
|
+
form_data = Resourceful::UrlencodedFormData.new
|
93
|
+
form_data.add( "gem_name", spec.name )
|
94
|
+
form_data.add( "version", spec.version.to_s )
|
95
|
+
yank_resource.request( :delete, form_data.read, {'Content-Type' => form_data.content_type } )
|
96
|
+
return full_uri_to_gem( spec )
|
97
|
+
rescue Resourceful::UnsuccessfulHttpRequestError => e
|
98
|
+
raise Stickler::Repository::Error, "Failure yanking: #{e.inspect}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
#
|
103
|
+
# See Api#delete
|
104
|
+
#
|
105
|
+
def delete( spec )
|
106
|
+
return false unless remote_gem_file_exist?( spec )
|
107
|
+
begin
|
108
|
+
gem_resource( spec ).delete
|
109
|
+
return true
|
110
|
+
rescue Resourceful::UnsuccessfulHttpRequestError => e
|
111
|
+
return false
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
#
|
116
|
+
# See Api#open
|
117
|
+
#
|
118
|
+
def open( spec, &block )
|
119
|
+
return nil unless remote_gem_file_exist?( spec )
|
120
|
+
begin
|
121
|
+
data = download_resource( gem_resource( spec ) )
|
122
|
+
io = StringIO.new( data , "rb" )
|
123
|
+
if block_given? then
|
124
|
+
begin
|
125
|
+
yield io
|
126
|
+
ensure
|
127
|
+
io.close
|
128
|
+
end
|
129
|
+
else
|
130
|
+
return io
|
131
|
+
end
|
132
|
+
rescue Resourceful::UnsuccessfulHttpRequestError => e
|
133
|
+
return nil
|
134
|
+
end
|
135
|
+
nil
|
136
|
+
end
|
137
|
+
|
138
|
+
private
|
139
|
+
|
140
|
+
def ensure_trailing_slash( uri )
|
141
|
+
uri += '/' unless uri =~ %r{/\Z}
|
142
|
+
return uri
|
143
|
+
end
|
144
|
+
|
145
|
+
def ensure_http( uri )
|
146
|
+
uri = "http://#{uri}" unless uri =~ %r{\Ahttp(s)?://}
|
147
|
+
return uri
|
148
|
+
end
|
149
|
+
|
150
|
+
def full_uri_to_gem( spec )
|
151
|
+
gems_uri.join( spec.file_name )
|
152
|
+
end
|
153
|
+
|
154
|
+
def specs_list_uri
|
155
|
+
Addressable::URI.join( uri, "specs.#{Gem.marshal_version}.gz" )
|
156
|
+
end
|
157
|
+
|
158
|
+
def specs_list_resource
|
159
|
+
@specs_list_resource ||= @http.resource( specs_list_uri )
|
160
|
+
end
|
161
|
+
|
162
|
+
def push_uri
|
163
|
+
Addressable::URI.join( uri, "api/v1/gems" )
|
164
|
+
end
|
165
|
+
|
166
|
+
def push_resource
|
167
|
+
@push_resource ||= @http.resource( push_uri, { 'Content-Type', 'application/octet-stream' } )
|
168
|
+
end
|
169
|
+
|
170
|
+
def yank_uri
|
171
|
+
Addressable::URI.join( uri, "api/v1/gems/yank" )
|
172
|
+
end
|
173
|
+
|
174
|
+
def yank_resource
|
175
|
+
@yank_resource ||= @http.resource( yank_uri )
|
176
|
+
end
|
177
|
+
|
178
|
+
def gem_resource( spec )
|
179
|
+
@http.resource( full_uri_to_gem( spec ) )
|
180
|
+
end
|
181
|
+
|
182
|
+
def download_specs_list
|
183
|
+
download_gzipped_resource( specs_list_resource )
|
184
|
+
end
|
185
|
+
|
186
|
+
def download_gzipped_resource( resource )
|
187
|
+
Gem.gunzip( download_resource( resource ) )
|
188
|
+
end
|
189
|
+
|
190
|
+
def download_gem( spec )
|
191
|
+
download_uri( full_uri_to_gem( spec ) )
|
192
|
+
end
|
193
|
+
|
194
|
+
def download_uri( uri )
|
195
|
+
download_resource( http.resource( uri ) )
|
196
|
+
end
|
197
|
+
|
198
|
+
def download_resource( resource )
|
199
|
+
begin
|
200
|
+
resource.get.body
|
201
|
+
rescue Resourceful::UnsuccessfulHttpRequestError => e
|
202
|
+
return false
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def remote_gem_file_exist?( spec )
|
207
|
+
gem_uri = full_uri_to_gem( spec )
|
208
|
+
remote_uri_exist?( gem_uri )
|
209
|
+
end
|
210
|
+
|
211
|
+
def remote_uri_exist?( uri )
|
212
|
+
begin
|
213
|
+
# FIXME: bug in Resourceful that uses cached HEAD responses
|
214
|
+
# to satisfy later GET requests.
|
215
|
+
rc = http.resource( uri ).head( 'Cache-Control' => 'no-store' ).successful?
|
216
|
+
return rc
|
217
|
+
rescue Resourceful::UnsuccessfulHttpRequestError => e
|
218
|
+
return false
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def speclite_from_gem_file( path )
|
223
|
+
speclite_from_specification( specification_from_gem_file( path ) )
|
224
|
+
end
|
225
|
+
|
226
|
+
def specification_from_gem_file( path )
|
227
|
+
format = Gem::Format.from_file_by_path( path )
|
228
|
+
return format.spec
|
229
|
+
end
|
230
|
+
|
231
|
+
def speclite_from_specification( spec )
|
232
|
+
Stickler::SpecLite.new( spec.name, spec.version.to_s, spec.platform )
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|