k_manager 0.0.13
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/.github/workflows/main.yml +31 -0
- data/.gitignore +50 -0
- data/.rspec +3 -0
- data/.rubocop.yml +85 -0
- data/Assessment1.md +127 -0
- data/Assessment2.md +88 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +25 -0
- data/Guardfile +30 -0
- data/LICENSE.txt +21 -0
- data/README.md +82 -0
- data/Rakefile +33 -0
- data/STORIES.md +42 -0
- data/ToDo.md +8 -0
- data/USAGE.md +19 -0
- data/bin/console +16 -0
- data/bin/k +36 -0
- data/bin/kgitsync +76 -0
- data/bin/khotfix +244 -0
- data/bin/setup +11 -0
- data/hooks/pre-commit +87 -0
- data/hooks/update-version +33 -0
- data/k_manager.gemspec +47 -0
- data/lib/k_manager.rb +50 -0
- data/lib/k_manager/configuration/project_config.rb +14 -0
- data/lib/k_manager/create_document.rb +31 -0
- data/lib/k_manager/documents/basic_document.rb +21 -0
- data/lib/k_manager/documents/builder_document.rb +18 -0
- data/lib/k_manager/documents/document_taggable.rb +94 -0
- data/lib/k_manager/documents/model_document.rb +19 -0
- data/lib/k_manager/project.rb +50 -0
- data/lib/k_manager/resources/base_resource.rb +182 -0
- data/lib/k_manager/resources/csv_file_resource.rb +27 -0
- data/lib/k_manager/resources/factories/document_factory.rb +52 -0
- data/lib/k_manager/resources/factories/ruby_document_factory.rb +57 -0
- data/lib/k_manager/resources/file_resource.rb +93 -0
- data/lib/k_manager/resources/json_file_resource.rb +22 -0
- data/lib/k_manager/resources/ruby_file_resource.rb +32 -0
- data/lib/k_manager/resources/unknown_file_resource.rb +22 -0
- data/lib/k_manager/resources/x_resource.rb +243 -0
- data/lib/k_manager/resources/yaml_file_resource.rb +21 -0
- data/lib/k_manager/version.rb +5 -0
- data/lib/k_manager/x_project.rb +698 -0
- data/lib/k_manager/x_project_manager.rb +133 -0
- data/lib/k_manager/x_register.rb +199 -0
- data/lib/k_manager/x_resource_documents/resource_document.rb +51 -0
- metadata +150 -0
@@ -0,0 +1,182 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KManager
|
4
|
+
module Resources
|
5
|
+
# A resource represents text based content in the project. The content
|
6
|
+
# maybe data, interpreted ruby code or a combination of the two.
|
7
|
+
#
|
8
|
+
# Currently resources refer to file based content, but it is envisaged
|
9
|
+
# that resources could come from a distributed source such as Gist,
|
10
|
+
# WebService, or even FTP.
|
11
|
+
#
|
12
|
+
# Resources can hold different types of static and smart content.
|
13
|
+
# Examples of static content include JSON, YAML and CSV
|
14
|
+
# Example of smart content include Ruby classes, PORO's and DSL's.
|
15
|
+
#
|
16
|
+
# NOTE: The resource represents the text content, but not the actual data or
|
17
|
+
# code that resides there. Instead a document is created to store the data or
|
18
|
+
# code. The reason for this is that some content files, especially DSL's may
|
19
|
+
# have more then one interpreted ruby structure included in the content and so
|
20
|
+
# a document gets created for each DSL, but for all other files, there is
|
21
|
+
# generally only one document.
|
22
|
+
class BaseResource
|
23
|
+
include KLog::Logging
|
24
|
+
|
25
|
+
# Status of the resource
|
26
|
+
# - :initialized
|
27
|
+
# - :content_loading
|
28
|
+
# - :content_loaded
|
29
|
+
# - :documents_registering
|
30
|
+
# - :documents_registered
|
31
|
+
# - :documents_loading
|
32
|
+
# - :documents_loaded
|
33
|
+
attr_reader :status
|
34
|
+
|
35
|
+
# Where is the source of content
|
36
|
+
#
|
37
|
+
# Implement in child classes, examples: :file, :uri, :dynamic
|
38
|
+
attr_reader :source
|
39
|
+
|
40
|
+
# Where is the type of the
|
41
|
+
#
|
42
|
+
# Implement in child classes, examples: :csv, :json, :ruby, :dsl, :yaml
|
43
|
+
attr_reader :type
|
44
|
+
|
45
|
+
attr_reader :project
|
46
|
+
|
47
|
+
# Content of resource, use read content to load this property
|
48
|
+
attr_reader :content
|
49
|
+
|
50
|
+
# List of documents derived from this resource
|
51
|
+
#
|
52
|
+
# Most resources will create one document, but a DSL can generate
|
53
|
+
# multiple documents and some future resources may do as well
|
54
|
+
#
|
55
|
+
# Currently there will always be a minimum of 1 document even if the resource
|
56
|
+
# is not a data resource, e.g. Ruby class
|
57
|
+
attr_accessor :documents
|
58
|
+
|
59
|
+
# Initialize base for resources
|
60
|
+
#
|
61
|
+
# @param [Hash] **opts Options for initializing the resource
|
62
|
+
# @option opts [Project] :project attach the resource to a project
|
63
|
+
def initialize(**opts)
|
64
|
+
@status = :initialized
|
65
|
+
@source = :unknown
|
66
|
+
@type = :unknown
|
67
|
+
|
68
|
+
attach_project(opts[:project]) if opts[:project]
|
69
|
+
@documents = []
|
70
|
+
end
|
71
|
+
|
72
|
+
def attach_project(project)
|
73
|
+
@project = project
|
74
|
+
@project.add_resource(self)
|
75
|
+
self
|
76
|
+
end
|
77
|
+
|
78
|
+
def document
|
79
|
+
@document ||= documents&.first
|
80
|
+
end
|
81
|
+
|
82
|
+
# Fire actions and keep track of status as they fire
|
83
|
+
#
|
84
|
+
# @param [Symbol] action what action is to be fired
|
85
|
+
# - :load_content for loading text content
|
86
|
+
# - :register_document for registering 1 or more documents (name and namespace) against the resource
|
87
|
+
# - :load_document for parsing the content into a document
|
88
|
+
def fire_action(action)
|
89
|
+
if action == :load_content && @status == :initialized
|
90
|
+
load_content_action
|
91
|
+
elsif action == :register_document && @status == :content_loaded
|
92
|
+
register_document_action
|
93
|
+
elsif action == :load_document && @status == :documents_registered
|
94
|
+
load_document_action
|
95
|
+
else
|
96
|
+
puts 'unknown'
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# What identifying key does this resource have?
|
101
|
+
#
|
102
|
+
# Child resources will have different ways of working this out,
|
103
|
+
# eg. File Resources will use the file name.
|
104
|
+
def infer_key
|
105
|
+
nil
|
106
|
+
end
|
107
|
+
|
108
|
+
def load_content
|
109
|
+
log.warn 'you need to implement load_content'
|
110
|
+
end
|
111
|
+
|
112
|
+
def register_document
|
113
|
+
log.warn 'you need to implement register_document'
|
114
|
+
end
|
115
|
+
|
116
|
+
# This might be better off in a factory method
|
117
|
+
# Klue.basic
|
118
|
+
def create_document
|
119
|
+
KManager::Documents::BasicDocument.new(
|
120
|
+
key: infer_key,
|
121
|
+
type: type,
|
122
|
+
namespace: '',
|
123
|
+
resource: self
|
124
|
+
)
|
125
|
+
end
|
126
|
+
|
127
|
+
# TODO: Unit Test
|
128
|
+
def attach_document(document, change_resource_type: nil)
|
129
|
+
@type = change_resource_type if change_resource_type
|
130
|
+
|
131
|
+
add_document(document)
|
132
|
+
end
|
133
|
+
|
134
|
+
def load_document
|
135
|
+
log.warn 'you need to implement load_document'
|
136
|
+
end
|
137
|
+
|
138
|
+
# rubocop:disable Metrics/AbcSize
|
139
|
+
def debug
|
140
|
+
log.section_heading('resource')
|
141
|
+
log.kv 'source' , source , 15
|
142
|
+
log.kv 'type' , type , 15
|
143
|
+
log.kv 'status' , status , 15
|
144
|
+
# 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
|
+
|
148
|
+
documents.each(&:debug)
|
149
|
+
end
|
150
|
+
# rubocop:enable Metrics/AbcSize
|
151
|
+
|
152
|
+
private
|
153
|
+
|
154
|
+
def add_document(document)
|
155
|
+
# First document in list goes into .document
|
156
|
+
@documents << document
|
157
|
+
document
|
158
|
+
end
|
159
|
+
|
160
|
+
def load_content_action
|
161
|
+
@status = :content_loading
|
162
|
+
@content = nil
|
163
|
+
load_content
|
164
|
+
@status = :content_loaded
|
165
|
+
end
|
166
|
+
|
167
|
+
def register_document_action
|
168
|
+
@status = :documents_registering
|
169
|
+
register_document
|
170
|
+
# document_factory.create_documents
|
171
|
+
@status = :documents_registered
|
172
|
+
end
|
173
|
+
|
174
|
+
def load_document_action
|
175
|
+
@status = :documents_loading
|
176
|
+
load_document
|
177
|
+
# document_factory.parse_content
|
178
|
+
@status = :documents_loaded
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'csv'
|
4
|
+
|
5
|
+
module KManager
|
6
|
+
module Resources
|
7
|
+
# Represents a CSV file resource.
|
8
|
+
class CsvFileResource < KManager::Resources::FileResource
|
9
|
+
def initialize(**opts)
|
10
|
+
super(**opts)
|
11
|
+
@type = :csv
|
12
|
+
end
|
13
|
+
|
14
|
+
def load_document
|
15
|
+
data = []
|
16
|
+
CSV.parse(content, headers: true, header_converters: :symbol).each do |row|
|
17
|
+
data << row.to_h
|
18
|
+
end
|
19
|
+
document.data = data
|
20
|
+
end
|
21
|
+
|
22
|
+
# def debug
|
23
|
+
# tp self.document.data, self.document.data.first.to_h.keys
|
24
|
+
# end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# # frozen_string_literal: true
|
3
|
+
# require 'csv'
|
4
|
+
|
5
|
+
# module KDsl
|
6
|
+
# module Resources
|
7
|
+
# module Factories
|
8
|
+
# # Base factory for creationg resource_documents
|
9
|
+
# # Tightly coupled to the resource using polymorphic composition
|
10
|
+
# # Something WRONG, should this be a module include instead of a Forwardable Class?
|
11
|
+
# class DocumentFactory
|
12
|
+
# extend Forwardable
|
13
|
+
|
14
|
+
# attr_reader :resource
|
15
|
+
|
16
|
+
# def_delegator :resource, :project
|
17
|
+
# def_delegator :resource, :content
|
18
|
+
# def_delegator :resource, :documents
|
19
|
+
# def_delegator :resource, :new_document
|
20
|
+
# def_delegator :resource, :add_document
|
21
|
+
# def_delegator :resource, :infer_document_key
|
22
|
+
# def_delegator :resource, :infer_document_type
|
23
|
+
# def_delegator :resource, :infer_document_namespace
|
24
|
+
|
25
|
+
# def initialize(resource, resource_type)
|
26
|
+
# @resource = resource
|
27
|
+
# resource.resource_type = resource_type
|
28
|
+
# end
|
29
|
+
|
30
|
+
# def self.instance(resource, source, file)
|
31
|
+
# if source === KDsl::Resources::Resource::SOURCE_FILE
|
32
|
+
# extension = File.extname(file).downcase
|
33
|
+
|
34
|
+
# case extension
|
35
|
+
# when '.rb'
|
36
|
+
# return KDsl::Resources::Factories::RubyDocumentFactory.new(resource)
|
37
|
+
# when '.csv'
|
38
|
+
# return KDsl::Resources::Factories::CsvDocumentFactory.new(resource)
|
39
|
+
# when '.json'
|
40
|
+
# return KDsl::Resources::Factories::JsonDocumentFactory.new(resource)
|
41
|
+
# when '.yaml'
|
42
|
+
# return KDsl::Resources::Factories::YamlDocumentFactory.new(resource)
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
|
46
|
+
# return KDsl::Resources::Factories::UnknownDocumentFactory.new(resource)
|
47
|
+
# end
|
48
|
+
|
49
|
+
# end
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
# end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# # frozen_string_literal: true
|
3
|
+
# require 'csv'
|
4
|
+
|
5
|
+
# module KDsl
|
6
|
+
# module Resources
|
7
|
+
# module Factories
|
8
|
+
# # Ruby RubyDocumentFactory can handle Ruby to produce a document
|
9
|
+
# # or KlueDSL content to produce one or more documents
|
10
|
+
# class RubyDocumentFactory < DocumentFactory
|
11
|
+
# def initialize(resource)
|
12
|
+
# super(resource, KDsl::Resources::Resource::TYPE_RUBY)
|
13
|
+
# end
|
14
|
+
|
15
|
+
# def create_documents
|
16
|
+
# KDsl.target_resource = self
|
17
|
+
|
18
|
+
# Object.class_eval content
|
19
|
+
|
20
|
+
# # Only DSL's will add new resource_documents
|
21
|
+
# if documents.length > 0
|
22
|
+
# resource.resource_type = KDsl::Resources::Resource::TYPE_RUBY_DSL
|
23
|
+
# end
|
24
|
+
|
25
|
+
# rescue => exeption
|
26
|
+
# # Report the error but still add the document so that you can see
|
27
|
+
# # it in the ResourceDocument list, it will be marked as Error
|
28
|
+
# resource.error = exeption
|
29
|
+
|
30
|
+
# L.exception resource.error
|
31
|
+
# ensure
|
32
|
+
# KDsl.target_resource = nil
|
33
|
+
|
34
|
+
# # A regular ruby file would not add resource_documents
|
35
|
+
# # so create one manually
|
36
|
+
# add_document(new_document) if documents.length === 0
|
37
|
+
# end
|
38
|
+
|
39
|
+
# def parse_content
|
40
|
+
# if self.resource.resource_type === KDsl::Resources::Resource::TYPE_RUBY_DSL
|
41
|
+
# documents.each do |document|
|
42
|
+
# begin
|
43
|
+
# document.execute_block
|
44
|
+
# rescue => exeption
|
45
|
+
# # Report the error but still add the document so that you can see
|
46
|
+
# # it in the ResourceDocument list, it will be marked as Error
|
47
|
+
# document.error = exeption
|
48
|
+
|
49
|
+
# L.exception @error
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
# end
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
# end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KManager
|
4
|
+
module Resources
|
5
|
+
require 'handlebars/helpers/string_formatting/dasherize'
|
6
|
+
|
7
|
+
# A file resource represents context that is loaded via a file.
|
8
|
+
#
|
9
|
+
# File resources have the benefit that file watchers can watch them
|
10
|
+
# locally and reload these resources on change.
|
11
|
+
class FileResource < KManager::Resources::BaseResource
|
12
|
+
include KLog::Logging
|
13
|
+
|
14
|
+
# Full path to file
|
15
|
+
#
|
16
|
+
# example: /Users/davidcruwys/dev/kgems/k_dsl/spec/factories/dsls/common-auth/admin_user.rb
|
17
|
+
attr_reader :file
|
18
|
+
|
19
|
+
def initialize(**opts)
|
20
|
+
super(**opts)
|
21
|
+
@source = :file
|
22
|
+
@file = opts[:file]
|
23
|
+
|
24
|
+
guard
|
25
|
+
end
|
26
|
+
|
27
|
+
class << self
|
28
|
+
def instance(**opts)
|
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
|
46
|
+
end
|
47
|
+
|
48
|
+
# Infer key is the file name without the extension stored in dash-case
|
49
|
+
def infer_key
|
50
|
+
file_name = Pathname.new(@file).basename.sub_ext('').to_s
|
51
|
+
Handlebars::Helpers::StringFormatting::Dasherize.new.parse(file_name)
|
52
|
+
end
|
53
|
+
|
54
|
+
def load_content
|
55
|
+
if File.exist?(file)
|
56
|
+
begin
|
57
|
+
@content = File.read(file)
|
58
|
+
rescue StandardError => e
|
59
|
+
log.error e
|
60
|
+
end
|
61
|
+
else
|
62
|
+
log.error "Source file not found: #{file}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def register_document
|
67
|
+
attach_document(create_document)
|
68
|
+
end
|
69
|
+
|
70
|
+
# rubocop:disable Metrics/AbcSize
|
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)
|
83
|
+
end
|
84
|
+
# rubocop:enable Metrics/AbcSize
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def guard
|
89
|
+
raise KType::Error, 'File resource requires a file option' if @file.nil? || @file == ''
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KManager
|
4
|
+
module Resources
|
5
|
+
# Represents a JSON file resource.
|
6
|
+
class JsonFileResource < KManager::Resources::FileResource
|
7
|
+
def initialize(**opts)
|
8
|
+
super(**opts)
|
9
|
+
@type = :json
|
10
|
+
end
|
11
|
+
|
12
|
+
def load_document
|
13
|
+
data = JSON.parse(content)
|
14
|
+
document.data = data
|
15
|
+
end
|
16
|
+
|
17
|
+
# def debug
|
18
|
+
# L.ostruct(KDsl::Util.data.to_struct(self.document.data))
|
19
|
+
# end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KManager
|
4
|
+
module Resources
|
5
|
+
# Represents a Ruby file resource.
|
6
|
+
class RubyFileResource < KManager::Resources::FileResource
|
7
|
+
def initialize(**opts)
|
8
|
+
super(**opts)
|
9
|
+
@type = :ruby
|
10
|
+
end
|
11
|
+
|
12
|
+
def register_document
|
13
|
+
KManager.target_resource = self
|
14
|
+
|
15
|
+
Object.class_eval content
|
16
|
+
|
17
|
+
# rescue StandardError => exception
|
18
|
+
# # Report the error but still add the document so that you can see
|
19
|
+
# # it in the ResourceDocument list, it will be marked as Error
|
20
|
+
# resource.error = exception
|
21
|
+
|
22
|
+
# L.exception resource.error
|
23
|
+
ensure
|
24
|
+
KManager.target_resource = nil
|
25
|
+
|
26
|
+
# A regular ruby file would not add resource_documents
|
27
|
+
# so create one manually
|
28
|
+
@document = super if documents.length.zero?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|