text-interpolator 1.0.5 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.idea/codeStyleSettings.xml +14 -0
- data/CHANGES +5 -1
- data/README.md +13 -4
- data/lib/text_interpolator/hash_processor.rb +125 -0
- data/lib/text_interpolator/text_interpolator.rb +5 -52
- data/lib/text_interpolator/version.rb +1 -1
- data/spec/text_interpolator_spec.rb +43 -16
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MGI1Y2YyNjFlYzEwZDEzNTJiMDhjNDNiNGJjNzBkYjI5N2M3OGVjYQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YzgyYzU5Zjc4MDQzZWFkZjBkYTUxZGNmZTExZmM5YjU2MjJjOGE3Mw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MzU2YjQ5MGQ2YWY4MWU2NTY3ZDg4ZWM4OTQ3MjUwZGRhMDc4ODE2ZGQwZGQ0
|
10
|
+
YzY0Y2ZmNTc0ZmU4YTg1MjI2NzhmOTMyMDFkM2QyZDE5YTYyZGI2YWE5ZmQz
|
11
|
+
NmQ2ZmVhOTQwMGU4NjE3NzIxZmIzYTNjYzc1MTE2N2E3ODY1N2Q=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZGU0YzEyNTFhNmJmMzQxYWI0NTUzZmI1MzA0ZWJlOGZhMjBjNGMxOWE3MTBm
|
14
|
+
ODA1MDE0ZDI1ZTU0MGVkMTM2OGU3YmE4ZjE1NmEwOGFkYjkxMmI3NzQ0NDMy
|
15
|
+
YjQ0N2U2MjIzYzM2ZmI1ZGQ2ZjZkOGViOTFlOTQyMzNkNjdiOWQ=
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<project version="4">
|
3
|
+
<component name="ProjectCodeStyleSettingsManager">
|
4
|
+
<option name="PER_PROJECT_SETTINGS">
|
5
|
+
<value>
|
6
|
+
<XML>
|
7
|
+
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
|
8
|
+
</XML>
|
9
|
+
</value>
|
10
|
+
</option>
|
11
|
+
<option name="PREFERRED_PROJECT_CODE_STYLE" value="alex" />
|
12
|
+
</component>
|
13
|
+
</project>
|
14
|
+
|
data/CHANGES
CHANGED
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
You have few options in ruby for variables interpolation:
|
6
6
|
|
7
|
-
- interpolation inside string:
|
7
|
+
- interpolation inside the string:
|
8
8
|
|
9
9
|
```ruby
|
10
10
|
var1 = 'some value 1'
|
@@ -36,9 +36,9 @@ result = template.result(binding)
|
|
36
36
|
puts result # We have var1: some value 1 and var2: some value 2.
|
37
37
|
```
|
38
38
|
|
39
|
-
This library can be used for interpolation inside file with string syntax
|
39
|
+
This library can be used for **interpolation inside file with string syntax**.
|
40
40
|
|
41
|
-
In order to achieve it uses this ruby trick:
|
41
|
+
In order to achieve it library uses this ruby trick:
|
42
42
|
|
43
43
|
```ruby
|
44
44
|
env = {var1: 'some value 1', var2: 'some value 2'}
|
@@ -58,12 +58,20 @@ It's straightforward:
|
|
58
58
|
# some_template.txt
|
59
59
|
|
60
60
|
We have var1: #{var1} and var2: #{var2}.
|
61
|
+
We have var3: #{settings.var3} and var4: #{settings.var4}.
|
61
62
|
|
62
63
|
# test.rb
|
63
64
|
|
64
65
|
require 'text_interpolator'
|
65
66
|
|
66
|
-
env ={
|
67
|
+
env = {
|
68
|
+
var1: 'some value 1',
|
69
|
+
var2: 'some value 2',
|
70
|
+
settings: {
|
71
|
+
var3: 'some value 3',
|
72
|
+
var4: 'some value 4'
|
73
|
+
}
|
74
|
+
}
|
67
75
|
|
68
76
|
template = File.read("some_template.txt")
|
69
77
|
|
@@ -72,4 +80,5 @@ text_interpolator = TextInterpolator.new
|
|
72
80
|
result = text_interpolator.interpolate template, env
|
73
81
|
|
74
82
|
puts result # We have var1: some value 1 and var2: some value 2.
|
83
|
+
# We have var3: some value 3 and var4: some value 4.
|
75
84
|
```
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
class HashProcessor
|
4
|
+
include Singleton
|
5
|
+
|
6
|
+
def process hash
|
7
|
+
errors = {}
|
8
|
+
|
9
|
+
content = interpolate_system_variables(hash)
|
10
|
+
|
11
|
+
var_table = build_variables_table(content) # one-dimensional collection of variables
|
12
|
+
|
13
|
+
result = interpolate_variables(content, var_table, errors)
|
14
|
+
|
15
|
+
[result, errors]
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def interpolate_system_variables hash
|
21
|
+
content = {}
|
22
|
+
|
23
|
+
hash.each do |key, value|
|
24
|
+
if value.kind_of? String
|
25
|
+
new_value = interpolate_system_variable value
|
26
|
+
|
27
|
+
content[key] = new_value if new_value
|
28
|
+
elsif value.kind_of? Hash
|
29
|
+
content[key] = interpolate_system_variables value
|
30
|
+
else
|
31
|
+
content[key] = value
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
content
|
36
|
+
end
|
37
|
+
|
38
|
+
def interpolate_system_variable value
|
39
|
+
new_value = value
|
40
|
+
|
41
|
+
while new_value.index('ENV[')
|
42
|
+
index1 = new_value.index("ENV[")
|
43
|
+
index2 = new_value.index("]")
|
44
|
+
|
45
|
+
name = new_value[index1+5..index2-2]
|
46
|
+
|
47
|
+
left = (index1 == 0) ? '' : new_value[0..index1-1]
|
48
|
+
right = new_value[index2+1..-1]
|
49
|
+
|
50
|
+
new_value = left + ENV[name] + right
|
51
|
+
end
|
52
|
+
|
53
|
+
new_value
|
54
|
+
end
|
55
|
+
|
56
|
+
def build_variables_table content
|
57
|
+
var_table = {}
|
58
|
+
|
59
|
+
content.each do |key, value|
|
60
|
+
build_variable(var_table, key, key, value)
|
61
|
+
end
|
62
|
+
|
63
|
+
var_table
|
64
|
+
end
|
65
|
+
|
66
|
+
def build_variable(var_table, compound_key, key, value)
|
67
|
+
if value.kind_of? String
|
68
|
+
var_table[key] = value
|
69
|
+
elsif value.kind_of? Hash
|
70
|
+
build_hash var_table, compound_key, value
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def build_hash var_table, compound_key, hash
|
75
|
+
hash.each do |key, value|
|
76
|
+
new_compound_key = "#{compound_key}.#{key}"
|
77
|
+
|
78
|
+
if value.kind_of? Hash
|
79
|
+
build_variable(var_table, new_compound_key, key, value)
|
80
|
+
else
|
81
|
+
var_table[new_compound_key.to_sym] = value
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def interpolate_variables content, env, errors
|
87
|
+
hash = {}
|
88
|
+
|
89
|
+
begin
|
90
|
+
substitutions = false
|
91
|
+
|
92
|
+
content.each do |key, value|
|
93
|
+
new_value = value
|
94
|
+
substitutions = false
|
95
|
+
|
96
|
+
if value.kind_of? String
|
97
|
+
if value.index(/\#\{/)
|
98
|
+
substitutions = true
|
99
|
+
|
100
|
+
new_value = value.gsub(/\#{/, '%{')
|
101
|
+
|
102
|
+
begin
|
103
|
+
new_value = StringIO.new(new_value).read % env
|
104
|
+
rescue KeyError => e
|
105
|
+
substitutions = false
|
106
|
+
|
107
|
+
errors << e.message
|
108
|
+
end
|
109
|
+
end
|
110
|
+
elsif value.kind_of? Hash
|
111
|
+
new_value = interpolate_variables value, env, errors
|
112
|
+
end
|
113
|
+
|
114
|
+
if hash[key] == new_value
|
115
|
+
substitutions = false
|
116
|
+
else
|
117
|
+
hash[key] = new_value
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end while substitutions
|
121
|
+
|
122
|
+
hash
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
@@ -1,7 +1,10 @@
|
|
1
1
|
require 'stringio'
|
2
|
+
require 'text_interpolator/hash_processor'
|
2
3
|
|
3
4
|
class TextInterpolator
|
4
5
|
|
6
|
+
attr_reader :errors
|
7
|
+
|
5
8
|
def interpolate object, env={}
|
6
9
|
if object.kind_of? String
|
7
10
|
interpolate_string object, env
|
@@ -33,59 +36,9 @@ class TextInterpolator
|
|
33
36
|
end
|
34
37
|
|
35
38
|
def interpolate_hash hash
|
36
|
-
|
37
|
-
new_value = interpolate_env_vars value
|
38
|
-
|
39
|
-
hash[key] = new_value if new_value
|
40
|
-
end
|
41
|
-
|
42
|
-
env = hash.reduce({}) do |result, value|
|
43
|
-
result[value[0]] = value[1]
|
44
|
-
|
45
|
-
result
|
46
|
-
end
|
39
|
+
result, @errors = *HashProcessor.instance.process(hash)
|
47
40
|
|
48
|
-
|
49
|
-
substitutions = false
|
50
|
-
|
51
|
-
hash.each do |key, value|
|
52
|
-
if value.kind_of? String
|
53
|
-
if value.index(/\#\{/)
|
54
|
-
substitutions = true
|
55
|
-
|
56
|
-
value = value.gsub(/\#{/, '%{')
|
57
|
-
|
58
|
-
hash[key] = StringIO.new(value).read % env
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end while substitutions
|
63
|
-
|
64
|
-
hash
|
65
|
-
end
|
66
|
-
|
67
|
-
private
|
68
|
-
|
69
|
-
def interpolate_env_vars value
|
70
|
-
if value.kind_of? String
|
71
|
-
while value.index('ENV[')
|
72
|
-
value = interpolate_env_var value
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
value
|
77
|
-
end
|
78
|
-
|
79
|
-
def interpolate_env_var value
|
80
|
-
index1 = value.index("ENV[")
|
81
|
-
index2 = value.index("]")
|
82
|
-
|
83
|
-
name = value[index1+5..index2-2]
|
84
|
-
|
85
|
-
left = (index1 == 0) ? '' : value[0..index1-1]
|
86
|
-
right = value[index2+1..-1]
|
87
|
-
|
88
|
-
left + ENV[name] + right
|
41
|
+
result
|
89
42
|
end
|
90
43
|
|
91
44
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
2
2
|
|
3
|
-
require 'json'
|
4
3
|
require 'text_interpolator'
|
5
4
|
|
6
5
|
describe TextInterpolator do
|
@@ -52,21 +51,15 @@ describe TextInterpolator do
|
|
52
51
|
end
|
53
52
|
|
54
53
|
describe "#interpolate_hash" do
|
55
|
-
it "interpolates hash" do
|
56
|
-
|
57
|
-
'
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
'"dest_dir": "#{oracle_base}/instantclient_11_2",' +
|
65
|
-
|
66
|
-
'"basic_zip": "#{src_dir}/instantclient-basic-macos.x64-#{oracle_version}.zip"' +
|
67
|
-
'}'
|
68
|
-
|
69
|
-
hash = JSON.parse(config, :symbolize_names => true)
|
54
|
+
it "interpolates simple hash" do
|
55
|
+
hash = {
|
56
|
+
user: ENV['USER'],
|
57
|
+
oracle_base: '/usr/local/oracle',
|
58
|
+
oracle_version: '11.2.0.4.0',
|
59
|
+
src_dir: '#{user}/downloads',
|
60
|
+
dest_dir: '#{oracle_base}/instantclient_11_2',
|
61
|
+
basic_zip: '#{src_dir}/instantclient-basic-macos.x64-#{oracle_version}.zip'
|
62
|
+
}
|
70
63
|
|
71
64
|
result = subject.interpolate_hash hash
|
72
65
|
|
@@ -75,5 +68,39 @@ describe TextInterpolator do
|
|
75
68
|
expect(result[:dest_dir]).to eq '/usr/local/oracle/instantclient_11_2'
|
76
69
|
expect(result[:basic_zip]).to eq ENV['USER'] + '/downloads/instantclient-basic-macos.x64-11.2.0.4.0.zip'
|
77
70
|
end
|
71
|
+
|
72
|
+
it "interpolates multi-level hash" do
|
73
|
+
hash = {
|
74
|
+
host: 'localhost',
|
75
|
+
user: ENV['USER'],
|
76
|
+
home: ENV['HOME'],
|
77
|
+
|
78
|
+
credentials: {
|
79
|
+
user: "some_user",
|
80
|
+
password: "some_password",
|
81
|
+
|
82
|
+
settings: {
|
83
|
+
user: "some_user2"
|
84
|
+
}
|
85
|
+
},
|
86
|
+
|
87
|
+
postgres: {
|
88
|
+
hostname: '#{host}',
|
89
|
+
user: '#{credentials.user}',
|
90
|
+
password: 'postgres'
|
91
|
+
},
|
92
|
+
|
93
|
+
mysql: {
|
94
|
+
user: '#{credentials.settings.user}',
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
result = subject.interpolate_hash hash
|
99
|
+
|
100
|
+
expect(result[:postgres][:user]).to eq hash[:credentials][:user]
|
101
|
+
expect(result[:mysql][:user]).to eq hash[:credentials][:settings][:user]
|
102
|
+
|
103
|
+
expect(subject.errors).to be_empty
|
104
|
+
end
|
78
105
|
end
|
79
106
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: text-interpolator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Shvets
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gemspec_deps_gen
|
@@ -45,6 +45,7 @@ extensions: []
|
|
45
45
|
extra_rdoc_files: []
|
46
46
|
files:
|
47
47
|
- .gitignore
|
48
|
+
- .idea/codeStyleSettings.xml
|
48
49
|
- .ruby-gemset
|
49
50
|
- .ruby-version
|
50
51
|
- CHANGES
|
@@ -53,6 +54,7 @@ files:
|
|
53
54
|
- README.md
|
54
55
|
- Rakefile
|
55
56
|
- lib/text_interpolator.rb
|
57
|
+
- lib/text_interpolator/hash_processor.rb
|
56
58
|
- lib/text_interpolator/text_interpolator.rb
|
57
59
|
- lib/text_interpolator/version.rb
|
58
60
|
- spec/spec_helper.rb
|