hocon 0.0.7 → 0.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.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +4 -2
  3. data/lib/hocon.rb +2 -0
  4. data/lib/hocon/config.rb +1010 -0
  5. data/lib/hocon/config_error.rb +32 -2
  6. data/lib/hocon/config_factory.rb +46 -0
  7. data/lib/hocon/config_include_context.rb +49 -0
  8. data/lib/hocon/config_includer_file.rb +27 -0
  9. data/lib/hocon/config_list.rb +49 -0
  10. data/lib/hocon/config_mergeable.rb +74 -0
  11. data/lib/hocon/config_object.rb +144 -1
  12. data/lib/hocon/config_parse_options.rb +33 -9
  13. data/lib/hocon/config_parseable.rb +51 -0
  14. data/lib/hocon/config_render_options.rb +4 -2
  15. data/lib/hocon/config_resolve_options.rb +31 -0
  16. data/lib/hocon/config_syntax.rb +5 -2
  17. data/lib/hocon/config_util.rb +73 -0
  18. data/lib/hocon/config_value.rb +122 -0
  19. data/lib/hocon/config_value_factory.rb +66 -2
  20. data/lib/hocon/config_value_type.rb +5 -2
  21. data/lib/hocon/impl.rb +2 -0
  22. data/lib/hocon/impl/abstract_config_node.rb +29 -0
  23. data/lib/hocon/impl/abstract_config_node_value.rb +11 -0
  24. data/lib/hocon/impl/abstract_config_object.rb +148 -42
  25. data/lib/hocon/impl/abstract_config_value.rb +251 -11
  26. data/lib/hocon/impl/array_iterator.rb +19 -0
  27. data/lib/hocon/impl/config_boolean.rb +7 -1
  28. data/lib/hocon/impl/config_concatenation.rb +177 -28
  29. data/lib/hocon/impl/config_delayed_merge.rb +329 -0
  30. data/lib/hocon/impl/config_delayed_merge_object.rb +274 -0
  31. data/lib/hocon/impl/config_document_parser.rb +647 -0
  32. data/lib/hocon/impl/config_double.rb +44 -0
  33. data/lib/hocon/impl/config_impl.rb +143 -19
  34. data/lib/hocon/impl/config_impl_util.rb +18 -0
  35. data/lib/hocon/impl/config_include_kind.rb +10 -0
  36. data/lib/hocon/impl/config_int.rb +13 -1
  37. data/lib/hocon/impl/config_node_array.rb +11 -0
  38. data/lib/hocon/impl/config_node_comment.rb +19 -0
  39. data/lib/hocon/impl/config_node_complex_value.rb +54 -0
  40. data/lib/hocon/impl/config_node_concatenation.rb +11 -0
  41. data/lib/hocon/impl/config_node_field.rb +81 -0
  42. data/lib/hocon/impl/config_node_include.rb +33 -0
  43. data/lib/hocon/impl/config_node_object.rb +276 -0
  44. data/lib/hocon/impl/config_node_path.rb +48 -0
  45. data/lib/hocon/impl/config_node_root.rb +60 -0
  46. data/lib/hocon/impl/config_node_simple_value.rb +42 -0
  47. data/lib/hocon/impl/config_node_single_token.rb +17 -0
  48. data/lib/hocon/impl/config_null.rb +15 -7
  49. data/lib/hocon/impl/config_number.rb +43 -4
  50. data/lib/hocon/impl/config_parser.rb +403 -0
  51. data/lib/hocon/impl/config_reference.rb +142 -0
  52. data/lib/hocon/impl/config_string.rb +55 -7
  53. data/lib/hocon/impl/container.rb +29 -0
  54. data/lib/hocon/impl/default_transformer.rb +24 -15
  55. data/lib/hocon/impl/from_map_mode.rb +3 -1
  56. data/lib/hocon/impl/full_includer.rb +2 -0
  57. data/lib/hocon/impl/memo_key.rb +42 -0
  58. data/lib/hocon/impl/mergeable_value.rb +8 -0
  59. data/lib/hocon/impl/origin_type.rb +8 -2
  60. data/lib/hocon/impl/parseable.rb +455 -91
  61. data/lib/hocon/impl/path.rb +181 -59
  62. data/lib/hocon/impl/path_builder.rb +24 -3
  63. data/lib/hocon/impl/path_parser.rb +280 -0
  64. data/lib/hocon/impl/replaceable_merge_stack.rb +22 -0
  65. data/lib/hocon/impl/resolve_context.rb +254 -0
  66. data/lib/hocon/impl/resolve_memos.rb +21 -0
  67. data/lib/hocon/impl/resolve_result.rb +39 -0
  68. data/lib/hocon/impl/resolve_source.rb +354 -0
  69. data/lib/hocon/impl/resolve_status.rb +3 -1
  70. data/lib/hocon/impl/simple_config.rb +264 -10
  71. data/lib/hocon/impl/simple_config_document.rb +48 -0
  72. data/lib/hocon/impl/simple_config_list.rb +282 -8
  73. data/lib/hocon/impl/simple_config_object.rb +424 -88
  74. data/lib/hocon/impl/simple_config_origin.rb +263 -71
  75. data/lib/hocon/impl/simple_include_context.rb +31 -1
  76. data/lib/hocon/impl/simple_includer.rb +196 -1
  77. data/lib/hocon/impl/substitution_expression.rb +38 -0
  78. data/lib/hocon/impl/token.rb +17 -4
  79. data/lib/hocon/impl/token_type.rb +6 -2
  80. data/lib/hocon/impl/tokenizer.rb +339 -109
  81. data/lib/hocon/impl/tokens.rb +330 -79
  82. data/lib/hocon/impl/unmergeable.rb +14 -1
  83. data/lib/hocon/impl/unsupported_operation_error.rb +6 -0
  84. data/lib/hocon/impl/url.rb +37 -0
  85. data/lib/hocon/parser.rb +7 -0
  86. data/lib/hocon/parser/config_document.rb +92 -0
  87. data/lib/hocon/parser/config_document_factory.rb +36 -0
  88. data/lib/hocon/parser/config_node.rb +30 -0
  89. metadata +67 -43
  90. data/lib/hocon/impl/config_float.rb +0 -13
  91. data/lib/hocon/impl/parser.rb +0 -977
  92. data/lib/hocon/impl/properties_parser.rb +0 -83
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+
3
+ require 'hocon/impl'
4
+ require 'hocon/impl/config_number'
5
+
6
+ class Hocon::Impl::ConfigDouble < Hocon::Impl::ConfigNumber
7
+ def initialize(origin, value, original_text)
8
+ super(origin, original_text)
9
+ @value = value
10
+ end
11
+
12
+ attr_reader :value
13
+
14
+ def value_type
15
+ Hocon::ConfigValueType::NUMBER
16
+ end
17
+
18
+ def unwrapped
19
+ @value
20
+ end
21
+
22
+ def transform_to_string
23
+ s = super
24
+ if s.nil?
25
+ @value.to_s
26
+ else
27
+ s
28
+ end
29
+ end
30
+
31
+ def long_value
32
+ @value.to_i
33
+ end
34
+
35
+ def double_value
36
+ @value
37
+ end
38
+
39
+ def new_copy(origin)
40
+ self.class.new(origin, @value, original_text)
41
+ end
42
+
43
+ # NOTE: skipping `writeReplace` from upstream, because it involves serialization
44
+ end
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'hocon/impl'
2
4
  require 'hocon/impl/simple_includer'
