Skip to content
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
18 changes: 7 additions & 11 deletions lib/puppet-languageserver-sidecar/puppet_helper_puppetstrings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,9 @@ def self.retrieve_via_puppet_strings(cache, options = {})
object_types = options[:object_types].nil? ? available_documentation_types : options[:object_types]
object_types.select! { |i| available_documentation_types.include?(i) }

result = {}
result = PuppetLanguageServer::Sidecar::Protocol::AggregateMetadata.new
return result if object_types.empty?

result[:classes] = PuppetLanguageServer::Sidecar::Protocol::PuppetClassList.new if object_types.include?(:class)
result[:functions] = PuppetLanguageServer::Sidecar::Protocol::PuppetFunctionList.new if object_types.include?(:function)
result[:types] = PuppetLanguageServer::Sidecar::Protocol::PuppetTypeList.new if object_types.include?(:type)

current_env = current_environment
for_agent = options[:for_agent].nil? ? true : options[:for_agent]
loaders = Puppet::Pops::Loaders.new(current_env, for_agent)
Expand All @@ -74,25 +70,25 @@ def self.retrieve_via_puppet_strings(cache, options = {})
next if file_doc.nil?

if object_types.include?(:class) # rubocop:disable Style/IfUnlessModifier This reads better
file_doc.classes.each { |item| result[:classes] << item }
file_doc.classes.each { |item| result.append!(item) }
end
if object_types.include?(:function) # rubocop:disable Style/IfUnlessModifier This reads better
file_doc.functions.each { |item| result[:functions] << item }
file_doc.functions.each { |item| result.append!(item) }
end
if object_types.include?(:type)
file_doc.types.each do |item|
result[:types] << item unless name == 'whit' || name == 'component' # rubocop:disable Style/MultipleComparison
result.append!(item) unless name == 'whit' || name == 'component' # rubocop:disable Style/MultipleComparison
end
end
end

# Remove Puppet3 functions which have a Puppet4 function already loaded
if object_types.include?(:function)
pup4_functions = result[:functions].select { |i| i.function_version == 4 }.map { |i| i.key }
result[:functions].reject! { |i| i.function_version == 3 && pup4_functions.include?(i.key) }
pup4_functions = result.functions.select { |i| i.function_version == 4 }.map { |i| i.key }
result.functions.reject! { |i| i.function_version == 3 && pup4_functions.include?(i.key) }
end

result.each { |key, item| PuppetLanguageServerSidecar.log_message(:debug, "[PuppetHelper::retrieve_via_puppet_strings] Finished loading #{item.count} #{key}") }
result.each_list { |key, item| PuppetLanguageServerSidecar.log_message(:debug, "[PuppetHelper::retrieve_via_puppet_strings] Finished loading #{item.count} #{key}") }
result
end

Expand Down
2 changes: 1 addition & 1 deletion lib/puppet-languageserver-sidecar/puppet_strings_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ class FileDocumentation
attr_accessor :types

def initialize(path = nil)
@path = path
@path = path
@classes = PuppetLanguageServer::Sidecar::Protocol::PuppetClassList.new
@functions = PuppetLanguageServer::Sidecar::Protocol::PuppetFunctionList.new
@types = PuppetLanguageServer::Sidecar::Protocol::PuppetTypeList.new
Expand Down
83 changes: 79 additions & 4 deletions lib/puppet-languageserver/sidecar_protocol.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,7 @@ def child_type
end
end

class NodeGraph
include Base

class NodeGraph < BaseClass
attr_accessor :dot_content
attr_accessor :error_content

Expand Down Expand Up @@ -337,7 +335,7 @@ def child_type
end
end

class Resource
class Resource < BaseClass
attr_accessor :manifest

def to_h
Expand Down Expand Up @@ -365,6 +363,83 @@ def child_type
Resource
end
end

# This class is a little special as it contains a lot logic.
# In essence this is just wrapping a hash with specific methods for the
# the different types of metadata (classes, functions etc.)
class AggregateMetadata < BaseClass
def initialize
super
@aggregate = {}
end

def classes
@aggregate[:classes]
end

def functions
@aggregate[:functions]
end

def types
@aggregate[:types]
end

def append!(obj)
list_for_object_class(obj.class) << obj
end

def to_json(*options)
@aggregate.to_json(options)
end

def from_json!(json_string)
obj = JSON.parse(json_string)
obj.each do |key, value|
info = METADATA_LIST[key.intern]
next if info.nil?
list = list_for_object_class(info[:item_class])
value.each { |i| list << info[:item_class].new.from_h!(i) }
end
self
end

def each_list
return unless block_given?
@aggregate.each { |k, v| yield k, v }
end

private

# When adding a new metadata item:
# - Add to the information to this hash
# - Add a method to access the aggregate
METADATA_LIST = {
:classes => {
:item_class => PuppetClass,
:list_class => PuppetClassList
},
:functions => {
:item_class => PuppetFunction,
:list_class => PuppetFunctionList
},
:types => {
:item_class => PuppetType,
:list_class => PuppetTypeList
}
}.freeze

