k_manager 0.0.13 → 0.0.28

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -0
  3. data/Gemfile +23 -0
  4. data/Rakefile +2 -0
  5. data/docs/flow.drawio +16 -0
  6. data/exe/k_manager +19 -0
  7. data/hooks/update-version +1 -1
  8. data/k_manager.gemspec +9 -0
  9. data/lib/k_manager/area.rb +49 -0
  10. data/lib/k_manager/cli/base_command.rb +23 -0
  11. data/lib/k_manager/cli/commands.rb +25 -0
  12. data/lib/k_manager/cli/info.rb +81 -0
  13. data/lib/k_manager/cli/new.rb +130 -0
  14. data/lib/k_manager/cli/version.rb +15 -0
  15. data/lib/k_manager/cli/watch.rb +65 -0
  16. data/lib/k_manager/document_factory.rb +81 -0
  17. data/lib/k_manager/manager.rb +158 -0
  18. data/lib/k_manager/overview/dashboard.rb +197 -0
  19. data/lib/k_manager/overview/dump_json.rb +35 -0
  20. data/lib/k_manager/overview/models.rb +76 -0
  21. data/lib/k_manager/overview/queries.rb +53 -0
  22. data/lib/k_manager/resources/base_resource.rb +203 -52
  23. data/lib/k_manager/resources/file_resource.rb +81 -58
  24. data/lib/k_manager/resources/{ruby_file_resource.rb → file_resources/ruby_file_resource.rb} +0 -0
  25. data/lib/k_manager/resources/{unknown_file_resource.rb → file_resources/unknown_file_resource.rb} +0 -0
  26. data/lib/k_manager/resources/mem_resource.rb +17 -0
  27. data/lib/k_manager/resources/resource_document_factory.rb +123 -0
  28. data/lib/k_manager/resources/resource_factory.rb +28 -0
  29. data/lib/k_manager/resources/resource_manager.rb +201 -0
  30. data/lib/k_manager/resources/resource_set.rb +90 -0
  31. data/lib/k_manager/resources/web_resource.rb +113 -0
  32. data/lib/k_manager/version.rb +1 -1
  33. data/lib/k_manager/watcher.rb +113 -0
  34. data/lib/k_manager/{x_project.rb → x_resource_documents/x_project.rb} +0 -0
  35. data/lib/k_manager/{x_project_manager.rb → x_resource_documents/x_project_manager.rb} +0 -0
  36. data/lib/k_manager/{x_register.rb → x_resource_documents/x_register.rb} +0 -0
  37. data/lib/k_manager.rb +111 -24
  38. data/tasks/watch.rake +18 -0
  39. metadata +118 -25
  40. data/Assessment1.md +0 -127
  41. data/Assessment2.md +0 -88
  42. data/lib/k_manager/configuration/project_config.rb +0 -14
  43. data/lib/k_manager/create_document.rb +0 -31
  44. data/lib/k_manager/documents/basic_document.rb +0 -21
  45. data/lib/k_manager/documents/builder_document.rb +0 -18
  46. data/lib/k_manager/documents/document_taggable.rb +0 -94
  47. data/lib/k_manager/documents/model_document.rb +0 -19
  48. data/lib/k_manager/project.rb +0 -50
  49. data/lib/k_manager/resources/csv_file_resource.rb +0 -27
  50. data/lib/k_manager/resources/factories/document_factory.rb +0 -52
  51. data/lib/k_manager/resources/json_file_resource.rb +0 -22
  52. data/lib/k_manager/resources/yaml_file_resource.rb +0 -21
