Skip to content

Commit ecfdbb2

Browse files
committed
Merge pull request #600 from dmitryilyin/master
Add the default value to the "loadyaml" function
2 parents 7a008a7 + 870a272 commit ecfdbb2

File tree

7 files changed

+214
-18
lines changed

7 files changed

+214
-18
lines changed

README.markdown

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,12 +661,42 @@ Returns the keys of a hash as an array. *Type*: rvalue.
661661

662662
#### `loadyaml`
663663

664-
Loads a YAML file containing an array, string, or hash, and returns the data in the corresponding native data type. For example:
664+
Loads a YAML file containing an array, string, or hash, and returns the data in the corresponding native data type.
665+
666+
For example:
665667

666668
~~~
667669
$myhash = loadyaml('/etc/puppet/data/myhash.yaml')
668670
~~~
669671

672+
The second parameter will be returned if the file was not found or could not be parsed.
673+
674+
For example:
675+
676+
~~~
677+
$myhash = loadyaml('no-file.yaml', {'default'=>'value'})
678+
~~~
679+
680+
*Type*: rvalue.
681+
682+
#### `loadjson`
683+
684+
Loads a JSON file containing an array, string, or hash, and returns the data in the corresponding native data type.
685+
686+
For example:
687+
688+
~~~
689+
$myhash = loadjson('/etc/puppet/data/myhash.json')
690+
~~~
691+
692+
The second parameter will be returned if the file was not found or could not be parsed.
693+
694+
For example:
695+
696+
~~~
697+
$myhash = loadjson('no-file.json', {'default'=>'value'})
698+
~~~
699+
670700
*Type*: rvalue.
671701

672702
#### `load_module_metadata`
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
module Puppet::Parser::Functions
2+
newfunction(:loadjson, :type => :rvalue, :arity => -2, :doc => <<-'ENDHEREDOC') do |args|
3+
Load a JSON file containing an array, string, or hash, and return the data
4+
in the corresponding native data type.
5+
The second parameter is the default value. It will be returned if the file
6+
was not found or could not be parsed.
7+
8+
For example:
9+
10+
$myhash = loadjson('/etc/puppet/data/myhash.json')
11+
$myhash = loadjson('no-file.json', {'default' => 'value'})
12+
ENDHEREDOC
13+
14+
raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless args.length >= 1
15+
16+
if File.exists?(args[0])
17+
begin
18+
content = File.read(args[0])
19+
PSON::load(content) || args[1]
20+
rescue Exception => e
21+
if args[1]
22+
args[1]
23+
else
24+
raise e
25+
end
26+
end
27+
else
28+
warning("Can't load '#{args[0]}' File does not exist!")
29+
args[1]
30+
end
31+
32+
end
33+
34+
end

lib/puppet/parser/functions/loadyaml.rb

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,32 @@
11
module Puppet::Parser::Functions
2+
newfunction(:loadyaml, :type => :rvalue, :arity => -2, :doc => <<-'ENDHEREDOC') do |args|
3+
Load a YAML file containing an array, string, or hash, and return the data
4+
in the corresponding native data type.
5+
The second parameter is the default value. It will be returned if the file
6+
was not found or could not be parsed.
27
3-
newfunction(:loadyaml, :type => :rvalue, :doc => <<-'ENDHEREDOC') do |args|
4-
Load a YAML file containing an array, string, or hash, and return the data
5-
in the corresponding native data type.
8+
For example:
69
7-
For example:
10+
$myhash = loadyaml('/etc/puppet/data/myhash.yaml')
11+
$myhash = loadyaml('no-file.yaml', {'default' => 'value'})
12+
ENDHEREDOC
813

9-
$myhash = loadyaml('/etc/puppet/data/myhash.yaml')
10-
ENDHEREDOC
14+
raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless args.length >= 1
15+
require 'yaml'
1116

