From 1b8f597c9b3dd9f8587cbb5034fd45a443292a31 Mon Sep 17 00:00:00 2001 From: Julian Squires Date: Thu, 6 Mar 2025 14:12:58 -0330 Subject: [PATCH] Avoid using the manifest lexer on YAML A YAML file like in the fixture added is parsed fine by Psych and yamllint, but puppet-lint chokes on it because it gets fed through the manifest lexer first, which can't cope with some things that are valid YAML. Since the one check that operates on YAML files doesn't support fixing and doesn't use tokens, it seems reasonable to bypass the lexer; more sophisticated YAML checks would need to use a separate YAML lexer anyway. Note that this can't be a unit test because those bypass the lexer processing. --- lib/puppet-lint/checks.rb | 7 +++++-- spec/acceptance/puppet_lint_spec.rb | 7 +++++++ spec/fixtures/test/manifests/parseable.yaml | 3 +++ spec/unit/puppet-lint/checks_spec.rb | 5 ----- 4 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 spec/fixtures/test/manifests/parseable.yaml diff --git a/lib/puppet-lint/checks.rb b/lib/puppet-lint/checks.rb index 77b66e8e..f4c1fcff 100644 --- a/lib/puppet-lint/checks.rb +++ b/lib/puppet-lint/checks.rb @@ -54,10 +54,11 @@ def load_data(path, content) # # Returns an Array of problem Hashes. def run(fileinfo, data) - load_data(fileinfo, data) - checks_run = [] if File.extname(fileinfo).downcase.match?(%r{\.ya?ml$}) + PuppetLint::Data.path = fileinfo + PuppetLint::Data.manifest_lines = data.split("\n", -1) + enabled_checks.select { |check| YAML_COMPATIBLE_CHECKS.include?(check) }.each do |check| klass = PuppetLint.configuration.check_object[check].new # FIXME: shadowing #problems @@ -65,6 +66,8 @@ def run(fileinfo, data) checks_run << [klass, problems] end else + load_data(fileinfo, data) + enabled_checks.each do |check| klass = PuppetLint.configuration.check_object[check].new # FIXME: shadowing #problems diff --git a/spec/acceptance/puppet_lint_spec.rb b/spec/acceptance/puppet_lint_spec.rb index cd16fbcc..db620904 100644 --- a/spec/acceptance/puppet_lint_spec.rb +++ b/spec/acceptance/puppet_lint_spec.rb @@ -43,4 +43,11 @@ expect(result[:stdout]).to have_warnings(2) end end + + context 'with a YAML file provided' do + it 'returns zero errors' do + result = puppet_lint([File.join(manifest_root, 'parseable.yaml')]) + expect(result[:stdout]).to have_errors(0) + end + end end diff --git a/spec/fixtures/test/manifests/parseable.yaml b/spec/fixtures/test/manifests/parseable.yaml new file mode 100644 index 00000000..c71c9402 --- /dev/null +++ b/spec/fixtures/test/manifests/parseable.yaml @@ -0,0 +1,3 @@ +--- +heredoc: | + contains $ diff --git a/spec/unit/puppet-lint/checks_spec.rb b/spec/unit/puppet-lint/checks_spec.rb index 2ba1fa3c..c9a07eda 100644 --- a/spec/unit/puppet-lint/checks_spec.rb +++ b/spec/unit/puppet-lint/checks_spec.rb @@ -223,11 +223,6 @@ allow(File).to receive(:extname).with(fileinfo).and_return('.yaml') end - it 'loads the yaml data' do - expect(instance).to receive(:load_data).with(fileinfo, data).and_call_original # rubocop: disable RSpec/SubjectStub - instance.run(fileinfo, data) - end - context 'when there are checks enabled' do let(:enabled_checks) { [:legacy_facts] } let(:enabled_check_classes) { enabled_checks.map { |r| PuppetLint.configuration.check_object[r] } }