@@ -0,0 +1,201 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KManager
4
+ # TODO: Write tests
5
+
6
+ # Example Director
7
+ # KDoc.diagram(:k_resource) do
8
+
9
+ # component(:resource_manager) do
10
+ # attr_rw(:resources)
11
+ # attr_rw(:fileset)
12
+
13
+ # method(:add_resource, description: "I will add a resource to the manager") do
14
+ # param(:resource_uri, description: 'xxxx')
15
+ # end
16
+
17
+ # method(:add_resource, description: "I will add a collection of resources to the manager via fileset or webset")
18
+ # method(:load_resource_content)
19
+ # end
20
+
21
+ # def on_action
22
+ # build_drawio("#{self.name}_class" , model: self.data, style: :class_diagram)
23
+ # build_drawio("#{self.name}_component" , model: self.data, style: :component_diagram)
24
+ # build_drawio("#{self.name}_swim" , model: self.data, style: :swimlane_diagram)
25
+ # end
26
+ # end
27
+
28
+ module Resources
29
+ class ResourceManager
30
+ extend Forwardable
31
+
32
+ include KLog::Logging
33
+ include KDoc::Guarded
34
+
35
+ attr_accessor :area
36
+
37
+ attr_accessor :fileset
38
+ attr_accessor :webset
39
+ attr_accessor :memset
40
+
41
+ # Resource set is built using file, web and memory resources
42
+ attr_accessor :resource_set
43
+
44
+ def initialize(area)
45
+ @area = area
46
+
47
+ @fileset = KFileset::FileSet.new
48
+ @webset = nil # TODO: when ready to implement URL based resources
49
+ @memset = nil # TODO: when ready to implement dynamic memory resources
50
+
51
+ @resource_factory = KManager::Resources::ResourceFactory.new
52
+ @resource_set = KManager::Resources::ResourceSet.new(area)
53
+ end
54
+
55
+ def_delegators :resource_set, :resources, :find_by_uri
56
+
57
+ # def resources
58
+ # resource_set.resources
59
+ # end
60
+
61
+ def resource_models
62
+ resource_set.resources.map(&:as_model)
63
+ end
64
+
65
+ def resource_changed(resource_uri, state)
66
+ create_resource(resource_uri) if state == :created
67
+ update_resource(resource_uri) if state == :updated
68
+ delete_resource(resource_uri) if state == :deleted
69
+
70
+ return if valid?
71
+
72
+ log_any_messages
73
+ clear_errors
74
+ end
75
+
76
+ def create_resource(resource_uri)
77
+ # TODO: skip if not whitelisted
78
+
79
+ # warn if the resource already existed (this should not happen)
80
+ # if fileset.whitelist
81
+ # build resource
82
+ # add resource to fileset
83
+ end
84
+
85
+ def update_resource(resource_uri)
86
+ # TODO: skip if not whitelisted
87
+
88
+ resource = resource_set.find_by_uri(resource_uri)
89
+
90
+ return warn("Resource not in Resource Set - Skipping: #{resource_uri.path}") unless resource
91
+
92
+ # TODO: Do I need to recreate, can I just reset instead?
93
+ replace_resource = resource.recreate(resource)
94
+ replace_resource.fire_action(:load_content)
95
+ replace_resource.fire_action(:register_document)
96
+ replace_resource.fire_action(:load_document)
97
+ resource_set.replace(replace_resource)
98
+ end
99
+
100
+ def delete_resource(resource_uri)
101
+ # TODO: skip if not whitelisted
102
+
103
+ # find resource
104
+ # if found, remove it
105
+ end
106
+
107
+ def add_resource_expand_path(file, **opts)
108
+ add_resource(File.expand_path(file), **opts)
109
+ end
110
+
111
+ # Add a resource based on a resource_uri
112
+ #
113
+ # @param [URI|String] resource_uri Path to the resource, if the path uses file:/// then it will add a file resource, if the path http: or https: then a web resource will be added
114
+ # TODO: Test File URI: relative_path
115
+ # TODO: Test File URI: absolute_path
116
+ # TODO: Test URI
117
+ # TODO: Test URI (Web)
118
+ # TODO: Test URI (File)
119
+ def add_resource(resource_uri, **opts)
120
+ resource_set.add(build_resource(resource_uri, **opts))
121
+ end
122
+
123
+ # TODO: Not sure if this is right
124
+ def build_resource(resource_uri, **opts)
125
+ resource_uri = parse_uri(resource_uri)
126
+ @resource_factory.instance(resource_uri, **opts)
127
+ end
128
+
129
+ def add_resources
130
+ add_web_resources
131
+ add_file_resources
132
+ end
133
+
134
+ # def update_resource(path)
135
+ # uri = path_to_uri(path)
136
+ # reset_existing_resource(uri)
137
+ # add_resource(uri)
138
+ # load_resource_content
139
+ # end
140
+
141
+ # Fire actions against all resources in this manager.
142
+ #
143
+ # @param [*Array<Symbol>] actions List of actions to run. [:load_content, :register_document, :load_document]
144
+ def fire_actions(*actions)
145
+ guard_action(actions)
146
+
147
+ load_content if actions.include?(:load_content)
148
+ register_documents if actions.include?(:register_document)
149
+ load_documents if actions.include?(:load_document)
150
+ end
151
+
152
+ def guard_action(actions)
153
+ actions.each do |action|
154
+ warn "ResourceManager.fire_actions - unknown action: #{action}" unless KManager::Resources::BaseResource.valid_action?(action)
155
+ end
156
+ end
157
+
158
+ def load_content
159
+ resources.each do |resource|
160
+ resource.fire_action(:load_content)
161
+ end
162
+ end
163
+
164
+ def register_documents
165
+ resources.each do |resource|
166
+ resource.fire_action(:register_document)
167
+ end
168
+ end
169
+
170
+ def load_documents
171
+ resources.each do |resource|
172
+ resource.fire_action(:load_document)
173
+ end
174
+ end
175
+
176
+ def debug
177
+ resources.each(&:debug)
178
+ end
179
+
180
+ private
181
+
182
+ def parse_uri(uri)
183
+ return uri if uri.is_a?(URI)
184
+ return URI.parse(uri) if uri =~ URI::ABS_URI # https://stackoverflow.com/questions/1805761/how-to-check-if-a-url-is-valid
185
+
186
+ URI.join('file:///', uri)
187
+ end
188
+
189
+ def add_web_resources
190
+ # TODO
191
+ # return if @webset.nil?
192
+ end
193
+
194
+ def add_file_resources
195
+ fileset.path_entries.each do |path_entry|
196
+ add_resource(path_entry.uri)
197
+ end
198
+ end
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KManager
4
+ # TODO: Write Tests
5
+
6
+ # A resource set holds a list of resources
7
+ #
8
+ # A resource could be a file, web-service, gist, ftp endpoint, memory object.
9
+ #
10
+ # ResourceSet is an internal component and is used by the ResourceManager
11
+ #
12
+ # The resource manager will create resources with the ResourceFactory and assign
13
+ # those resources to the ResourceSet
14
+ #
15
+ # The only supported resource types so far are:
16
+ # - File
17
+ #
18
+ # Resources can be registered with the ResourceSet using register_* methods
19
+ #
20
+ # somepath
21
+ # somepath/my_dsls
22
+ # somepath/my_dsls/path1
23
+ # somepath/my_dsls/path2
24
+ # somepath/my_dsls/path2/child
25
+ # somepath/my_dsls/path2/old (skip this path)
26
+ # somepath/my_data/
27
+ # somepath/my_templates
28
+ module Resources
29
+ class ResourceSet
30
+ include KLog::Logging
31
+
32
+ attr_reader :area
33
+ attr_reader :resources
34
+
35
+ def initialize(area)
36
+ @area = area
37
+ @resources = []
38
+ end
39
+
40
+ def add(resource)
41
+ return log.warn "Resource already added: #{resource.resource_path}" if find(resource)
42
+
43
+ resource.area = area
44
+ resources << resource
45
+ resource
46
+ end
47
+
48
+ def replace(resource)
49
+ index = find_index(resource)
50
+ return log.warn "Resource to replace does not exist: #{resource.resource_path}" unless index
51
+
52
+ resource.area = area
53
+ resources[index] = resource
54
+ resource
55
+ end
56
+
57
+ def add_resources(resource_list)
58
+ resource_list.each do |resource|
59
+ add(resource)
60
+ end
61
+ end
62
+
63
+ def debug
64
+ resources.each(&:debug)
65
+ nil
66
+ end
67
+
68
+ def find_by_uri(resource_uri)
69
+ resources.find { |r| r.resource_path == resource_uri.path }
70
+ end
71
+
72
+ private
73
+
74
+ def find(resource)
75
+ index = find_index(resource)
76
+ return nil unless index
77
+
78
+ resources[index] # .find { |r| r.resource_path == resource.resource_path }
79
+ end
80
+
81
+ def find_index(resource)
82
+ resources.index { |r| r.resource_path == resource.resource_path }
83
+ end
84
+
85
+ # def to_h
86
+ # resources.map(&:to_h)
87
+ # end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KManager
4
+ module Resources
5
+ require 'handlebars/helpers/string_formatting/dasherize'
6
+
7
+ # A web resource represents content that is loaded via a web URI.
8
+ #
9
+ # Web resources do not support watchers and so if you want to handle
10
+ # content changes then you will either need to poll the resource periodically
11
+ # or have a server with open channel for web-hooks.
12
+ class WebResource < KManager::Resources::BaseResource
13
+ include KLog::Logging
14
+
15
+ def initialize(uri, **opts)
16
+ warn('URI::HTTP/HTTPS type is expected for Web Resource') unless uri.is_a?(URI::HTTP)
17
+ super(uri, **opts)
18
+ log_any_messages unless valid?
19
+ end
20
+
21
+ # Infer key is the file name without the extension stored in dash-case
22
+ def infer_key
23
+ last_segment = uri.path.split('/').last
24
+ Handlebars::Helpers::StringFormatting::Snake.new.parse(last_segment)
25
+ end
26
+
27
+ def default_scheme
28
+ :https
29
+ end
30
+
31
+ def resource_path
32
+ @resource_path ||= source_path
33
+ end
34
+
35
+ def resource_relative_path
36
+ uri.path
37
+ end
38
+
39
+ def resource_valid?
40
+ return @resource_valid if defined? @resource_valid
41
+
42
+ @resource_valid = url_exist?(source_path)
43
+ end
44
+
45
+ def load_content
46
+ if resource_valid?
47
+ begin
48
+ @content = fetch(source_path)
49
+ rescue StandardError => e
50
+ log.error e
51
+ end
52
+ else
53
+ guard("Source url not valid: #{resource_path}")
54
+ end
55
+ end
56
+
57
+ def attribute_values(prefix = nil)
58
+ result = super(prefix)
59
+ result["#{prefix}path".to_sym] = resource_path
60
+ result["#{prefix}relative_path".to_sym] = resource_relative_path
61
+ result["#{prefix}exist".to_sym] = resource_valid?
62
+ result
63
+ end
64
+
65
+ def debug
66
+ super do
67
+ log.kv 'infer_key' , infer_key , 20
68
+ log.kv 'url' , source_path , 20
69
+ log.kv 'resource_path' , resource_path , 20
70
+ log.kv 'resource_valid?' , resource_valid? , 20
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ # rubocop:disable Metrics/AbcSize
77
+ def url_exist?(url_str, limit = 10)
78
+ raise ArgumentError, 'too many HTTP redirects' if limit.zero?
79
+
80
+ url = URI.parse(url_str)
81
+ req = Net::HTTP.new(url.host, url.port)
82
+ req.use_ssl = (url.scheme == 'https')
83
+ res = req.request_head(url.path || '/')
84
+ if res.is_a?(Net::HTTPRedirection)
85
+ url_exist?(res['location'], limit - 1) # Go after any redirect and make sure you can access the redirected URL
86
+ else
87
+ !%w[4 5].include?(res.code[0]) # Not from 4xx or 5xx families
88
+ end
89
+ rescue Errno::ENOENT
90
+ false # false if can't find the server
91
+ end
92
+ # rubocop:enable Metrics/AbcSize
93
+
94
+ def fetch(url_str, limit = 10)
95
+ raise ArgumentError, 'too many HTTP redirects' if limit.zero?
96
+
97
+ url = URI.parse(url_str)
98
+ res = Net::HTTP.get_response(url)
99
+
100
+ case res
101
+ when Net::HTTPSuccess
102
+ res.body
103
+ when Net::HTTPRedirection
104
+ location = res['location']
105
+ puts "redirected to #{location}"
106
+ fetch(location, limit - 1)
107
+ else
108
+ res.value
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KManager
4
- VERSION = '0.0.13'
4
+ VERSION = '0.0.28'
5
5
  end
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'filewatcher'
4
+ require 'io/console'
5
+
6
+ module KManager
7
+ # NOTE: Does Watcher belong in this GEM?
8
+ class Watcher
9
+ include KLog::Logging
10
+
11
+ attr_reader :watch_folder
12
+ attr_reader :boot_file
13
+
14
+ def initialize(watch_folder, boot_file)
15
+ @watch_folder = watch_folder
16
+ @boot_file = boot_file
17
+ end
18
+
19
+ # process_created_file(filename) if event == :created
20
+ # process_updated_file(filename) if event == :updated # || event == :created
21
+ # process_deleted_file(filename) if event == :deleted
22
+
23
+ # rubocop:disable Lint/RescueException, Metrics/AbcSize, Metrics/MethodLength
24
+ def start
25
+ boot_up
26
+
27
+ update_dashboard
28
+
29
+ watcher = Filewatcher.new(watch_folder)
30
+
31
+ watcher.watch do |changes|
32
+ watcher.pause
33
+ if changes.length > 1
34
+ log.kv 'HOW MANY CHANGES', changes.length
35
+ log.block changes
36
+ end
37
+
38
+ changes.each do |filename, event|
39
+ # NOTE: KManager will not support space in file name, but this will at least deal with file copies, where " copy" is added to a file name.
40
+ filename = filename.gsub(' ', '%20')
41
+
42
+ log_file_event(event, filename)
43
+
44
+ uri = URI::File.build(host: nil, path: filename)
45
+
46
+ start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
47
+ KManager.resource_changed(uri, event)
48
+ finish_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
49
+ time_taken = finish_time - start_time
50
+
51
+ sleep KManager.opts.sleep if KManager.opts.sleep.positive?
52
+
53
+ clear_screen
54
+
55
+ log_file_event(event, filename)
56
+ log.kv 'Time Taken', time_taken.to_d.round(3, :truncate).to_f if KManager.opts.show.time_taken
57
+
58
+ update_dashboard
59
+
60
+ puts KManager.opts.show.finished_message if KManager.opts.show.finished
61
+ end
62
+ watcher.resume
63
+ end
64
+ rescue Interrupt, SystemExit
65
+ raise
66
+ rescue Exception => e
67
+ log.exception(e)
68
+ end
69
+ # rubocop:enable Lint/RescueException, Metrics/AbcSize, Metrics/MethodLength
70
+
71
+ private
72
+
73
+ def log_file_event(event, filename)
74
+ current = Time.now.strftime('%H:%M:%S')
75
+ output = "#{current} - #{event}: #{filename}"
76
+
77
+ log.warn(output) if event == :updated
78
+ log.error(output) if event == :deleted
79
+ log.info(output) if event == :created
80
+ end
81
+
82
+ def boot_up
83
+ clear_screen
84
+
85
+ if File.exist?(boot_file)
86
+ content = File.read(boot_file)
87
+ Object.class_eval(content, boot_file)
88
+ return
89
+ end
90
+
91
+ log.error("Boot file not found: #{boot_file}")
92
+ end
93
+
94
+ def update_dashboard
95
+ dashboard = KManager::Overview::Dashboard.new(KManager.manager)
96
+ # dashboard.areas
97
+ dashboard.resources
98
+ dashboard.documents
99
+ end
100
+
101
+ def update_load_path(filename)
102
+ dirname = File.dirname(filename)
103
+
104
+ # This needs to be in detailed logging
105
+ $LOAD_PATH.unshift(dirname) unless $LOAD_PATH.find { |path| path.start_with?(dirname) }
106
+ end
107
+
108
+ def clear_screen
109
+ puts "\n" * 70
110
+ $stdout.clear_screen
111
+ end
112
+ end
113
+ end
data/lib/k_manager.rb CHANGED
@@ -1,44 +1,131 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'csv'
4
+ require 'dry-struct'
5
+ require 'forwardable'
6
+ require 'k_log'
7
+ require 'k_config'
3
8
  require 'k_doc'