3
5
  require 'hocon/config_error'
@@ -6,14 +8,17 @@ require 'hocon/impl/simple_config_origin'
6
8
  require 'hocon/impl/simple_config_list'
7
9
  require 'hocon/impl/config_boolean'
8
10
  require 'hocon/impl/config_null'
11
+ require 'hocon/impl/parseable'
9
12
 
10
13
  class Hocon::Impl::ConfigImpl
11
- @default_includer = Hocon::Impl::SimpleIncluder.new
14
+ @default_includer = Hocon::Impl::SimpleIncluder.new(nil)
12
15
  @default_value_origin = Hocon::Impl::SimpleConfigOrigin.new_simple("hardcoded value")
13
16
  @default_true_value = Hocon::Impl::ConfigBoolean.new(@default_value_origin, true)
14
17
  @default_false_value = Hocon::Impl::ConfigBoolean.new(@default_value_origin, false)
15
18
  @default_null_value = Hocon::Impl::ConfigNull.new(@default_value_origin)
16
19
  @default_empty_list = Hocon::Impl::SimpleConfigList.new(@default_value_origin, Array.new)
20
+ @default_empty_object = Hocon::Impl::SimpleConfigObject.empty(@default_value_origin)
21
+
17
22
 
18
23
  ConfigBugOrBrokenError = Hocon::ConfigError::ConfigBugOrBrokenError
