diff options
author | Andrew Parker <andy@puppetlabs.com> | 2013-09-12 15:59:27 -0700 |
---|---|---|
committer | Andrew Parker <andy@puppetlabs.com> | 2013-09-12 15:59:27 -0700 |
commit | c98f21d2b29dccaa22436cb62bae27b134f8070c (patch) | |
tree | 238f48d32b56298a5f01a1278e1928eb1d40cec3 | |
parent | 82c2574027e23838459148261196b7781d3098dc (diff) | |
download | puppet-c98f21d2b29dccaa22436cb62bae27b134f8070c.tar.gz |
(#22471) Extract YAML interaction into shared code
The extra logic that is needed to interact with both Psych and Syck was
duplicated in the Puppet::Util::Storage and Puppet::Indirector::Yaml
classes. This pulls out a common module that wraps YAML and provides
consistent, and safe, semantics for using YAML for reading and writing.
This also removes the check ofr ::ArgumentError in addition to
::StandardError because it seems that ::ArgumentError is a sublcass of
::StandardError.
-rw-r--r-- | lib/puppet/util/yaml.rb | 23 | ||||
-rw-r--r-- | spec/unit/util/yaml_spec.rb | 41 |
2 files changed, 64 insertions, 0 deletions
diff --git a/lib/puppet/util/yaml.rb b/lib/puppet/util/yaml.rb new file mode 100644 index 000000000..d0c37ae77 --- /dev/null +++ b/lib/puppet/util/yaml.rb @@ -0,0 +1,23 @@ +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) + 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 new file mode 100644 index 000000000..960388ade --- /dev/null +++ b/spec/unit/util/yaml_spec.rb @@ -0,0 +1,41 @@ +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 + + def write_file(name, contents) + File.open(name, "w") do |fh| + fh.write(contents) + end + end +end |