def list_for_object_class(klass)
METADATA_LIST.each do |name, info|
if klass == info[:item_class]
@aggregate[name] = info[:list_class].new if @aggregate[name].nil?
return @aggregate[name]
end
end

raise "Unknown object class #{klass.name}"
end
end
end
end
end
35 changes: 29 additions & 6 deletions lib/puppet_languageserver_sidecar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,13 @@ def self.require_gems(options)

ACTION_LIST = %w[
noop
default_aggregate
default_classes
default_functions
default_types
node_graph
resource_list
workspace_aggregate
workspace_classes
workspace_functions
workspace_types
Expand Down Expand Up @@ -258,26 +260,35 @@ def self.execute(options)
when 'noop'
[]

when 'default_aggregate'
cache = options[:disable_cache] ? PuppetLanguageServerSidecar::Cache::Null.new : PuppetLanguageServerSidecar::Cache::FileSystem.new
if use_puppet_strings
PuppetLanguageServerSidecar::PuppetHelper.retrieve_via_puppet_strings(cache, :object_types => PuppetLanguageServerSidecar::PuppetHelper.available_documentation_types)
else
log_message(:warn, 'The default_aggregate action is only supported with the puppetstrings feature flag')
{}
end

when 'default_classes'
cache = options[:disable_cache] ? PuppetLanguageServerSidecar::Cache::Null.new : PuppetLanguageServerSidecar::Cache::FileSystem.new
if use_puppet_strings
PuppetLanguageServerSidecar::PuppetHelper.retrieve_via_puppet_strings(cache, :object_types => [:class])[:classes]
PuppetLanguageServerSidecar::PuppetHelper.retrieve_via_puppet_strings(cache, :object_types => [:class]).classes
else
PuppetLanguageServerSidecar::PuppetHelper.retrieve_classes(cache)
end

when 'default_functions'
cache = options[:disable_cache] ? PuppetLanguageServerSidecar::Cache::Null.new : PuppetLanguageServerSidecar::Cache::FileSystem.new
if use_puppet_strings
PuppetLanguageServerSidecar::PuppetHelper.retrieve_via_puppet_strings(cache, :object_types => [:function])[:functions]
PuppetLanguageServerSidecar::PuppetHelper.retrieve_via_puppet_strings(cache, :object_types => [:function]).functions
else
PuppetLanguageServerSidecar::PuppetHelper.retrieve_functions(cache)
end

when 'default_types'
cache = options[:disable_cache] ? PuppetLanguageServerSidecar::Cache::Null.new : PuppetLanguageServerSidecar::Cache::FileSystem.new
if use_puppet_strings
PuppetLanguageServerSidecar::PuppetHelper.retrieve_via_puppet_strings(cache, :object_types => [:type])[:types]
PuppetLanguageServerSidecar::PuppetHelper.retrieve_via_puppet_strings(cache, :object_types => [:type]).types
else
PuppetLanguageServerSidecar::PuppetHelper.retrieve_types(cache)
end
Expand Down Expand Up @@ -307,14 +318,26 @@ def self.execute(options)
end
PuppetLanguageServerSidecar::PuppetHelper.get_puppet_resource(typename, title)

when 'workspace_aggregate'
return nil unless inject_workspace_as_module || inject_workspace_as_environment
cache = options[:disable_cache] ? PuppetLanguageServerSidecar::Cache::Null.new : PuppetLanguageServerSidecar::Cache::FileSystem.new
if use_puppet_strings
PuppetLanguageServerSidecar::PuppetHelper.retrieve_via_puppet_strings(cache,
:object_types => PuppetLanguageServerSidecar::PuppetHelper.available_documentation_types,
:root_path => PuppetLanguageServerSidecar::Workspace.root_path)
else
log_message(:warn, 'The workspace_aggregate action is only supported with the puppetstrings feature flag')
{}
end

when 'workspace_classes'
null_cache = PuppetLanguageServerSidecar::Cache::Null.new
return nil unless inject_workspace_as_module || inject_workspace_as_environment
if use_puppet_strings
cache = options[:disable_cache] ? PuppetLanguageServerSidecar::Cache::Null.new : PuppetLanguageServerSidecar::Cache::FileSystem.new
PuppetLanguageServerSidecar::PuppetHelper.retrieve_via_puppet_strings(cache,
:object_types => [:class],
:root_path => PuppetLanguageServerSidecar::Workspace.root_path)[:classes]
:root_path => PuppetLanguageServerSidecar::Workspace.root_path).classes
else
PuppetLanguageServerSidecar::PuppetHelper.retrieve_classes(null_cache,
:root_path => PuppetLanguageServerSidecar::Workspace.root_path)
Expand All @@ -328,7 +351,7 @@ def self.execute(options)
cache = options[:disable_cache] ? PuppetLanguageServerSidecar::Cache::Null.new : PuppetLanguageServerSidecar::Cache::FileSystem.new
PuppetLanguageServerSidecar::PuppetHelper.retrieve_via_puppet_strings(cache,
:object_types => [:function],
:root_path => PuppetLanguageServerSidecar::Workspace.root_path)[:functions]
:root_path => PuppetLanguageServerSidecar::Workspace.root_path).functions
else
PuppetLanguageServerSidecar::PuppetHelper.retrieve_functions(null_cache,
:root_path => PuppetLanguageServerSidecar::Workspace.root_path)
Expand All @@ -341,7 +364,7 @@ def self.execute(options)
cache = options[:disable_cache] ? PuppetLanguageServerSidecar::Cache::Null.new : PuppetLanguageServerSidecar::Cache::FileSystem.new
PuppetLanguageServerSidecar::PuppetHelper.retrieve_via_puppet_strings(cache,
:object_types => [:type],
:root_path => PuppetLanguageServerSidecar::Workspace.root_path)[:types]
:root_path => PuppetLanguageServerSidecar::Workspace.root_path).types
else
PuppetLanguageServerSidecar::PuppetHelper.retrieve_types(null_cache)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,37 @@ def expect_same_array_content(a, b)
end
end

