puppet-check 2.5.1 → 2.5.2

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: a3c5911fe2362e7462d111f97705eea6b60842ce107bb94d35e6f8657cea6812
4
- data.tar.gz: 52413822ec2375afd5fab3bb933220ad15bbcab285641f6717d94057c7fe0554
3
+ metadata.gz: 98b3c25f3adb4837ec7ce74efb4e06c422defab2a7360646b4daae7dda962c0f
4
+ data.tar.gz: 4814ad9b99fd205914ad1b976280d70479264ebff708aa0390a22346d1c4c1e6
5
5
  SHA512:
6
- metadata.gz: fa0c790ee8186c5d1f2eb7091c78d789c68fef7d16292fe3a70c3d41a41d1eb65c3ece36462578bfe2874bb236316fa9b5737f7316f6902d1017bb15c182cf0a
7
- data.tar.gz: 87e82df7685a13f4122838b225ef8e44d8de30b9e14f8cbb75577b76074fff5f40ca895c7bef00a7648862abba1edc31d5e237b0cb4ba8e0e5e1eb5aa4486304
6
+ metadata.gz: 714bc3ea74a76dd03a2dac33274e12b236f898cfe5f6257ea1a04dd7f0a61124d4509d1b73e2c74f2bf8b8d987aa3343ece7fce5a8e387a211464f400e7aecc7
7
+ data.tar.gz: 9c0737fee70f019f5189a499981b4a54b1449cb43d297b92ce2e8da5fe13dfa7194b4239db4417394626747de8acc250b3d5388b20687a469998c02d4b46418d
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ### 2.5.2
2
+ - Fix incorrect exit code `0` when `octocatalog` detects catalog compilation failure.
3
+ - Avoid mutation of and optimize Rubocop argument interfacing.
4
+ - Fix existing module install check when using Puppet Forge source for RSpec.
5
+ - Upgrade EYAML validation functionality from beta to release candidate.
6
+
1
7
  ### 2.5.1
2
8
  - Fix explicit `fail_on_warnings` default value assignment.
3
9
  - Improve message transformation for Puppet::Face errors and warnings.
data/README.md CHANGED
@@ -13,7 +13,7 @@
13
13
  ## Description
14
14
  Puppet Check is a gem that provides a comprehensive, streamlined, and efficient analysis of the syntax, style, and validity of your entire Puppet code and data.
15
15
 
16
- **IMPORTANT**: The current support for encrypted yaml validation is experimental and should be considered a beta feature as of 2.3.0.
16
+ **IMPORTANT**: The current support for encrypted yaml validation is semi-experimental and should be considered a release candidate feature as of 2.5.2.
17
17
 
18
18
  ### Former Method for Code and Data Checks
