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
data/lib/stickler/repository.rb
CHANGED
@@ -1,502 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
#++
|
6
|
-
|
7
|
-
require 'stickler'
|
8
|
-
require 'fileutils'
|
9
|
-
require 'ostruct'
|
10
|
-
require 'highline'
|
11
|
-
require 'stickler/configuration'
|
12
|
-
require 'stickler/source_group'
|
1
|
+
require 'stickler/error'
|
2
|
+
require 'rubygems/format'
|
3
|
+
require 'rubygems/platform'
|
4
|
+
require 'rubygems/dependency'
|
13
5
|
|
14
6
|
module Stickler
|
15
|
-
|
16
|
-
|
17
|
-
# is very similar to a GEM_HOME directory. The layout is as follows, this is
|
18
|
-
# all assumed to be under STICKLER_HOME.
|
19
|
-
#
|
20
|
-
# stickler.yml - the Stickler configuration file for this repository.
|
21
|
-
# The existence of this file indicates this is the root
|
22
|
-
# of a stickler repository
|
23
|
-
# gems/ - storage of the actual gem files
|
24
|
-
# cache/ - cache of gem files downloaded from upstream sources
|
25
|
-
# managed by the rubygems fetcher classes
|
26
|
-
# specifications/ - ruby gemspec files
|
27
|
-
# log/ - directory holding rotating logs files for stickler
|
28
|
-
# dist/ - directory holding the distributable gem index location,
|
29
|
-
# rsync this to your webserver, or serve from it directly.
|
30
|
-
#
|
31
|
-
#
|
32
|
-
class Repository
|
33
|
-
class Error < ::StandardError ; end
|
34
|
-
|
35
|
-
# The repository directory. the directory containing the stickler.yml file
|
36
|
-
attr_reader :directory
|
37
|
-
|
38
|
-
# The configuration
|
39
|
-
attr_reader :configuration
|
40
|
-
|
41
|
-
# Are requrements satisfied in a minimal or maximal approach
|
42
|
-
attr_reader :requirement_satisfaction_behavior
|
43
|
-
|
44
|
-
class << self
|
45
|
-
def other_dir_names
|
46
|
-
%w[ gems_dir log_dir specification_dir dist_dir cache_dir ]
|
47
|
-
end
|
48
|
-
|
49
|
-
def config_file_basename
|
50
|
-
"stickler.yml"
|
51
|
-
end
|
52
|
-
|
53
|
-
def basedir
|
54
|
-
"stickler"
|
55
|
-
end
|
56
|
-
|
57
|
-
#
|
58
|
-
# What should the default stickler directory be, this is one of two
|
59
|
-
# things. If there is a stickler.yml file in the current directory, then
|
60
|
-
# the default directory is the current directory, otherwise, it is the
|
61
|
-
# _stickler_ directory below the current_directory
|
62
|
-
#
|
63
|
-
def default_directory
|
64
|
-
defaults = [ File.join( Dir.pwd, config_file_basename ), File.join( Dir.pwd, basedir ) ]
|
65
|
-
defaults.each do |def_dir|
|
66
|
-
if File.exist?( def_dir ) then
|
67
|
-
return File.dirname( def_dir ) if File.file?( def_dir )
|
68
|
-
return def_dir
|
69
|
-
end
|
70
|
-
end
|
71
|
-
return defaults.last
|
72
|
-
end
|
73
|
-
|
74
|
-
#
|
75
|
-
# gem requirement information
|
76
|
-
#
|
77
|
-
def requirement_meta
|
78
|
-
[ [ "=" , "Equals version" ],
|
79
|
-
[ "!=" , "Not equal to version" ],
|
80
|
-
[ ">" , "Greater than version" ],
|
81
|
-
[ "<" , "Less than version" ],
|
82
|
-
[ ">=" , "Greater than or equal to" ],
|
83
|
-
[ "<=" , "Less than or equal to" ],
|
84
|
-
[ "~>" , "Approximately greater than" ]]
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
#
|
89
|
-
# Initialize a stickler repository
|
90
|
-
#
|
91
|
-
def initialize( opts )
|
92
|
-
|
93
|
-
@directory = File.expand_path( opts['directory'] )
|
94
|
-
@requirement_satisfaction_behavior = ( opts['requirements'] || "maximum" ).to_sym
|
95
|
-
enhance_logging( opts ) if File.directory?( log_dir )
|
96
|
-
@overwrite = opts['force']
|
97
|
-
|
98
|
-
@configuration = nil
|
99
|
-
load_configuration if File.exist?( config_file )
|
100
|
-
|
101
|
-
end
|
102
|
-
|
103
|
-
def configuration_loaded?
|
104
|
-
@configuration.nil?
|
105
|
-
end
|
106
|
-
|
107
|
-
#
|
108
|
-
# should existing items be overwritten
|
109
|
-
#
|
110
|
-
def overwrite?
|
111
|
-
@overwrite
|
112
|
-
end
|
113
|
-
|
114
|
-
#
|
115
|
-
# update logging by turning on a log file in the repository directory, and
|
116
|
-
# possibly turning off the stdout logger that is the default.
|
117
|
-
#
|
118
|
-
def enhance_logging( opts )
|
119
|
-
|
120
|
-
layout = ::Logging::Layouts::Pattern.new(
|
121
|
-
:pattern => "[%d] %c %6p %5l : %m\n",
|
122
|
-
:date_pattern => "%Y-%m-%d %H:%M:%S"
|
123
|
-
)
|
124
|
-
Logging::Logger.root.add_appenders ::Logging::Appenders::RollingFile.new( 'stickler_rolling_logfile',
|
125
|
-
{ :filename => log_file,
|
126
|
-
:layout => layout,
|
127
|
-
# at 5MB roll the log
|
128
|
-
:size => 5 * (1024**2),
|
129
|
-
:keep => 5,
|
130
|
-
:safe => true,
|
131
|
-
:level => :debug
|
132
|
-
})
|
133
|
-
end
|
134
|
-
|
135
|
-
#
|
136
|
-
# return a handle to the repository configuration found in stickler.yml.
|
137
|
-
#
|
138
|
-
def load_configuration
|
139
|
-
begin
|
140
|
-
@configuration = Configuration.new( config_file )
|
141
|
-
source_group # force load
|
142
|
-
rescue => e
|
143
|
-
logger.error "Failure to load configuration #{e}"
|
144
|
-
exit 1
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
#
|
149
|
-
# The configuration file for the repository
|
150
|
-
#
|
151
|
-
def config_file
|
152
|
-
@config_file ||= File.join( directory, Repository.config_file_basename )
|
153
|
-
end
|
154
|
-
|
155
|
-
#
|
156
|
-
# The log directory
|
157
|
-
#
|
158
|
-
def log_dir
|
159
|
-
@log_dir ||= File.join( directory, 'log' )
|
160
|
-
end
|
161
|
-
|
162
|
-
#
|
163
|
-
# The log file
|
164
|
-
#
|
165
|
-
def log_file
|
166
|
-
@log_file ||= File.join( log_dir, 'stickler.log' )
|
167
|
-
end
|
168
|
-
|
169
|
-
#
|
170
|
-
# The gem storage directory.
|
171
|
-
#
|
172
|
-
# This holds the raw gem files downloaded from the sources. This is
|
173
|
-
# equivalent to a gem installations 'gems' directory.
|
174
|
-
#
|
175
|
-
def gems_dir
|
176
|
-
@gems_dir ||= File.join( directory, 'gems' )
|
177
|
-
end
|
178
|
-
|
179
|
-
#
|
180
|
-
# The Gem specification directory
|
181
|
-
#
|
182
|
-
def specification_dir
|
183
|
-
@specification_dir ||= File.join( directory, 'specifications' )
|
184
|
-
end
|
185
|
-
|
186
|
-
#
|
187
|
-
# The cache dir for the downloads
|
188
|
-
#
|
189
|
-
def cache_dir
|
190
|
-
@cache_dir ||= File.join( directory, 'cache' )
|
191
|
-
end
|
192
|
-
|
193
|
-
#
|
194
|
-
# The Distribution directory
|
195
|
-
#
|
196
|
-
# this is the document root for the webserver that will serve your rubygems.
|
197
|
-
# Or they can be served directly from this location
|
198
|
-
#
|
199
|
-
def dist_dir
|
200
|
-
@dist_dir ||= File.join( directory, 'dist' )
|
201
|
-
end
|
202
|
-
|
203
|
-
#
|
204
|
-
# logging handler
|
205
|
-
#
|
206
|
-
def logger
|
207
|
-
@logger ||= ::Logging::Logger[self]
|
208
|
-
end
|
209
|
-
|
210
|
-
#
|
211
|
-
# The SourceGroup containing all of the sources for this repository
|
212
|
-
#
|
213
|
-
def source_group
|
214
|
-
unless @source_group
|
215
|
-
sg = SourceGroup.new( self )
|
216
|
-
Console.info "Setting up sources"
|
217
|
-
configuration.sources.each do |source_uri|
|
218
|
-
sg.add_source( source_uri )
|
219
|
-
end
|
220
|
-
@source_group = sg
|
221
|
-
end
|
222
|
-
return @source_group
|
223
|
-
end
|
224
|
-
|
225
|
-
#
|
226
|
-
# Is the repository valid?
|
227
|
-
#
|
228
|
-
def valid?
|
229
|
-
if @valid.nil? then
|
230
|
-
begin
|
231
|
-
valid!
|
232
|
-
@valid = true
|
233
|
-
rescue StandardError => e
|
234
|
-
logger.error "Repository is not valid : #{e}"
|
235
|
-
@valid = false
|
236
|
-
end
|
237
|
-
end
|
238
|
-
return @valid
|
239
|
-
end
|
240
|
-
|
241
|
-
#
|
242
|
-
# raise an error if the repository is not valid
|
243
|
-
#
|
244
|
-
def valid!
|
245
|
-
raise Error, "#{directory} does not exist" unless File.exist?( directory )
|
246
|
-
raise Error, "#{directory} is not writable" unless File.writable?( directory )
|
247
|
-
|
248
|
-
raise Error, "#{config_file} does not exist" unless File.exist?( config_file )
|
249
|
-
raise Error, "#{config_file} is not loaded" unless configuration
|
250
|
-
|
251
|
-
Repository.other_dir_names.each do |method|
|
252
|
-
other_dir = self.send( method )
|
253
|
-
raise Error, "#{other_dir} does not exist" unless File.exist?( other_dir )
|
254
|
-
raise Error, "#{other_dir} is not writeable" unless File.writable?( other_dir )
|
255
|
-
end
|
256
|
-
|
257
|
-
if File.exist?( log_file ) then
|
258
|
-
raise Error, "#{log_file} is not writable" unless File.writable?( log_file )
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
#
|
263
|
-
# Setup the repository.
|
264
|
-
#
|
265
|
-
# This is executed with the 'setup' mode on the command line. Only those
|
266
|
-
# files and directories that do not already exist are created. Nothing is
|
267
|
-
# destroyed.
|
268
|
-
#
|
269
|
-
def setup
|
270
|
-
if File.exist?( directory ) then
|
271
|
-
Console.info "repository root already exists #{directory}"
|
272
|
-
else
|
273
|
-
FileUtils.mkdir_p( directory )
|
274
|
-
Console.info "created repository root #{directory}"
|
275
|
-
end
|
276
|
-
|
277
|
-
Repository.other_dir_names.each do |method|
|
278
|
-
d = self.send( method )
|
279
|
-
if File.exist?( d ) then
|
280
|
-
Console.info "directory #{d} already exists"
|
281
|
-
else
|
282
|
-
FileUtils.mkdir_p( d )
|
283
|
-
Console.info "created directory #{d}"
|
284
|
-
end
|
285
|
-
end
|
286
|
-
|
287
|
-
if overwrite? or not File.exist?( config_file ) then
|
288
|
-
FileUtils.cp Stickler::Paths.data_path( Repository.config_file_basename ), config_file
|
289
|
-
Console.info "copied in default configuration to #{config_file}"
|
290
|
-
else
|
291
|
-
Console.info "configuration file #{config_file} already exists"
|
292
|
-
end
|
293
|
-
|
294
|
-
# load the configuration for the repo
|
295
|
-
load_configuration
|
296
|
-
|
297
|
-
rescue => e
|
298
|
-
$stderr.puts "Unable to setup the respository"
|
299
|
-
$stderr.puts e
|
300
|
-
$stderr.puts e.backtrace.join("\n")
|
301
|
-
exit 1
|
302
|
-
end
|
303
|
-
|
304
|
-
#
|
305
|
-
# Report information about the repository. This is what is called from the
|
306
|
-
# 'info' mode on the commandline
|
307
|
-
#
|
308
|
-
def info
|
309
|
-
return unless valid?
|
310
|
-
|
311
|
-
Console.info ""
|
312
|
-
Console.info "Upstream Sources"
|
313
|
-
Console.info "----------------"
|
314
|
-
Console.info ""
|
315
|
-
|
316
|
-
max_width = configuration.sources.collect { |s| s.length }.max
|
317
|
-
source_group.sources.each do |source|
|
318
|
-
Console.info " #{source.uri.to_s.rjust( max_width )} : #{source.source_specs.size} gems available"
|
319
|
-
Console.info " #{" ".rjust( max_width )} : #{source_group.existing_specs_for_source_uri( source.uri ).size} gems existing"
|
320
|
-
end
|
321
|
-
|
322
|
-
|
323
|
-
Console.info ""
|
324
|
-
Console.info "Configured gems (in stickler.yml)"
|
325
|
-
Console.info "---------------------------------"
|
326
|
-
Console.info ""
|
327
|
-
configuration.gem_dependencies.sort.each do |dep|
|
328
|
-
Console.info "#{dep.name} : #{dep.version_requirements}"
|
329
|
-
end
|
330
|
-
|
331
|
-
Console.info ""
|
332
|
-
Console.info "Existing gems"
|
333
|
-
Console.info "-------------"
|
334
|
-
Console.info ""
|
335
|
-
|
336
|
-
source_group.gems.keys.sort.each do |g|
|
337
|
-
puts g
|
338
|
-
end
|
339
|
-
|
340
|
-
|
341
|
-
end
|
342
|
-
|
343
|
-
#
|
344
|
-
# Add a source to the repository
|
345
|
-
#
|
346
|
-
def add_source( source_uri )
|
347
|
-
load_configuration unless configuration_loaded?
|
348
|
-
if configuration.sources.include?( source_uri ) then
|
349
|
-
Console.info "#{source_uri} already in sources"
|
350
|
-
else
|
351
|
-
source_group.add_source( source_uri )
|
352
|
-
configuration.sources << source_uri
|
353
|
-
configuration.write
|
354
|
-
Console.info "#{source_uri} added to sources"
|
355
|
-
end
|
356
|
-
end
|
357
|
-
|
358
|
-
#
|
359
|
-
# Remove a source from the repository
|
360
|
-
#
|
361
|
-
def remove_source( source_uri )
|
362
|
-
load_configuration unless configuration_loaded?
|
363
|
-
uri = ::URI.parse source_uri
|
364
|
-
if configuration.sources.delete( source_uri ) then
|
365
|
-
source_group.remove_source( source_uri )
|
366
|
-
configuration.write
|
367
|
-
Console.info "#{source_uri} removed from sources"
|
368
|
-
else
|
369
|
-
Console.info "#{source_uri} is not one of your sources"
|
370
|
-
Console.info "Your sources are:"
|
371
|
-
configuration.sources.each do |src|
|
372
|
-
Console.info " #{src}"
|
373
|
-
end
|
374
|
-
end
|
375
|
-
end
|
376
|
-
|
377
|
-
#
|
378
|
-
# Add a gem to the repository
|
379
|
-
#
|
380
|
-
def add_gem( gem_name, version )
|
381
|
-
|
382
|
-
Console.info ""
|
383
|
-
|
384
|
-
::HighLine.track_eof = false
|
385
|
-
hl = ::HighLine.new( STDIN, STDOUT, :auto)
|
386
|
-
hl.say("You need to pick the #{gem_name} Requirement to configure Stickler.")
|
387
|
-
hl.say("This involves picking one of the following Requirement operators")
|
388
|
-
hl.say('See http://docs.rubygems.org/read/chapter/16#page74 for operator info.')
|
389
|
-
hl.say("\nYou need to (1) pick an operator and (2) pick a requirement.")
|
390
|
-
hl.say("The most common operators are >=, > and ~>")
|
391
|
-
|
392
|
-
op = hl.choose(*Repository.requirement_meta.collect { |k,v| "#{k.ljust(3)}#{v}" } ) do |m|
|
393
|
-
m.prompt = "(1) Pick an operator ? "
|
394
|
-
end
|
395
|
-
|
396
|
-
op = op.split.first # get only the operator, not the trailing text
|
397
|
-
|
398
|
-
version = ::Gem::Requirement.default if version == :latest
|
399
|
-
search_pattern = ::Gem::Dependency.new( gem_name, version )
|
400
|
-
choices = []
|
401
|
-
source_group.search( search_pattern ).each do |spec|
|
402
|
-
choices << "#{op} #{spec.version.to_s}"
|
403
|
-
end
|
404
|
-
choices = choices.sort.reverse
|
405
|
-
|
406
|
-
hl.say("\nNow to pick a requirement. Based upon your chosen operator '#{op}',")
|
407
|
-
hl.say("These are the available version of the #{gem_name} gem.")
|
408
|
-
requirement = hl.choose do |m|
|
409
|
-
m.flow = :columns_down
|
410
|
-
m.prompt = "(2) Pick a requirement ? "
|
411
|
-
m.choices( *choices )
|
412
|
-
end
|
413
|
-
|
414
|
-
Console.info ""
|
415
|
-
|
416
|
-
dep = ::Gem::Dependency.new( gem_name, requirement )
|
417
|
-
if configuration.gem_dependencies.include?( dep ) then
|
418
|
-
Console.info "#{dep} is already in your list of gems"
|
419
|
-
else
|
420
|
-
source_group.add_from_dependency( dep )
|
421
|
-
configuration.gem_dependencies << dep
|
422
|
-
configuration.write
|
423
|
-
end
|
424
|
-
end
|
425
|
-
|
426
|
-
#
|
427
|
-
# Remove a gem from the repository
|
428
|
-
#
|
429
|
-
def remove_gem( gem_name, version )
|
430
|
-
Console.info ""
|
431
|
-
version = ::Gem::Requirement.default if version == :all
|
432
|
-
search_pattern = ::Gem::Dependency.new( gem_name, version )
|
433
|
-
ulist = source_group.search_existing( search_pattern )
|
434
|
-
source_group.search_existing( search_pattern ).each do |spec|
|
435
|
-
source_group.remove( spec )
|
436
|
-
configuration.gem_dependencies.reject! { |d| d.name == spec.name }
|
437
|
-
end
|
438
|
-
configuration.write
|
439
|
-
end
|
440
|
-
|
441
|
-
#
|
442
|
-
# Sync the repository
|
443
|
-
#
|
444
|
-
def sync( rebuild = false )
|
445
|
-
Console.info ""
|
446
|
-
Console.info "Making sure that all gems listed in configuration are available"
|
447
|
-
Console.info ""
|
448
|
-
|
449
|
-
if rebuild then
|
450
|
-
Console.info "Removing existing gems and specifications ... "
|
451
|
-
Dir[ File.join( gems_dir, "*.gem" ) ].each { |g| FileUtils.rm_f g }
|
452
|
-
Dir[ File.join( specification_dir , "*.gemspec" ) ].each { |s| FileUtils.rm_f s }
|
453
|
-
end
|
454
|
-
configuration.gem_dependencies.each do |dep|
|
455
|
-
source_group.add_from_dependency( dep )
|
456
|
-
end
|
457
|
-
end
|
458
|
-
|
459
|
-
#
|
460
|
-
# generate the system configuration to be used by rubygem clients of the
|
461
|
-
# repository that stickler managers
|
462
|
-
#
|
463
|
-
def generate_sysconfig( to = $stdout )
|
464
|
-
Console.info "Generating configuration to stdout"
|
465
|
-
txt = <<-cfg
|
466
|
-
#
|
467
|
-
# This is the system wide configuration to be used by
|
468
|
-
# rubygem clients that install gems from the repository
|
469
|
-
# located at :
|
470
|
-
#
|
471
|
-
# #{configuration.downstream_source}
|
472
|
-
#
|
473
|
-
# On Unix like machines install in
|
474
|
-
#
|
475
|
-
# /etc/gemrc
|
476
|
-
#
|
477
|
-
# On Windows machines install in
|
478
|
-
#
|
479
|
-
# C:\\Documents and Settings\\All Users\\Application Data\\gemrc
|
480
|
-
#
|
481
|
-
---
|
482
|
-
:sources:
|
483
|
-
- #{configuration.downstream_source}
|
484
|
-
cfg
|
485
|
-
to.puts txt
|
486
|
-
end
|
487
|
-
|
488
|
-
#
|
489
|
-
# Generate the gem index that can be rsynced to another location
|
490
|
-
#
|
491
|
-
#
|
492
|
-
def generate_index
|
493
|
-
require 'rubygems/indexer'
|
494
|
-
Console.info "Generating rubygems index in #{dist_dir}"
|
495
|
-
FileUtils.rm_rf dist_dir
|
496
|
-
FileUtils.mkdir_p dist_dir
|
497
|
-
FileUtils.cp_r gems_dir, dist_dir
|
498
|
-
indexer = ::Gem::Indexer.new dist_dir
|
499
|
-
indexer.generate_index
|
500
|
-
end
|
7
|
+
module Repository
|
8
|
+
class Error < ::Stickler::Error ; end
|
501
9
|
end
|
502
|
-
end
|
10
|
+
end
|
data/lib/stickler/spec_lite.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'rubygems/platform'
|
2
|
+
require 'rubygems/version'
|
3
|
+
|
1
4
|
module Stickler
|
2
5
|
#
|
3
6
|
# A lightweight version of a gemspec that only responds to name, version,
|
@@ -6,43 +9,86 @@ module Stickler
|
|
6
9
|
# encapsulates that.
|
7
10
|
#
|
8
11
|
class SpecLite
|
12
|
+
include Comparable
|
13
|
+
|
9
14
|
attr_reader :name
|
10
15
|
attr_reader :version
|
11
16
|
attr_reader :platform
|
12
17
|
|
13
|
-
def initialize( name, version, platform )
|
18
|
+
def initialize( name, version, platform = Gem::Platform::RUBY )
|
14
19
|
@name = name
|
15
|
-
@version = version
|
16
|
-
@
|
17
|
-
@platform = platform
|
20
|
+
@version = Gem::Version.new( version )
|
21
|
+
@platform = Gem::Platform.new( platform )
|
18
22
|
end
|
19
23
|
|
20
24
|
def full_name
|
21
25
|
if platform == Gem::Platform::RUBY or platform.nil? then
|
22
|
-
|
26
|
+
name_version
|
23
27
|
else
|
24
|
-
"#{
|
28
|
+
"#{name_version}-#{platform}"
|
25
29
|
end
|
26
30
|
end
|
31
|
+
alias :to_s :full_name
|
32
|
+
|
33
|
+
def file_name
|
34
|
+
full_name + ".gem"
|
35
|
+
end
|
36
|
+
|
37
|
+
def spec_file_name
|
38
|
+
full_name + ".gemspec"
|
39
|
+
end
|
27
40
|
|
28
41
|
def name_version
|
29
42
|
"#{name}-#{version}"
|
30
43
|
end
|
31
44
|
|
32
45
|
def to_a
|
46
|
+
[ name, version.to_s, platform.to_s ]
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# Convert to the array format used by rubygems itself
|
51
|
+
#
|
52
|
+
def to_rubygems_a
|
33
53
|
[ name, version, platform.to_s ]
|
34
54
|
end
|
35
55
|
|
36
|
-
|
37
|
-
|
56
|
+
#
|
57
|
+
# Lets be comparable!
|
58
|
+
#
|
59
|
+
def <=>(other)
|
60
|
+
return 0 if other.object_id == self.object_id
|
61
|
+
other = coerce( other )
|
62
|
+
[ :name, :version, :platform ].each do |method|
|
63
|
+
result = ( self.send( method ).<=>( other.send( method ) ) )
|
64
|
+
return result unless 0 == result
|
65
|
+
end
|
66
|
+
return 0
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# See if another Spec is the same as this spec
|
71
|
+
#
|
72
|
+
def =~(other)
|
73
|
+
other = coerce( other )
|
74
|
+
return (other and
|
75
|
+
self.name == other.name and
|
76
|
+
self.version.to_s == other.version.to_s and
|
77
|
+
self.platform == other.platform )
|
38
78
|
end
|
39
|
-
end
|
40
|
-
end
|
41
79
|
|
42
|
-
|
43
|
-
|
44
|
-
def
|
45
|
-
|
80
|
+
private
|
81
|
+
|
82
|
+
def coerce( other )
|
83
|
+
if self.class === other then
|
84
|
+
other
|
85
|
+
elsif other.respond_to?( :name ) and
|
86
|
+
other.respond_to?( :version ) and
|
87
|
+
other.respond_to?( :platform ) then
|
88
|
+
SpecLite.new( other.name, other.version, other.platform )
|
89
|
+
else
|
90
|
+
return false
|
91
|
+
end
|
46
92
|
end
|
47
93
|
end
|
48
94
|
end
|
data/lib/stickler/version.rb
CHANGED
@@ -3,16 +3,16 @@
|
|
3
3
|
# All rights reserved. Licensed under the same terms as Ruby. No warranty is
|
4
4
|
# provided. See LICENSE and COPYING for details.
|
5
5
|
#++
|
6
|
-
|
6
|
+
|
7
7
|
module Stickler
|
8
8
|
|
9
9
|
# Version access in every possibly way that people might want to get it.
|
10
10
|
#
|
11
11
|
module Version
|
12
12
|
|
13
|
-
MAJOR =
|
14
|
-
MINOR =
|
15
|
-
BUILD =
|
13
|
+
MAJOR = 2
|
14
|
+
MINOR = 0
|
15
|
+
BUILD = 0
|
16
16
|
|
17
17
|
def self.to_ary
|
18
18
|
[ MAJOR, MINOR, BUILD ]
|
@@ -27,10 +27,10 @@ module Stickler
|
|
27
27
|
end
|
28
28
|
|
29
29
|
# Version string constant
|
30
|
-
STRING = Version.to_s
|
30
|
+
STRING = Version.to_s
|
31
31
|
|
32
32
|
end
|
33
33
|
|
34
34
|
# Version string constant
|
35
|
-
VERSION = Version.to_s
|
35
|
+
VERSION = Version.to_s
|
36
36
|
end
|
data/lib/stickler/web.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'stickler/middleware/compression'
|
2
|
+
require 'stickler/middleware/gemcutter'
|
3
|
+
require 'stickler/middleware/mirror'
|
4
|
+
require 'stickler/middleware/index'
|
5
|
+
require 'rack/cascade'
|
6
|
+
|
7
|
+
module Stickler
|
8
|
+
class Web < ::Sinatra::Base
|
9
|
+
|
10
|
+
disable :sessions
|
11
|
+
enable :logging, :dump_errors, :clean_trace
|
12
|
+
|
13
|
+
use Stickler::Middleware::Compression
|
14
|
+
use Stickler::Middleware::Gemcutter, :serve_indexes => false
|
15
|
+
use Stickler::Middleware::Mirror, :serve_indexes => false
|
16
|
+
use Stickler::Middleware::Index, :serve_indexes => true
|
17
|
+
run Stickler::Middleware::NotFound
|
18
|
+
end
|
19
|
+
end
|
Binary file
|
Binary file
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{bar}
|
5
|
+
s.version = "1.0.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Jeremy Hinegardner"]
|
9
|
+
s.date = %q{2010-06-23}
|
10
|
+
s.description = %q{bar gem}
|
11
|
+
s.email = %q{jeremy@hinegardner.org}
|
12
|
+
s.files = ["README.rdoc", "lib/bar.rb", "bin/bar", "Rakefile", "bar.gemspec"]
|
13
|
+
s.homepage = %q{http://github.com/copiousfreetime/stickler}
|
14
|
+
s.require_paths = ["lib"]
|
15
|
+
s.rubygems_version = %q{1.3.5}
|
16
|
+
s.summary = %q{bar gem}
|
17
|
+
|
18
|
+
if s.respond_to? :specification_version then
|
19
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
20
|
+
s.specification_version = 3
|
21
|
+
|
22
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
23
|
+
s.add_runtime_dependency(%q<rake>, [">= 0"])
|
24
|
+
else
|
25
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
26
|
+
end
|
27
|
+
else
|
28
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|