summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Parker <andy@puppetlabs.com>2013-09-12 15:59:27 -0700
committerAndrew Parker <andy@puppetlabs.com>2013-09-12 15:59:27 -0700
commitc98f21d2b29dccaa22436cb62bae27b134f8070c (patch)
tree238f48d32b56298a5f01a1278e1928eb1d40cec3
parent82c2574027e23838459148261196b7781d3098dc (diff)
downloadpuppet-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.rb23
-rw-r--r--spec/unit/util/yaml_spec.rb41
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