hcl-checker 1.4.0 → 1.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 195128a0325ac3b7fa3add01a739dbe3ce0aeb5b3314edfc74d195caa3a0aa61
4
- data.tar.gz: ab84f84386083bdbb9aaea917716ea7e8462eaed2b89a2ab4f887fb4c3b2ee93
3
+ metadata.gz: e385b2693e62154b496432fb0baf5022d64fdc0827b5703d33be6a05dbfb50c6
4
+ data.tar.gz: 931d2e6fe0348c24164bfc17d6686ebd6b64ac41e2acb9884af1d51c189764c1
5
5
  SHA512:
6
- metadata.gz: b53587ad90fa9ed3cf6c2fbfd5cad15f6b526e62e5c63298fbd963a1629d6283a0bac0ab7276674acba8a1d67e38bc2118fe8f9a0a11a5d362afef4957cc745a
7
- data.tar.gz: 4d908d23f548138a2e4e876709cda19321650203d13219f8ac8fe3748cd1427e628f9cb834f80bf684252a7d06d9a97d72663f3ac6c19699a0149593e3450a0d
6
+ metadata.gz: c23f7d1562b29c3523de8be84d57a7690ff5c1f7680a368df049b7c21dd4b3246f2417a79df09f797ad00bd2743ec218effe67ffd020132174a79c5dd2ccaf4a
7
+ data.tar.gz: 8874919303dad9cbb0285fa69a042ddb4a444df7c71d76c41d8cb39639e333fddcdec13768cedb4fffcde4fdabcc3f9c70e805b89c5744cf643b0e267dd7b449
data/.rubocop.yml ADDED
@@ -0,0 +1,32 @@
1
+ AllCops:
2
+ NewCops: enable
3
+ Exclude:
4
+ - lib/hcl/lexer.rb
5
+ - lib/hcl/parser.rb
6
+
7
+ Layout/LineLength:
8
+ Enabled: false
9
+
10
+ Metrics/AbcSize:
11
+ Enabled: false
12
+
13
+ Metrics/BlockLength:
14
+ Enabled: false
15
+
16
+ Metrics/ClassLength:
17
+ Enabled: false
18
+
19
+ Metrics/CyclomaticComplexity:
20
+ Enabled: false
21
+
22
+ Metrics/MethodLength:
23
+ Enabled: false
24
+
25
+ Metrics/PerceivedComplexity:
26
+ Enabled: false
27
+
28
+ Style/Documentation:
29
+ Enabled: false
30
+
31
+ Style/FrozenStringLiteralComment:
32
+ EnforcedStyle: never
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
3
  # This is needed due https://nvd.nist.gov/vuln/detail/CVE-2018-14404
4
4
  # A NULL pointer dereference vulnerability exists in the xpath.c:xmlXPathCompOpEval()
@@ -7,10 +7,9 @@ source "https://rubygems.org"
7
7
  # with the use of the libxml2 library may be vulnerable to a denial of service attack due
8
8
  # to a crash of the application.
9
9
  # Nokogiri >= 1.8.5 solves this problem
10
- gem "nokogiri", ">= 1.10.8"
10
+ gem 'nokogiri', '>= 1.11.4'
11
11
 
12
-
13
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
12
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
14
13
 
15
14
  # Specify your gem's dependencies in hcl-checker.gemspec
16
15
  gemspec