12-
unless args.length == 1
13-
raise Puppet::ParseError, ("loadyaml(): wrong number of arguments (#{args.length}; must be 1)")
14-
end
15-
16-
if File.exists?(args[0]) then
17-
YAML.load_file(args[0])
17+
if File.exists?(args[0])
18+
begin
19+
YAML::load_file(args[0]) || args[1]
20+
rescue Exception => e
21+
if args[1]
22+
args[1]
23+
else
24+
raise e
25+
end
26+
end
1827
else
19-
warning("Can't load " + args[0] + ". File does not exist!")
20-
nil
28+
warning("Can't load '#{args[0]}' File does not exist!")
29+
args[1]
2130
end
2231

2332
end

spec/acceptance/loadjson_spec.rb

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#! /usr/bin/env ruby -S rspec
2+
require 'spec_helper_acceptance'
3+
4+
tmpdir = default.tmpdir('stdlib')
5+
6+
describe 'loadjson function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do
7+
describe 'success' do
8+
it 'loadjsons array of values' do
9+
shell("echo '{\"aaa\":1,\"bbb\":2,\"ccc\":3,\"ddd\":4}' > #{tmpdir}/testjson.json")
10+
pp = <<-EOS
11+
$o = loadjson('#{tmpdir}/testjson.json')
12+
notice(inline_template('loadjson[aaa] is <%= @o["aaa"].inspect %>'))
13+
notice(inline_template('loadjson[bbb] is <%= @o["bbb"].inspect %>'))
14+
notice(inline_template('loadjson[ccc] is <%= @o["ccc"].inspect %>'))
15+
notice(inline_template('loadjson[ddd] is <%= @o["ddd"].inspect %>'))
16+
EOS
17+
18+
apply_manifest(pp, :catch_failures => true) do |r|
19+
expect(r.stdout).to match(/loadjson\[aaa\] is 1/)
20+
expect(r.stdout).to match(/loadjson\[bbb\] is 2/)
21+
expect(r.stdout).to match(/loadjson\[ccc\] is 3/)
22+
expect(r.stdout).to match(/loadjson\[ddd\] is 4/)
23+
end
24+
end
25+
26+
it 'returns the default value if there is no file to load' do
27+
pp = <<-EOS
28+
$o = loadjson('#{tmpdir}/no-file.json', {'default' => 'value'})
29+
notice(inline_template('loadjson[default] is <%= @o["default"].inspect %>'))
30+
EOS
31+
32+
apply_manifest(pp, :catch_failures => true) do |r|
33+
expect(r.stdout).to match(/loadjson\[default\] is "value"/)
34+
end
35+
end
36+
37+
it 'returns the default value if the file was parsed with an error' do
38+
shell("echo '!' > #{tmpdir}/testjson.json")
39+
pp = <<-EOS
40+
$o = loadjson('#{tmpdir}/testjson.json', {'default' => 'value'})
41+
notice(inline_template('loadjson[default] is <%= @o["default"].inspect %>'))
42+
EOS
43+
44+
apply_manifest(pp, :catch_failures => true) do |r|
45+
expect(r.stdout).to match(/loadjson\[default\] is "value"/)
46+
end
47+
end
48+
end
49+
describe 'failure' do
50+
it 'fails with no arguments'
51+
end
52+
end

spec/acceptance/loadyaml_spec.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,29 @@
2626
expect(r.stdout).to match(/loadyaml\[ddd\] is 4/)
2727
end
2828
end
29+
30+
it 'returns the default value if there is no file to load' do
31+
pp = <<-EOS
32+
$o = loadyaml('#{tmpdir}/no-file.yaml', {'default' => 'value'})
33+
notice(inline_template('loadyaml[default] is <%= @o["default"].inspect %>'))
34+
EOS
35+
36+
apply_manifest(pp, :catch_failures => true) do |r|
37+
expect(r.stdout).to match(/loadyaml\[default\] is "value"/)
38+
end
39+
end
40+
41+
it 'returns the default value if the file was parsed with an error' do
42+
shell("echo '!' > #{tmpdir}/testyaml.yaml")
43+
pp = <<-EOS
44+
$o = loadyaml('#{tmpdir}/testyaml.yaml', {'default' => 'value'})
45+
notice(inline_template('loadyaml[default] is <%= @o["default"].inspect %>'))
46+
EOS
47+
48+
apply_manifest(pp, :catch_failures => true) do |r|
49+
expect(r.stdout).to match(/loadyaml\[default\] is "value"/)
50+
end
51+
end
2952
end
3053
describe 'failure' do
3154
it 'fails with no arguments'

