Class: Hako::EnvExpander
- Inherits:
-
Object
show all
- Defined in:
- lib/hako/env_expander.rb
Defined Under Namespace
Classes: ExpansionError, Literal, Variable
Instance Method Summary
collapse
Constructor Details
#initialize(providers) ⇒ EnvExpander
Returns a new instance of EnvExpander.
17
18
19
|
# File 'lib/hako/env_expander.rb', line 17
def initialize(providers)
@providers = providers
end
|
Instance Method Details
#expand(env) ⇒ Hash<String, String>
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
|
# File 'lib/hako/env_expander.rb', line 23
def expand(env)
parsed_env = parse_env(env)
variables = Set.new
parsed_env.each_value do |tokens|
tokens.each do |t|
if t.is_a?(Variable)
variables << t.name
end
end
end
values = {}
@providers.each do |provider|
if variables.empty?
break
end
provider.ask(variables.to_a).each do |var, val|
values[var] = val
variables.delete(var)
end
end
unless variables.empty?
raise ExpansionError.new("Could not resolve embedded variables from $providers=#{@providers}: #{variables.to_a}")
end
expanded_env = {}
parsed_env.each do |key, tokens|
expanded_env[key] = tokens.map { |t| expand_value(values, t) }.join('')
end
expanded_env
end
|
#expand_value(values, token) ⇒ Object
127
128
129
130
131
132
133
134
135
136
|
# File 'lib/hako/env_expander.rb', line 127
def expand_value(values, token)
case token
when Literal
token.literal
when Variable
values.fetch(token.name)
else
raise ExpansionError.new("Unknown token type: #{token.class}")
end
end
|
#parse(value) ⇒ Array
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
# File 'lib/hako/env_expander.rb', line 104
def parse(value)
s = StringScanner.new(value)
tokens = []
pos = 0
while s.scan_until(/#\{(.*?)\}/)
pre = s.string.byteslice(pos...(s.pos - s.matched.size))
var = s[1]
unless pre.empty?
tokens << Literal.new(pre)
end
if var.empty?
raise ExpansionError.new('Empty interpolation is not allowed')
else
tokens << Variable.new(var)
end
pos = s.pos
end
unless s.rest.empty?
tokens << Literal.new(s.rest)
end
tokens
end
|
#parse_env(env) ⇒ Hash<String, Array<Literal, Variable>>
91
92
93
94
95
96
97
98
99
100
|
# File 'lib/hako/env_expander.rb', line 91
def parse_env(env)
parsed_env = {}
env.each do |key, val|
unless val.is_a?(String)
raise ExpansionError.new("#{key} must be a String but got #{val.class}: #{val.inspect}")
end
parsed_env[key] = parse(val)
end
parsed_env
end
|
#validate!(env) ⇒ Boolean
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
|
# File 'lib/hako/env_expander.rb', line 57
def validate!(env)
parsed_env = parse_env(env)
variables = Set.new
parsed_env.each_value do |tokens|
tokens.each do |t|
if t.is_a?(Variable)
variables << t.name
end
end
end
@providers.each do |provider|
if variables.empty?
break
end
if provider.can_ask_keys?
provider.ask_keys(variables.to_a).each do |var|
variables.delete(var)
end
else
Hako.logger.warn("EnvProvider#validate! is skipped because #{provider.class} doesn't support ask_keys method")
return false
end
end
unless variables.empty?
raise ExpansionError.new("Could not find embedded variables from $providers=#{@providers}: #{variables.to_a}")
end
true
end
|