The `require_packages` function call is used to declare one or more packages a dependency for the current scope. at a high level the functions dose the following
With a starting manifest like:
```
lang=puppet
class {'foobar':
require_package('foo', 'bar')
file {'/etc/foobar.conf':
ensure => present,
}
service {'foobar':
ensure => running,
require => File[/etc/foobar.conf'],
}
}
class {'foobar': }
```
we end up, in the compiled catalogue, with something a bit more like this:
```
lang=puppet
class {'packages::foo':
package{'foo':
ensure => 'present'
}
}
class {'packages::bar':
package{'bar':
ensure => 'present'
}
}
class {'foobar':
file {'/etc/foobar.conf':
ensure => present,
}
service {'foobar':
ensure => running,
require => File[/etc/foobar.conf'],
}
}
class {'packages::foo':}
class {'packages::bar':}
class {'foobar':
require => Class['packages::foo', 'packages::bar'],
}
```
The other benefit of this function is that it also handles duplicate resources declarations, similar to the puppetlabs-stdlib `ensure_packages` function.
the require_packages function predates my time here however the initial commit message gives a good explanation for its intention and benefits over ensure_packages:
It's similar to ensure_packages(), but it's cleaner and faster. It takes a
single package name as an argument and it creates a virtual class that wraps it
and makes it a requirement for the current scope. We can use this to avoid
duplicate def'n errors for packages that may legitimately be specified in the
software stacks of multiple modules / roles.
However I'm not sure if theses claims are still valid. Specifically when compared to eunsure_packages:
* ensure_packages can now also take a single string or array of strings.
* The cleaner point is subjective however the ensure_packages function in stdlib has received some refactoring since require_package was initially merged
* I have not tested the faster claim
The thing that ensure_packages doesn't have is the ability to "create a virtual class that wraps [the package] and makes it a requirement for the current scope". Im ensure of the specific problem this was trying to resolve however in the early days of puppet dependency mapping was a bit of a pain and not necessarily intuitive as such dependencies where often missed. Puppet has improved this behavior somewhat by honoring manifest order when applying resources which reduces the need to explicitly define most dependencies and for complex dependencies that do need to be defined I believe it is clearer to explicitly define them. I also feel that this function is rather un-standard (i.e. dynamic resource creation and catalogue manipulation) and causes unexpected results when looking at the raw catalogue.
As such and assuming i havn;t missed something, i propose working towards dropping `require_packages` from wmflib and migrating to ensure_packages.
Taking the foobar class a migration to ensure_packages would look as follows
```
lang=puppet
class {'foobar':
$packages = ['foo', 'bar']
ensure_packages($packages)
file {'/etc/foobar.conf':
ensure => present,
require => Package[$packages]
}
service {'foobar':
ensure => running,
require => File[/etc/foobar.conf'],
}
}
class {'foobar': }
```
tagging @Joe/@akosiaris to correct anything i may have got wrong or what i may have missed