Class: HclParser::Loader
- Inherits:
-
Object
- Object
- HclParser::Loader
- Defined in:
- lib/hcl_parser/loader.rb
Constant Summary collapse
- COMMENT_REGEX =
/^(^|\s)#/i
Instance Method Summary collapse
-
#code ⇒ Object
The parser being used cannot handle unquoted literal type values and comments.
- #complex_type_line?(l) ⇒ Boolean
- #complex_type_lines?(lines) ⇒ Boolean
- #empty? ⇒ Boolean
- #fix_quotes(raw) ⇒ Object
-
#initialize(raw) ⇒ Loader
constructor
A new instance of Loader.
- #load ⇒ Object
- #quote_line(l) ⇒ Object
- #remove_comments(raw) ⇒ Object
- #rewrite_complex_types(raw) ⇒ Object
- #simple_default_assignment?(line) ⇒ Boolean
- #variable_end_index(lines, variable_start_index) ⇒ Object
Constructor Details
#initialize(raw) ⇒ Loader
Returns a new instance of Loader.
5 6 7 |
# File 'lib/hcl_parser/loader.rb', line 5 def initialize(raw) @raw = raw end |
Instance Method Details
#code ⇒ Object
The parser being used cannot handle unquoted literal type values and comments. Hacking it and updating the raw code as a workaround. May have to fix the parser or write a new parser.
17 18 19 20 21 |
# File 'lib/hcl_parser/loader.rb', line 17 def code return @code if @code @code = fix_quotes(@raw) @code = rewrite_complex_types(@code) end |
#complex_type_line?(l) ⇒ Boolean
81 82 83 |
# File 'lib/hcl_parser/loader.rb', line 81 def complex_type_line?(l) l.match(/object\(/) || l.match(/=\s*"any/) end |
#complex_type_lines?(lines) ⇒ Boolean
75 76 77 78 79 |
# File 'lib/hcl_parser/loader.rb', line 75 def complex_type_lines?(lines) !!lines.find do |l| complex_type_line?(l) end end |
#empty? ⇒ Boolean
92 93 94 95 96 97 |
# File 'lib/hcl_parser/loader.rb', line 92 def empty? text = remove_comments(code) lines = text.split("\n") lines.reject! { |l| l.strip.empty? } lines.empty? end |
#fix_quotes(raw) ⇒ Object
109 110 111 112 113 114 115 |
# File 'lib/hcl_parser/loader.rb', line 109 def fix_quotes(raw) lines = raw.split("\n") lines.map! do |l| quote_line(l) end lines.join("\n") end |
#load ⇒ Object
9 10 11 12 |
# File 'lib/hcl_parser/loader.rb', line 9 def load return {} if empty? # Rhcl parser cannot handle empty file Rhcl.parse(code) end |
#quote_line(l) ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/hcl_parser/loader.rb', line 117 def quote_line(l) return "# " if l =~ COMMENT_REGEX # return empty comment so parser wont try to parse it return l unless l =~ /(type|default)\s*=/ # just check for type and default return l if l =~ /(type|default)\s*=\s*['"]([a-zA-Z0-9()]+)["']/ # check quotes in the type value # Reaching here means there is probably a type value without quotes # Try to capture unquoted value so we can add quotes md = l.match(/(type|default)\s*=\s*([a-zA-Z0-9()]+)/) if md prop, value = md[1], md[2] %Q|#{prop} = "#{value}"| else # Example: type = "list(object({ l # unable to capture quotes, passthrough as fallback end end |
#remove_comments(raw) ⇒ Object
100 101 102 103 104 105 106 107 |
# File 'lib/hcl_parser/loader.rb', line 100 def remove_comments(raw) lines = raw.split("\n") # filter out commented lines lines.reject! { |l| l =~ COMMENT_REGEX } # filter out empty lines lines.reject! { |l| l.strip.empty? } lines.join("\n") end |
#rewrite_complex_types(raw) ⇒ Object
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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/hcl_parser/loader.rb', line 23 def rewrite_complex_types(raw) lines = raw.split("\n") results = [] variable_start_found = false variable_start_index = nil variable_end_index = nil rewrite_lines = false lines.each_with_index do |l,i| # We dont rewrite lines until the next line/iteration # This is actually the next iteration since we set rewrite_lines = true previously # in rewrite_lines = complex_type_lines?(lookahead_lines) if rewrite_lines if complex_type_line?(l) # Doesnt matter what the default value is as long as there is one # Doing this in case the default value spans multiple lines results << ' default = "any"' elsif simple_default_assignment?(l) results << l else results << "# #{l}" end else results << l end # End of logic in the next iteration # Start of logic in the current iteration variable_start_found = l.match(/^variable /) if variable_start_found variable_start_index = i variable_end_index = variable_end_index(lines, variable_start_index) lookahead_lines = lines[variable_start_index..variable_end_index] rewrite_lines = complex_type_lines?(lookahead_lines) end # Disable rewriting before reaching the end of the variable definition so: i + 1 if variable_end_index == i + 1 variable_start_index = nil variable_end_index = nil rewrite_lines = false end end results.join("\n") end |
#simple_default_assignment?(line) ⇒ Boolean
71 72 73 |
# File 'lib/hcl_parser/loader.rb', line 71 def simple_default_assignment?(line) line.match(/default\s*=\s*("|'|null)/) end |
#variable_end_index(lines, variable_start_index) ⇒ Object
85 86 87 88 89 90 |
# File 'lib/hcl_parser/loader.rb', line 85 def variable_end_index(lines, variable_start_index) lines.each_with_index do |l,i| next unless i >= variable_start_index return i if l.match(/^}/) || l.match(/{\s*}/) end end |