19
24
  ConfigNotResolvedError = Hocon::ConfigError::ConfigNotResolvedError
@@ -23,9 +28,16 @@ class Hocon::Impl::ConfigImpl
23
28
  @default_includer
24
29
  end
25
30
 
31
+
32
+ class FileNameSource < Hocon::Impl::SimpleIncluder::NameSource
33
+ def name_to_parseable(name, parse_options)
34
+ Hocon::Impl::Parseable.new_file(name, parse_options)
35
+ end
36
+ end
37
+
26
38
  def self.improve_not_resolved(what, original)
27
39
  new_message = "#{what.render} has not been resolved, you need to call Config#resolve, see API docs for Config#resolve"
28
- if new_message == original.get_message
40
+ if new_message == original.message
29
41
  return original
30
42
  else
31
43
  return ConfigNotResolvedError.new(new_message, original)
@@ -40,14 +52,11 @@ class Hocon::Impl::ConfigImpl
40
52
  end
41
53
  end
42
54
 
43
- def self.empty_object(origin)
44
- # we want null origin to go to SimpleConfigObject.empty() to get the
45
- # origin "empty config" rather than "hardcoded value"
46
- if origin == @default_value_origin
47
- return default_empty_object
48
- else
49
- return Hocon::Impl::SimpleConfigObject.empty(origin)
50
- end
55
+ def self.parse_file_any_syntax(basename, base_options)
56
+ source = FileNameSource.new()
57
+ Hocon::Impl::SimpleIncluder.from_basename(source,
58
+ File.expand_path(basename),
59
+ base_options)
51
60
  end
52
61
 
53
62
  def self.empty_list(origin)
@@ -65,7 +74,7 @@ class Hocon::Impl::ConfigImpl
65
74
 
66
75
  def self.from_any_ref_mode(object, origin, map_mode)
67
76
  if origin.nil?
68
- raise ConfigBugOrBrokenError.new("origin not supposed to be nil", nil)
77
+ raise ConfigBugOrBrokenError.new("origin not supposed to be nil")
69
78
  end
70
79
  if object.nil?
71
80
  if origin != @default_value_origin
@@ -73,6 +82,8 @@ class Hocon::Impl::ConfigImpl
73
82
  else
74
83
  return @default_null_value
75
84
  end
85
+ elsif object.is_a?(Hocon::Impl::AbstractConfigValue)
86
+ return object
76
87
  elsif object.is_a?(TrueClass) || object.is_a?(FalseClass)
77
88
  if origin != @default_value_origin
78
89
  return Hocon::Impl::ConfigBoolean.new(origin, object)
@@ -82,7 +93,7 @@ class Hocon::Impl::ConfigImpl
82
93
  return @default_false_value
83
94
  end
84
95
  elsif object.is_a?(String)
85
- return Hocon::Impl::ConfigString.new(origin, object)
96
+ return Hocon::Impl::ConfigString::Quoted.new(origin, object)
86
97
  elsif object.is_a?(Numeric)