19
19
  ![Old](https://raw.githubusercontent.com/mschuchard/puppet-check/master/images/puppetcheck_old.png)
@@ -25,6 +25,7 @@ class DataParser
25
25
  # checks eyaml (.eyaml/.eyml)
26
26
  def self.eyaml(files, public, private)
27
27
  require 'openssl'
28
+ require 'base64'
28
29
 
29
30
  # keys specified?
30
31
  if public.nil? || private.nil?
@@ -42,34 +43,47 @@ class DataParser
42
43
  rsa = OpenSSL::PKey::RSA.new(File.read(private))
43
44
  x509 = OpenSSL::X509::Certificate.new(File.read(public))
44
45
 
46
+ # iterate through files and decrypt eyaml values
45
47
  files.each do |file|
46
- # check encoded yaml syntax
48
+ # load the file
47
49
  parsed = YAML.safe_load_file(file, permitted_classes: [Symbol], permitted_symbols: [], aliases: true)
48
50
 
49
- # extract encoded values
50
- # ENC[PKCS7]
51
-
52
- # decrypt the encoded yaml
53
- # decrypted = OpenSSL::PKCS7.new(File.read(file)).decrypt(rsa, x509)
54
-
55
- # check decoded eyaml syntax
56
- # decoded = YAML.safe_load(decrypted)
57
-
58
- # merge data hashes
59
- # parsed = merge(parsed, decoded)
51
+ # decrypt any ENC[PKCS7,...] leaf values found in the parsed structure
52
+ decoded = decrypt_eyaml(parsed, rsa, x509)
60
53
  rescue StandardError => err
61
54
  PuppetCheck.files[:errors][file] = err.to_s.gsub("(#{file}): ", '').split("\n")
62
55
  else
63
56
  warnings = []
64
57
 
65
58
  # perform some rudimentary hiera checks if data exists and is hieradata
66
- warnings = hiera(parsed, file) if parsed
59
+ warnings = hiera(decoded, file) if decoded
67
60
 
68
61
  next PuppetCheck.files[:warnings][file] = warnings unless warnings.empty?
69
62
  PuppetCheck.files[:clean].push(file.to_s)
70
63
  end
71
64
  end
72
65
 
66
+ # recursively decrypts ENC[PKCS7,...] leaf values in a parsed eyaml structure
67
+ private_class_method def self.decrypt_eyaml(data, rsa, x509)
68
+ case data
69
+ when Hash
70
+ # recurse into hash values, keys are never encrypted
71
+ data.transform_values { |v| decrypt_eyaml(v, rsa, x509) }
72
+ when Array
73
+ # recurse into array elements
74
+ data.map { |v| decrypt_eyaml(v, rsa, x509) }
75
+ when String
76
+ # leave plain (non-ENC) strings untouched
77
+ match = data.match(/\AENC\[PKCS7,(.+)\]\z/m)
78
+ return data unless match
79
+
80
+ # decode the base64 payload to DER and decrypt
81
+ OpenSSL::PKCS7.new(Base64.decode64(match[1])).decrypt(rsa, x509)
82
+ else
83
+ data
84
+ end
85
+ end
86
+
73
87
  # metadata consts
74
88
  REQUIRED_KEYS = %w[name version author license summary source dependencies].freeze
75
89
  REQ_DEP_KEYS = %w[requirements dependencies].freeze
@@ -97,7 +97,7 @@ class RSpecPuppetSupport
97
97
  # download external module dependency with forge
98
98
  private_class_method def self.forge(forge_name, args = '')
99
99
  # is the module present? do an upgrade; otherwise, do an install
100
- subcommand = File.directory?("spec/fixtures/modules/#{forge_name}") ? 'upgrade' : 'install'
100
+ subcommand = File.directory?("spec/fixtures/modules/#{forge_name.split('-').last}") ? 'upgrade' : 'install'
101
101
  spawn("puppet module #{subcommand} --modulepath spec/fixtures/modules/ #{args} #{forge_name}")
102
102
  end
103
103
 
@@ -23,10 +23,15 @@ class RubyParser
23
23
  # check ruby style
24
24
  if style
25
25
  # add rubocop rspec plugin if the file is a spec
26
- rc_args.push('--plugin', 'rubocop-rspec') if file =~ /_spec\.rb$/
26
+ if file =~ /_spec\.rb$/
27
+ # invoke RuboCop with rspec plugin
28
+ rubocop_warnings = Utils.capture_stdout { rubocop_cli.run(rc_args + ['--plugin', 'rubocop-rspec','--enable-pending-cops', '--plugin', 'rubocop-performance', '--format', 'json', file]) }
29
+ else
30
+ # invoke rubocop
31
+ rubocop_warnings = Utils.capture_stdout { rubocop_cli.run(rc_args + ['--enable-pending-cops', '--plugin', 'rubocop-performance', '--format', 'json', file]) }
32
+ end
27
33
 
28
- # check RuboCop and parse warnings' JSON output
29
- rubocop_warnings = Utils.capture_stdout { rubocop_cli.run(rc_args + ['--enable-pending-cops', '--plugin', 'rubocop-performance', '--format', 'json', file]) }
34
+ # parse rubocop offenses' structured JSON output
30
35
  rubocop_offenses = JSON.parse(rubocop_warnings)['files'][0]['offenses'].map { |warning| "#{warning['location']['line']}:#{warning['location']['column']} #{warning['message']}" }
31
36
 
32
37
  # check Reek using examiner api
data/lib/puppet_check.rb CHANGED
@@ -42,12 +42,15 @@ class PuppetCheck
42
42
  # if octocatalog-diff is not installed then continue immediately
43
43
  rescue NameError
44
44
  puts 'puppet-check: immediately continuing to results'
45
+ 0
45
46
  # smoke check failure? output message and return 2
46
47
  rescue OctocatalogDiff::Errors::CatalogError => err
47
48
  puts 'There was a smoke check error:'
48
49
  puts err
49
50
  puts catalog.error_message unless catalog.valid?
50
51
  2
52
+ else
53
+ 0
51
54
  end
52
55
  # perform regression checks if there were no errors and the user desires
53
56
  # begin
@@ -61,7 +64,6 @@ class PuppetCheck
61
64
 
62
65
  # code to output differences in catalog?
63
66
  # everything passed? return 0
64
- 0
65
67
  else
66
68
  # error files? return 2
67
69
  2
@@ -120,14 +122,14 @@ class PuppetCheck
120
122
  manifests, files = files.partition { |file| File.extname(file) == '.pp' }
121
123
  PuppetParser.manifest(manifests, style, puppetlint_args) unless manifests.empty?
122
124
  # check puppet templates
123
- templates, files = files.partition { |file| File.extname(file) == '.epp' }
124
- PuppetParser.template(templates) unless templates.empty?
125
+ epp, files = files.partition { |file| File.extname(file) == '.epp' }
126
+ PuppetParser.template(epp) unless epp.empty?
125
127
  # check ruby files
126
128
  rubies, files = files.partition { |file| File.extname(file) == '.rb' }
127
129
  RubyParser.ruby(rubies, style, rubocop_args) unless rubies.empty?
128
130
  # check ruby templates
129
- templates, files = files.partition { |file| File.extname(file) == '.erb' }
130
- RubyParser.template(templates) unless templates.empty?
131
+ erb, files = files.partition { |file| File.extname(file) == '.erb' }
132
+ RubyParser.template(erb) unless erb.empty?
131
133
  # check yaml data
132
134
  yamls, files = files.partition { |file| File.extname(file) =~ /\.ya?ml$/ }
133
135
  DataParser.yaml(yamls) unless yamls.empty?
data/puppet-check.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = 'puppet-check'
3
- spec.version = '2.5.1'
3
+ spec.version = '2.5.2'
4
4
  spec.authors = ['Matt Schuchard']
5
5
  spec.description = 'Puppet Check is a gem that provides a comprehensive, streamlined, and efficient analysis of the syntax, style, and validity of your entire Puppet code and data.'
6
6
  spec.summary = 'A streamlined comprehensive set of checks for your entire Puppet code and data'
@@ -0,0 +1,3 @@
1
+ ---
2
+ bad:
3
+ eyaml: ENC[PKCS7,not-a-valid-pkcs7-payload==]
@@ -0,0 +1,6 @@
1
+ ---
2
+ items:
3
+ - name: one
4
+ secret: ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAWYkSR19bdTGCu3NUMRGjHUIkXidzM4ejpICm7voB4JLUYyrwPxnvb8d761VA6JJwLe6dPmppm1x62k6Sp9HXyP3BqkhBlshLsgbNSbhMoLBPxfpjQhRTDFbeqZq35aY6grqj25AYB18Grfja8RoSK4jLHBECPJr0lUgW4qBANgV7KcaZndwxyDfTPFA3vCtc4r1l/r4Bg9esyV3ClJHP5A7bOmw38aibGcu1O4CHLEHCt3plvqrF7vElSFBJi62I7omGvdJitY+CVe6eTJiHLn3HnP9jeRGdRiC2eGhS+A7sE8JXK3n/ZtKFiH78payBlU6BWolgapBC3RnFw9jabTA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBB/Ep4/M8NuRlUOin0nQKjXgBArdhX8G2RtUEdfdl3ujD89]
5
+ - name: two
6
+ secret: plain
@@ -64,13 +64,71 @@ describe DataParser do
64
64
  expect(PuppetCheck.files[:warnings]).to eql({})