9
+ require 'k_domain'
10
+ require 'k_director'
11
+ require 'k_fileset'
4
12
  require 'k_builder'
5
13
  require 'k_ext/github'
6
- require 'k_log'
7
14
 
8
- require 'k_manager/create_document'
15
+ # IS THIS NEEDED? this was used for infer_key
16
+ require 'handlebars/helpers/string_formatting/dasherize'
17
+ require 'handlebars/helpers/string_formatting/snake'
18
+
9
19
  require 'k_manager/version'
10
- require 'k_manager/configuration/project_config'
11
- require 'k_manager/documents/document_taggable'
12
- require 'k_manager/documents/basic_document'
13
- require 'k_manager/documents/model_document'
14
- require 'k_manager/documents/builder_document'
20
+ require 'k_manager/overview/models'
21
+ require 'k_manager/overview/queries'
22
+ require 'k_manager/overview/dump_json'
23
+ require 'k_manager/overview/dashboard'
24
+ require 'k_manager/resources/resource_set'
15
25
  require 'k_manager/resources/base_resource'
16
26
  require 'k_manager/resources/file_resource'
17
- require 'k_manager/resources/csv_file_resource'
18
- require 'k_manager/resources/json_file_resource'
19
- require 'k_manager/resources/ruby_file_resource'
20
- require 'k_manager/resources/yaml_file_resource'
21
- require 'k_manager/resources/unknown_file_resource'
22
- require 'k_manager/project'
27
+ require 'k_manager/resources/web_resource'
28
+ require 'k_manager/resources/mem_resource'
29
+ require 'k_manager/resources/resource_document_factory'
30
+ require 'k_manager/resources/resource_factory'
31
+ require 'k_manager/resources/resource_manager'
32
+ require 'k_manager/document_factory'
33
+ require 'k_manager/manager'
34
+ require 'k_manager/area'
35
+ require 'k_manager/watcher'
23
36
 
