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.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/main.yml +31 -0
  3. data/.gitignore +50 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +85 -0
  6. data/Assessment1.md +127 -0
  7. data/Assessment2.md +88 -0
  8. data/CODE_OF_CONDUCT.md +74 -0
  9. data/Gemfile +25 -0
  10. data/Guardfile +30 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +82 -0
  13. data/Rakefile +33 -0
  14. data/STORIES.md +42 -0
  15. data/ToDo.md +8 -0
  16. data/USAGE.md +19 -0
  17. data/bin/console +16 -0
  18. data/bin/k +36 -0
  19. data/bin/kgitsync +76 -0
  20. data/bin/khotfix +244 -0
  21. data/bin/setup +11 -0
  22. data/hooks/pre-commit +87 -0
  23. data/hooks/update-version +33 -0
  24. data/k_manager.gemspec +47 -0
  25. data/lib/k_manager.rb +50 -0
  26. data/lib/k_manager/configuration/project_config.rb +14 -0
  27. data/lib/k_manager/create_document.rb +31 -0
  28. data/lib/k_manager/documents/basic_document.rb +21 -0
  29. data/lib/k_manager/documents/builder_document.rb +18 -0
  30. data/lib/k_manager/documents/document_taggable.rb +94 -0
  31. data/lib/k_manager/documents/model_document.rb +19 -0
  32. data/lib/k_manager/project.rb +50 -0
  33. data/lib/k_manager/resources/base_resource.rb +182 -0
  34. data/lib/k_manager/resources/csv_file_resource.rb +27 -0
  35. data/lib/k_manager/resources/factories/document_factory.rb +52 -0
  36. data/lib/k_manager/resources/factories/ruby_document_factory.rb +57 -0
  37. data/lib/k_manager/resources/file_resource.rb +93 -0
  38. data/lib/k_manager/resources/json_file_resource.rb +22 -0
  39. data/lib/k_manager/resources/ruby_file_resource.rb +32 -0
  40. data/lib/k_manager/resources/unknown_file_resource.rb +22 -0
  41. data/lib/k_manager/resources/x_resource.rb +243 -0
  42. data/lib/k_manager/resources/yaml_file_resource.rb +21 -0
  43. data/lib/k_manager/version.rb +5 -0
  44. data/lib/k_manager/x_project.rb +698 -0
  45. data/lib/k_manager/x_project_manager.rb +133 -0
  46. data/lib/k_manager/x_register.rb +199 -0
  47. data/lib/k_manager/x_resource_documents/resource_document.rb +51 -0
  48. 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