Class: Stickler::Middleware::Index

Inherits:
Sinatra::Base
  • Object
show all
Includes:
Logable, Helpers::Compression, Helpers::Specs
Defined in:
lib/stickler/middleware/index.rb

Overview

Index is a Rack middleware that passes all requests through except for the following urls:

/specs.#Gem.marhsal_version.gz

The [ name, version, platform ] index of <b>all<b> the gems in the entire repository

/latest_specs.#Gem.marshal_version.gz

The [ name, version, platform ] index of the most recent version of each gem in the repository.

/prerelease_specs.#Gem.marshal-version.gz

The [ name, version, platform ] index of the prerelease versions of the prerelease gems in the repository

/quick/Marshal.#Gem.marshal_version/*.gemspec.rz

The gemspec of each gem

/gems/*.gem

The actual .gem file to serve

For the specs urls, it responds with the summation of all the specs that are in all the repositories served by stickler

Options

This class is also the base class for all the other GemServer type middlewares, so there is an optional behavior to NOT respond to the index url requests.

:serve_indexes

true or false it defaults to true. This option is used when Index is used in a stack with other Index derived middlewares. In this case, all of the Index derived middlewares should set :serve_indexes => false except for the bottom one. It should set :serve_indexes => true. This allows all the Index derived middlewares to cooperatively respond to the /specs and </b>/latests_specs</b> urls.

Usage

use Stickler::Middleware::Index, :serve_indexes => true use Stickler::Middleware::Index, :serve_indexes => false

Direct Known Subclasses

Local, Mirror

Constant Summary collapse

NAME_VERSION_PLATFORM_REGEX =
"(.+)-([0-9.]+[0-9a-z.]*)(?:-(.+))?"

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Logable

#logger

Methods included from Helpers::Specs

#collect_specs_via, #latest_specs, #prerelease_specs, #released_specs, #specs, #specs_by_first_upcase_char, #specs_by_name, #specs_by_repo, #specs_grouped_by_name

Methods included from Helpers::Compression

#compression, #compression=

Constructor Details

#initialize(app, opts = {}) ⇒ Index

Returns a new instance of Index.



62
63
64
65
66
67
# File 'lib/stickler/middleware/index.rb', line 62

def initialize( app, opts = {} )
  @app           = app
  @repo          = ::Stickler::Repository::Null.new
  @serve_indexes = opts.has_key?( :serve_indexes ) ? opts[:serve_indexes] : true
  super( app )
end

Instance Attribute Details

#repoObject (readonly)

The respository of the Index is a Repository::Null



54
55
56
# File 'lib/stickler/middleware/index.rb', line 54

def repo
  @repo
end

Instance Method Details

#marshal(data) ⇒ Object



177
178
179
180
# File 'lib/stickler/middleware/index.rb', line 177

def marshal( data )
  content_type 'application/octet-stream'
  ::Marshal.dump( data )
end

#marshalled_specs(spec_a) ⇒ Object

Convert to the array format used by gem servers everywhere



153
154
155
156
# File 'lib/stickler/middleware/index.rb', line 153

def marshalled_specs( spec_a )
  a = spec_a.collect { |s| s.to_rubygems_a }
  marshal( optimize_specs( a ) )
end

#optimize_specs(specs) ⇒ Object

Optimize the specs marshalling by using identical objects as much as possible. this is take directly from RubyGems source code. See rubygems/indexer.rb #compact_specs



163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/stickler/middleware/index.rb', line 163

def optimize_specs( specs )
  names     = {}
  versions  = {}
  platforms = {}

  specs.collect do |(name, version, platform)|
    names[name]         = name     unless names.include?( name )
    versions[version]   = version  unless versions.include?( version )
    platforms[platform] = platform unless platforms.include?( platform )

    [ names[name], versions[version], platforms[platform] ]
  end
end

#serve_indexes(specs, with_compression = :none) ⇒ Object

Serve the indexes up as the response if @serve_indexes is true. Otherwise return false



107
108
109
110
111
112
113
114
# File 'lib/stickler/middleware/index.rb', line 107

def serve_indexes( specs, with_compression = :none )
  if @serve_indexes then
    self.compression = to_compression_flag( with_compression )
    return marshalled_specs( specs )
  else
    pass
  end
end

#to_compression_flag(with_compression) ⇒ Object



182
183
184
185
186
187
# File 'lib/stickler/middleware/index.rb', line 182

def to_compression_flag( with_compression )
  return with_compression if [ :gzip, :deflate, :none ].include?( with_compression )
  return :gzip            if with_compression =~ /\.gz\Z/i
  return :deflate         if with_compression =~ /\.(Z|rz)\Z/i
  return :none
end