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.
Files changed (109) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +510 -0
  3. data/CODEOWNERS +2 -0
  4. data/CODE_OF_CONDUCT.md +46 -0
  5. data/CONTRIBUTING.md +54 -0
  6. data/Gemfile +53 -0
  7. data/LICENSE +201 -0
  8. data/README.md +308 -0
  9. data/Rakefile +185 -0
  10. data/bin/puppet-debugserver +8 -0
  11. data/bin/puppet-languageserver +7 -0
  12. data/bin/puppet-languageserver-sidecar +7 -0
  13. data/lib/dsp/dsp.rb +7 -0
  14. data/lib/dsp/dsp_base.rb +62 -0
  15. data/lib/dsp/dsp_protocol.rb +4619 -0
  16. data/lib/lsp/lsp.rb +10 -0
  17. data/lib/lsp/lsp_base.rb +63 -0
  18. data/lib/lsp/lsp_custom.rb +170 -0
  19. data/lib/lsp/lsp_enums.rb +143 -0
  20. data/lib/lsp/lsp_protocol.rb +2785 -0
  21. data/lib/lsp/lsp_protocol_callhierarchy.proposed.rb +239 -0
  22. data/lib/lsp/lsp_protocol_colorprovider.rb +100 -0
  23. data/lib/lsp/lsp_protocol_configuration.rb +82 -0
  24. data/lib/lsp/lsp_protocol_declaration.rb +73 -0
  25. data/lib/lsp/lsp_protocol_foldingrange.rb +129 -0
  26. data/lib/lsp/lsp_protocol_implementation.rb +75 -0
  27. data/lib/lsp/lsp_protocol_progress.rb +200 -0
  28. data/lib/lsp/lsp_protocol_selectionrange.rb +79 -0
  29. data/lib/lsp/lsp_protocol_sematictokens.proposed.rb +340 -0
  30. data/lib/lsp/lsp_protocol_typedefinition.rb +75 -0
  31. data/lib/lsp/lsp_protocol_workspacefolders.rb +174 -0
  32. data/lib/lsp/lsp_types.rb +1534 -0
  33. data/lib/puppet-debugserver/debug_session/break_points.rb +137 -0
  34. data/lib/puppet-debugserver/debug_session/flow_control.rb +161 -0
  35. data/lib/puppet-debugserver/debug_session/hook_handlers.rb +295 -0
  36. data/lib/puppet-debugserver/debug_session/puppet_session_run_mode.rb +66 -0
  37. data/lib/puppet-debugserver/debug_session/puppet_session_state.rb +122 -0
  38. data/lib/puppet-debugserver/hooks.rb +132 -0
  39. data/lib/puppet-debugserver/message_handler.rb +277 -0
  40. data/lib/puppet-debugserver/puppet_debug_session.rb +541 -0
  41. data/lib/puppet-debugserver/puppet_monkey_patches.rb +118 -0
  42. data/lib/puppet-languageserver/client_session_state.rb +119 -0
  43. data/lib/puppet-languageserver/crash_dump.rb +50 -0
  44. data/lib/puppet-languageserver/epp/validation_provider.rb +34 -0
  45. data/lib/puppet-languageserver/facter_helper.rb +25 -0
  46. data/lib/puppet-languageserver/global_queues/sidecar_queue.rb +205 -0
  47. data/lib/puppet-languageserver/global_queues/single_instance_queue.rb +126 -0
  48. data/lib/puppet-languageserver/global_queues/validation_queue.rb +102 -0
  49. data/lib/puppet-languageserver/global_queues.rb +16 -0
  50. data/lib/puppet-languageserver/manifest/completion_provider.rb +331 -0
  51. data/lib/puppet-languageserver/manifest/definition_provider.rb +99 -0
  52. data/lib/puppet-languageserver/manifest/document_symbol_provider.rb +228 -0
  53. data/lib/puppet-languageserver/manifest/folding_provider.rb +226 -0
  54. data/lib/puppet-languageserver/manifest/format_on_type_provider.rb +143 -0
  55. data/lib/puppet-languageserver/manifest/hover_provider.rb +221 -0
  56. data/lib/puppet-languageserver/manifest/signature_provider.rb +169 -0
  57. data/lib/puppet-languageserver/manifest/validation_provider.rb +127 -0
  58. data/lib/puppet-languageserver/message_handler.rb +462 -0
  59. data/lib/puppet-languageserver/providers.rb +18 -0
  60. data/lib/puppet-languageserver/puppet_helper.rb +108 -0
  61. data/lib/puppet-languageserver/puppet_lexer_helper.rb +55 -0
  62. data/lib/puppet-languageserver/puppet_monkey_patches.rb +39 -0
  63. data/lib/puppet-languageserver/puppet_parser_helper.rb +212 -0
  64. data/lib/puppet-languageserver/puppetfile/validation_provider.rb +185 -0
  65. data/lib/puppet-languageserver/server_capabilities.rb +48 -0
  66. data/lib/puppet-languageserver/session_state/document_store.rb +272 -0
  67. data/lib/puppet-languageserver/session_state/language_client.rb +239 -0
  68. data/lib/puppet-languageserver/session_state/object_cache.rb +162 -0
  69. data/lib/puppet-languageserver/sidecar_protocol.rb +532 -0
  70. data/lib/puppet-languageserver/uri_helper.rb +46 -0
  71. data/lib/puppet-languageserver-sidecar/cache/base.rb +36 -0
  72. data/lib/puppet-languageserver-sidecar/cache/filesystem.rb +111 -0
  73. data/lib/puppet-languageserver-sidecar/cache/null.rb +27 -0
  74. data/lib/puppet-languageserver-sidecar/facter_helper.rb +41 -0
  75. data/lib/puppet-languageserver-sidecar/puppet_environment_monkey_patches.rb +52 -0
  76. data/lib/puppet-languageserver-sidecar/puppet_helper.rb +281 -0
  77. data/lib/puppet-languageserver-sidecar/puppet_modulepath_monkey_patches.rb +146 -0
  78. data/lib/puppet-languageserver-sidecar/puppet_monkey_patches.rb +9 -0
  79. data/lib/puppet-languageserver-sidecar/puppet_parser_helper.rb +77 -0
  80. data/lib/puppet-languageserver-sidecar/puppet_strings_helper.rb +399 -0
  81. data/lib/puppet-languageserver-sidecar/puppet_strings_monkey_patches.rb +16 -0
  82. data/lib/puppet-languageserver-sidecar/sidecar_protocol_extensions.rb +16 -0
  83. data/lib/puppet-languageserver-sidecar/workspace.rb +89 -0
  84. data/lib/puppet_debugserver.rb +164 -0
  85. data/lib/puppet_editor_services/connection/base.rb +62 -0
  86. data/lib/puppet_editor_services/connection/stdio.rb +25 -0
  87. data/lib/puppet_editor_services/connection/tcp.rb +34 -0
  88. data/lib/puppet_editor_services/handler/base.rb +16 -0
  89. data/lib/puppet_editor_services/handler/debug_adapter.rb +63 -0
  90. data/lib/puppet_editor_services/handler/json_rpc.rb +133 -0
  91. data/lib/puppet_editor_services/logging.rb +45 -0
  92. data/lib/puppet_editor_services/protocol/base.rb +27 -0
  93. data/lib/puppet_editor_services/protocol/debug_adapter.rb +135 -0
  94. data/lib/puppet_editor_services/protocol/debug_adapter_messages.rb +171 -0
  95. data/lib/puppet_editor_services/protocol/json_rpc.rb +241 -0
  96. data/lib/puppet_editor_services/protocol/json_rpc_messages.rb +200 -0
  97. data/lib/puppet_editor_services/server/base.rb +42 -0
  98. data/lib/puppet_editor_services/server/stdio.rb +85 -0
  99. data/lib/puppet_editor_services/server/tcp.rb +349 -0
  100. data/lib/puppet_editor_services/server.rb +15 -0
  101. data/lib/puppet_editor_services/version.rb +36 -0
  102. data/lib/puppet_editor_services.rb +8 -0
  103. data/lib/puppet_languageserver.rb +263 -0
  104. data/lib/puppet_languageserver_sidecar.rb +361 -0
  105. data/puppet-debugserver +11 -0
  106. data/puppet-editor-services.gemspec +29 -0
  107. data/puppet-languageserver +15 -0
  108. data/puppet-languageserver-sidecar +14 -0
  109. 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