hcl-checker 1.1.1 → 1.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dba14fa38ca8a55c4d6fff75c7f0fea2de7a8bc5e21dc4aaa2d0812e4dc0483e
4
- data.tar.gz: bc3cd480f8edb04c18d1ffabdbea3f6234ca39e2d2518e6aedfcbf590537bb91
3
+ metadata.gz: db4fad85fc6cac710e6cf24082498ce2454f89f19204afc977413913a0e58699
4
+ data.tar.gz: 8d6be4dd1a00565006886e0dadbee8d2737de8d2b0819eed26d76d0573dbddb2
5
5
  SHA512:
6
- metadata.gz: 5ba8f95741ad1409547546af252178b7ab96dcf5111934fa1f5391610a96ec1d199211c2912006a043106cb3c40f12e35440830ddc5b9f64589e550f7057bb3a
7
- data.tar.gz: f27f4fb782b3a47a788ea5f966f5d38a54becb71dbec6a564a3d9623c7cee1b0050b906b51c7ac86b192e74c15bd4a2c5fa3bc9705d74c1543ab98db12168f12
6
+ metadata.gz: 878423137f46f8043861744bbb8ff9026f5472caa0d8f9cfa0eb532f612f82bad0451b5c154b0aec19a98fdd9b568860a578d36903ef55fee9f3efbeec03e6a6
7
+ data.tar.gz: 63ebcea583cc378a141a41435ab0c32b0a9ee88a21fbbac197b7f0756fd8c46461f55987730fc591e0cfee124b85cb6558be5281e41e1ea52f32ad421f8842f8
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.8.5"
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,22 +1,23 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hcl-checker (1.1.1)
4
+ hcl-checker (1.6.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- diff-lcs (1.3)
10
- filesize (0.1.1)
9
+ diff-lcs (1.4.4)
10
+ filesize (0.2.0)
11
11
  jsobfu (0.4.2)
12
12
  rkelly-remix
13
- json (2.0.4)
14
- metasm (1.0.3)
15
- mini_portile2 (2.4.0)
16
- nokogiri (1.10.1)
17
- mini_portile2 (~> 2.4.0)
18
- racc (1.4.14)
19
- rake (10.4.2)
13
+ json (2.3.1)
14
+ metasm (1.0.4)
15
+ mini_portile2 (2.5.3)
16
+ nokogiri (1.11.7)
17
+ mini_portile2 (~> 2.5.0)
18
+ racc (~> 1.4)
19
+ racc (1.5.0)
20
+ rake (12.3.3)
20
21
  rb-readline (0.5.5)
21
22
  rex (2.0.12)
22
23
  filesize (~> 0)
@@ -25,34 +26,34 @@ GEM
25
26
  metasm (~> 1)
26
27
  nokogiri (~> 1)
27
28
  rb-readline (~> 0)
28
- rexical (1.0.5)
29
+ rexical (1.0.7)
29
30
  rkelly-remix (0.0.7)
30
- rspec (3.7.0)
31
- rspec-core (~> 3.7.0)
32
- rspec-expectations (~> 3.7.0)
33
- rspec-mocks (~> 3.7.0)
34
- rspec-core (3.7.1)
35
- rspec-support (~> 3.7.0)
36
- rspec-expectations (3.7.0)
31
+ rspec (3.9.0)
32
+ rspec-core (~> 3.9.0)
33
+ rspec-expectations (~> 3.9.0)
34
+ rspec-mocks (~> 3.9.0)
35
+ rspec-core (3.9.2)
36
+ rspec-support (~> 3.9.3)
37
+ rspec-expectations (3.9.2)
37
38
  diff-lcs (>= 1.2.0, < 2.0)
38
- rspec-support (~> 3.7.0)
39
- rspec-mocks (3.7.0)
39
+ rspec-support (~> 3.9.0)
40
+ rspec-mocks (3.9.1)
40
41
  diff-lcs (>= 1.2.0, < 2.0)
41
- rspec-support (~> 3.7.0)
42
- rspec-support (3.7.0)
42
+ rspec-support (~> 3.9.0)
43
+ rspec-support (3.9.3)
43
44
 
44
45
  PLATFORMS
45
46
  ruby
46
47
 
47
48
  DEPENDENCIES
48
- bundler (~> 1.16)
49
+ bundler (~> 2.2.10)
49
50
  hcl-checker!
50
- nokogiri (>= 1.8.5)
51
- racc (= 1.4.14)
52
- rake (~> 10.0)
51
+ nokogiri (>= 1.11.4)
52
+ racc (= 1.5.0)
53
+ rake (~> 12.3.3)
53
54
  rex (= 2.0.12)
54
- rexical (= 1.0.5)
55
+ rexical (>= 1.0.7)
55
56
  rspec (~> 3.0)
56
57
 
57
58
  BUNDLED WITH
58
- 1.16.2
59
+ 2.2.20
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # Hcl::Checker
2
2
 
3
- **Hashicorp Configuration Language** syntax checker and parser.
3
+ **Hashicorp Configuration Language** syntax checker and parser.
4
4
 
5
5
  Parser originally created by [Sikula](https://github.com/sikula) and available
6
6
  at [Ruby HCL Repository](https://github.com/sikula/ruby-hcl). Only works with
7
- [HCL Version 1](https://github.com/hashicorp/hcl).
7
+ [HCL Version 1](https://github.com/hashicorp/hcl).
8
8
 
9
9
  ## Installation
10
10
 
@@ -84,7 +84,7 @@ $ bundle exec rake build_grammar
84
84
  Building Lexer....done
85
85
  Building Parser....done
86
86
  ```
87
-
87
+
88
88
  ## Contributing
89
89
 
90
90
  Bug reports and pull requests are welcome on GitHub at
@@ -96,5 +96,3 @@ to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
96
96
 
97
97
  The gem is available as open source under the terms of the [MIT
98
98
  License](https://opensource.org/licenses/MIT).
99
-
100
-
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,7 +19,9 @@ macro
20
19
  RIGHTBRACE \}
21
20
  LEFTBRACKET \[
22
21
  RIGHTBRACKET \]
23
- HEREDOCUMENT \<<-
22
+ LEFTPARENTHESES \(
23
+ RIGHTPARENTHESES \)
24
+ HEREDOCUMENT \<<\-?
24
25
 
25
26
  rule
26
27
  # [:state] pattern [actions]
@@ -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,10 +26,13 @@ rule
24
26
  | objectlist
25
27
  ;
26
28
 
27
-
28
29
  objectlist:
29
- objectitem
30
+ objectitem COMMA
31
+ { result = [val[0]] }
32
+ | objectitem
30
33
  { result = [val[0]] }
34
+ | objectlist objectitem COMMA
35
+ { result = val[0] << val[1] }
31
36
  | objectlist objectitem
32
37
  { result = val[0] << val[1] }
33
38
  ;
@@ -36,7 +41,7 @@ rule
36
41
  LEFTBRACE objectlist RIGHTBRACE
37
42
  { result = flatten_objectlist(val[1]) }
38
43
  | LEFTBRACE RIGHTBRACE
39
- { return }
44
+ { return {} }
40
45
  ;
41
46
 
42
47
  objectkey:
@@ -57,6 +62,10 @@ rule
57
62
  { result = val[0], val[2] }
58
63
  | objectkey EQUAL list
59
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] }
60
69
  | block
61
70
  { result = val[0] }
62
71
  ;
@@ -79,7 +88,7 @@ rule
79
88
  LEFTBRACKET listitems RIGHTBRACKET
80
89
  { result = val[1] }
81
90
  | LEFTBRACKET RIGHTBRACKET
82
- { return }
91
+ { return [] }
83
92
  ;
84
93
 
85
94
  listitems:
@@ -113,7 +122,7 @@ rule
113
122
  end
114
123
 
115
124
  ---- header
116
- require_relative './lexer'
125
+ require_relative 'lexer'
117
126
 
118
127
  ---- inner
119
128
  #//
@@ -121,19 +130,31 @@ require_relative './lexer'
121
130
  #// keys are encountered.
122
131
  #//
123
132
  #// from decoder.go: if we're at the root or we're directly within
124
- #// a list, decode to hashes, otherwise lists
133
+ #// a list, decode to hashes, otherwise lists
125
134
  #//
126
135
  #// from object.go: there is a flattened list structure
127
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
+ #//
128
141
  def flatten_objectlist(list)
129
- list.each_with_object({}) do |a, h|
130
- h[a.first] =
131
- case a.last
132
- when Hash
142
+ (list || {}).each_with_object({}) do |a, h|
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
133
152
  deep_merge(h[a.first] || {}, a.last)
134
- else
135
- h[a.first] = a.last
153
+ else raise ArgumentError
136
154
  end
155
+ else
156
+ h[a.first] = a.last
157
+ end
137
158
  end
138
159
  end
139
160
 
@@ -145,10 +166,12 @@ require_relative './lexer'
145
166
  end
146
167
 
147
168
 
148
- def parse(input)
149
- @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)
150
172
  do_parse
151
- return @result
173
+
174
+ @result
152
175
  end
153
176
 
154
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
 
@@ -6,7 +6,7 @@ Gem::Specification.new do |spec|
6
6
  spec.name = 'hcl-checker'
7
7
  spec.version = HCL::Checker::VERSION
8
8
  spec.authors = ['Marcelo Castellani']
9
- spec.email = ['marcelofc.rock@gmail.com']
9
+ spec.email = ['marcelo@linux.com']
10
10
 
11
11
  spec.summary = 'Hashicorp Configuration Language parser for Ruby'
12
12
  spec.description = 'Hashicorp Configuration Language parser and checker for Ruby'
@@ -17,12 +17,23 @@ 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', '~> 1.16'
22
- spec.add_development_dependency 'rake', '~> 10.0'
23
- spec.add_development_dependency 'rspec', '~> 3.0'
24
- spec.add_development_dependency 'racc', '1.4.14'
22
+ spec.add_development_dependency 'bundler', '~> 2.2.10'
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
- spec.add_development_dependency 'rexical', '1.0.5'
26
+ spec.add_development_dependency 'rexical', '>= 1.0.7'
27
+ spec.add_development_dependency 'rspec', '~> 3.0'
28
+
29
+ spec.post_install_message = '
30
+ Hello, me again. This version fixes:
31
+
32
+ - Add support for multiple elements of the same type
33
+ - Fix bug where empty objects and empty lists were being parsed as nil
34
+ - Update bundler version
35
+ - Update nokogiri version
27
36
 
37
+ Thank you :)
38
+ '
28
39
  end