Class: Stickler::Repository::Local

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Logable
Defined in:
lib/stickler/repository/local.rb

Overview

A local repository of gems. It implements the Repository::Api and stores all the gems and specifications local to a root directory.

It currently has two subdirectories:

gems/ -> holding the .gem files specifications/ -> holding the .gemspec files

Defined Under Namespace

Classes: Error

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Logable

#logger

Constructor Details

#initialize(root_dir, name = nil) ⇒ Local

Returns a new instance of Local.



98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/stickler/repository/local.rb', line 98

def initialize( root_dir, name = nil )
  @root_dir = File.expand_path( root_dir ) + File::SEPARATOR
  @name     = name || @root_dir
  @gems_dir = File.join( @root_dir, 'gems/' )
  @specifications_dir = File.join( @root_dir, 'specifications/' )
  @temp_dir = File.join( @root_dir, "tmp/" )

  # setup the dirs before doing the index because the @specifications_dir
  # may not exist yet.
  setup_dirs

  @index = ::Stickler::Repository::Index.new( @specifications_dir )
end

Instance Attribute Details

#gems_dirObject (readonly)

the directory containing the .gem files



32
33
34
# File 'lib/stickler/repository/local.rb', line 32

def gems_dir
  @gems_dir
end

#indexObject (readonly)

the index of the repository



41
42
43
# File 'lib/stickler/repository/local.rb', line 41

def index
  @index
end

#nameObject (readonly)

The name to give to this repository



26
27
28
# File 'lib/stickler/repository/local.rb', line 26

def name
  @name
end

#root_dirObject (readonly)

the root directory of the repository



29
30
31
# File 'lib/stickler/repository/local.rb', line 29

def root_dir
  @root_dir
end

#specifications_dirObject (readonly)

the directory containing the .gemspec files



35
36
37
# File 'lib/stickler/repository/local.rb', line 35

def specifications_dir
  @specifications_dir
end

#temp_dirObject (readonly)

a temporary directory for odds and ends



38
39
40
# File 'lib/stickler/repository/local.rb', line 38

def temp_dir
  @temp_dir
end

Class Method Details

.new(root_dir, name = nil) ⇒ Object

:call-seq:

Local.new( '/tmp/repo' )
Local.new( '/tmp/repo', "Temporary Repo" )

Create a new Local repository. Local repository instances are shared if the root_dir is the same. That is

repo1 = Local.new( '/foo/bar' )
repo2 = Local.new( '/foo/bar' )

repo1 and repo2 will be references to the sname object

If a new is called for an already existing repo, and the name of the repo is not nil, and different than the existing repo an exception is raised.



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/stickler/repository/local.rb', line 81

def self.new( root_dir, name = nil )
  repo = nil
  @mutex.synchronize do
    local_key = File.expand_path( root_dir ) + File::SEPARATOR
    repo = @repos[local_key]
    if repo.nil? then
      repo = super( local_key, name )
      @repos[local_key] = repo
    else
      if name and (repo.name != name) then
        raise Error, "A repository already exists for #{root_dir} with name has the name #{repo.name} which conflicts with the given name #{name}"
      end
    end
  end
  repo
end

.purgeObject

Purge the list of local repos that are known. This is mainly used in testing.



60
61
62
# File 'lib/stickler/repository/local.rb', line 60

def self.purge
  @mutex.synchronize { @repos.clear }
end

.reposObject

Return the list of all the Local repositories



52
53
54
# File 'lib/stickler/repository/local.rb', line 52

def self.repos
  return @repos
end

Instance Method Details

#add(io) ⇒ Object

:call-seq:

repo.add( io ) -> Stickler::SpecLite

A lower level version of #push. The item passed in is an IO like object that contains the binary stream that is a .gem file. IO must respond to #read and #rewind.



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/stickler/repository/local.rb', line 175

def add( io )
  # spooling to a temp file because Gem::Format.from_io() closes the io
  # stream it is sent.  Why it does this, I do not know.
  tempfile = Tempfile.new(  "uploaded-gem.", temp_dir )
  tempfile.write( io.read )
  tempfile.rewind

  format    = Gem::Format.from_file_by_path( tempfile.path )
  spec      = Stickler::SpecLite.new( format.spec.name, format.spec.version, format.spec.platform )
  specs     = search_for( spec )

  raise Error, "gem #{spec.full_name} already exists" unless specs.empty?

  tempfile.rewind
  return install( spec, tempfile )
ensure
  tempfile.close!
end

#delete(spec) ⇒ Object

See Api#delete



154
155
156
# File 'lib/stickler/repository/local.rb', line 154

def delete( spec )
  uninstall( spec )
end

#full_path_to_gem(spec) ⇒ Object



233
234
235
# File 'lib/stickler/repository/local.rb', line 233

def full_path_to_gem( spec )
  File.join( gems_dir, spec.file_name )
end

#full_path_to_specification(spec) ⇒ Object



237
238
239
# File 'lib/stickler/repository/local.rb', line 237

def full_path_to_specification( spec )
  File.join( specifications_dir, spec.spec_file_name )
end

#gem_file_exist?(spec) ⇒ Boolean

Returns:

  • (Boolean)


241
242
243
# File 'lib/stickler/repository/local.rb', line 241

def gem_file_exist?( spec )
  File.exist?( full_path_to_gem( spec ) )
end

#gems_uriObject

See Api#gems_uri



122
123
124
# File 'lib/stickler/repository/local.rb', line 122

def gems_uri
  @gems_uri ||= Addressable::URI.convert_path( gems_dir )
end

#get(spec) ⇒ Object

See Api#get



209
210
211
212
# File 'lib/stickler/repository/local.rb', line 209

def get( spec )
  return IO.read( full_path_to_gem( spec ) ) if gem_file_exist?( spec )
  return nil
end

#open(spec, &block) ⇒ Object

See Api#open



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/stickler/repository/local.rb', line 217

def open( spec, &block )
  return nil unless gem_file_exist?( spec )
  path = full_path_to_gem( spec )
  f = File.open( path, "rb" )
  if block_given? then
    begin
      yield f
    ensure
      f.close
    end
  else
    return f
  end
  return nil
end

#push(path) ⇒ Object

See Api#push



197
198
199
200
201
202
203
204
# File 'lib/stickler/repository/local.rb', line 197

def push( path )
  spec = specification_from_gem_file( path )
  result = nil
  File.open( path ) do |io|
    result = add( io )
  end
  return result
end

#search_for(spec) ⇒ Object

See Api#search_for



147
148
149
# File 'lib/stickler/repository/local.rb', line 147

def search_for( spec )
  return index.search( spec )
end

#specification_file_exist?(spec) ⇒ Boolean

Returns:

  • (Boolean)


245
246
247
# File 'lib/stickler/repository/local.rb', line 245

def specification_file_exist?( spec )
  File.exist?( full_path_to_specification( spec ) )
end

#uriObject

See Api#uri



115
116
117
# File 'lib/stickler/repository/local.rb', line 115

def uri
  @uri ||= Addressable::URI.convert_path( root_dir )
end

#uri_for_gem(spec) ⇒ Object

See Api#uri_from_gem



129
130
131
132
# File 'lib/stickler/repository/local.rb', line 129

def uri_for_gem( spec )
  return nil unless gem_file_exist?( spec )
  return self.gems_uri.join( spec.file_name )
end

#yank(spec) ⇒ Object

See Api#yank



161
162
163
164
# File 'lib/stickler/repository/local.rb', line 161

def yank( spec )
  uninstall_specification( spec ) if specification_file_exist?( spec )
  return uri_for_gem( spec )
end