puppet-editor-services 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +510 -0
- data/CODEOWNERS +2 -0
- data/CODE_OF_CONDUCT.md +46 -0
- data/CONTRIBUTING.md +54 -0
- data/Gemfile +53 -0
- data/LICENSE +201 -0
- data/README.md +308 -0
- data/Rakefile +185 -0
- data/bin/puppet-debugserver +8 -0
- data/bin/puppet-languageserver +7 -0
- data/bin/puppet-languageserver-sidecar +7 -0
- data/lib/dsp/dsp.rb +7 -0
- data/lib/dsp/dsp_base.rb +62 -0
- data/lib/dsp/dsp_protocol.rb +4619 -0
- data/lib/lsp/lsp.rb +10 -0
- data/lib/lsp/lsp_base.rb +63 -0
- data/lib/lsp/lsp_custom.rb +170 -0
- data/lib/lsp/lsp_enums.rb +143 -0
- data/lib/lsp/lsp_protocol.rb +2785 -0
- data/lib/lsp/lsp_protocol_callhierarchy.proposed.rb +239 -0
- data/lib/lsp/lsp_protocol_colorprovider.rb +100 -0
- data/lib/lsp/lsp_protocol_configuration.rb +82 -0
- data/lib/lsp/lsp_protocol_declaration.rb +73 -0
- data/lib/lsp/lsp_protocol_foldingrange.rb +129 -0
- data/lib/lsp/lsp_protocol_implementation.rb +75 -0
- data/lib/lsp/lsp_protocol_progress.rb +200 -0
- data/lib/lsp/lsp_protocol_selectionrange.rb +79 -0
- data/lib/lsp/lsp_protocol_sematictokens.proposed.rb +340 -0
- data/lib/lsp/lsp_protocol_typedefinition.rb +75 -0
- data/lib/lsp/lsp_protocol_workspacefolders.rb +174 -0
- data/lib/lsp/lsp_types.rb +1534 -0
- data/lib/puppet-debugserver/debug_session/break_points.rb +137 -0
- data/lib/puppet-debugserver/debug_session/flow_control.rb +161 -0
- data/lib/puppet-debugserver/debug_session/hook_handlers.rb +295 -0
- data/lib/puppet-debugserver/debug_session/puppet_session_run_mode.rb +66 -0
- data/lib/puppet-debugserver/debug_session/puppet_session_state.rb +122 -0
- data/lib/puppet-debugserver/hooks.rb +132 -0
- data/lib/puppet-debugserver/message_handler.rb +277 -0
- data/lib/puppet-debugserver/puppet_debug_session.rb +541 -0
- data/lib/puppet-debugserver/puppet_monkey_patches.rb +118 -0
- data/lib/puppet-languageserver/client_session_state.rb +119 -0
- data/lib/puppet-languageserver/crash_dump.rb +50 -0
- data/lib/puppet-languageserver/epp/validation_provider.rb +34 -0
- data/lib/puppet-languageserver/facter_helper.rb +25 -0
- data/lib/puppet-languageserver/global_queues/sidecar_queue.rb +205 -0
- data/lib/puppet-languageserver/global_queues/single_instance_queue.rb +126 -0
- data/lib/puppet-languageserver/global_queues/validation_queue.rb +102 -0
- data/lib/puppet-languageserver/global_queues.rb +16 -0
- data/lib/puppet-languageserver/manifest/completion_provider.rb +331 -0
- data/lib/puppet-languageserver/manifest/definition_provider.rb +99 -0
- data/lib/puppet-languageserver/manifest/document_symbol_provider.rb +228 -0
- data/lib/puppet-languageserver/manifest/folding_provider.rb +226 -0
- data/lib/puppet-languageserver/manifest/format_on_type_provider.rb +143 -0
- data/lib/puppet-languageserver/manifest/hover_provider.rb +221 -0
- data/lib/puppet-languageserver/manifest/signature_provider.rb +169 -0
- data/lib/puppet-languageserver/manifest/validation_provider.rb +127 -0
- data/lib/puppet-languageserver/message_handler.rb +462 -0
- data/lib/puppet-languageserver/providers.rb +18 -0
- data/lib/puppet-languageserver/puppet_helper.rb +108 -0
- data/lib/puppet-languageserver/puppet_lexer_helper.rb +55 -0
- data/lib/puppet-languageserver/puppet_monkey_patches.rb +39 -0
- data/lib/puppet-languageserver/puppet_parser_helper.rb +212 -0
- data/lib/puppet-languageserver/puppetfile/validation_provider.rb +185 -0
- data/lib/puppet-languageserver/server_capabilities.rb +48 -0
- data/lib/puppet-languageserver/session_state/document_store.rb +272 -0
- data/lib/puppet-languageserver/session_state/language_client.rb +239 -0
- data/lib/puppet-languageserver/session_state/object_cache.rb +162 -0
- data/lib/puppet-languageserver/sidecar_protocol.rb +532 -0
- data/lib/puppet-languageserver/uri_helper.rb +46 -0
- data/lib/puppet-languageserver-sidecar/cache/base.rb +36 -0
- data/lib/puppet-languageserver-sidecar/cache/filesystem.rb +111 -0
- data/lib/puppet-languageserver-sidecar/cache/null.rb +27 -0
- data/lib/puppet-languageserver-sidecar/facter_helper.rb +41 -0
- data/lib/puppet-languageserver-sidecar/puppet_environment_monkey_patches.rb +52 -0
- data/lib/puppet-languageserver-sidecar/puppet_helper.rb +281 -0
- data/lib/puppet-languageserver-sidecar/puppet_modulepath_monkey_patches.rb +146 -0
- data/lib/puppet-languageserver-sidecar/puppet_monkey_patches.rb +9 -0
- data/lib/puppet-languageserver-sidecar/puppet_parser_helper.rb +77 -0
- data/lib/puppet-languageserver-sidecar/puppet_strings_helper.rb +399 -0
- data/lib/puppet-languageserver-sidecar/puppet_strings_monkey_patches.rb +16 -0
- data/lib/puppet-languageserver-sidecar/sidecar_protocol_extensions.rb +16 -0
- data/lib/puppet-languageserver-sidecar/workspace.rb +89 -0
- data/lib/puppet_debugserver.rb +164 -0
- data/lib/puppet_editor_services/connection/base.rb +62 -0
- data/lib/puppet_editor_services/connection/stdio.rb +25 -0
- data/lib/puppet_editor_services/connection/tcp.rb +34 -0
- data/lib/puppet_editor_services/handler/base.rb +16 -0
- data/lib/puppet_editor_services/handler/debug_adapter.rb +63 -0
- data/lib/puppet_editor_services/handler/json_rpc.rb +133 -0
- data/lib/puppet_editor_services/logging.rb +45 -0
- data/lib/puppet_editor_services/protocol/base.rb +27 -0
- data/lib/puppet_editor_services/protocol/debug_adapter.rb +135 -0
- data/lib/puppet_editor_services/protocol/debug_adapter_messages.rb +171 -0
- data/lib/puppet_editor_services/protocol/json_rpc.rb +241 -0
- data/lib/puppet_editor_services/protocol/json_rpc_messages.rb +200 -0
- data/lib/puppet_editor_services/server/base.rb +42 -0
- data/lib/puppet_editor_services/server/stdio.rb +85 -0
- data/lib/puppet_editor_services/server/tcp.rb +349 -0
- data/lib/puppet_editor_services/server.rb +15 -0
- data/lib/puppet_editor_services/version.rb +36 -0
- data/lib/puppet_editor_services.rb +8 -0
- data/lib/puppet_languageserver.rb +263 -0
- data/lib/puppet_languageserver_sidecar.rb +361 -0
- data/puppet-debugserver +11 -0
- data/puppet-editor-services.gemspec +29 -0
- data/puppet-languageserver +15 -0
- data/puppet-languageserver-sidecar +14 -0
- metadata +240 -0
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PuppetLanguageServer
|
|
4
|
+
module Sidecar
|
|
5
|
+
module Protocol
|
|
6
|
+
module Base
|
|
7
|
+
def to_json(*_options)
|
|
8
|
+
raise NotImplementedError
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def from_json!(_json_string)
|
|
12
|
+
raise NotImplementedError
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class ActionParams < Hash
|
|
17
|
+
include Base
|
|
18
|
+
|
|
19
|
+
def to_json(*options)
|
|
20
|
+
::JSON.generate(to_h, options)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def from_json!(json_string)
|
|
24
|
+
obj = ::JSON.parse(json_string)
|
|
25
|
+
obj.each do |key, value|
|
|
26
|
+
self[key] = value
|
|
27
|
+
end
|
|
28
|
+
self
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class BaseClass
|
|
33
|
+
include Base
|
|
34
|
+
|
|
35
|
+
def to_json(*options)
|
|
36
|
+
to_h.to_json(options)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def from_json!(json_string)
|
|
40
|
+
from_h!(::JSON.parse(json_string))
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def ==(other)
|
|
44
|
+
return false unless other.class == self.class
|
|
45
|
+
|
|
46
|
+
self.class
|
|
47
|
+
.instance_methods(false)
|
|
48
|
+
.reject { |name| name.to_s.end_with?('=', '!') }
|
|
49
|
+
.reject { |name| %i[to_h to_json].include?(name) }
|
|
50
|
+
.each do |method_name|
|
|
51
|
+
return false unless send(method_name) == other.send(method_name)
|
|
52
|
+
end
|
|
53
|
+
true
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def eql?(other)
|
|
57
|
+
return false unless other.class == self.class
|
|
58
|
+
|
|
59
|
+
self.class
|
|
60
|
+
.instance_methods(false)
|
|
61
|
+
.reject { |name| name.to_s.end_with?('=', '!') }
|
|
62
|
+
.reject { |name| %i[to_h to_json].include?(name) }
|
|
63
|
+
.each do |method_name|
|
|
64
|
+
return false unless send(method_name).eql?(other.send(method_name))
|
|
65
|
+
end
|
|
66
|
+
true
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def hash
|
|
70
|
+
props = self.class
|
|
71
|
+
.instance_methods(false)
|
|
72
|
+
.reject { |name| name.to_s.end_with?('=', '!') }
|
|
73
|
+
.reject { |name| %i[to_h to_json].include?(name) }
|
|
74
|
+
.map do |method_name|
|
|
75
|
+
send(method_name).hash
|
|
76
|
+
end
|
|
77
|
+
props.hash
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# key => Unique name of the object
|
|
82
|
+
# calling_source => The file that was invoked to create the object
|
|
83
|
+
# source => The file that _actually_ created the object
|
|
84
|
+
# line => The line number in the source file where the object was created
|
|
85
|
+
# char => The character number in the source file where the object was created
|
|
86
|
+
# length => The length of characters from `char` in the source file where the object was created
|
|
87
|
+
class BasePuppetObject < BaseClass
|
|
88
|
+
attr_accessor :key, :calling_source, :source, :line, :char, :length
|
|
89
|
+
|
|
90
|
+
def to_h
|
|
91
|
+
{
|
|
92
|
+
'key' => key,
|
|
93
|
+
'calling_source' => calling_source,
|
|
94
|
+
'source' => source,
|
|
95
|
+
'line' => line,
|
|
96
|
+
'char' => char,
|
|
97
|
+
'length' => length
|
|
98
|
+
}
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def from_h!(value)
|
|
102
|
+
self.key = value['key'].nil? ? nil : value['key'].intern
|
|
103
|
+
self.calling_source = value['calling_source']
|
|
104
|
+
self.source = value['source']
|
|
105
|
+
self.line = value['line']
|
|
106
|
+
self.char = value['char']
|
|
107
|
+
self.length = value['length']
|
|
108
|
+
self
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
private
|
|
112
|
+
|
|
113
|
+
def value_from_hash(hash, key)
|
|
114
|
+
# The key could be a Symbol or String in the hash
|
|
115
|
+
hash[key].nil? ? hash[key.to_s] : hash[key]
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
class BasePuppetObjectList < Array
|
|
120
|
+
include Base
|
|
121
|
+
|
|
122
|
+
def to_json(*options)
|
|
123
|
+
"[#{map { |item| item.to_json(options) }.join(',')}]"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def from_json!(json_string)
|
|
127
|
+
obj = ::JSON.parse(json_string)
|
|
128
|
+
obj.each do |child_hash|
|
|
129
|
+
child = child_type.new
|
|
130
|
+
self << child.from_h!(child_hash)
|
|
131
|
+
end
|
|
132
|
+
self
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def child_type
|
|
136
|
+
Object
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
class PuppetNodeGraph < BaseClass
|
|
141
|
+
attr_accessor :vertices, :edges, :error_content
|
|
142
|
+
|
|
143
|
+
def to_json(*options)
|
|
144
|
+
{
|
|
145
|
+
'vertices' => vertices,
|
|
146
|
+
'edges' => edges,
|
|
147
|
+
'error_content' => error_content
|
|
148
|
+
}.to_json(options)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def from_json!(json_string)
|
|
152
|
+
obj = ::JSON.parse(json_string)
|
|
153
|
+
self.vertices = obj['vertices']
|
|
154
|
+
self.edges = obj['edges']
|
|
155
|
+
self.error_content = obj['error_content']
|
|
156
|
+
self
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
class PuppetClass < BasePuppetObject
|
|
161
|
+
attr_accessor :parameters, :doc
|
|
162
|
+
|
|
163
|
+
def to_h
|
|
164
|
+
super.to_h.merge(
|
|
165
|
+
'doc' => doc,
|
|
166
|
+
'parameters' => parameters
|
|
167
|
+
)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def from_h!(value)
|
|
171
|
+
super
|
|
172
|
+
|
|
173
|
+
self.doc = value['doc']
|
|
174
|
+
self.parameters = {}
|
|
175
|
+
unless value['parameters'].nil?
|
|
176
|
+
value['parameters'].each do |attr_name, obj_attr|
|
|
177
|
+
# TODO: This should be a class, not a hash
|
|
178
|
+
parameters[attr_name] = {
|
|
179
|
+
type: value_from_hash(obj_attr, :type),
|
|
180
|
+
doc: value_from_hash(obj_attr, :doc)
|
|
181
|
+
}
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
self
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
class PuppetClassList < BasePuppetObjectList
|
|
189
|
+
def child_type
|
|
190
|
+
PuppetClass
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
class PuppetDataType < BasePuppetObject
|
|
195
|
+
attr_accessor :doc, :alias_of, :attributes, :is_type_alias
|
|
196
|
+
|
|
197
|
+
def initialize
|
|
198
|
+
super
|
|
199
|
+
self.attributes = PuppetDataTypeAttributeList.new
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def to_h
|
|
203
|
+
super.to_h.merge(
|
|
204
|
+
'doc' => doc,
|
|
205
|
+
'alias_of' => alias_of,
|
|
206
|
+
'attributes' => attributes.map(&:to_h),
|
|
207
|
+
'is_type_alias' => is_type_alias
|
|
208
|
+
)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def from_h!(value)
|
|
212
|
+
super
|
|
213
|
+
|
|
214
|
+
self.doc = value['doc']
|
|
215
|
+
self.alias_of = value['alias_of']
|
|
216
|
+
value['attributes'].each { |attr| attributes << PuppetDataTypeAttribute.new.from_h!(attr) } unless value['attributes'].nil?
|
|
217
|
+
self.is_type_alias = value['is_type_alias']
|
|
218
|
+
self
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
class PuppetDataTypeList < BasePuppetObjectList
|
|
223
|
+
def child_type
|
|
224
|
+
PuppetDataType
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
class PuppetDataTypeAttribute < BaseClass
|
|
229
|
+
attr_accessor :key, :doc, :default_value, :types
|
|
230
|
+
|
|
231
|
+
def to_h
|
|
232
|
+
{
|
|
233
|
+
'key' => key,
|
|
234
|
+
'default_value' => default_value,
|
|
235
|
+
'doc' => doc,
|
|
236
|
+
'types' => types
|
|
237
|
+
}
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def from_h!(value)
|
|
241
|
+
self.key = value['key']
|
|
242
|
+
self.default_value = value['default_value']
|
|
243
|
+
self.doc = value['doc']
|
|
244
|
+
self.types = value['types']
|
|
245
|
+
self
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
class PuppetDataTypeAttributeList < BasePuppetObjectList
|
|
250
|
+
def child_type
|
|
251
|
+
PuppetDataTypeAttribute
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
class PuppetFunction < BasePuppetObject
|
|
256
|
+
attr_accessor :doc, :signatures
|
|
257
|
+
# The version of this function, typically 3 or 4.
|
|
258
|
+
attr_accessor :function_version
|
|
259
|
+
|
|
260
|
+
def initialize
|
|
261
|
+
super
|
|
262
|
+
self.signatures = PuppetFunctionSignatureList.new
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
def to_h
|
|
266
|
+
super.to_h.merge(
|
|
267
|
+
'doc' => doc,
|
|
268
|
+
'function_version' => function_version,
|
|
269
|
+
'signatures' => signatures.map(&:to_h)
|
|
270
|
+
)
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def from_h!(value)
|
|
274
|
+
super
|
|
275
|
+
|
|
276
|
+
self.doc = value['doc']
|
|
277
|
+
self.function_version = value['function_version']
|
|
278
|
+
value['signatures'].each { |sig| signatures << PuppetFunctionSignature.new.from_h!(sig) } unless value['signatures'].nil?
|
|
279
|
+
self
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
class PuppetFunctionList < BasePuppetObjectList
|
|
284
|
+
def child_type
|
|
285
|
+
PuppetFunction
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
class PuppetFunctionSignature < BaseClass
|
|
290
|
+
attr_accessor :key, :doc, :return_types, :parameters
|
|
291
|
+
|
|
292
|
+
def initialize
|
|
293
|
+
super
|
|
294
|
+
self.parameters = PuppetFunctionSignatureParameterList.new
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
def to_h
|
|
298
|
+
{
|
|
299
|
+
'key' => key,
|
|
300
|
+
'doc' => doc,
|
|
301
|
+
'return_types' => return_types,
|
|
302
|
+
'parameters' => parameters.map(&:to_h)
|
|
303
|
+
}
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def from_h!(value)
|
|
307
|
+
self.key = value['key']
|
|
308
|
+
self.doc = value['doc']
|
|
309
|
+
self.return_types = value['return_types']
|
|
310
|
+
value['parameters'].each { |param| parameters << PuppetFunctionSignatureParameter.new.from_h!(param) } unless value['parameters'].nil?
|
|
311
|
+
self
|
|
312
|
+
end
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
class PuppetFunctionSignatureList < BasePuppetObjectList
|
|
316
|
+
def child_type
|
|
317
|
+
PuppetFunctionSignature
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
class PuppetFunctionSignatureParameter < BaseClass
|
|
322
|
+
attr_accessor :name, :types, :doc, :signature_key_offset, :signature_key_length # Zero based offset where this parameter exists in the signature key # The length of text where this parameter exists in the signature key
|
|
323
|
+
|
|
324
|
+
def to_h
|
|
325
|
+
{
|
|
326
|
+
'name' => name,
|
|
327
|
+
'doc' => doc,
|
|
328
|
+
'types' => types,
|
|
329
|
+
'signature_key_offset' => signature_key_offset,
|
|
330
|
+
'signature_key_length' => signature_key_length
|
|
331
|
+
}
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
def from_h!(value)
|
|
335
|
+
self.name = value['name']
|
|
336
|
+
self.doc = value['doc']
|
|
337
|
+
self.types = value['types']
|
|
338
|
+
self.signature_key_offset = value['signature_key_offset']
|
|
339
|
+
self.signature_key_length = value['signature_key_length']
|
|
340
|
+
self
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
class PuppetFunctionSignatureParameterList < BasePuppetObjectList
|
|
345
|
+
def child_type
|
|
346
|
+
PuppetFunctionSignatureParameter
|
|
347
|
+
end
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
class PuppetType < BasePuppetObject
|
|
351
|
+
attr_accessor :doc, :attributes
|
|
352
|
+
|
|
353
|
+
def to_h
|
|
354
|
+
super.to_h.merge(
|
|
355
|
+
'doc' => doc,
|
|
356
|
+
'attributes' => attributes
|
|
357
|
+
)
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
def from_h!(value)
|
|
361
|
+
super
|
|
362
|
+
|
|
363
|
+
self.doc = value['doc']
|
|
364
|
+
self.attributes = {}
|
|
365
|
+
unless value['attributes'].nil?
|
|
366
|
+
value['attributes'].each do |attr_name, obj_attr|
|
|
367
|
+
attributes[attr_name.intern] = {
|
|
368
|
+
# TODO: This should be a class, not a hash
|
|
369
|
+
type: value_from_hash(obj_attr, :type).intern,
|
|
370
|
+
doc: value_from_hash(obj_attr, :doc),
|
|
371
|
+
required?: value_from_hash(obj_attr, :required?),
|
|
372
|
+
isnamevar?: value_from_hash(obj_attr, :isnamevar?)
|
|
373
|
+
}
|
|
374
|
+
end
|
|
375
|
+
end
|
|
376
|
+
self
|
|
377
|
+
end
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
class PuppetTypeList < BasePuppetObjectList
|
|
381
|
+
def child_type
|
|
382
|
+
PuppetType
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
class Resource < BaseClass
|
|
387
|
+
attr_accessor :manifest
|
|
388
|
+
|
|
389
|
+
def to_h
|
|
390
|
+
{
|
|
391
|
+
'manifest' => manifest
|
|
392
|
+
}
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
def from_h!(value)
|
|
396
|
+
self.manifest = value['manifest']
|
|
397
|
+
self
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
def to_json(*options)
|
|
401
|
+
to_h.to_json(options)
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
def from_json!(json_string)
|
|
405
|
+
from_h!(::JSON.parse(json_string))
|
|
406
|
+
end
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
class ResourceList < BasePuppetObjectList
|
|
410
|
+
def child_type
|
|
411
|
+
Resource
|
|
412
|
+
end
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
# This class is a little special as it contains a lot logic.
|
|
416
|
+
# In essence this is just wrapping a hash with specific methods for the
|
|
417
|
+
# the different types of metadata (classes, functions etc.)
|
|
418
|
+
class AggregateMetadata < BaseClass
|
|
419
|
+
def initialize
|
|
420
|
+
super
|
|
421
|
+
@aggregate = {}
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
def classes
|
|
425
|
+
@aggregate[:classes]
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
def datatypes
|
|
429
|
+
@aggregate[:datatypes]
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
def functions
|
|
433
|
+
@aggregate[:functions]
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
def types
|
|
437
|
+
@aggregate[:types]
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
def concat!(array)
|
|
441
|
+
return if array.nil? || array.empty?
|
|
442
|
+
|
|
443
|
+
array.each { |item| append!(item) }
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
def append!(obj)
|
|
447
|
+
list_for_object_class(obj.class) << obj
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
def to_json(*options)
|
|
451
|
+
@aggregate.to_json(options)
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
def from_json!(json_string)
|
|
455
|
+
obj = ::JSON.parse(json_string)
|
|
456
|
+
obj.each do |key, value|
|
|
457
|
+
info = METADATA_LIST[key.intern]
|
|
458
|
+
next if info.nil?
|
|
459
|
+
|
|
460
|
+
list = list_for_object_class(info[:item_class])
|
|
461
|
+
value.each { |i| list << info[:item_class].new.from_h!(i) }
|
|
462
|
+
end
|
|
463
|
+
self
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
def each_list(&block)
|
|
467
|
+
return unless block
|
|
468
|
+
|
|
469
|
+
@aggregate.each(&block)
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
private
|
|
473
|
+
|
|
474
|
+
# When adding a new metadata item:
|
|
475
|
+
# - Add to the information to this hash
|
|
476
|
+
# - Add a method to access the aggregate
|
|
477
|
+
METADATA_LIST = {
|
|
478
|
+
classes: {
|
|
479
|
+
item_class: PuppetClass,
|
|
480
|
+
list_class: PuppetClassList
|
|
481
|
+
},
|
|
482
|
+
datatypes: {
|
|
483
|
+
item_class: PuppetDataType,
|
|
484
|
+
list_class: PuppetDataTypeList
|
|
485
|
+
},
|
|
486
|
+
functions: {
|
|
487
|
+
item_class: PuppetFunction,
|
|
488
|
+
list_class: PuppetFunctionList
|
|
489
|
+
},
|
|
490
|
+
types: {
|
|
491
|
+
item_class: PuppetType,
|
|
492
|
+
list_class: PuppetTypeList
|
|
493
|
+
}
|
|
494
|
+
}.freeze
|
|
495
|
+
|
|
496
|
+
def list_for_object_class(klass)
|
|
497
|
+
METADATA_LIST.each do |name, info|
|
|
498
|
+
if klass == info[:item_class]
|
|
499
|
+
@aggregate[name] = info[:list_class].new if @aggregate[name].nil?
|
|
500
|
+
return @aggregate[name]
|
|
501
|
+
end
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
raise "Unknown object class #{klass.name}"
|
|
505
|
+
end
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
class Fact < BasePuppetObject
|
|
509
|
+
attr_accessor :value
|
|
510
|
+
|
|
511
|
+
def to_h
|
|
512
|
+
super.to_h.merge(
|
|
513
|
+
'value' => value
|
|
514
|
+
)
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
def from_h!(value)
|
|
518
|
+
super
|
|
519
|
+
|
|
520
|
+
self.value = value['value']
|
|
521
|
+
self
|
|
522
|
+
end
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
class FactList < BasePuppetObjectList
|
|
526
|
+
def child_type
|
|
527
|
+
Fact
|
|
528
|
+
end
|
|
529
|
+
end
|
|
530
|
+
end
|
|
531
|
+
end
|
|
532
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'uri'
|
|
4
|
+
require 'puppet'
|
|
5
|
+
|
|
6
|
+
module PuppetLanguageServer
|
|
7
|
+
module UriHelper
|
|
8
|
+
def self.build_file_uri(path)
|
|
9
|
+
if path.nil?
|
|
10
|
+
nil
|
|
11
|
+
else
|
|
12
|
+
"file://#{Puppet::Util.uri_encode(path.start_with?('/') ? path : "/#{path}")}"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.uri_path(uri_string)
|
|
17
|
+
uri_string.nil? ? nil : Puppet::Util.uri_to_path(URI(uri_string))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Compares two URIs and returns the relative path
|
|
21
|
+
#
|
|
22
|
+
# @param root_uri [String] The root URI to compare to
|
|
23
|
+
# @param uri [String] The URI to compare to the root
|
|
24
|
+
# @param case_sensitive [Boolean] Whether the path comparison is case senstive or not. Default is true
|
|
25
|
+
# @return [String] Returns the relative path string if the URI is indeed a child of the root, otherwise returns nil
|
|
26
|
+
def self.relative_uri_path(root_uri, uri, case_sensitive = true)
|
|
27
|
+
actual_root = URI(root_uri)
|
|
28
|
+
actual_uri = URI(uri)
|
|
29
|
+
return nil unless actual_root.scheme == actual_uri.scheme
|
|
30
|
+
|
|
31
|
+
# CGI.unescape doesn't handle space rules properly in uri paths
|
|
32
|
+
# URI::parser.unescape does, but returns strings in their original encoding
|
|
33
|
+
# Mostly safe here as we're only worried about file based URIs
|
|
34
|
+
parser = URI::DEFAULT_PARSER
|
|
35
|
+
root_path = parser.unescape(actual_root.path)
|
|
36
|
+
uri_path = parser.unescape(actual_uri.path)
|
|
37
|
+
if case_sensitive
|
|
38
|
+
return nil unless uri_path.slice(0, root_path.length) == root_path
|
|
39
|
+
else
|
|
40
|
+
return nil unless uri_path.slice(0, root_path.length).casecmp(root_path).zero?
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
uri_path.slice(root_path.length..-1)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PuppetLanguageServerSidecar
|
|
4
|
+
module Cache
|
|
5
|
+
CLASSES_SECTION = 'classes'
|
|
6
|
+
FUNCTIONS_SECTION = 'functions'
|
|
7
|
+
TYPES_SECTION = 'types'
|
|
8
|
+
PUPPETSTRINGS_SECTION = 'puppetstrings'
|
|
9
|
+
|
|
10
|
+
class Base
|
|
11
|
+
attr_reader :cache_options
|
|
12
|
+
|
|
13
|
+
def initialize(options = {})
|
|
14
|
+
@cache_options = options
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def active?
|
|
18
|
+
false
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def load(_absolute_path, _section)
|
|
22
|
+
raise NotImplementedError
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def save(_absolute_path, _section, _content_string)
|
|
26
|
+
raise NotImplementedError
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# WARNING - This method is only intended for testing the cache
|
|
30
|
+
# and should not be used for normal operations
|
|
31
|
+
def clear!
|
|
32
|
+
raise NotImplementedError
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|