87
98
  # here we always keep the same type that was passed to us,
88
99
  # rather than figuring out if a Long would fit in an Int
@@ -90,7 +101,7 @@ class Hocon::Impl::ConfigImpl
90
101
  # not using ConfigNumber.newNumber() when we have a
91
102
  # Double, Integer, or Long.
92
103
  if object.is_a?(Float)
93
- return Hocon::Impl::ConfigFloat.new(origin, object, nil)
104
+ return Hocon::Impl::ConfigDouble.new(origin, object, nil)
94
105
  elsif object.is_a?(Integer)
95
106
  return Hocon::Impl::ConfigInt.new(origin, object, nil)
96
107
  else
@@ -98,7 +109,7 @@ class Hocon::Impl::ConfigImpl
98
109
  end
99
110
  elsif object.is_a?(Hash)
100
111
  if object.empty?
101
- return self.empty_object(origin)
112
+ return self.empty_object_from_origin(origin)
102
113
  end
103
114
 
104
115
  if map_mode == FromMapMode::KEYS_ARE_KEYS
@@ -106,15 +117,14 @@ class Hocon::Impl::ConfigImpl
106
117
  object.each do |key, entry|
107
118
  if not key.is_a?(String)
108
119
  raise ConfigBugOrBrokenError.new(
109
- "bug in method caller: not valid to create ConfigObject from map with non-String key: #{key}",
110
- nil)
120
+ "bug in method caller: not valid to create ConfigObject from map with non-String key: #{key}")
111
121
  end
112
122
  value = self.from_any_ref_mode(entry, origin, map_mode)
113
123
  values[key] = value
114
124
  end
115
125
  return Hocon::Impl::SimpleConfigObject.new(origin, values)
116
126
  else
117
- return Hocon::Impl::PropertiesParser.from_path_map(origin, object)
127
+ raise ConfigBugOrBrokenError, "java properties format not supported"
118
128
  end
119
129
  elsif object.is_a?(Enumerable)
120
130
  if object.count == 0
@@ -129,7 +139,121 @@ class Hocon::Impl::ConfigImpl
129
139
 
130
140
  return Hocon::Impl::SimpleConfigList.new(origin, values)
131
141
  else
