-
-
Notifications
You must be signed in to change notification settings - Fork 916
/
api_v1_depedencies.rb
80 lines (60 loc) · 1.55 KB
/
api_v1_depedencies.rb
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
require 'dalli'
class V1MarshaledDepedencies
LIMIT = 250
BadRequest = [404, {}, ["Go away"]]
TooMany = [413, {},
["Too many gems to resolve, please request less than #{LIMIT}"]]
def data_for(name, ary, cache)
gem = Rubygem.find_by_name(name)
raise "Unknown gem - #{name}" unless gem
these = []
gem.versions.order(:number).reverse_each do |ver|
deps = ver.dependencies.find_all { |d| d.scope == "runtime" }
data = {
:name => name,
:number => ver.number,
:platform => ver.platform,
:dependencies => deps.map { |d| [d.name, d.requirements] }
}
these << data
ary << data
end
if cache
cache.set "gem.#{name}", Marshal.dump(these)
end
ary
end
CACHE = Dalli::Client.new("localhost:11211")
def call(env)
request = Rack::Request.new(env)
return BadRequest unless request.path == "/api/v1/dependencies"
gems = request.params['gems']
return BadRequest unless gems
gems = gems.split(",")
return TooMany if gems.size > LIMIT
ary = []
cache = CACHE.clone
gems.each do |g|
begin
data = cache.get "gem.#{g}"
if data
ary += Marshal.load(data)
else
begin
data_for g, ary, cache
rescue
return BadRequest
end
end
rescue Dalli::RingError
begin
data_for g, ary, nil
rescue
return BadRequest
end
end
end
body = Marshal.dump ary
[200, {}, [body]]
end
end