Skip to content

Add stdlib::has_function #1386

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions lib/puppet/functions/stdlib/has_function.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

# @summary
# Returns whether the Puppet runtime has access to a given function.
#
# @example Using stdlib::has_function()
# stdlib::has_function('stdlib::has_function') # true
# stdlib::has_function('not_a_function') # false
#
# Determines whether the Puppet runtime has access to a function by the
# name provided.
#
# @return
# Returns true if the provided function name is available, false otherwise.
#
Puppet::Functions.create_function(:'stdlib::has_function', Puppet::Functions::InternalFunction) do
dispatch :has_function do
scope_param
param 'String[1]', :function_name
return_type 'Boolean'
end

def has_function(scope, function_name) # rubocop:disable Naming/PredicateName
loaders = scope.compiler.loaders
loader = loaders.private_environment_loader
return true unless loader&.load(:function, function_name).nil?

# If the loader cannot find the function it might be
# a 3x-style function stubbed in on-the-fly for testing.
func_3x = Puppet::Parser::Functions.function(function_name.to_sym)
func_3x.is_a?(String) && !func_3x.empty?
end
end
36 changes: 36 additions & 0 deletions spec/functions/has_function_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# frozen_string_literal: true

require 'spec_helper'

describe 'stdlib::has_function' do
let(:pre_condition) { 'function puppet_func {}' }

before(:each) do
Puppet::Parser::Functions.newfunction(:test_3x_func) do |_args|
true
end
end

it { is_expected.not_to be_nil }

# Itself, a namespaced function:
it { is_expected.to run.with_params('stdlib::has_function').and_return(true) }

# A namespaced function which does not exist:
it { is_expected.to run.with_params('stdlib::not_a_function').and_return(false) }

# A top-function which does not exist:
it { is_expected.to run.with_params('not_a_function').and_return(false) }

# A Puppet core function:
it { is_expected.to run.with_params('assert_type').and_return(true) }

# A Puppet function stubbed during testing:
it { is_expected.to run.with_params('puppet_func').and_return(true) }

# A file-loaded 3x style function in stdlib:
it { is_expected.to run.with_params('validate_augeas').and_return(true) }

# A stubbed 3x-style function:
it { is_expected.to run.with_params('test_3x_func').and_return(true) }
end