132
- raise ConfigBugOrBrokenError.new("bug in method caller: not valid to create ConfigValue from: #{object}", nil)
142
+ raise ConfigBugOrBrokenError.new("bug in method caller: not valid to create ConfigValue from: #{object}")
143
+ end
144
+ end
145
+
146
+
147
+
148
+ def self.env_variables_as_config_object
149
+ EnvVariablesHolder.get_env_variables
150
+ end
151
+
152
+ # This class is a lot simpler than the Java version ...
153
+ # The Java version uses system properties to toggle these settings.
154
+ # We don't have system properties in MRI so it's not clear what to do here.
155
+ # Initially, I ported this as more of a direct translation from the Java code,
156
+ # but I ran into issues around how to translate stupid Java static
157
+ # initialization crap to Ruby, so what we have here is a much simpler version
158
+ # that is # equivalent.
159
+ #
160
+ # There's no way to toggle this logging without changing code, but it's
161
+ # actually proved to be useful for debugging purposes while porting code
162
+ # down from Java.
163
+ class DebugHolder
164
+ class << self
165
+
166
+ def trace_loads_enabled
167
+ TRACE_LOADS_ENABLED
168
+ end
169
+
170
+ def trace_substitutions_enabled
171
+ TRACE_SUBSTITUTIONS_ENABLED
172
+ end
173
+
174
+ private
175
+
176
+ TRACE_LOADS_ENABLED = false
177
+ TRACE_SUBSTITUTIONS_ENABLED = false
178
+ end
179
+ end
180
+
181
+ def self.trace_loads_enabled
182
+ # Ignoring 'catch ExceptionInInitializerError' from that java version,
183
+ # that is just terrible java code anyway.
184
+ DebugHolder.trace_loads_enabled
185
+ end
186
+
187
+ def self.trace_substitution_enabled
188
+ # Ignoring 'catch ExceptionInInitializerError' from that java version,
189
+ # that is just terrible java code anyway.
190
+ DebugHolder.trace_substitutions_enabled
191
+ end
192
+
193
+ def self.trace(message, indent_level = 0)
194
+ while indent_level > 0
195
+ $stderr.putc(" ")
196
+ indent_level -= 1
197
+ end
198
+ $stderr.puts(message)
199
+ end
200
+
201
+ def self.empty_object_from_origin(origin)
202
+ # we want null origin to go to SimpleConfigObject.empty() to get the
203
+ # origin "empty config" rather than "hardcoded value"
204
+ if origin == @default_value_origin
205
+ @default_empty_object
206
+ else
207
+ Hocon::Impl::SimpleConfigObject.empty(origin)
208
+ end
209
+ end
210
+
211
+ def self.empty_object(origin_description)
212
+ if !origin_description.nil?
213
+ origin = Hocon::Impl::SimpleConfigOrigin.new_simple(origin_description)
214
+ else
215
+ origin = nil
216
+ end
217
+
218
+ empty_object_from_origin(origin)
219
+ end
220
+
221
+ def self.empty_config(origin_description)
222
+ empty_object(origin_description).to_config
223
+ end
224
+
225
+ def empty(origin)
226
+ self.class.empty_object_from_origin(origin)
227
+ end
228
+
229
+ def self.default_reference
230
+ resource = Hocon::Impl::Parseable.new_resources("reference.conf",
231
+ Hocon::ConfigParseOptions.defaults)
232
+ resource.parse.to_config
233
+ end
234
+
235
+ private
236
+
237
+ def self.load_env_variables
238
+ env = ENV
239
+ m = {}
240
+ env.each do |key, value|
241
+ m[key] = Hocon::Impl::ConfigString::Quoted.new(
242
+ Hocon::Impl::SimpleConfigOrigin.new_simple("env var #{key}"), value)
243
+ end
244
+
245
+ Hocon::Impl::SimpleConfigObject.new(
246
+ Hocon::Impl::SimpleConfigOrigin.new_simple("env variables"),
247
+ m,
248
+ Hocon::Impl::ResolveStatus::RESOLVED,
249
+ false)
250
+ end
251
+
252
+ class EnvVariablesHolder
253
+ ENV_VARIABLES = Hocon::Impl::ConfigImpl.load_env_variables
254
+
255
+ def self.get_env_variables
256
+ ENV_VARIABLES
133
257
  end
134
258
  end
135
- end
259
+ end
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'hocon/impl'
2
4
  require 'stringio'
3
5
 
@@ -68,6 +70,22 @@ class Hocon::Impl::ConfigImplUtil
68
70
  s
69
71
  end
70
72
 
73
+ def self.join_path(*elements)
74
+ Hocon::Impl::Path.from_string_list(elements).render
75
+ end
76
+
77
+ def self.split_path(path)
78
+ p = Hocon::Impl::Path.new_path(path)
79
+ elements = []
80
+
81
+ until p.nil?
82
+ elements << p.first
83
+ p = p.remainder
84
+ end
85
+
86
+ elements
87
+ end
88
+
71
89
  def self.whitespace?(c)
72
90
  # this implementation is *not* a port of the java code, because it relied on
73
91
  # the method java.lang.Character#isWhitespace. This is probably
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ require 'hocon/impl'
4
+
5
+ module Hocon::Impl::ConfigIncludeKind
6
+ URL = 0
7
+ FILE = 1
8
+ CLASSPATH = 2
9
+ HEURISTIC = 3
10
+ end
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'hocon/impl'
2
4
  require 'hocon/impl/config_number'
3
5
  require 'hocon/config_value_type'
@@ -8,6 +10,8 @@ class Hocon::Impl::ConfigInt < Hocon::Impl::ConfigNumber
8
10
  @value = value