data/Gemfile.lock CHANGED
@@ -1,20 +1,19 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hcl-checker (1.4.0)
4
+ hcl-checker (1.6.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- diff-lcs (1.4.4)
9
+ diff-lcs (1.5.0)
10
10
  filesize (0.2.0)
11
11
  jsobfu (0.4.2)
12
12
  rkelly-remix
13
- json (2.3.1)
14
- metasm (1.0.4)
15
- mini_portile2 (2.4.0)
16
- nokogiri (1.10.10)
17
- mini_portile2 (~> 2.4.0)
13
+ json (2.6.1)
14
+ metasm (1.0.5)
15
+ nokogiri (1.13.6-arm64-darwin)
16
+ racc (~> 1.4)
18
17
  racc (1.5.0)
19
18
  rake (12.3.3)
20
19
  rb-readline (0.5.5)
@@ -27,27 +26,27 @@ GEM
27
26
  rb-readline (~> 0)
28
27
  rexical (1.0.7)
29
28
  rkelly-remix (0.0.7)
30
- rspec (3.9.0)
31
- rspec-core (~> 3.9.0)
32
- rspec-expectations (~> 3.9.0)
33
- rspec-mocks (~> 3.9.0)
34
- rspec-core (3.9.2)
35
- rspec-support (~> 3.9.3)
36
- rspec-expectations (3.9.2)
29
+ rspec (3.11.0)
30
+ rspec-core (~> 3.11.0)
31
+ rspec-expectations (~> 3.11.0)
32
+ rspec-mocks (~> 3.11.0)
33
+ rspec-core (3.11.0)
34
+ rspec-support (~> 3.11.0)
35
+ rspec-expectations (3.11.0)
37
36
  diff-lcs (>= 1.2.0, < 2.0)
38
- rspec-support (~> 3.9.0)
39
- rspec-mocks (3.9.1)
37
+ rspec-support (~> 3.11.0)
38
+ rspec-mocks (3.11.1)
40
39
  diff-lcs (>= 1.2.0, < 2.0)
41
- rspec-support (~> 3.9.0)
42
- rspec-support (3.9.3)
40
+ rspec-support (~> 3.11.0)
41
+ rspec-support (3.11.0)
43
42
 
44
43
  PLATFORMS
45
- ruby
44
+ arm64-darwin-21
46
45
 
47
46
  DEPENDENCIES
48
- bundler (~> 2.1.4)
47
+ bundler (~> 2.3.13)
49
48
  hcl-checker!
50
- nokogiri (>= 1.10.8)
49
+ nokogiri (>= 1.11.4)
51
50
  racc (= 1.5.0)
52
51
  rake (~> 12.3.3)
53
52
  rex (= 2.0.12)
@@ -55,4 +54,4 @@ DEPENDENCIES
55
54
  rspec (~> 3.0)
56
55
 
57
56
  BUNDLED WITH
58
- 2.1.4
57
+ 2.3.13
data/README.md CHANGED
@@ -47,21 +47,21 @@ You can validate the `hcl_string` contents with `valid?` method. This will
47
47
  return `true` if is a valid HCL or `false` if not.
48
48
 
49
49
  ```
50
- 2.3.2 :014 > HCL1::Checker.valid? hcl_string
50
+ 2.3.2 :014 > HCL::Checker.valid? hcl_string
51
51
  => true
52
52
  ```
53
53
 
54
54
  You can parse the `hcl_string` into a `Hash` with `parse` method.
55
55
 
56
56
  ```
57
- 2.3.2 :015 > HCL1::Checker.parse(hcl_string)
57
+ 2.3.2 :015 > HCL::Checker.parse(hcl_string)
58
58
  => {"provider"=>{"aws"=>{"region"=>"${var.aws_region}", "access_key"=>"${var.aws_access_key}", "secret_key"=>"${var.aws_secret_key}"}}, "resource"=>{"aws_vpc"=>{"default"=>{"cidr_block"=>"10.0.0.0/16", "enable_dns_hostnames"=>true, "tags"=>{"Name"=>"Event Store VPC"}}}}}
59
59
  ```
60
60
 
61
61
  If after a `parse` you got `false` you can check `last_error` with:
62
62
 
63
63
  ```
64
- 2.4.2 :063 > HCL1::Checker.last_error
64
+ 2.4.2 :063 > HCL::Checker.last_error
65
65
  => "Parse error at \"eec8b16c-ee89-4ea0-bdcc-d094300a42e8\" , (invalid token: ,)"
66
66
  ```
67
67
 
data/Rakefile CHANGED
@@ -1,19 +1,18 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new do |c|
5
- options = ["--color"]
6
- options += ["--format", "documentation"]
5
+ options = ['--color']
6
+ options += ['--format', 'documentation']
7
7
  c.rspec_opts = options
8
8
  end
9
9
 
10
- desc "Generate Grammar files for HCL"
10
+ desc 'Generate Grammar files for HCL'
11
11
  task :build_grammar do
12
12
  print 'Building Lexer'
13
- `rex ./assets/lexer.rex -o ./lib/hcl/lexer.rb`
13
+ `rex ./assets/lexer.rex -o ./lib/hcl/checker/lexer.rb`
14
14
  print "....done\n"
15
15
  print 'Building Parser'
16
- `racc ./assets/parse.y -o ./lib/hcl/parser.rb`
16
+ `racc ./assets/parse.y -o ./lib/hcl/checker/parser.rb`
17
17
  print "....done\n\n"
18
18
  end
19
-
data/assets/lexer.rex CHANGED
@@ -1,8 +1,7 @@
1
-
2
- class HCLLexer
1
+ class HCL::Checker::Lexer
3
2
  option
4
3
  independent
5
-
4
+
6
5
  macro
7
6
  NEWLINE \n|\r
8
7
  BLANK \s+
@@ -20,6 +19,8 @@ macro
20
19
  RIGHTBRACE \}
