k_manager 0.0.13

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