9
11
  end
10
12
 
13
+ attr_reader :value
14
+
11
15
  def value_type
12
16
  Hocon::ConfigValueType::NUMBER
13
17
  end
@@ -25,7 +29,15 @@ class Hocon::Impl::ConfigInt < Hocon::Impl::ConfigNumber
25
29
  end
26
30
  end
27
31
 
32
+ def long_value
33
+ @value
34
+ end
35
+
36
+ def double_value
37
+ @value
38
+ end
39
+
28
40
  def new_copy(origin)
29
41
  Hocon::Impl::ConfigInt.new(origin, @value, @original_text)
30
42
  end
31
- end
43
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ require 'hocon/impl'
4
+ require 'hocon/impl/config_node_complex_value'
5
+
6
+ class Hocon::Impl::ConfigNodeArray
7
+ include Hocon::Impl::ConfigNodeComplexValue
8
+ def new_node(nodes)
9
+ self.class.new(nodes)
10
+ end
11
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ require 'hocon/impl'
4
+ require 'hocon/config_error'
5
+ require 'hocon/impl/config_node_single_token'
6
+ require 'hocon/impl/tokens'
7
+
8
+ class Hocon::Impl::ConfigNodeComment < Hocon::Impl::ConfigNodeSingleToken
9
+ def initialize(comment)
10
+ super(comment)
11
+ unless Hocon::Impl::Tokens.comment?(@token)
12
+ raise Hocon::ConfigError::ConfigBugOrBrokenError, 'Tried to create a ConfigNodeComment from a non-comment token'
13
+ end
14
+ end
15
+
16
+ def comment_text
17
+ Hocon::Impl::Tokens.comment_text(@token)
18
+ end
19
+ end
@@ -0,0 +1,54 @@
1
+ # encoding: utf-8
2
+
3
+ require 'hocon/impl'
4
+ require 'hocon/impl/abstract_config_node_value'
5
+ require 'hocon/impl/config_node_field'
6
+ require 'hocon/impl/config_node_include'
7
+ require 'hocon/impl/config_node_single_token'
8
+ require 'hocon/impl/tokens'
9
+ require 'hocon/config_error'
10
+
11
+ module Hocon::Impl::ConfigNodeComplexValue
12
+ include Hocon::Impl::AbstractConfigNodeValue
13
+ def initialize(children)
14
+ @children = children
15
+ end
16
+
17
+ attr_reader :children
18
+
19
+ def tokens
20
+ tokens = []
21
+ @children.each do |child|
22
+ tokens += child.tokens
23
+ end
24
+ tokens
25
+ end
26
+
27
+ def indent_text(indentation)
28
+ children_copy = @children.clone
29
+ i = 0
30
+ while i < children_copy.size
31
+ child = children_copy[i]
32
+ if child.is_a?(Hocon::Impl::ConfigNodeSingleToken) && Hocon::Impl::Tokens.newline?(child.token)
33
+ children_copy.insert(i + 1, indentation)
34
+ i += 1
35
+ elsif child.is_a?(Hocon::Impl::ConfigNodeField)
36
+ value = child.value
37
+ if value.is_a?(Hocon::Impl::ConfigNodeComplexValue)
38
+ children_copy[i] = child.replace_value(value.indent_text(indentation))
39
+ end
40
+ elsif child.is_a?(Hocon::Impl::ConfigNodeComplexValue)
41
+ children_copy[i] = child.indent_text(indentation)
42
+ end
43
+ i += 1
44
+ end
45
+ new_node(children_copy)
46
+ end
47
+
48
+ # This method will just call into the object's constructor, but it's needed
49
+ # for use in the indentText() method so we can avoid a gross if/else statement
50
+ # checking the type of this
51
+ def new_node(nodes)
52
+ raise Hocon::ConfigError::ConfigBugOrBrokenError, "subclasses of ConfigNodeComplexValue should override `new_node` (#{self.class})"
53
+ end
54
+ end