1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
# frozen_string_literal: true
##
# The local source finds gems in the current directory for fulfilling
# dependencies.
require 'rubygems/package'
class Gem::Source::Local < Gem::Source
def initialize # :nodoc:
@specs = nil
@api_uri = nil
@uri = nil
@load_specs_names = {}
end
##
# Local sorts before Gem::Source and after Gem::Source::Installed
def <=>(other)
case other
when Gem::Source::Installed,
Gem::Source::Lock then
-1
when Gem::Source::Local then
0
when Gem::Source then
1
else
nil
end
end
def inspect # :nodoc:
keys = @specs ? @specs.keys.sort : 'NOT LOADED'
"#<%s specs: %p>" % [self.class, keys]
end
def load_specs(type) # :nodoc:
@load_specs_names[type] ||= begin
names = []
@specs = {}
Dir["*.gem"].each do |file|
begin
pkg = Gem::Package.new(file)
rescue SystemCallError, Gem::Package::FormatError
# ignore
else
tup = pkg.spec.name_tuple
@specs[tup] = [File.expand_path(file), pkg]
case type
when :released
unless pkg.spec.version.prerelease?
names << pkg.spec.name_tuple
end
when :prerelease
if pkg.spec.version.prerelease?
names << pkg.spec.name_tuple
end
when :latest
tup = pkg.spec.name_tuple
cur = names.find { |x| x.name == tup.name }
if !cur
names << tup
elsif cur.version < tup.version
names.delete cur
names << tup
end
else
names << pkg.spec.name_tuple
end
end
end
names
end
end
def find_gem(gem_name, version = Gem::Requirement.default, # :nodoc:
prerelease = false)
load_specs :complete
found = []
@specs.each do |n, data|
if n.name == gem_name
s = data[1].spec
if version.satisfied_by?(s.version)
if prerelease
found << s
elsif !s.version.prerelease? || version.prerelease?
found << s
end
end
end
end
found.max_by { |s| s.version }
end
def fetch_spec(name) # :nodoc:
load_specs :complete
if data = @specs[name]
data.last.spec
else
raise Gem::Exception, "Unable to find spec for #{name.inspect}"
end
end
def download(spec, cache_dir = nil) # :nodoc:
load_specs :complete
@specs.each do |name, data|
return data[0] if data[1].spec == spec
end
raise Gem::Exception, "Unable to find file for '#{spec.full_name}'"
end
def pretty_print(q) # :nodoc:
q.group 2, '[Local gems:', ']' do
q.breakable
q.seplist @specs.keys do |v|
q.text v.full_name
end
end
end
end
|