diff options
author | Dmitry Ilyin <dilyin@mirantis.com> | 2016-04-26 21:51:43 +0300 |
---|---|---|
committer | Dmitry Ilyin <dilyin@mirantis.com> | 2016-04-26 21:58:29 +0300 |
commit | 870a272cee6889934d60c4bfd7a814bcf47011f1 (patch) | |
tree | 4450edb42afb65d84ffe57a440747f56d4dbbfda | |
parent | b63849c7865e4191e9df5a7651c16c072facee3d (diff) |
Add the default value to the "loadyaml" function
This value will be returned if the is no file
to load or a file could not be parsed.
It's similar to the "parseyaml" function's
default value.
Add the "loadjson" function too
-rw-r--r-- | README.markdown | 32 | ||||
-rw-r--r-- | lib/puppet/parser/functions/loadjson.rb | 34 | ||||
-rw-r--r-- | lib/puppet/parser/functions/loadyaml.rb | 37 | ||||
-rw-r--r-- | spec/acceptance/loadjson_spec.rb | 52 | ||||
-rw-r--r-- | spec/acceptance/loadyaml_spec.rb | 23 | ||||
-rw-r--r-- | spec/functions/loadjson_spec.rb | 38 | ||||
-rwxr-xr-x | spec/functions/loadyaml_spec.rb | 16 |
7 files changed, 214 insertions, 18 deletions
diff --git a/README.markdown b/README.markdown index 6cedc2a..eff3b28 100644 --- a/README.markdown +++ b/README.markdown @@ -660,12 +660,42 @@ Returns the keys of a hash as an array. *Type*: rvalue. #### `loadyaml` -Loads a YAML file containing an array, string, or hash, and returns the data in the corresponding native data type. For example: +Loads a YAML file containing an array, string, or hash, and returns the data in the corresponding native data type. + +For example: ~~~ $myhash = loadyaml('/etc/puppet/data/myhash.yaml') ~~~ +The second parameter will be returned if the file was not found or could not be parsed. + +For example: + + ~~~ + $myhash = loadyaml('no-file.yaml', {'default'=>'value'}) + ~~~ + +*Type*: rvalue. + +#### `loadjson` + +Loads a JSON file containing an array, string, or hash, and returns the data in the corresponding native data type. + +For example: + + ~~~ + $myhash = loadjson('/etc/puppet/data/myhash.json') + ~~~ + +The second parameter will be returned if the file was not found or could not be parsed. + +For example: + + ~~~ + $myhash = loadjson('no-file.json', {'default'=>'value'}) + ~~~ + *Type*: rvalue. #### `load_module_metadata` diff --git a/lib/puppet/parser/functions/loadjson.rb b/lib/puppet/parser/functions/loadjson.rb new file mode 100644 index 0000000..3a3372b --- /dev/null +++ b/lib/puppet/parser/functions/loadjson.rb @@ -0,0 +1,34 @@ +module Puppet::Parser::Functions + newfunction(:loadjson, :type => :rvalue, :arity => -2, :doc => <<-'ENDHEREDOC') do |args| +Load a JSON file containing an array, string, or hash, and return the data +in the corresponding native data type. +The second parameter is the default value. It will be returned if the file +was not found or could not be parsed. + +For example: + + $myhash = loadjson('/etc/puppet/data/myhash.json') + $myhash = loadjson('no-file.json', {'default' => 'value'}) + ENDHEREDOC + + raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless args.length >= 1 + + if File.exists?(args[0]) + begin + content = File.read(args[0]) + PSON::load(content) || args[1] + rescue Exception => e + if args[1] + args[1] + else + raise e + end + end + else + warning("Can't load '#{args[0]}' File does not exist!") + args[1] + end + + end + +end diff --git a/lib/puppet/parser/functions/loadyaml.rb b/lib/puppet/parser/functions/loadyaml.rb index ca655f6..9696362 100644 --- a/lib/puppet/parser/functions/loadyaml.rb +++ b/lib/puppet/parser/functions/loadyaml.rb @@ -1,23 +1,32 @@ module Puppet::Parser::Functions + newfunction(:loadyaml, :type => :rvalue, :arity => -2, :doc => <<-'ENDHEREDOC') do |args| +Load a YAML file containing an array, string, or hash, and return the data +in the corresponding native data type. +The second parameter is the default value. It will be returned if the file +was not found or could not be parsed. - newfunction(:loadyaml, :type => :rvalue, :doc => <<-'ENDHEREDOC') do |args| - Load a YAML file containing an array, string, or hash, and return the data - in the corresponding native data type. +For example: - For example: + $myhash = loadyaml('/etc/puppet/data/myhash.yaml') + $myhash = loadyaml('no-file.yaml', {'default' => 'value'}) + ENDHEREDOC - $myhash = loadyaml('/etc/puppet/data/myhash.yaml') - ENDHEREDOC + raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless args.length >= 1 + require 'yaml' - unless args.length == 1 - raise Puppet::ParseError, ("loadyaml(): wrong number of arguments (#{args.length}; must be 1)") - end - - if File.exists?(args[0]) then - YAML.load_file(args[0]) + if File.exists?(args[0]) + begin + YAML::load_file(args[0]) || args[1] + rescue Exception => e + if args[1] + args[1] + else + raise e + end + end else - warning("Can't load " + args[0] + ". File does not exist!") - nil + warning("Can't load '#{args[0]}' File does not exist!") + args[1] end end diff --git a/spec/acceptance/loadjson_spec.rb b/spec/acceptance/loadjson_spec.rb new file mode 100644 index 0000000..2992c37 --- /dev/null +++ b/spec/acceptance/loadjson_spec.rb @@ -0,0 +1,52 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper_acceptance' + +tmpdir = default.tmpdir('stdlib') + +describe 'loadjson function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do + describe 'success' do + it 'loadjsons array of values' do + shell("echo '{\"aaa\":1,\"bbb\":2,\"ccc\":3,\"ddd\":4}' > #{tmpdir}/testjson.json") + pp = <<-EOS + $o = loadjson('#{tmpdir}/testjson.json') + notice(inline_template('loadjson[aaa] is <%= @o["aaa"].inspect %>')) + notice(inline_template('loadjson[bbb] is <%= @o["bbb"].inspect %>')) + notice(inline_template('loadjson[ccc] is <%= @o["ccc"].inspect %>')) + notice(inline_template('loadjson[ddd] is <%= @o["ddd"].inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/loadjson\[aaa\] is 1/) + expect(r.stdout).to match(/loadjson\[bbb\] is 2/) + expect(r.stdout).to match(/loadjson\[ccc\] is 3/) + expect(r.stdout).to match(/loadjson\[ddd\] is 4/) + end + end + + it 'returns the default value if there is no file to load' do + pp = <<-EOS + $o = loadjson('#{tmpdir}/no-file.json', {'default' => 'value'}) + notice(inline_template('loadjson[default] is <%= @o["default"].inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/loadjson\[default\] is "value"/) + end + end + + it 'returns the default value if the file was parsed with an error' do + shell("echo '!' > #{tmpdir}/testjson.json") + pp = <<-EOS + $o = loadjson('#{tmpdir}/testjson.json', {'default' => 'value'}) + notice(inline_template('loadjson[default] is <%= @o["default"].inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/loadjson\[default\] is "value"/) + end + end + end + describe 'failure' do + it 'fails with no arguments' + end +end diff --git a/spec/acceptance/loadyaml_spec.rb b/spec/acceptance/loadyaml_spec.rb index 1e910a9..ba3f0b7 100644 --- a/spec/acceptance/loadyaml_spec.rb +++ b/spec/acceptance/loadyaml_spec.rb @@ -26,6 +26,29 @@ describe 'loadyaml function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('op expect(r.stdout).to match(/loadyaml\[ddd\] is 4/) end end + + it 'returns the default value if there is no file to load' do + pp = <<-EOS + $o = loadyaml('#{tmpdir}/no-file.yaml', {'default' => 'value'}) + notice(inline_template('loadyaml[default] is <%= @o["default"].inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/loadyaml\[default\] is "value"/) + end + end + + it 'returns the default value if the file was parsed with an error' do + shell("echo '!' > #{tmpdir}/testyaml.yaml") + pp = <<-EOS + $o = loadyaml('#{tmpdir}/testyaml.yaml', {'default' => 'value'}) + notice(inline_template('loadyaml[default] is <%= @o["default"].inspect %>')) + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/loadyaml\[default\] is "value"/) + end + end end describe 'failure' do it 'fails with no arguments' diff --git a/spec/functions/loadjson_spec.rb b/spec/functions/loadjson_spec.rb new file mode 100644 index 0000000..12a9b82 --- /dev/null +++ b/spec/functions/loadjson_spec.rb @@ -0,0 +1,38 @@ +require 'spec_helper' + +describe 'loadjson' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(ArgumentError, /wrong number of arguments/i) } + + context 'when a non-existing file is specified' do + let(:filename) { '/tmp/doesnotexist' } + before { + File.expects(:exists?).with(filename).returns(false).once + PSON.expects(:load).never + } + it { is_expected.to run.with_params(filename, {'default' => 'value'}).and_return({'default' => 'value'}) } + end + + context 'when an existing file is specified' do + let(:filename) { '/tmp/doesexist' } + let(:data) { { 'key' => 'value' } } + let(:json) { '{"key":"value"}' } + before { + File.expects(:exists?).with(filename).returns(true).once + File.expects(:read).with(filename).returns(json).once + PSON.expects(:load).with(json).returns(data).once + } + it { is_expected.to run.with_params(filename).and_return(data) } + end + + context 'when the file could not be parsed' do + let(:filename) { '/tmp/doesexist' } + let(:json) { '{"key":"value"}' } + before { + File.expects(:exists?).with(filename).returns(true).once + File.expects(:read).with(filename).returns(json).once + PSON.stubs(:load).with(json).once.raises StandardError, 'Something terrible have happened!' + } + it { is_expected.to run.with_params(filename, {'default' => 'value'}).and_return({'default' => 'value'}) } + end +end diff --git a/spec/functions/loadyaml_spec.rb b/spec/functions/loadyaml_spec.rb index ffc714d..9f16a1a 100755 --- a/spec/functions/loadyaml_spec.rb +++ b/spec/functions/loadyaml_spec.rb @@ -2,16 +2,17 @@ require 'spec_helper' describe 'loadyaml' do it { is_expected.not_to eq(nil) } - it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } - it { is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params().and_raise_error(ArgumentError, /wrong number of arguments/i) } + context 'when a non-existing file is specified' do let(:filename) { '/tmp/doesnotexist' } before { File.expects(:exists?).with(filename).returns(false).once YAML.expects(:load_file).never } - it { is_expected.to run.with_params(filename).and_return(nil) } + it { is_expected.to run.with_params(filename, {'default' => 'value'}).and_return({'default' => 'value'}) } end + context 'when an existing file is specified' do let(:filename) { '/tmp/doesexist' } let(:data) { { 'key' => 'value' } } @@ -21,4 +22,13 @@ describe 'loadyaml' do } it { is_expected.to run.with_params(filename).and_return(data) } end + + context 'when the file could not be parsed' do + let(:filename) { '/tmp/doesexist' } + before { + File.expects(:exists?).with(filename).returns(true).once + YAML.stubs(:load_file).with(filename).once.raises StandardError, 'Something terrible have happened!' + } + it { is_expected.to run.with_params(filename, {'default' => 'value'}).and_return({'default' => 'value'}) } + end end |