Skip to content

Commit

Permalink
Merge pull request #600 from dmitryilyin/master
Browse files Browse the repository at this point in the history
Add the default value to the "loadyaml" function
  • Loading branch information
bmjen committed May 12, 2016
2 parents 7a008a7 + 870a272 commit ecfdbb2
Show file tree
Hide file tree
Showing 7 changed files with 214 additions and 18 deletions.
32 changes: 31 additions & 1 deletion README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -661,12 +661,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`
Expand Down
34 changes: 34 additions & 0 deletions lib/puppet/parser/functions/loadjson.rb
Original file line number Diff line number Diff line change
@@ -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
37 changes: 23 additions & 14 deletions lib/puppet/parser/functions/loadyaml.rb
Original file line number Diff line number Diff line change
@@ -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
Expand Down
52 changes: 52 additions & 0 deletions spec/acceptance/loadjson_spec.rb
Original file line number Diff line number Diff line change
@@ -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
23 changes: 23 additions & 0 deletions spec/acceptance/loadyaml_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,29 @@
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'
Expand Down
38 changes: 38 additions & 0 deletions spec/functions/loadjson_spec.rb
Original file line number Diff line number Diff line change
@@ -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
16 changes: 13 additions & 3 deletions spec/functions/loadyaml_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@

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' } }
Expand All @@ -21,4 +22,13 @@
}
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

0 comments on commit ecfdbb2

Please sign in to comment.