24
37
  module KManager
25
- extend CreateDocument
26
-
27
38
  # raise KManager::Error, 'Sample message'
28
39
  class Error < StandardError; end
29
40
 
30
41
  class << self
31
- def new_project_config(&block)
32
- config = KManager::Configuration::ProjectConfig.new
33
- block.call(config) if block_given?
34
- config
42
+ extend Forwardable
43
+
44
+ # ----------------------------------------------------------------------
45
+ # Concurrency management for currently focused resource
46
+ # ----------------------------------------------------------------------
47
+
48
+ # NOTE: Can mutex be moved into manager?
49
+ attr_reader :current_resource
50
+
51
+ def resource_mutex
52
+ @resource_mutex ||= Mutex.new
53
+ end
54
+
55
+ def for_resource(resource = nil)
56
+ resource_mutex.synchronize do
57
+ @current_resource = resource
58
+ yield(current_resource)
59
+ @current_resource = nil
60
+ end
61
+ end
62
+
63
+ def for_current_resource
64
+ raise KManager::Error, 'Attempting to yield current_resource, when a different thread has the lock?' unless resource_mutex.owned?
65
+
66
+ yield(@current_resource)
67
+ end
68
+
69
+ # ----------------------------------------------------------------------
70
+ # Debug Flags
71
+ # ----------------------------------------------------------------------
72
+
73
+ def debug_state
74
+ return @debug_state if defined? @debug_state
75
+
76
+ @debug_state = :disabled
35
77
  end
