Class: AutomateIt::Plugin::Manager
- Defined in:
- lib/automateit/plugin/manager.rb
Overview
Plugin::Manager
A manager provides high-level wrappers for features, e.g. installing software packages. It does not actually implement these features, but instead manages a set of drivers. When one of the manager’s wrapper methods is called, it queries the drivers to find the most suitable one and dispatches the user’s request to that driver.
For example, the PlatformManager is a Manager class that manages a set of Driver instances, including PlatformManager::Uname and PlatformManager::LSB. When you invoke the high-level PlatformManager#query wrapper method, it interrogates the drivers to find which one is best-suited for this method and then dispatches the request to that driver’s low-level implementation of this method.
The manager subclasses typically have no functionality of their own and just contain wrapper methods and documentation.
Direct Known Subclasses
AccountManager, AddressManager, EditManager, FieldManager, AutomateIt::PlatformManager, ServiceManager, ShellManager, TagManager, TemplateManager
Constant Summary
Constants included from Constants
Constants::PERROR, Constants::PEXEC, Constants::PNOTE, Constants::VERSION, Constants::WARNING_BOILERPLATE
Instance Attribute Summary collapse
-
#drivers ⇒ Object
Drivers for this manager as a hash of driver tokens to driver instances.
Attributes inherited from Common
Class Method Summary collapse
-
.abstract_manager ⇒ Object
Declare that this manager class is abstract.
-
.alias_methods(*methods) ⇒ Object
Methods to alias into the Interpreter, specified as an array of symbols.
-
.driver_classes ⇒ Object
Driver classes used by this Manager.
-
.inherited(subclass) ⇒ Object
Register managers.
Instance Method Summary collapse
-
#[](token) ⇒ Object
Returns the Driver with the specified token.
-
#available?(method, *args, &block) ⇒ Boolean
Is a driver available for this
method
andargs
? Uses automatic-detection routines and returns a boolean to indicate if a suitable driver is available. -
#default(token = nil) ⇒ Object
Manipulate the default driver.
-
#default=(token) ⇒ Object
Set the default driver to the
token
. -
#dispatch(*args, &block) ⇒ Object
Dispatch a method by guessing its name.
-
#dispatch_safely(*args, &block) ⇒ Object
Same as #dispatch but returns nil if couldn’t dispatch, rather than raising an exception.
-
#dispatch_safely_to(method, *args, &block) ⇒ Object
Same as #dispatch_to but returns nil if couldn’t dispatch, rather than raising an exception.
-
#dispatch_to(method, *args, &block) ⇒ Object
Dispatch the
method
withargs
andblock
to the appropriate driver. -
#driver_for(method, *args, &block) ⇒ Object
Get the most suitable driver for this
method
andargs
. -
#driver_suitability_levels_for(method, *args, &block) ⇒ Object
Returns structure which helps choose a suitable driver for the
method
andargs
. -
#instantiate_drivers ⇒ Object
Instantiate drivers for this manager.
-
#setup(opts = {}) ⇒ Object
Options: * :default – The token of the driver to set as the default.
Methods inherited from Base
Methods inherited from Common
#initialize, #log, #nitpick, #noop, #noop=, #noop?, #preview, #preview=, #preview?, #preview_for, #superuser?, #writing, #writing=, #writing?
Constructor Details
This class inherits a constructor from AutomateIt::Common
Instance Attribute Details
#drivers ⇒ Object
Drivers for this manager as a hash of driver tokens to driver instances.
51 52 53 |
# File 'lib/automateit/plugin/manager.rb', line 51 def drivers @drivers end |
Class Method Details
.abstract_manager ⇒ Object
Declare that this manager class is abstract. It can be subclassed but will not be instantiated by the Interpreter.
32 33 34 |
# File 'lib/automateit/plugin/manager.rb', line 32 def self.abstract_manager classes.delete(self) end |
.alias_methods(*methods) ⇒ Object
Methods to alias into the Interpreter, specified as an array of symbols.
40 41 42 43 44 45 46 47 |
# File 'lib/automateit/plugin/manager.rb', line 40 def self.alias_methods(*methods) if methods.empty? self.aliased_methods else self.aliased_methods ||= Set.new self.aliased_methods.merge(methods.flatten) end end |
.driver_classes ⇒ Object
Driver classes used by this Manager.
54 55 56 |
# File 'lib/automateit/plugin/manager.rb', line 54 def self.driver_classes Driver.classes[token] || [] end |
.inherited(subclass) ⇒ Object
Register managers.
26 27 28 |
# File 'lib/automateit/plugin/manager.rb', line 26 def self.inherited(subclass) # :nodoc: classes << subclass unless classes.include?(subclass) end |
Instance Method Details
#[](token) ⇒ Object
Returns the Driver with the specified token. E.g., :apt
will return the APT
driver.
93 94 95 |
# File 'lib/automateit/plugin/manager.rb', line 93 def [](token) return @drivers[token] end |
#available?(method, *args, &block) ⇒ Boolean
Is a driver available for this method
and args
? Uses automatic-detection routines and returns a boolean to indicate if a suitable driver is available. Unlike #driver_for, this will not raise an exception.
222 223 224 225 226 227 228 229 |
# File 'lib/automateit/plugin/manager.rb', line 222 def available?(method, *args, &block) begin driver_for(method, *args, &block) true rescue NotImplementedError false end end |
#default(token = nil) ⇒ Object
Manipulate the default driver. Without arguments, gets the driver token as a symbol. With argument, sets the default driver to the token
, e.g., the argument :apt
will make the APT
driver the default.
100 101 102 103 104 105 106 |
# File 'lib/automateit/plugin/manager.rb', line 100 def default(token=nil) if token.nil? @default else @default = token end end |
#default=(token) ⇒ Object
Set the default driver to the token
. See also #default.
109 110 111 |
# File 'lib/automateit/plugin/manager.rb', line 109 def default=(token) default(token) end |
#dispatch(*args, &block) ⇒ Object
Dispatch a method by guessing its name. This is the recommended way to write wrappers for a Manager methods.
Example:
class MyManager < Plugin::Manager
# Your RDoc here
def my_method(*args)
# Will guess that you want to +dispatch_to+ the +my_method+ by
# introspecting the name of the wrapper method.
dispatch(*args)
end
...
end
126 127 128 129 130 |
# File 'lib/automateit/plugin/manager.rb', line 126 def dispatch(*args, &block) # Extract caller's method as symbol to save user from having to specify it method = caller[0].match(/:in `(.+?)'/)[1].to_sym dispatch_to(method, *args, &block) end |
#dispatch_safely(*args, &block) ⇒ Object
Same as #dispatch but returns nil if couldn’t dispatch, rather than raising an exception.
174 175 176 177 |
# File 'lib/automateit/plugin/manager.rb', line 174 def dispatch_safely(*args, &block) method = caller[0].match(/:in `(.+?)'/)[1].to_sym dispatch_safely_to(method, *args, &block) end |
#dispatch_safely_to(method, *args, &block) ⇒ Object
Same as #dispatch_to but returns nil if couldn’t dispatch, rather than raising an exception.
164 165 166 167 168 169 170 |
# File 'lib/automateit/plugin/manager.rb', line 164 def dispatch_safely_to(method, *args, &block) begin dispatch_to(method, *args, &block) rescue NotImplementedError nil end end |
#dispatch_to(method, *args, &block) ⇒ Object
Dispatch the method
with args
and block
to the appropriate driver. If the arguments include an option of the form :with => :mytoken
argument, then the method will be dispatched to the driver represented by :mytoken
. If no :with argument is specified, the most-suitable driver will be automatically selected. If no suitable driver is available, a NotImplementedError will be raised.
Examples:
# Run 'hostnames' method on most appropriate AddressManager driver:
address_manager.dispatch_to(:hostnames)
# Run AddressManager::Portable#hostnames
address_manager.dispatch_to(:hostnames, :with => :portable)
You will typically not want to use this method directly and instead write wrappers that call #dispatch because it can guess the name of the method
argument for you.
149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/automateit/plugin/manager.rb', line 149 def dispatch_to(method, *args, &block) list, = args_and_opts(*args) driver = \ if and [:with] @drivers[[:with].to_sym] elsif default @drivers[default.to_sym] else driver_for(method, *args, &block) end driver.send(method, *args, &block) end |
#driver_for(method, *args, &block) ⇒ Object
Get the most suitable driver for this method
and args
. Uses automatic-detection routines and returns the most suitable driver instance found, else raises a NotImplementedError if no suitable driver is found.
204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/automateit/plugin/manager.rb', line 204 def driver_for(method, *args, &block) begin driver, level = driver_suitability_levels_for(method, *args, &block).sort_by{|k,v| v}.last rescue IndexError driver = nil level = -1 end if driver and level > 0 return @drivers[driver] else raise NotImplementedError.new("can't find driver for method '#{method}' with arguments: #{args.inspect}") end end |
#driver_suitability_levels_for(method, *args, &block) ⇒ Object
Returns structure which helps choose a suitable driver for the method
and args
. Result is a hash of driver tokens and their suitability levels.
For example, if we ask the AddressManager for suitability levels for the AddressManager#hostnames method, we might find that there are two drivers (:portable is the token for AddressManager::Portable) and that the :linux driver is most appropriate because it has the highest suitability level:
address_manager.driver_suitability_levels_for(:hostnames)
# => {:portable=>1, :linux=>2}
191 192 193 194 195 196 197 198 |
# File 'lib/automateit/plugin/manager.rb', line 191 def driver_suitability_levels_for(method, *args, &block) results = {} @drivers.each_pair do |name, driver| next unless driver.respond_to?(method) results[name] = driver.suitability(method, *args, &block) end return results end |
#instantiate_drivers ⇒ Object
Instantiate drivers for this manager. This method is smart enough that it can be called multiple times and will only instantiate drivers it hasn’t instantiated yet. All drivers will share an instance of the Interpreter, thus providing common state storage.
77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/automateit/plugin/manager.rb', line 77 def instantiate_drivers @drivers ||= {} self.class.driver_classes.each do |driver_class| driver_token = driver_class.token unless @drivers[driver_token] @drivers[driver_token] = driver_class.allocate end end self.class.driver_classes.each do |driver_class| driver_token = driver_class.token @drivers[driver_token].setup(:interpreter => @interpreter) end end |
#setup(opts = {}) ⇒ Object
Options:
-
:default – The token of the driver to set as the default.
60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/automateit/plugin/manager.rb', line 60 def setup(opts={}) super(opts) @default ||= nil instantiate_drivers if driver = opts[:default] || opts[:driver] default(opts[:default]) if opts[:default] @drivers[driver].setup(opts) end end |