21
20
  LEFTBRACKET \[
22
21
  RIGHTBRACKET \]
22
+ LEFTPARENTHESES \(
23
+ RIGHTPARENTHESES \)
23
24
  HEREDOCUMENT \<<\-?
24
25
 
25
26
  rule
@@ -36,37 +37,39 @@ rule
36
37
  {QUOTE} { [:STRING, consume_string(text)] }
37
38
  {HEREDOCUMENT} { [:STRING, consume_heredoc] }
38
39
  #-------------------------------------------------------------------------------
39
- {LEFTBRACE} { [:LEFTBRACE, text]}
40
- {RIGHTBRACE} { [:RIGHTBRACE, text]}
41
- {LEFTBRACKET} { [:LEFTBRACKET, text]}
42
- {RIGHTBRACKET} { [:RIGHTBRACKET, text]}
40
+ {LEFTBRACE} { [:LEFTBRACE, text]}
41
+ {RIGHTBRACE} { [:RIGHTBRACE, text]}
42
+ {LEFTBRACKET} { [:LEFTBRACKET, text]}
43
+ {RIGHTBRACKET} { [:RIGHTBRACKET, text]}
44
+ {LEFTPARENTHESES} { [:LEFTPARENTHESES, text]}
45
+ {RIGHTPARENTHESES} { [:RIGHTPARENTHESES, text]}
43
46
  #-------------------------------------------------------------------------------
44
47
  {COMMA} { [:COMMA, text]}
45
48
  {IDENTIFIER} { [:IDENTIFIER, text]}
46
49
  {EQUAL} { [:EQUAL, text]}
47
50
  {MINUS} { [:MINUS, text]}
48
51
 
49
-
50
52
  inner
51
-
52
53
  def lex(input)
53
54
  scan_setup(input)
54
55
  tokens = []
55
56
  while token = next_token
56
57
  tokens << token
57
58
  end
59
+
58
60
  tokens
59
61
  end
60
62
 
61
63
 
62
64
  def to_boolean(input)
63
- input =
64
- if input =~ /true/
65
- true
66
- elsif input =~ /false/
67
- false
68
- end
69
- return input
65
+ case input
66
+ when /true/
67
+ true
68
+ when /false/
69
+ false
70
+ else
71
+ raise "Invalid value for `to_boolean`, expected true/false got #{input}"
72
+ end
70
73
  end
71
74
 
72
75
 
@@ -90,19 +93,21 @@ inner
90
93
  result = ''
91
94
  nested = 0
92
95
 
