k_manager 0.0.13 → 0.0.22
Sign up to get free protection for your applications and to get access to all the features.
- 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
|