k_manager 0.0.13 → 0.0.22
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 +4 -4
- data/.rubocop.yml +1 -0
- data/Gemfile +18 -0
- data/Rakefile +2 -0
- data/docs/flow.drawio +16 -0
- data/exe/k_manager +20 -0
- data/k_manager.gemspec +6 -0
- data/lib/k_manager/area.rb +47 -0
- data/lib/k_manager/document_factory.rb +74 -0
- data/lib/k_manager/manager.rb +58 -0
- data/lib/k_manager/overview/dashboard.rb +187 -0
- data/lib/k_manager/overview/dump_json.rb +35 -0
- data/lib/k_manager/overview/models.rb +76 -0
- data/lib/k_manager/overview/queries.rb +53 -0
- data/lib/k_manager/resources/base_resource.rb +189 -52
- data/lib/k_manager/resources/file_resource.rb +80 -58
- data/lib/k_manager/resources/{ruby_file_resource.rb → file_resources/ruby_file_resource.rb} +0 -0
- data/lib/k_manager/resources/{unknown_file_resource.rb → file_resources/unknown_file_resource.rb} +0 -0
- data/lib/k_manager/resources/mem_resource.rb +17 -0
- data/lib/k_manager/resources/resource_document_factory.rb +119 -0
- data/lib/k_manager/resources/resource_factory.rb +28 -0
- data/lib/k_manager/resources/resource_manager.rb +216 -0
- data/lib/k_manager/resources/resource_set.rb +90 -0
- data/lib/k_manager/resources/web_resource.rb +113 -0
- data/lib/k_manager/version.rb +1 -1
- data/lib/k_manager/watcher.rb +75 -0
- data/lib/k_manager/{x_project.rb → x_resource_documents/x_project.rb} +0 -0
- data/lib/k_manager/{x_project_manager.rb → x_resource_documents/x_project_manager.rb} +0 -0
- data/lib/k_manager/{x_register.rb → x_resource_documents/x_register.rb} +0 -0
- data/lib/k_manager.rb +93 -20
- data/tasks/watch.rake +113 -0
- metadata +70 -24
- data/Assessment1.md +0 -127
- data/Assessment2.md +0 -88
- data/lib/k_manager/create_document.rb +0 -31
- data/lib/k_manager/documents/basic_document.rb +0 -21
- data/lib/k_manager/documents/builder_document.rb +0 -18
- data/lib/k_manager/documents/document_taggable.rb +0 -94
- data/lib/k_manager/documents/model_document.rb +0 -19
- data/lib/k_manager/project.rb +0 -50
- data/lib/k_manager/resources/csv_file_resource.rb +0 -27
- data/lib/k_manager/resources/factories/document_factory.rb +0 -52
- data/lib/k_manager/resources/json_file_resource.rb +0 -22
- data/lib/k_manager/resources/yaml_file_resource.rb +0 -21
@@ -5,6 +5,8 @@ module KManager
|
|
5
5
|
# A resource represents text based content in the project. The content
|
6
6
|
# maybe data, interpreted ruby code or a combination of the two.
|
7
7
|
#
|
8
|
+
# Any non-binary file that is useful for processing.
|
9
|
+
#
|
8
10
|
# Currently resources refer to file based content, but it is envisaged
|
9
11
|
# that resources could come from a distributed source such as Gist,
|
10
12
|
# WebService, or even FTP.
|
@@ -21,9 +23,21 @@ module KManager
|
|
21
23
|
# generally only one document.
|
22
24
|
class BaseResource
|
23
25
|
include KLog::Logging
|
26
|
+
include KDoc::Guarded
|
27
|
+
|
28
|
+
ACTIONS = %i[load_content register_document load_document].freeze
|
24
29
|
|
30
|
+
class << self
|
31
|
+
def valid_action?(action)
|
32
|
+
ACTIONS.include?(action)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
attr_reader :uri # https://ruby-doc.org/stdlib-2.6.1/libdoc/uri/rdoc/URI/Generic.html
|
37
|
+
|
38
|
+
# TODO: Refactor from status to state and extract to a State class
|
25
39
|
# Status of the resource
|
26
|
-
# - :
|
40
|
+
# - :alive (i am alive, or instantiated)
|
27
41
|
# - :content_loading
|
28
42
|
# - :content_loaded
|
29
43
|
# - :documents_registering
|
@@ -32,17 +46,25 @@ module KManager
|
|
32
46
|
# - :documents_loaded
|
33
47
|
attr_reader :status
|
34
48
|
|
35
|
-
#
|
49
|
+
# What content type does the underlying resource type generally contain
|
36
50
|
#
|
37
|
-
#
|
38
|
-
attr_reader :source
|
39
|
-
|
40
|
-
# Where is the type of the
|
51
|
+
# Examples:
|
41
52
|
#
|
42
|
-
#
|
43
|
-
|
53
|
+
# :csv - CSV text content
|
54
|
+
# :json - JSON text content
|
55
|
+
# :yaml - YAML text content
|
56
|
+
# :xml - XML text content
|
57
|
+
# :ruby - Ruby code file of unknown capability
|
58
|
+
# :ruby_dsl - Ruby code holding some type of known DSL such as a KDoc
|
59
|
+
# DISCUSS: should this subtype be delegated to an attribute on a responsible class
|
60
|
+
attr_reader :content_type
|
44
61
|
|
45
|
-
|
62
|
+
# TODO: Write Test
|
63
|
+
# Area is an option property what will only be set when working with Area
|
64
|
+
attr_accessor :area
|
65
|
+
|
66
|
+
# Optional namespace that the resource belongs to.
|
67
|
+
attr_reader :namespace
|
46
68
|
|
47
69
|
# Content of resource, use read content to load this property
|
48
70
|
attr_reader :content
|
@@ -60,19 +82,22 @@ module KManager
|
|
60
82
|
#
|
61
83
|
# @param [Hash] **opts Options for initializing the resource
|
62
84
|
# @option opts [Project] :project attach the resource to a project
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
85
|
+
# NAMESPACE can probably be taken from file set relative path
|
86
|
+
def initialize(uri, **opts)
|
87
|
+
self.uri = uri
|
88
|
+
|
89
|
+
@status = :alive
|
90
|
+
@namespace = value_remove(opts, :namespace)
|
91
|
+
@content_type = @content_type || value_remove(opts, :content_type) || infer_content_type || default_content_type
|
92
|
+
@content = value_remove(opts, :content)
|
67
93
|
|
68
|
-
attach_project(opts[:project]) if opts[:project]
|
94
|
+
# attach_project(opts[:project]) if opts[:project]
|
69
95
|
@documents = []
|
70
96
|
end
|
71
97
|
|
72
|
-
def
|
73
|
-
|
74
|
-
|
75
|
-
self
|
98
|
+
def source_path
|
99
|
+
# Expectation that uri is of type URI::HTTP or URI::HTTPS
|
100
|
+
uri.to_s
|
76
101
|
end
|
77
102
|
|
78
103
|
def document
|
@@ -85,15 +110,31 @@ module KManager
|
|
85
110
|
# - :load_content for loading text content
|
86
111
|
# - :register_document for registering 1 or more documents (name and namespace) against the resource
|
87
112
|
# - :load_document for parsing the content into a document
|
113
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
88
114
|
def fire_action(action)
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
115
|
+
# TODO: Write test for valid
|
116
|
+
return unless valid?
|
117
|
+
|
118
|
+
case action
|
119
|
+
when :load_content
|
120
|
+
load_content_action if alive?
|
121
|
+
when :register_document
|
122
|
+
register_document_action if content_loaded?
|
123
|
+
when :load_document
|
124
|
+
load_document_action if documents_registered?
|
95
125
|
else
|
96
|
-
|
126
|
+
log.warn "Action: '#{action}' is invalid for status: '#{status}'"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
130
|
+
|
131
|
+
def fire_next_action
|
132
|
+
if alive?
|
133
|
+
fire_action(:load_content)
|
134
|
+
elsif content_loaded?
|
135
|
+
fire_action(:register_document)
|
136
|
+
elsif documents_registered?
|
137
|
+
fire_action(:load_document)
|
97
138
|
end
|
98
139
|
end
|
99
140
|
|
@@ -106,60 +147,156 @@ module KManager
|
|
106
147
|
end
|
107
148
|
|
108
149
|
def load_content
|
109
|
-
log.warn 'you need to implement load_content'
|
150
|
+
# log.warn 'you need to implement load_content'
|
110
151
|
end
|
111
152
|
|
112
153
|
def register_document
|
113
|
-
log.warn 'you need to implement register_document'
|
154
|
+
# log.warn 'you need to implement register_document'
|
155
|
+
KManager::Resources::ResourceDocumentFactory.create_documents(self)
|
114
156
|
end
|
115
157
|
|
116
|
-
#
|
117
|
-
|
118
|
-
|
119
|
-
|
158
|
+
# rubocop:disable Lint/RescueException
|
159
|
+
def load_document
|
160
|
+
# log.warn 'you need to implement register_document'
|
161
|
+
documents.each(&:execute_block)
|
162
|
+
rescue Exception => e
|
163
|
+
guard(e.message)
|
164
|
+
debug
|
165
|
+
log.exception(e, style: :short)
|
166
|
+
end
|
167
|
+
# rubocop:enable Lint/RescueException
|
168
|
+
|
169
|
+
# This is when you need a simple container
|
170
|
+
def new_document(data)
|
171
|
+
document = KDoc::Container.new(
|
120
172
|
key: infer_key,
|
121
|
-
type:
|
122
|
-
namespace:
|
123
|
-
|
173
|
+
type: content_type,
|
174
|
+
namespace: namespace,
|
175
|
+
default_data_type: data.class,
|
176
|
+
data: data
|
124
177
|
)
|
178
|
+
attach_document(document)
|
125
179
|
end
|
126
180
|
|
127
|
-
|
128
|
-
|
129
|
-
@type = change_resource_type if change_resource_type
|
181
|
+
def attach_document(document, change_content_type: nil)
|
182
|
+
@content_type = change_content_type if change_content_type
|
130
183
|
|
131
|
-
|
184
|
+
document.owner = self
|
185
|
+
@documents << document
|
186
|
+
document
|
132
187
|
end
|
133
188
|
|
134
|
-
def
|
135
|
-
|
189
|
+
def scheme
|
190
|
+
uri&.scheme&.to_sym || default_scheme
|
191
|
+
end
|
192
|
+
|
193
|
+
def host
|
194
|
+
uri&.host
|
195
|
+
end
|
196
|
+
|
197
|
+
# What schema does the underlying resource connect with by default
|
198
|
+
#
|
199
|
+
# Examples:
|
200
|
+
#
|
201
|
+
# :file
|
202
|
+
# :web (http: https: fpt:)
|
203
|
+
# :mem - some type of memory structure
|
204
|
+
def default_scheme
|
205
|
+
:unknown
|
206
|
+
end
|
207
|
+
|
208
|
+
# Optionally overridden, this is the case with FileResource
|
209
|
+
def infer_content_type
|
210
|
+
nil
|
211
|
+
end
|
212
|
+
|
213
|
+
def default_content_type
|
214
|
+
:unknown
|
215
|
+
end
|
216
|
+
|
217
|
+
def alive?
|
218
|
+
@status == :alive
|
219
|
+
end
|
220
|
+
|
221
|
+
def content_loaded?
|
222
|
+
@status == :content_loaded
|
223
|
+
end
|
224
|
+
|
225
|
+
def documents_registered?
|
226
|
+
@status == :documents_registered
|
227
|
+
end
|
228
|
+
|
229
|
+
def documents_loaded?
|
230
|
+
@status == :documents_loaded
|
231
|
+
end
|
232
|
+
|
233
|
+
# Setting the URI can be overridden by WebResource and FileResource
|
234
|
+
def uri=(uri)
|
235
|
+
return if uri.nil?
|
236
|
+
|
237
|
+
@uri = URI(uri) if uri.is_a?(String)
|
238
|
+
@uri = uri if uri.is_a?(URI)
|
239
|
+
|
240
|
+
# log.kv 'uri type', uri.class
|
241
|
+
# It might be useful to have a Resource Specific Guard being called to warn if the wrong URI type is inferred from here
|
242
|
+
# supported URI::Class (Generic, File, HTTP, HTTPS)
|
136
243
|
end
|
137
244
|
|
138
245
|
# rubocop:disable Metrics/AbcSize
|
139
|
-
def
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
246
|
+
def attribute_values(prefix = nil)
|
247
|
+
result = {}
|
248
|
+
result["#{prefix}id".to_sym] = object_id
|
249
|
+
result["#{prefix}key".to_sym] = infer_key
|
250
|
+
result["#{prefix}namespace".to_sym] = namespace
|
251
|
+
result["#{prefix}status".to_sym] = status
|
252
|
+
result["#{prefix}source".to_sym] = source_path
|
253
|
+
result["#{prefix}content_type".to_sym] = content_type
|
254
|
+
result["#{prefix}content".to_sym] = content
|
255
|
+
result["#{prefix}document_count".to_sym] = documents.length
|
256
|
+
result["#{prefix}errors".to_sym] = error_hash
|
257
|
+
result["#{prefix}valid".to_sym] = valid?
|
258
|
+
result["#{prefix}scheme".to_sym] = scheme
|
259
|
+
result["#{prefix}host".to_sym] = host
|
260
|
+
result
|
261
|
+
end
|
262
|
+
# rubocop:enable Metrics/AbcSize
|
263
|
+
|
264
|
+
# rubocop:disable Metrics/AbcSize
|
265
|
+
def debug(heading = 'resource')
|
266
|
+
width = 20
|
267
|
+
log.section_heading(heading)
|
268
|
+
log.kv 'area' , area.name , width if area
|
269
|
+
log.kv 'area namespace' , area.namespace , width if area
|
270
|
+
log.kv 'scheme' , scheme , width
|
271
|
+
log.kv 'host' , host , width
|
272
|
+
log.kv 'source_path' , source_path , width
|
273
|
+
log.kv 'content_type' , content_type , width
|
274
|
+
log.kv 'status' , status , width
|
275
|
+
log.kv 'content' , content.nil? ? '' : content[0..100].gsub("\n", '\n') , width
|
276
|
+
log.kv 'documents' , documents.length , width
|
277
|
+
|
278
|
+
yield if block_given?
|
279
|
+
|
280
|
+
log_any_messages
|
281
|
+
|
282
|
+
# log.kv 'infer_key', infer_key , width
|
144
283
|
# log.kv 'project' , project
|
145
|
-
log.kv 'content' , content.nil? ? '' : content[0..100].gsub("\n", '\n') , 15
|
146
|
-
log.kv 'documents', documents.length , 15
|
147
284
|
|
148
285
|
documents.each(&:debug)
|
286
|
+
nil
|
149
287
|
end
|
150
288
|
# rubocop:enable Metrics/AbcSize
|
151
289
|
|
152
290
|
private
|
153
291
|
|
154
|
-
def
|
155
|
-
|
156
|
-
|
157
|
-
|
292
|
+
def value_remove(opts, key)
|
293
|
+
return opts.delete(key) if opts.key?(key)
|
294
|
+
|
295
|
+
nil
|
158
296
|
end
|
159
297
|
|
160
298
|
def load_content_action
|
161
299
|
@status = :content_loading
|
162
|
-
@content = nil
|
163
300
|
load_content
|
164
301
|
@status = :content_loaded
|
165
302
|
end
|
@@ -2,91 +2,113 @@
|
|
2
2
|
|
3
3
|
module KManager
|
4
4
|
module Resources
|
5
|
-
|
6
|
-
|
7
|
-
# A file resource represents context that is loaded via a file.
|
5
|
+
# A file resource represents content that is loaded via a file.
|
8
6
|
#
|
9
7
|
# File resources have the benefit that file watchers can watch them
|
10
|
-
# locally and reload these resources on change.
|
8
|
+
# locally and reload when these resources on change.
|
11
9
|
class FileResource < KManager::Resources::BaseResource
|
12
10
|
include KLog::Logging
|
13
11
|
|
14
|
-
|
12
|
+
KNOWN_EXTENSIONS = {
|
13
|
+
'.rb' => :ruby,
|
14
|
+
'.csv' => :csv,
|
15
|
+
'.json' => :json,
|
16
|
+
'.yaml' => :yaml
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
def initialize(uri, **opts)
|
20
|
+
warn('URI::File type expected for File Resource') unless uri.is_a?(URI::File)
|
21
|
+
super(uri, **opts)
|
22
|
+
log_any_messages unless valid?
|
23
|
+
end
|
24
|
+
|
25
|
+
# Infer key is the file name without the extension stored in dash-case
|
26
|
+
def infer_key
|
27
|
+
file_name = Pathname.new(source_path).basename.sub_ext('').to_s
|
28
|
+
Handlebars::Helpers::StringFormatting::Snake.new.parse(file_name)
|
29
|
+
end
|
30
|
+
|
31
|
+
def default_scheme
|
32
|
+
:file
|
33
|
+
end
|
34
|
+
|
35
|
+
# Currently in base
|
36
|
+
# def register_document
|
37
|
+
# KManager::Resources::ResourceDocumentFactory.create_documents(self)
|
38
|
+
# end
|
39
|
+
|
40
|
+
def attribute_values(prefix = nil)
|
41
|
+
result = super(prefix)
|
42
|
+
result["#{prefix}path".to_sym] = resource_path
|
43
|
+
result["#{prefix}relative_path".to_sym] = resource_relative_path
|
44
|
+
result["#{prefix}exist".to_sym] = resource_valid?
|
45
|
+
result
|
46
|
+
end
|
47
|
+
|
48
|
+
def debug
|
49
|
+
super do
|
50
|
+
log.kv 'infer_key' , infer_key , 20
|
51
|
+
log.kv 'file' , source_path , 20
|
52
|
+
log.kv 'resource_path' , resource_path , 20
|
53
|
+
log.kv 'resource_valid?' , resource_valid? , 20
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Source path - aka Full path to file
|
15
58
|
#
|
16
59
|
# example: /Users/davidcruwys/dev/kgems/k_dsl/spec/factories/dsls/common-auth/admin_user.rb
|
17
|
-
|
60
|
+
def source_path
|
61
|
+
uri.path
|
62
|
+
end
|
18
63
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
@file = opts[:file]
|
64
|
+
# TODO: Write tests
|
65
|
+
def recreate(resource)
|
66
|
+
raise 'Recreate only works for resources of the same type' unless resource.is_a?(self.class)
|
23
67
|
|
24
|
-
|
68
|
+
# area: resource.area,
|
69
|
+
# content_type: resource.content_type,
|
70
|
+
opts = {
|
71
|
+
namespace: resource.namespace
|
72
|
+
}
|
73
|
+
|
74
|
+
resource.class.new(resource.uri, **opts)
|
25
75
|
end
|
26
76
|
|
27
|
-
|
28
|
-
|
29
|
-
file = opts[:file]
|
30
|
-
|
31
|
-
extension = ::File.extname(file).downcase
|
32
|
-
|
33
|
-
case extension
|
34
|
-
when '.rb'
|
35
|
-
KManager::Resources::RubyFileResource.new(**opts)
|
36
|
-
when '.csv'
|
37
|
-
KManager::Resources::CsvFileResource.new(**opts)
|
38
|
-
when '.json'
|
39
|
-
KManager::Resources::JsonFileResource.new(**opts)
|
40
|
-
when '.yaml'
|
41
|
-
KManager::Resources::YamlFileResource.new(**opts)
|
42
|
-
else
|
43
|
-
KManager::Resources::UnknownFileResource.new(**opts)
|
44
|
-
end
|
45
|
-
end
|
77
|
+
def resource_path
|
78
|
+
@resource_path ||= absolute_path(source_path)
|
46
79
|
end
|
47
80
|
|
48
|
-
|
49
|
-
|
50
|
-
file_name = Pathname.new(@file).basename.sub_ext('').to_s
|
51
|
-
Handlebars::Helpers::StringFormatting::Dasherize.new.parse(file_name)
|
81
|
+
def resource_relative_path(from_path = Dir.pwd)
|
82
|
+
Pathname.new(resource_path).relative_path_from(from_path).to_s
|
52
83
|
end
|
53
84
|
|
85
|
+
def resource_valid?
|
86
|
+
File.exist?(resource_path)
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
54
91
|
def load_content
|
55
|
-
if
|
92
|
+
if resource_valid?
|
56
93
|
begin
|
57
|
-
@content = File.read(
|
94
|
+
@content = File.read(resource_path)
|
58
95
|
rescue StandardError => e
|
59
96
|
log.error e
|
60
97
|
end
|
61
98
|
else
|
62
|
-
|
99
|
+
guard("Source file not found: #{resource_path}")
|
63
100
|
end
|
64
101
|
end
|
65
102
|
|
66
|
-
def
|
67
|
-
|
68
|
-
end
|
103
|
+
def absolute_path(path)
|
104
|
+
pn = Pathname(path)
|
69
105
|
|
70
|
-
|
71
|
-
def debug
|
72
|
-
log.section_heading('resource')
|
73
|
-
log.kv 'source' , source , 15
|
74
|
-
log.kv 'file' , file , 15
|
75
|
-
log.kv 'type' , type , 15
|
76
|
-
log.kv 'infer_key', infer_key , 15
|
77
|
-
log.kv 'status' , status , 15
|
78
|
-
# log.kv 'project' , project
|
79
|
-
log.kv 'content' , content.nil? ? '' : content[0..100].gsub("\n", '\n') , 15
|
80
|
-
log.kv 'documents', documents.length , 15
|
81
|
-
|
82
|
-
documents.each(&:debug)
|
106
|
+
pn.exist? ? pn.realpath.to_s : File.expand_path(path)
|
83
107
|
end
|
84
|
-
# rubocop:enable Metrics/AbcSize
|
85
|
-
|
86
|
-
private
|
87
108
|
|
88
|
-
def
|
89
|
-
|
109
|
+
def infer_content_type
|
110
|
+
extension = ::File.extname(source_path).downcase
|
111
|
+
KNOWN_EXTENSIONS[extension]
|
90
112
|
end
|
91
113
|
end
|
92
114
|
end
|
File without changes
|
data/lib/k_manager/resources/{unknown_file_resource.rb → file_resources/unknown_file_resource.rb}
RENAMED
File without changes
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
module KManager
|
6
|
+
module Resources
|
7
|
+
require 'handlebars/helpers/string_formatting/dasherize'
|
8
|
+
|
9
|
+
# A memory resource represents content that is generated programmatically and just stored in memory.
|
10
|
+
class MemResource < KManager::Resources::BaseResource
|
11
|
+
def initialize(**opts)
|
12
|
+
fake_uri = URI.parse("mem://#{SecureRandom.alphanumeric(4)}")
|
13
|
+
super(fake_uri, **opts)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KManager
|
4
|
+
module Resources
|
5
|
+
# Create documents based on the target resource
|
6
|
+
#
|
7
|
+
# This factory will lock the resource and then create
|
8
|
+
# new documents based on the content of the resource.
|
9
|
+
#
|
10
|
+
# In the case of a ruby resource, this factory will evaluate the ruby
|
11
|
+
# code dynamically and any ruby file with standard document DSL's will
|
12
|
+
# create additional documents using KManager::DocumentFactory
|
13
|
+
class ResourceDocumentFactory
|
14
|
+
# TODO: The original system always created 1 document, so need to consider if 0-more should become 1-more
|
15
|
+
class << self
|
16
|
+
include KLog::Logging
|
17
|
+
# Build 0-more documents and attach them to the resource.
|
18
|
+
#
|
19
|
+
# The resource is stored in the KManager.current_resource context
|
20
|
+
# and wrapped by a Mutex so that any self registering documents can
|
21
|
+
# figure out which resource to register themselves against
|
22
|
+
def create_documents(target_resource)
|
23
|
+
KManager.for_resource(target_resource) do |resource|
|
24
|
+
process_resource(resource)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# Create 0-Many documents and attach to the resource
|
31
|
+
#
|
32
|
+
# @param [BaseResource] resource The resource that created and is thus owns the document
|
33
|
+
# @param [Symbol] content_type Type of content, %i[csv json yaml ruby unknown]
|
34
|
+
# @param [String] key is the unique resource key
|
35
|
+
# @param [String] content Resource content as a raw string, examples could be CSV, JSON, YAML, RUBY or some other text content
|
36
|
+
def process_resource(resource)
|
37
|
+
case resource.content_type
|
38
|
+
when :csv
|
39
|
+
resource.new_document(process_csv(resource.content))
|
40
|
+
when :json
|
41
|
+
resource.new_document(process_json(resource.content))
|
42
|
+
when :yaml
|
43
|
+
resource.new_document(process_yaml(resource.content))
|
44
|
+
when :ruby
|
45
|
+
process_ruby(resource)
|
46
|
+
:ruby
|
47
|
+
else
|
48
|
+
:unknown
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def process_csv(content)
|
53
|
+
rows = []
|
54
|
+
|
55
|
+
CSV.parse(content, headers: true, header_converters: :symbol) do |row|
|
56
|
+
rows << row.to_h
|
57
|
+
end
|
58
|
+
rows
|
59
|
+
rescue StandardError => e
|
60
|
+
log.exception(e, style: :message)
|
61
|
+
[]
|
62
|
+
end
|
63
|
+
|
64
|
+
def process_json(content)
|
65
|
+
JSON.parse(content)
|
66
|
+
rescue StandardError => e
|
67
|
+
log.exception(e, style: :message)
|
68
|
+
{}
|
69
|
+
end
|
70
|
+
|
71
|
+
def process_yaml(content)
|
72
|
+
YAML.safe_load(content)
|
73
|
+
rescue StandardError => e
|
74
|
+
log.exception(e, style: :message)
|
75
|
+
{}
|
76
|
+
end
|
77
|
+
|
78
|
+
# rubocop:disable Lint/RescueException
|
79
|
+
def process_ruby(resource)
|
80
|
+
# puts content
|
81
|
+
# KManager::Manager.current_resource
|
82
|
+
# KDsl.target_resource = self
|
83
|
+
|
84
|
+
Object.class_eval resource.content, resource.resource_path
|
85
|
+
|
86
|
+
# # Only DSL's will add new resource_documents
|
87
|
+
# if documents.length > 0
|
88
|
+
# resource.resource_type = KDsl::Resources::Resource::TYPE_RUBY_DSL
|
89
|
+
# end
|
90
|
+
rescue Exception => e
|
91
|
+
# Report the error but still add the document so that you can see
|
92
|
+
# it in the ResourceDocument list, it will be marked as Error
|
93
|
+
# resource.error = ex
|
94
|
+
resource.guard(e.message)
|
95
|
+
resource.debug
|
96
|
+
log.exception(e, style: :short)
|
97
|
+
|
98
|
+
# L.exception resource.error
|
99
|
+
|
100
|
+
# KDsl.target_resource = nil
|
101
|
+
|
102
|
+
# # A regular ruby file would not add resource_documents
|
103
|
+
# # so create one manually
|
104
|
+
# add_document(new_document) if documents.length === 0
|
105
|
+
end
|
106
|
+
# rubocop:enable Lint/RescueException
|
107
|
+
|
108
|
+
# # TEST REQUIRED
|
109
|
+
# def add_document(document)
|
110
|
+
# # project.register_dsl(document)
|
111
|
+
# project.add_resource_document(self, document)
|
112
|
+
# document.resource = self
|
113
|
+
# documents << document
|
114
|
+
# document
|
115
|
+
# end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KManager
|
4
|
+
module Resources
|
5
|
+
class ResourceFactory
|
6
|
+
# TODO: Write tests
|
7
|
+
|
8
|
+
# Create a resource based on a resource URI.
|
9
|
+
#
|
10
|
+
# Resources may be of type File or Web
|
11
|
+
#
|
12
|
+
# The resource content_type should be passed in when it cannot be inferred (e.g. WebResource)
|
13
|
+
# for a FileResource this option is optional and will be inferred from the file extension.
|
14
|
+
def instance(resource_uri, **opts)
|
15
|
+
scheme = resource_uri.scheme.to_sym
|
16
|
+
|
17
|
+
case scheme
|
18
|
+
when :file
|
19
|
+
FileResource.new(resource_uri, **opts)
|
20
|
+
when :http, :https
|
21
|
+
WebResource.new(resource_uri, **opts)
|
22
|
+
else
|
23
|
+
raise 'Unknown schema'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|