forked from jscruggs/metric_fu
/
gem_version.rb
92 lines (79 loc) · 2.69 KB
/
gem_version.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
81
82
83
84
85
86
87
88
89
90
91
92
# coding: utf-8
require "rubygems"
module MetricFu
class GemVersion
# regexp from https://github.com/gemnasium/gemnasium-parser/blob/807d7ccc/lib/gemnasium/parser/patterns.rb#L11
# under MIT License
GEM_NAME = /[a-zA-Z0-9\-_\.]+/
QUOTED_GEM_NAME = /(?:(?<gq>["'])(?<name>#{GEM_NAME})\k<gq>|%q<(?<name>#{GEM_NAME})>)/
MATCHER = /(?:=|!=|>|<|>=|<=|~>)/
VERSION = /[0-9]+(?:\.[a-zA-Z0-9]+)*/
REQUIREMENT = /[ \t]*(?:#{MATCHER}[ \t]*)?#{VERSION}[ \t]*/
REQUIREMENT_LIST = /(?<qr1>["'])(?<req1>#{REQUIREMENT})\k<qr1>(?:[ \t]*,[ \t]*(?<qr2>["'])(?<req2>#{REQUIREMENT})\k<qr2>)?/
REQUIREMENTS = /(?:#{REQUIREMENT_LIST}|\[[ \t]*#{REQUIREMENT_LIST}[ \t]*\])/
COMMENT = /(#[^\n]*)?/
ADD_DEPENDENCY_CALL = /^[ \t]*\w+\.add(?<type>_runtime|_development)?_dependency\(?[ \t]*#{QUOTED_GEM_NAME}(.freeze)?(?:[ \t]*,[ \t]*#{REQUIREMENTS})?[ \t]*\)?[ \t]*#{COMMENT}$/
def initialize
@gem_spec = File.open(gemspec, "rb") { |f| f.readlines }
end
def gemspec
File.join(MetricFu.root_dir, "metric_fu.gemspec")
end
def new_dependency(name, version)
Gem::Dependency.new(name, version, :runtime)
end
def gem_runtime_dependencies
@gem_runtime_dependencies ||=
begin
@gem_spec.grep(/add_dependency|add_runtime/).map do |line|
match = line.match(ADD_DEPENDENCY_CALL)
name = match["name"].downcase.sub("metric_fu-", "")
version = [match["req1"], match["req2"]].compact
new_dependency(name, version)
end.compact << new_dependency("rcov", ["~> 0.8"])
end
end
def for(name)
name.downcase!
dep = gem_runtime_dependencies.find(unknown_dependency(name)) do |gem_dep|
gem_dep.name == name
end
dep.requirements_list
end
def unknown_dependency(name)
-> { new_dependency(name, [">= 0"]) }
end
RESOLVER = new
def self.for(name)
RESOLVER.for(name).dup
end
def self.dependencies
RESOLVER.gem_runtime_dependencies.dup
end
def self.activated_gems
if Gem::Specification.respond_to?(:stubs)
Gem::Specification.stubs
else
Gem.loaded_specs.values
end.select(&:activated?)
end
def self.activated_version(name)
activated_gems.find do |gem|
return gem.version.version if gem.name == name
end
end
def self.dependency_summary(gem_dep)
name = gem_dep.name
version = activated_version(gem_dep.name) || gem_dep.requirements_list
{
"name" => name,
"version" => version,
}
end
def self.dependencies_summary
dependencies.map do |gem_dep|
dependency_summary(gem_dep)
end
end
end
end