describe 'when running default_aggregate action' do
let (:cmd_options) { ['--action', 'default_aggregate'] }

it 'should return a cachable deserializable aggregate object with all default metadata' do
expect_empty_cache

result = run_sidecar(cmd_options)
deserial = PuppetLanguageServer::Sidecar::Protocol::AggregateMetadata.new
expect { deserial.from_json!(result) }.to_not raise_error

# The contents of the result are tested later

# Now run using cached information
expect_populated_cache

result2 = run_sidecar(cmd_options)
deserial2 = PuppetLanguageServer::Sidecar::Protocol::AggregateMetadata.new()
expect { deserial2.from_json!(result2) }.to_not raise_error

deserial.class
.instance_methods(false)
.reject { |name| %i[to_json from_json! each_list append!].include?(name) }
.each do |method_name|
# There should be at least one item
expect(deserial.send(method_name).count).to be > 0
# Before and after should be the same
expect_same_array_content(deserial.send(method_name), deserial2.send(method_name))
end
end
end

describe 'when running default_classes action' do
let (:cmd_options) { ['--action', 'default_classes'] }

Expand Down Expand Up @@ -236,6 +267,37 @@ def expect_same_array_content(a, b)
end
end

describe 'when running workspace_aggregate action' do
let (:cmd_options) { ['--action', 'workspace_aggregate', '--local-workspace', workspace] }

it 'should return a cachable deserializable aggregate object with all default metadata' do
expect_empty_cache

result = run_sidecar(cmd_options)
deserial = PuppetLanguageServer::Sidecar::Protocol::AggregateMetadata.new
expect { deserial.from_json!(result) }.to_not raise_error

# The contents of the result are tested later

# Now run using cached information
expect_populated_cache

result2 = run_sidecar(cmd_options)
deserial2 = PuppetLanguageServer::Sidecar::Protocol::AggregateMetadata.new()
expect { deserial2.from_json!(result2) }.to_not raise_error

deserial.class
.instance_methods(false)
.reject { |name| %i[to_json from_json! each_list append!].include?(name) }
.each do |method_name|
# There should be at least one item
expect(deserial.send(method_name).count).to be > 0
# Before and after should be the same
expect_same_array_content(deserial.send(method_name), deserial2.send(method_name))
end
end
end

describe 'when running workspace_classes action' do
let (:cmd_options) { ['--action', 'workspace_classes', '--local-workspace', workspace] }

Expand Down Expand Up @@ -348,6 +410,37 @@ def expect_same_array_content(a, b)
end
end

describe 'when running workspace_aggregate action' do
let (:cmd_options) { ['--action', 'workspace_aggregate', '--local-workspace', workspace] }

it 'should return a cachable deserializable aggregate object with all default metadata' do
expect_empty_cache

result = run_sidecar(cmd_options)
deserial = PuppetLanguageServer::Sidecar::Protocol::AggregateMetadata.new
expect { deserial.from_json!(result) }.to_not raise_error

# The contents of the result are tested later

# Now run using cached information
expect_populated_cache

result2 = run_sidecar(cmd_options)
deserial2 = PuppetLanguageServer::Sidecar::Protocol::AggregateMetadata.new()
expect { deserial2.from_json!(result2) }.to_not raise_error

deserial.class
.instance_methods(false)
.reject { |name| %i[to_json from_json! each_list append!].include?(name) }
.each do |method_name|
# There should be at least one item
expect(deserial.send(method_name).count).to be > 0
# Before and after should be the same
expect_same_array_content(deserial.send(method_name), deserial2.send(method_name))
end
end
end

describe 'when running workspace_classes action' do
let (:cmd_options) { ['--action', 'workspace_classes', '--local-workspace', workspace] }

Expand Down
Loading