1require 'rubygems/source'
2
3class Gem::Source::Local < Gem::Source
4  def initialize
5    @uri = nil
6  end
7
8  def load_specs(type)
9    names = []
10
11    @specs = {}
12
13    Dir["*.gem"].each do |file|
14      begin
15        pkg = Gem::Package.new(file)
16      rescue SystemCallError, Gem::Package::FormatError
17        # ignore
18      else
19        tup = pkg.spec.name_tuple
20        @specs[tup] = [File.expand_path(file), pkg]
21
22        case type
23        when :released
24          unless pkg.spec.version.prerelease?
25            names << pkg.spec.name_tuple
26          end
27        when :prerelease
28          if pkg.spec.version.prerelease?
29            names << pkg.spec.name_tuple
30          end
31        when :latest
32          tup = pkg.spec.name_tuple
33
34          cur = names.find { |x| x.name == tup.name }
35          if !cur
36            names << tup
37          elsif cur.version < tup.version
38            names.delete cur
39            names << tup
40          end
41        else
42          names << pkg.spec.name_tuple
43        end
44      end
45    end
46
47    names
48  end
49
50  def find_gem(gem_name, version=Gem::Requirement.default,
51               prerelease=false)
52    load_specs :complete
53
54    found = []
55
56    @specs.each do |n, data|
57      if n.name == gem_name
58        s = data[1].spec
59
60        if version.satisfied_by?(s.version)
61          if prerelease
62            found << s
63          elsif !s.version.prerelease?
64            found << s
65          end
66        end
67      end
68    end
69
70    found.sort_by { |s| s.version }.last
71  end
72
73  def fetch_spec(name)
74    load_specs :complete
75
76    if data = @specs[name]
77      data.last.spec
78    else
79      raise Gem::Exception, "Unable to find spec for '#{name}'"
80    end
81  end
82
83  def download(spec, cache_dir=nil)
84    load_specs :complete
85
86    @specs.each do |name, data|
87      return data[0] if data[1].spec == spec
88    end
89
90    raise Gem::Exception, "Unable to find file for '#{spec.full_name}'"
91  end
92end
93