Skip to content

Commit

Permalink
(puppetlabsGH-121) Load Puppet 4 Functions as version 3 into the sidecar
Browse files Browse the repository at this point in the history
Previously only Puppet 3 API functions were loaded.  This commit monkey
patches and tracks the Puppet 4 API function creator.  The function enumerator
is then expanded to also resolve Puppet 4 API functions.
  • Loading branch information
glennsarti committed Apr 15, 2019
1 parent 5c4dad7 commit ec4a065
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
7 changes: 7 additions & 0 deletions lib/puppet-languageserver-sidecar/puppet_helper_pup4api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,13 @@ def self.retrieve_via_pup4_api(_cache, options = {})
obj = PuppetLanguageServerSidecar::Protocol::PuppetFunction.from_puppet(name, item)
result[:functions] << obj
end
# Enumerate V4 Functions from the monkey patching
Puppet::Functions.monkey_function_list
.select { |_k, i| path_has_child?(options[:root_path], i[:source_location][:source]) }
.each do |name, item|
obj = PuppetLanguageServerSidecar::Protocol::PuppetFunction.from_puppet(name, item)
result[:functions] << obj
end
PuppetLanguageServerSidecar.log_message(:debug, "[PuppetHelper::retrieve_via_pup4_api] Finished loading #{result[:functions].count} functions")
end

Expand Down
45 changes: 45 additions & 0 deletions lib/puppet-languageserver-sidecar/puppet_monkey_patches_pup4api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,51 @@ def monkey_function_list
end
end

# Monkey Patch 4.x functions so where know where they were loaded from
module Puppet
module Functions
class << self
alias_method :original_create_function, :create_function
end

def self.create_function(func_name, function_base = Function, &block)
# See if we've hooked elsewhere. This can happen while in debuggers (pry). If we're not in the previous caller
# stack then just use the last caller
monkey_index = Kernel.caller_locations.find_index { |loc| loc.label == 'create_function' && loc.path.match(/puppet_monkey_patches_pup4api\.rb/) }
monkey_index = -1 if monkey_index.nil?
caller = Kernel.caller_locations[monkey_index + 1]
# Call the original new function method
result = original_create_function(func_name, function_base, &block)
monkey_append_function_info(result.name, result,
:source_location => {
:source => caller.absolute_path,
:line => caller.lineno - 1 # Convert to a zero based line number system
})

result
end

def self.monkey_clear_function_info
@monkey_function_list = {}
end

def self.monkey_append_function_info(name, func, options = {})
@monkey_function_list = {} if @monkey_function_list.nil?
@monkey_function_list[name] = {
:arity => func.signatures.empty? ? -1 : func.signatures[0].args_range[0], # Fake the arity parameter
:name => name,
:type => :rvalue, # All Puppet 4 functions return a value
:doc => nil # Docs are filled in post processing via Yard
}.merge(options)
end

def self.monkey_function_list
@monkey_function_list = {} if @monkey_function_list.nil?
@monkey_function_list.clone
end
end
end

# Add an additional method on Puppet Types to store their source location
require 'puppet/type'
module Puppet
Expand Down

0 comments on commit ec4a065

Please sign in to comment.