spec/functions/loadjson_spec.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
require 'spec_helper'
2+
3+
describe 'loadjson' do
4+
it { is_expected.not_to eq(nil) }
5+
it { is_expected.to run.with_params().and_raise_error(ArgumentError, /wrong number of arguments/i) }
6+
7+
context 'when a non-existing file is specified' do
8+
let(:filename) { '/tmp/doesnotexist' }
9+
before {
10+
File.expects(:exists?).with(filename).returns(false).once
11+
PSON.expects(:load).never
12+
}
13+
it { is_expected.to run.with_params(filename, {'default' => 'value'}).and_return({'default' => 'value'}) }
14+
end
15+
16+
context 'when an existing file is specified' do
17+
let(:filename) { '/tmp/doesexist' }
18+
let(:data) { { 'key' => 'value' } }
19+
let(:json) { '{"key":"value"}' }
20+
before {
21+
File.expects(:exists?).with(filename).returns(true).once
22+
File.expects(:read).with(filename).returns(json).once
23+
PSON.expects(:load).with(json).returns(data).once
24+
}
25+
it { is_expected.to run.with_params(filename).and_return(data) }
26+
end
27+
28+
context 'when the file could not be parsed' do
29+
let(:filename) { '/tmp/doesexist' }
30+
let(:json) { '{"key":"value"}' }
31+
before {
32+
File.expects(:exists?).with(filename).returns(true).once
33+
File.expects(:read).with(filename).returns(json).once
34+
PSON.stubs(:load).with(json).once.raises StandardError, 'Something terrible have happened!'
35+
}
36+
it { is_expected.to run.with_params(filename, {'default' => 'value'}).and_return({'default' => 'value'}) }
37+
end
38+
end

spec/functions/loadyaml_spec.rb

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22

33
describe 'loadyaml' do
44
it { is_expected.not_to eq(nil) }
5-
it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) }
6-
it { is_expected.to run.with_params('', '').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) }
5+
it { is_expected.to run.with_params().and_raise_error(ArgumentError, /wrong number of arguments/i) }
6+
77
context 'when a non-existing file is specified' do
88
let(:filename) { '/tmp/doesnotexist' }
99
before {
1010
File.expects(:exists?).with(filename).returns(false).once
1111
YAML.expects(:load_file).never
1212
}
13-
it { is_expected.to run.with_params(filename).and_return(nil) }
13+
it { is_expected.to run.with_params(filename, {'default' => 'value'}).and_return({'default' => 'value'}) }
1414
end
15+
1516
context 'when an existing file is specified' do
1617
let(:filename) { '/tmp/doesexist' }
1718
let(:data) { { 'key' => 'value' } }
@@ -21,4 +22,13 @@
2122
}
2223
it { is_expected.to run.with_params(filename).and_return(data) }
2324
end
25+
26+
context 'when the file could not be parsed' do
27+
let(:filename) { '/tmp/doesexist' }
28+
before {
29+
File.expects(:exists?).with(filename).returns(true).once
30+
YAML.stubs(:load_file).with(filename).once.raises StandardError, 'Something terrible have happened!'
31+
}
32+
it { is_expected.to run.with_params(filename, {'default' => 'value'}).and_return({'default' => 'value'}) }
33+
end
2434
end

0 commit comments

Comments
 (0)