93
- begin
96
+ loop do
94
97
  case(text = @ss.scan_until(%r{\"|\$\{|\}|\\}))
95
98
  when %r{\$\{\z}
96
99
  nested += 1
97
100
  when %r{\}\z}
98
- nested -= 1 if nested > 0
101
+ nested -= 1 if nested.positive?
99
102
  when %r{\\\z}
100
103
  result += text.chop + @ss.getch
101
104
  next
102
105
  end
103
106
 
104
107
  result += text.to_s
105
- end until nested == 0 && text =~ %r{\"\z}
108
+
109
+ break if nested.zero? && text =~ %r{\"\z}
110
+ end
106
111
 
107
112
  result.chop
108
113
  end
data/assets/parse.y CHANGED
@@ -1,4 +1,4 @@
1
- class HCLParser
1
+ class HCL::Checker::Parser
2
2
  token BOOL
3
3
  FLOAT
4
4
  NUMBER
@@ -12,6 +12,8 @@ token BOOL
12
12
  RIGHTBRACE
13
13
  LEFTBRACKET
14
14
  RIGHTBRACKET
15
+ LEFTPARENTHESES
16
+ RIGHTPARENTHESES
15
17
  PERIOD
16
18
  EPLUS
17
19
  EMINUS
@@ -24,7 +26,6 @@ rule
24
26
  | objectlist
25
27
  ;
26
28
 
27
-
28
29
  objectlist:
29
30
  objectitem COMMA
30
31
  { result = [val[0]] }
@@ -40,7 +41,7 @@ rule
40
41
  LEFTBRACE objectlist RIGHTBRACE
41
42
  { result = flatten_objectlist(val[1]) }
42
43
  | LEFTBRACE RIGHTBRACE
43
- { return }
44
+ { return {} }
44
45
  ;
45
46
 
46
47
  objectkey:
@@ -61,6 +62,10 @@ rule
61
62
  { result = val[0], val[2] }
62
63
  | objectkey EQUAL list
63
64
  { result = val[0], val[2] }
65
+ | objectkey EQUAL IDENTIFIER LEFTPARENTHESES IDENTIFIER RIGHTPARENTHESES
66
+ { result = val[0], "#{val[2]}(#{val[4]})" }
67
+ | objectkey EQUAL IDENTIFIER
68
+ { result = val[0], val[2] }
64
69
  | block
65
70
  { result = val[0] }
66
71
  ;
@@ -83,7 +88,7 @@ rule
83
88
  LEFTBRACKET listitems RIGHTBRACKET
84
89
  { result = val[1] }
85
90
  | LEFTBRACKET RIGHTBRACKET
86
- { return }
91
+ { return [] }
87
92
  ;
88
93
 
89
94
  listitems:
@@ -117,7 +122,7 @@ rule
117
122
  end
118
123
 
119
124
  ---- header
120
- require_relative './lexer'
125
+ require_relative 'lexer'
121
126
 
122
127
  ---- inner
123
128
  #//
@@ -125,19 +130,31 @@ require_relative './lexer'
125
130
  #// keys are encountered.
126
131
  #//
127
132
  #// from decoder.go: if we're at the root or we're directly within
128
- #// a list, decode to hashes, otherwise lists
133
+ #// a list, decode to hashes, otherwise lists
129
134
  #//
130
135
  #// from object.go: there is a flattened list structure
131
136
  #//
137
+ #// if @duplicate_mode is set:
138
+ #// - :array then duplicates will be appended to an array
139
+ #// - :merge then duplicates will be deep merged into a hash
140
+ #//
132
141
  def flatten_objectlist(list)
133
142
  (list || {}).each_with_object({}) do |a, h|
134
- h[a.first] =
135
- case a.last
136
- when Hash
143
+ if h.keys.include?(a.first)
144
+ case @duplicate_mode
145
+ when :array
146
+ if h[a.first].is_a?(Array)
147
+ h[a.first].push(a.last)
148
+ else
149
+ h[a.first] = [ h[a.first], a.last ]
150
+ end
151
+ when :merge
137
152
  deep_merge(h[a.first] || {}, a.last)
138
- else
139
- h[a.first] = a.last
153
+ else raise ArgumentError
140
154
  end
155
+ else
156
+ h[a.first] = a.last
157
+ end
141
158
  end
142
159
  end
143
160
 
@@ -149,10 +166,12 @@ require_relative './lexer'
149
166
  end
150
167
 
151
168
 
152
- def parse(input)
153
- @lexer = HCLLexer.new.lex(input)
169
+ def parse(input, duplicate_mode = :array)
170
+ @duplicate_mode = duplicate_mode
171
+ @lexer = HCL::Checker::Lexer.new.lex(input)
154
172
  do_parse
155
- return @result
173
+
174
+ @result
156
175
  end
157
176
 
158
177
 
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "hcl/checker"
3
+ require 'bundler/setup'
4
+ require 'hcl/checker'
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +10,5 @@ require "hcl/checker"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
13
+ require 'irb'
14
14
  IRB.start(__FILE__)
data/hcl-checker.gemspec CHANGED
@@ -1,4 +1,4 @@
1
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
  require 'hcl/checker/version'
4
4
 
@@ -17,36 +17,20 @@ Gem::Specification.new do |spec|
17
17
  f.match(%r{^(test|spec|features)/})
18
18
  end
19
19
  spec.require_paths = ['lib']
20
+ spec.required_ruby_version = '>= 2.5.0'
20
21
 
21
- spec.add_development_dependency 'bundler', '~> 2.1.4'
22
- spec.add_development_dependency 'rake', '~> 12.3.3'
23
- spec.add_development_dependency 'rspec', '~> 3.0'
22
+ spec.add_development_dependency 'bundler', '~> 2.3.13'
24
23
  spec.add_development_dependency 'racc', '1.5.0'
24
+ spec.add_development_dependency 'rake', '~> 12.3.3'
25
25
  spec.add_development_dependency 'rex', '2.0.12'
26
26
  spec.add_development_dependency 'rexical', '>= 1.0.7'
27
+ spec.add_development_dependency 'rspec', '~> 3.0'
27
28
 
28
- spec.post_install_message = %q{
29
- Hello, I am updating this Gem to support version 2.0 of the HCL.
30
-
31
- In the meantime, it is important that you know that there will be a
32
- compatibility break with the current version, for Gem to support both
33
- versions.
34
-
35
- Therefore, instead of using just HCL::Checker you must tell which
36
- version you are using, like this:
37
-
38
- HCL1::Checker
39
-
40
- Or
41
-
42
- HCL2::Checker
43
-
44
- At the moment both HCL::Checker and HCL1::Checker will work, but with
45
- the release of support for version 2 the HCL::Checker syntax will no
46
- longer work.
29
+ spec.post_install_message = '
30
+ Hello, me again. This version fixes:
47
31
 
48
- So, update your code.
32
+ - Update dependencies due security issues
49
33
 
50
34
  Thank you :)
51
- }
35
+ '
52
36
  end
@@ -4,8 +4,7 @@
4
4
  # from lexical definition file "./assets/lexer.rex".
5
5
  #++
6
6
 
7
-
8
- class HCLLexer
7
+ class HCL::Checker::Lexer
9
8
  require 'strscan'
10
9
 
11
10
  class ScanError < StandardError ; end
@@ -85,16 +84,22 @@ class HCLLexer
85
84
  action { [:STRING, consume_heredoc] }
86
85
 
87
86
  when (text = @ss.scan(/\{/))
88
- action { [:LEFTBRACE, text]}
87
+ action { [:LEFTBRACE, text]}
89
88
 
90
89
  when (text = @ss.scan(/\}/))
91
- action { [:RIGHTBRACE, text]}
90
+ action { [:RIGHTBRACE, text]}
92
91
 
93
92
  when (text = @ss.scan(/\[/))
94
- action { [:LEFTBRACKET, text]}
93
+ action { [:LEFTBRACKET, text]}
95
94
 
96
95
  when (text = @ss.scan(/\]/))
97
- action { [:RIGHTBRACKET, text]}
96
+ action { [:RIGHTBRACKET, text]}
97
+
98
+ when (text = @ss.scan(/\(/))
99
+ action { [:LEFTPARENTHESES, text]}
100
+
101
+ when (text = @ss.scan(/\)/))
102
+ action { [:RIGHTPARENTHESES, text]}
98
103
 
99
104
  when (text = @ss.scan(/\,/))
100
105
  action { [:COMMA, text]}
@@ -129,13 +134,14 @@ class HCLLexer
129
134
  tokens
130
135
  end
131
136
  def to_boolean(input)
132
- input =
133
- if input =~ /true/
134
- true
135
- elsif input =~ /false/
136
- false
137
- end
138
- return input
137
+ case input
138
+ when /true/
139
+ true
140
+ when /false/
141
+ false
142
+ else
143
+ raise "Invalid value for `to_boolean`, expected true/false got #{input}"
144
+ end
139
145
  end
140
146
  def consume_comment(input)
141
147
  nested = 1
@@ -153,18 +159,19 @@ class HCLLexer
153
159
  def consume_string(input)
154
160
  result = ''
155
161
  nested = 0
156
- begin
162
+ loop do
157
163
  case(text = @ss.scan_until(%r{\"|\$\{|\}|\\}))
158
164
  when %r{\$\{\z}
159
165
  nested += 1
160
166
  when %r{\}\z}
161
- nested -= 1 if nested > 0
167
+ nested -= 1 if nested.positive?
162
168
  when %r{\\\z}
163
169
  result += text.chop + @ss.getch
164
170
  next
165
171
  end
166
172
  result += text.to_s
167
- end until nested == 0 && text =~ %r{\"\z}
173
+ break if nested.zero? && text =~ %r{\"\z}
174
+ end
168
175
  result.chop
169
176
  end
170
177
  def consume_heredoc