65
65
  expect(PuppetCheck.files[:clean]).to eql(["#{FIXTURES_DIR}hieradata/good.eyaml"])
66
66
  end
67
+ it 'puts an eyaml file with an undecryptable PKCS7 payload in the error files hash; distinctly from a YAML syntax error' do
68
+ DataParser.eyaml(["#{FIXTURES_DIR}hieradata/decrypt_error.eyaml"], "#{FIXTURES_DIR}keys/public_key.pkcs7.pem", "#{FIXTURES_DIR}keys/private_key.pkcs7.pem")
69
+ expect(PuppetCheck.files[:errors].keys).to eql(["#{FIXTURES_DIR}hieradata/decrypt_error.eyaml"])
70
+ expect(PuppetCheck.files[:errors]["#{FIXTURES_DIR}hieradata/decrypt_error.eyaml"].join("\n")).to match(/PKCS7/i)
71
+ expect(PuppetCheck.files[:errors]["#{FIXTURES_DIR}hieradata/decrypt_error.eyaml"].join("\n")).not_to match(/^block sequence entries are not allowed/)
72
+ expect(PuppetCheck.files[:warnings]).to eql({})
73
+ expect(PuppetCheck.files[:clean]).to eql([])
74
+ end
75
+ it 'decrypts an ENC[PKCS7,...] value nested inside an array of hashes and puts the file in the clean files array' do
76
+ DataParser.eyaml(["#{FIXTURES_DIR}hieradata/nested_array.eyaml"], "#{FIXTURES_DIR}keys/public_key.pkcs7.pem", "#{FIXTURES_DIR}keys/private_key.pkcs7.pem")
77
+ expect(PuppetCheck.files[:errors]).to eql({})
78
+ expect(PuppetCheck.files[:warnings]).to eql({})
79
+ expect(PuppetCheck.files[:clean]).to eql(["#{FIXTURES_DIR}hieradata/nested_array.eyaml"])
80
+ end
81
+ end
82
+
83
+ context '.decrypt_eyaml' do
84
+ before(:all) do
85
+ require 'openssl'
86
+ require 'base64'
87
+ end
88
+
89
+ let(:rsa) { OpenSSL::PKey::RSA.new(File.read("#{FIXTURES_DIR}keys/private_key.pkcs7.pem")) }
90
+ let(:x509) { OpenSSL::X509::Certificate.new(File.read("#{FIXTURES_DIR}keys/public_key.pkcs7.pem")) }
91
+
92
+ # encrypts a plaintext value against the fixture cert and wraps it as eyaml expects
93
+ def encrypt(plaintext)
94
+ pkcs7 = OpenSSL::PKCS7.encrypt([x509], plaintext, OpenSSL::Cipher.new('AES-256-CBC'), OpenSSL::PKCS7::BINARY)
95
+ "ENC[PKCS7,#{Base64.strict_encode64(pkcs7.to_der)}]"
96
+ end
97
+
98
+ it 'decrypts a single ENC[PKCS7,...] string to its original plaintext' do
99
+ expect(DataParser.send(:decrypt_eyaml, encrypt('puppetcheck'), rsa, x509)).to eql('puppetcheck')
100
+ end
101
+ it 'leaves a plain non-ENC string untouched' do
102
+ expect(DataParser.send(:decrypt_eyaml, 'plaintext value', rsa, x509)).to eql('plaintext value')
103
+ end
104
+ it 'leaves a string that merely resembles but does not fully match the ENC[PKCS7,...] pattern untouched' do
105
+ expect(DataParser.send(:decrypt_eyaml, 'prefix ENC[PKCS7,abc] suffix', rsa, x509)).to eql('prefix ENC[PKCS7,abc] suffix')
106
+ end
107
+ it 'recurses into hash values and decrypts them, while never decrypting hash keys' do
108
+ encrypted = encrypt('secret-value')
109
+ result = DataParser.send(:decrypt_eyaml, { encrypted => 'plain-key-value', 'plain-key' => encrypted }, rsa, x509)
110
+ expect(result.keys).to eql([encrypted, 'plain-key'])
111
+ expect(result[encrypted]).to eql('plain-key-value')
112
+ expect(result['plain-key']).to eql('secret-value')
113
+ end
114
+ it 'recurses into array elements and decrypts them' do
115
+ expect(DataParser.send(:decrypt_eyaml, ['plain', encrypt('array-secret')], rsa, x509)).to eql(['plain', 'array-secret'])
116
+ end
117
+ it 'recurses through nested hash/array/hash structures' do
118
+ expect(DataParser.send(:decrypt_eyaml, { 'list' => [{ 'inner' => encrypt('nested-secret') }] }, rsa, x509)).to eql({ 'list' => [{ 'inner' => 'nested-secret' }] })
119
+ end
120
+ it 'returns non-string/hash/array scalars unchanged' do
121
+ expect(DataParser.send(:decrypt_eyaml, 42, rsa, x509)).to eql(42)
122
+ expect(DataParser.send(:decrypt_eyaml, nil, rsa, x509)).to be_nil
123
+ expect(DataParser.send(:decrypt_eyaml, true, rsa, x509)).to be true
124
+ end
67
125
  end
