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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MjVjNjkyZGJhOTY1MWYwMTNhYzc0NzkyNzQzODE4YTBlZDlhY2IxMQ==
4
+ MGI1Y2YyNjFlYzEwZDEzNTJiMDhjNDNiNGJjNzBkYjI5N2M3OGVjYQ==
5
5
  data.tar.gz: !binary |-
6
- NmI4OTA5MDAxOGNjYTQ2ZjVkYjY4ZWJhM2NkZGRkMTdlNzllY2U2Mw==
6
+ YzgyYzU5Zjc4MDQzZWFkZjBkYTUxZGNmZTExZmM5YjU2MjJjOGE3Mw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- OTI4NWQxNzkxYzE1NjRiOTgzOTZkNDU1ZDQ2MDlkMmNjZTZhZjhjMDhmODRh
10
- NDkzOTE4NWY3MDcxYjgxYThiZTJmNGY1ZDAyOGMxZjFkZGFhZDhjZmMzNThj
11
- MmVhZDY3MGQ3MDdlNjNkYTRmOTM1MTg2N2IwZTNkMjJhZDQ2YWE=
9
+ MzU2YjQ5MGQ2YWY4MWU2NTY3ZDg4ZWM4OTQ3MjUwZGRhMDc4ODE2ZGQwZGQ0
10
+ YzY0Y2ZmNTc0ZmU4YTg1MjI2NzhmOTMyMDFkM2QyZDE5YTYyZGI2YWE5ZmQz
11
+ NmQ2ZmVhOTQwMGU4NjE3NzIxZmIzYTNjYzc1MTE2N2E3ODY1N2Q=
12
12
  data.tar.gz: !binary |-
13
- NTBhNGExODJkMDZjNjc3MDM2NWFjMjkxYmM4Njg0NGQzNjZkNTVmYjNlZTVk
14
- ZjBiYjE4YjhkMWMyMDNhNDcyNjk0NTU3YzE3YTIxZjc3YzEzZDY2ZGU4NGI3
15
- NWY4ZTUyN2RlYzhjNjc3OWFhYmU1NDcyOTgxYTI0ODQ2YTQ3Njg=
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
@@ -22,4 +22,8 @@
22
22
 
23
23
  == Version 1.0.5
24
24
 
25
- * Bug fix.
25
+ * Bug fix.
26
+
27
+ == Version 1.1.0
28
+
29
+ * Adding qualified variable names.
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 ={var1: 'some value 1', var2: 'some value 2'}
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
- hash.each do |key, value|
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
- begin
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,3 +1,3 @@
1
1
  class TextInterpolator
2
- VERSION = "1.0.5"
2
+ VERSION = "1.1.0"
3
3
  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
- config =
57
- '{' +
58
- '"user": "ENV[\'USER\']",' +
59
-
60
- '"oracle_base": "/usr/local/oracle",' +
61
- '"oracle_version": "11.2.0.4.0",'+
62
-
63
- '"src_dir": "#{user}/downloads",' +
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.5
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-03 00:00:00.000000000 Z
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