Skip to content

Commit cd6ec5f

Browse files
committed
Make ensure_packages work with ensure => present
This unbreaks the breaking change made in #1196 Also refactored to create a separate dispatch method for the case when `packages` is a `Hash`, and having that call the main `ensure_packages` method. This simplifies the code by only ever calling `ensure_resource` instead of calling `ensure_resources` for hashes. Defaulting `default_attributes` to an empty hash instead of `nil` in the method signatures further simplifies the code. Fixes #1252
1 parent ef733aa commit cd6ec5f

File tree

2 files changed

+75
-15
lines changed

2 files changed

+75
-15
lines changed

lib/puppet/functions/ensure_packages.rb

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,56 @@
66
# third argument to the ensure_resource() function.
77
Puppet::Functions.create_function(:ensure_packages, Puppet::Functions::InternalFunction) do
88
# @param packages
9-
# The packages to ensure are installed. If it's a Hash it will be passed to `ensure_resource`
9+
# The packages to ensure are installed.
1010
# @param default_attributes
1111
# Default attributes to be passed to the `ensure_resource()` function
1212
# @return [Undef] Returns nothing.
1313
dispatch :ensure_packages do
1414
scope_param
15-
param 'Variant[String[1], Array[String[1]], Hash[String[1], Any]]', :packages
15+
param 'Variant[String[1], Array[String[1]]]', :packages
1616
optional_param 'Hash', :default_attributes
1717
return_type 'Undef'
1818
end
1919

20-
def ensure_packages(scope, packages, default_attributes = nil)
21-
if default_attributes
20+
# @param packages
21+
# The packages to ensure are installed. The keys are packages and values are the attributes specific to that package.
22+
# @param default_attributes
23+
# Default attributes. Package specific attributes from the `packages` parameter will take precedence.
24+
# @return [Undef] Returns nothing.
25+
dispatch :ensure_packages_hash do
26+
scope_param
27+
param 'Hash[String[1], Any]', :packages
28+
optional_param 'Hash', :default_attributes
29+
return_type 'Undef'
30+
end
31+
32+
def ensure_packages(scope, packages, default_attributes = {})
33+
Array(packages).each do |package_name|
2234
defaults = { 'ensure' => 'installed' }.merge(default_attributes)
23-
if defaults['ensure'] == 'present'
24-
defaults['ensure'] = 'installed'
25-
end
26-
else
27-
defaults = { 'ensure' => 'installed' }
35+
36+
# `present` and `installed` are aliases for the `ensure` attribute. If `ensure` is set to either of these values replace
37+
# with `installed` by default but `present` if this package is already in the catalog with `ensure => present`
38+
defaults['ensure'] = default_ensure(package_name) if ['present', 'installed'].include?(defaults['ensure'])
39+
40+
scope.call_function('ensure_resource', ['package', package_name, defaults])
2841
end
42+
nil
43+
end
2944

30-
if packages.is_a?(Hash)
31-
scope.call_function('ensure_resources', ['package', packages.dup, defaults])
32-
else
33-
Array(packages).each do |package_name|
34-
scope.call_function('ensure_resource', ['package', package_name, defaults])
35-
end
45+
def ensure_packages_hash(scope, packages, default_attributes = {})
46+
packages.each do |package, attributes|
47+
ensure_packages(scope, package, default_attributes.merge(attributes))
3648
end
3749
nil
3850
end
51+
52+
private
53+
54+
def default_ensure(package_name)
55+
if call_function('defined_with_params', "Package[#{package_name}]", { 'ensure' => 'present' })
56+
'present'
57+
else
58+
'installed'
59+
end
60+
end
3961
end

spec/functions/ensure_packages_spec.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@
3232
subject.execute({ 'foo' => { 'provider' => 'rpm' }, 'bar' => { 'provider' => 'gem' } }, 'ensure' => 'present')
3333
subject.execute('パッケージ' => { 'ensure' => 'absent' })
3434
subject.execute('ρǻ¢κầģẻ' => { 'ensure' => 'absent' })
35+
subject.execute(
36+
{
37+
'package_one' => {},
38+
'package_two' => {},
39+
'package_three' => { 'provider' => 'puppetserver_gem' },
40+
},
41+
{ 'provider' => 'puppet_gem' },
42+
)
3543
end
3644

3745
# this lambda is required due to strangeness within rspec-puppet's expectation handling
@@ -42,6 +50,14 @@
4250
it { expect(-> { catalogue }).to contain_package('パッケージ').with('ensure' => 'absent') }
4351
it { expect(-> { catalogue }).to contain_package('ρǻ¢κầģẻ').with('ensure' => 'absent') }
4452
end
53+
54+
describe 'default attributes' do
55+
it 'package specific attributes take precedence' do
56+
expect(-> { catalogue }).to contain_package('package_one').with('provider' => 'puppet_gem')
57+
expect(-> { catalogue }).to contain_package('package_two').with('provider' => 'puppet_gem')
58+
expect(-> { catalogue }).to contain_package('package_three').with('provider' => 'puppetserver_gem')
59+
end
60+
end
4561
end
4662

4763
context 'when given a catalog with "package { puppet: ensure => installed }"' do
@@ -54,4 +70,26 @@
5470
it { expect(-> { catalogue }).to contain_package('puppet').with_ensure('installed') }
5571
end
5672
end
73+
74+
context 'when given a catalog with "package { puppet: ensure => present }"' do
75+
let(:pre_condition) { 'package { puppet: ensure => present }' }
76+
77+
describe 'after running ensure_package("puppet", { "ensure" => "present" })' do
78+
before(:each) { subject.execute('puppet', 'ensure' => 'present') }
79+
80+
it { expect(-> { catalogue }).to contain_package('puppet').with_ensure('present') }
81+
end
82+
83+
describe 'after running ensure_package("puppet", { "ensure" => "installed" })' do
84+
before(:each) { subject.execute('puppet', 'ensure' => 'installed') }
85+
86+
it { expect(-> { catalogue }).to contain_package('puppet').with_ensure('present') }
87+
end
88+
89+
describe 'after running ensure_package(["puppet"])' do
90+
before(:each) { subject.execute(['puppet']) }
91+
92+
it { expect(-> { catalogue }).to contain_package('puppet').with_ensure('present') }
93+
end
94+
end
5795
end

0 commit comments

Comments
 (0)