68
126
 
69
127
  context '.json' do
70
128
  it 'puts a bad syntax json file in the error files hash' do
71
129
  DataParser.json(["#{FIXTURES_DIR}hieradata/syntax.json"])
72
130
  expect(PuppetCheck.files[:errors].keys).to eql(["#{FIXTURES_DIR}hieradata/syntax.json"])
73
- expect(PuppetCheck.files[:errors]["#{FIXTURES_DIR}hieradata/syntax.json"].join("\n")).to match(/after object value, got.*at line 2 column 3/)
131
+ expect(PuppetCheck.files[:errors]["#{FIXTURES_DIR}hieradata/syntax.json"].join("\n")).to match(/after object value, got.*at line 3 column 3/)
74
132
  expect(PuppetCheck.files[:warnings]).to eql({})
75
133
  expect(PuppetCheck.files[:clean]).to eql([])
76
134
  end
@@ -121,4 +179,4 @@ describe DataParser do
121
179
  expect(PuppetCheck.files[:clean]).to eql(["#{FIXTURES_DIR}task_metadata/task_good.json"])
122
180
  end
123
181
  end
124
- end
182
+ end
@@ -112,16 +112,51 @@ describe PuppetCheck do
112
112
  end
113
113
 
114
114
  context '.execute_parsers' do
