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.



94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/stickler/repository/local.rb', line 94

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



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

def gems_dir
  @gems_dir
end

#indexObject (readonly)

the index of the repository



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

def index
  @index
end

#nameObject (readonly)

The name to give to this repository



22
23
24
# File 'lib/stickler/repository/local.rb', line 22

def name
  @name
end

#root_dirObject (readonly)

the root directory of the repository



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

def root_dir
  @root_dir
end

#specifications_dirObject (readonly)

the directory containing the .gemspec files



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

def specifications_dir
  @specifications_dir
end

#temp_dirObject (readonly)

a temporary directory for odds and ends



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

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.



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/stickler/repository/local.rb', line 77

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.



56
57
58
# File 'lib/stickler/repository/local.rb', line 56

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

.reposObject

Return the list of all the Local repositories



48
49
50
# File 'lib/stickler/repository/local.rb', line 48

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.



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/stickler/repository/local.rb', line 180

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. This may be
  # removed once we are no longer using older rubygems
  tempfile = Tempfile.new(  "uploaded-gem.", temp_dir )
  tempfile.write( io.read )
  tempfile.rewind

  container = Stickler::GemContainer.new( tempfile.path )
  spec      = Stickler::SpecLite.new( container.spec.name, container.spec.version, container.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



150
151
152
# File 'lib/stickler/repository/local.rb', line 150

def delete( spec )
  uninstall( spec )
end

#full_path_to_gem(spec) ⇒ Object



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

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

#full_path_to_specification(spec) ⇒ Object



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

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

#gem_file_exist?(spec) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#gems_uriObject

See Api#gems_uri



118
119
120
# File 'lib/stickler/repository/local.rb', line 118

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

#get(spec) ⇒ Object

See Api#get



214
215
216
217
# File 'lib/stickler/repository/local.rb', line 214

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



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/stickler/repository/local.rb', line 222

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



203
204
205
206
207
208
209
# File 'lib/stickler/repository/local.rb', line 203

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

#search_for(spec) ⇒ Object

See Api#search_for



143
144
145
# File 'lib/stickler/repository/local.rb', line 143

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

#specification_file_exist?(spec) ⇒ Boolean

Returns:

  • (Boolean)


250
251
252
# File 'lib/stickler/repository/local.rb', line 250

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

#unyank(spec) ⇒ Object

See Api#unyank



165
166
167
168
169
# File 'lib/stickler/repository/local.rb', line 165

def unyank( spec )
  return nil if specification_file_exist?( spec )
  return nil unless gem_file_exist?( spec )
  install_specification( spec )
end

#uriObject

See Api#uri



111
112
113
# File 'lib/stickler/repository/local.rb', line 111

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

#uri_for_gem(spec) ⇒ Object

See Api#uri_from_gem



125
126
127
128
# File 'lib/stickler/repository/local.rb', line 125

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



157
158
159
160
# File 'lib/stickler/repository/local.rb', line 157

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