-
Notifications
You must be signed in to change notification settings - Fork 36
/
patterns.rb
64 lines (52 loc) · 2.28 KB
/
patterns.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
module Gemnasium
module Parser
module Patterns
GEM_NAME = /[a-zA-Z0-9\-_]+/
MATCHER = /(?:=|!=|>|<|>=|<=|~>)/
VERSION = /[0-9]+(?:\.[a-zA-Z0-9]+)*/
REQUIREMENT = /\s*(?:#{MATCHER}\s*)?#{VERSION}\s*/
REQUIREMENT_LIST = /(?<qr1>["'])(?<req1>#{REQUIREMENT})\k<qr1>(?:\s*,\s*(?<qr2>["'])(?<req2>#{REQUIREMENT})\k<qr2>)?/
REQUIREMENTS = /(?:#{REQUIREMENT_LIST}|\[\s*#{REQUIREMENT_LIST}\s*\])/
KEY = /(?::\w+|:?"\w+"|:?'\w+')/
SYMBOL = /(?::\w+|:"[^"#]+"|:'[^']+')/
STRING = /(?:"[^"#]*"|'[^']*')/
BOOLEAN = /(?:true|false)/
NIL = /nil/
ELEMENT = /(?:#{SYMBOL}|#{STRING})/
ARRAY = /\[(?:#{ELEMENT}(?:\s*,\s*#{ELEMENT})*)?\]/
VALUE = /(?:#{BOOLEAN}|#{NIL}|#{ELEMENT}|#{ARRAY}|)/
PAIR = /(?:(#{KEY})\s*=>\s*(#{VALUE})|(\w+):\s+(#{VALUE}))/
OPTIONS = /#{PAIR}(?:\s*,\s*#{PAIR})*/
COMMENT = /(#.*)?/
GEM_CALL = /^\s*gem\(?\s*(?<q1>["'])(?<name>#{GEM_NAME})\k<q1>(?:\s*,\s*#{REQUIREMENT_LIST})?(?:\s*,\s*(?<opts>#{OPTIONS}))?\s*\)?\s*#{COMMENT}$/
SYMBOLS = /#{SYMBOL}(\s*,\s*#{SYMBOL})*/
GROUP_CALL = /^(?<i1>\s*)group\(?\s*(?<grps>#{SYMBOLS})\s*\)?\s+do\s*?\n(?<blk>.*?)\n^\k<i1>end\s*$/m
GIT_CALL = /^(?<i1>\s*)git[\s\(].*?do\s*?\n(?<blk>.*?)\n^\k<i1>end\s*$/m
PATH_CALL = /^(?<i1>\s*)path[\s\(].*?do\s*?\n(?<blk>.*?)\n^\k<i1>end\s*$/m
GEMSPEC_CALL = /^\s*gemspec(?:\(?\s*(?<opts>#{OPTIONS}))?\s*\)?\s*$/
ADD_DEPENDENCY_CALL = /^\s*\w+\.add(?<type>_runtime|_development)?_dependency\(?\s*(?<q1>["'])(?<name>#{GEM_NAME})\k<q1>(?:\s*,\s*#{REQUIREMENTS})?\s*\)?\s*#{COMMENT}$/
def self.options(string)
{}.tap do |hash|
return hash unless string
pairs = Hash[*string.match(OPTIONS).captures.compact]
pairs.each{|k,v| hash[key(k)] = value(v) }
end
end
def self.key(string)
string.tr(%(:"'), "")
end
def self.value(string)
case string
when ARRAY then values(string.tr("[]", ""))
when SYMBOL then string.tr(%(:"'), "").to_sym
when STRING then string.tr(%("'), "")
when BOOLEAN then string == "true"
when NIL then nil
end
end
def self.values(string)
string.strip.split(/\s*,\s*/).map{|v| value(v) }
end
end
end
end