115
- it 'correctly organizes a set of files and invokes the correct parsers' do
116
- # parser_output = instance_double('execute_parsers', files: %w[puppet.pp puppet_template.epp ruby.rb ruby_template.erb yaml.yaml yaml.yml json.json Puppetfile Modulefile foobarbaz], style: false, pl_args: [], rc_args: [])
117
- # expect(parser_output).to receive(:manifest).with(%w[puppet.pp])
118
- # expect(parser_output).to receive(:template).with(%w[puppet_template.epp])
119
- # expect(parser_output).to receive(:ruby).with(%w[ruby.rb])
120
- # expect(parser_output).to receive(:template).with(%w[ruby_template.erb])
121
- # expect(parser_output).to receive(:yaml).with(%w[yaml.yaml yaml.yml])
122
- # expect(parser_output).to receive(:json).with(%w[json.json])
123
- # expect(parser_output).to receive(:librarian).with(%w[Puppetfile Modulefile])
124
- # expect(PuppetCheck.files[:ignored]).to eql(%w[foobarbaz])
115
+ before(:each) do
116
+ PuppetCheck.files = { errors: {}, warnings: {}, clean: [], ignored: [] }
117
+ end
118
+ let(:puppet_check) { PuppetCheck.new }
119
+
120
+ it 'correctly routes each file type to the appropriate parser and ignores unrecognized files' do
121
+ expect(PuppetParser).to receive(:manifest).with(['manifests/good.pp'], false, [])
122
+ expect(PuppetParser).to receive(:template).with(['templates/good.epp'])
123
+ expect(RubyParser).to receive(:ruby).with(['lib/good.rb'], false, [])
124
+ expect(RubyParser).to receive(:template).with(['templates/good.erb'])
125
+ expect(DataParser).to receive(:yaml).with(['hieradata/good.yaml', 'hieradata/good.yml'])
126
+ expect(DataParser).to receive(:json).with(['hieradata/good.json'])
127
+ expect(DataParser).to receive(:eyaml).with(['hieradata/good.eyaml'], nil, nil)
128
+ expect(RubyParser).to receive(:librarian).with(['librarian/Puppetfile_good'], false, [])
129
+
130
+ puppet_check.send(:execute_parsers, %w[manifests/good.pp templates/good.epp lib/good.rb templates/good.erb hieradata/good.yaml hieradata/good.yml hieradata/good.json hieradata/good.eyaml librarian/Puppetfile_good foobarbaz], false, [], [], nil, nil)
131
+
132
+ expect(PuppetCheck.files[:ignored]).to eql(['foobarbaz'])
133
+ end
134
+
135
+ it 'passes style and arg options through to the correct parsers and skips parser calls when a given file category is empty' do
136
+ expect(PuppetParser).to receive(:manifest).with(['manifests/good.pp'], true, ['--no-140chars-check'])
137
+ expect(PuppetParser).not_to receive(:template)
138
+ expect(RubyParser).to receive(:ruby).with(['lib/good.rb'], true, ['--except', 'Style/FrozenStringLiteralComment'])
139
+ expect(RubyParser).to receive(:librarian).with(['librarian/Puppetfile_good'], true, ['--except', 'Style/FrozenStringLiteralComment'])
140
+ expect(RubyParser).not_to receive(:template)
141
+ expect(DataParser).to receive(:yaml).with(['hieradata/good.yaml'])
142
+ expect(DataParser).not_to receive(:json)
143
+ expect(DataParser).not_to receive(:eyaml)
144
+
145
+ puppet_check.send(
146
+ :execute_parsers,
147
+ %w[manifests/good.pp lib/good.rb hieradata/good.yaml librarian/Puppetfile_good],
148
+ true,
149
+ ['--no-140chars-check'],
150
+ ['--except', 'Style/FrozenStringLiteralComment'],
151
+ nil,
152
+ nil
153
+ )
154
+ end
155
+
156
+ it 'returns PuppetCheck.files' do
157
+ allow(PuppetParser).to receive(:manifest)
158
+ result = puppet_check.send(:execute_parsers, ['manifests/good.pp'], false, [], [], nil, nil)
159
+ expect(result).to eql(PuppetCheck.files)
125
160
  end
