text-interpolator 1.0.5 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|