36
78
 
37
- # Instance of the currently focused resource
38
- # if document get created dynamically due to class_eval then they
39
- # can attach themselves to the currently focussed resource via
40
- # KManager.target_resource.add_document(document)
41
- attr_accessor :target_resource
79
+ def debug_enable
80
+ @debug_state = :enabled
81
+ end
82
+
83
+ def debug?
84
+ debug_state == :enabled
85
+ end
86
+
87
+ # ----------------------------------------------------------------------
88
+ # Manager facade methods
89
+ # ----------------------------------------------------------------------
90
+
91
+ def manager
92
+ @manager ||= Manager.new
93
+ end
94
+
95
+ def reset
96
+ # @resource_mutex.unlock if @resource_mutex
97
+ # @current_resource = nil
98
+ @manager = Manager.new
99
+ end
100
+
101
+ def_delegators :manager,
102
+ :opts,
103
+ :areas,
104
+ :add_area,
105
+ :find_document,
106
+ :fire_actions,
107
+ :resource_changed,
108
+ :reboot,
109
+ :debug
110
+
111
+ # ----------------------------------------------------------------------
112
+ # Document factory facade methods
113
+ # ----------------------------------------------------------------------
114
+
115
+ def document_factory
116
+ @document_factory ||= DocumentFactory.new
117
+ end
118
+
119
+ def_delegators :document_factory, :action, :model, :csv, :json, :yaml
120
+
121
+ # ----------------------------------------------------------------------
122
+ # Utilities
123
+ # ----------------------------------------------------------------------
124
+
125
+ def clear_screen
126
+ puts "\n" * 70
127
+ $stdout.clear_screen
128
+ end
42
129
  end
43
130
  end
44
131