126
161
  end
127
162
  end
@@ -15,9 +15,9 @@ describe PuppetCheck do
15
15
  expect(PuppetCheck::CLI.run(%w[-s --puppet-lint no-hard_tabs-check,no-140chars-check --rubocop Layout/LineLength,Style/Encoding --public keys/public_key.pkcs7.pem --private keys/private_key.pkcs7.pem --smoke -n good.example.com --octoconfig spec/octocatalog-diff/octocatalog-diff.cfg.rb .])).to eql(2)
16
16
  end
17
17
 
18
- expect(PuppetCheck.files[:errors].length).to eql(11)
18
+ expect(PuppetCheck.files[:errors].length).to eql(12)
19
19
  expect(PuppetCheck.files[:warnings].length).to eql(13)
20
- expect(PuppetCheck.files[:clean].length).to eql(13)
20
+ expect(PuppetCheck.files[:clean].length).to eql(14)
21
21
  expect(PuppetCheck.files[:ignored].length).to eql(3)
22
22
  end
23
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppet-check
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.1
4
+ version: 2.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Schuchard
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-05-02 00:00:00.000000000 Z
11
+ date: 2026-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: puppet
@@ -153,9 +153,11 @@ files:
153
153
  - lib/puppet_check.rb
154
154
  - puppet-check.gemspec
155
155
  - spec/fixtures/foobarbaz
156
+ - spec/fixtures/hieradata/decrypt_error.eyaml
156
157
  - spec/fixtures/hieradata/good.eyaml
157
158
  - spec/fixtures/hieradata/good.json
158
159
  - spec/fixtures/hieradata/good.yaml
160
+ - spec/fixtures/hieradata/nested_array.eyaml
159
161
  - spec/fixtures/hieradata/style.eyaml
160
162
  - spec/fixtures/hieradata/style.yaml
161
163
  - spec/fixtures/hieradata/syntax.eyaml