diff --git a/lib/puppet/util/yaml.rb b/lib/puppet/util/yaml.rb index d0c37ae77..246080843 100644 --- a/lib/puppet/util/yaml.rb +++ b/lib/puppet/util/yaml.rb @@ -1,23 +1,24 @@ require 'yaml' module Puppet::Util::Yaml if defined?(::Psych::SyntaxError) YamlLoadExceptions = [::StandardError, ::Psych::SyntaxError] else YamlLoadExceptions = [::StandardError] end class YamlLoadError < Puppet::Error; end - def self.load_file(filename) - YAML.load_file(filename) + def self.load_file(filename, default_value = false) + yaml = YAML.load_file(filename) + yaml || default_value rescue *YamlLoadExceptions => detail raise YamlLoadError.new(detail.message, detail) end def self.dump(structure, filename) Puppet::Util.replace_file(filename, 0660) do |fh| YAML.dump(structure, fh) end end end diff --git a/spec/unit/util/yaml_spec.rb b/spec/unit/util/yaml_spec.rb index 960388ade..978afb0a2 100644 --- a/spec/unit/util/yaml_spec.rb +++ b/spec/unit/util/yaml_spec.rb @@ -1,41 +1,55 @@ require 'spec_helper' require 'puppet/util/yaml' describe Puppet::Util::Yaml do include PuppetSpec::Files let(:filename) { tmpfile("yaml") } it "reads a YAML file from disk" do write_file(filename, YAML.dump({ "my" => "data" })) expect(Puppet::Util::Yaml.load_file(filename)).to eq({ "my" => "data" }) end it "writes data formatted as YAML to disk" do Puppet::Util::Yaml.dump({ "my" => "data" }, filename) expect(Puppet::Util::Yaml.load_file(filename)).to eq({ "my" => "data" }) end it "raises an error when the file is invalid YAML" do write_file(filename, "{ invalid") expect { Puppet::Util::Yaml.load_file(filename) }.to raise_error(Puppet::Util::Yaml::YamlLoadError) end it "raises an error when the file does not exist" do expect { Puppet::Util::Yaml.load_file("no") }.to raise_error(Puppet::Util::Yaml::YamlLoadError, /No such file or directory/) end it "raises an error when the filename is illegal" do expect { Puppet::Util::Yaml.load_file("not\0allowed") }.to raise_error(Puppet::Util::Yaml::YamlLoadError, /null byte/) end + context "when the file is empty" do + it "returns false" do + Puppet::FileSystem::File.new(filename).touch + + expect(Puppet::Util::Yaml.load_file(filename)).to be_false + end + + it "allows return value to be overridden" do + Puppet::FileSystem::File.new(filename).touch + + expect(Puppet::Util::Yaml.load_file(filename, {})).to eq({}) + end + end + def write_file(name, contents) File.open(name, "w") do |fh| fh.write(contents) end end end