diff options
Diffstat (limited to 'lib/puppet/interface.rb')
| -rw-r--r-- | lib/puppet/interface.rb | 103 |
1 files changed, 55 insertions, 48 deletions
diff --git a/lib/puppet/interface.rb b/lib/puppet/interface.rb index 2e52de43d..901e83af6 100644 --- a/lib/puppet/interface.rb +++ b/lib/puppet/interface.rb @@ -1,60 +1,31 @@ require 'puppet' +require 'puppet/util/autoload' class Puppet::Interface + require 'puppet/interface/action_manager' - class << self - attr_accessor :default_format, :abstract - - # Is this an actual interface, or a base class for others? - def abstract? - abstract - end - - def set_default_format(format) - self.default_format = format.to_sym - end - end - + include Puppet::Interface::ActionManager + extend Puppet::Interface::ActionManager # This is just so we can search for actions. We only use its # list of directories to search. def self.autoloader - require 'puppet/util/autoload' @autoloader ||= Puppet::Util::Autoload.new(:application, "puppet/interface") end - # Declare that this app can take a specific action, and provide - # the code to do so. - def self.action(name, &block) - @actions ||= [] - name = name.to_s.downcase.to_sym - raise "Action #{name} already defined for #{self}" if actions.include?(name) - - @actions << name - - define_method(name, &block) - end - - def self.actions - @actions ||= [] - (if superclass.respond_to?(:actions) - @actions + superclass.actions - else - @actions - end).sort { |a,b| a.to_s <=> b.to_s } - end - # Return an interface by name, loading from disk if necessary. def self.interface(name) - require "puppet/interface/#{name.to_s.downcase}" - self.const_get(name.to_s.capitalize) + @interfaces ||= {} + unless @interfaces[unify_name(name)] + require "puppet/interface/#{unify_name(name)}" + end + @interfaces[unify_name(name)] rescue Exception => detail puts detail.backtrace if Puppet[:trace] $stderr.puts "Unable to find interface '#{name.to_s}': #{detail}." - Kernel::exit(1) end # Try to find actions defined in other files. - def self.load_actions + def self.load_actions(name) path = "puppet/interface/#{name}" autoloader.search_directories.each do |dir| @@ -68,17 +39,43 @@ class Puppet::Interface end end + def self.register_interface(name, instance) + @interfaces ||= {} + @interfaces[unify_name(name)] = instance + const_set(name2const(name), instance) + end + + def self.unload_interface(name) + @interfaces ||= {} + @interfaces.delete(unify_name(name)) + const = name2const(name) + const_get(const) + remove_const(const) + rescue + # nothing - if the constant-getting fails, just return + end + + def self.unify_name(name) + name.to_s.downcase.to_sym + end + + def self.name2const(name) + name.to_s.capitalize + end + + attr_accessor :default_format + + def set_default_format(format) + self.default_format = format.to_sym + end + # Return the interface name. - def self.name + def name @name || self.to_s.sub(/.+::/, '').downcase end attr_accessor :type, :verb, :name, :arguments - def action?(name) - self.class.actions.include?(name.to_sym) - end - # Print the configuration for the current terminus class action :showconfig do |*args| if t = indirection.terminus_class @@ -88,12 +85,22 @@ class Puppet::Interface end end - def initialize(options = {}) + def initialize(name, options = {}, &block) + @name = name + + @default_format = :pson options.each { |opt, val| send(opt.to_s + "=", val) } - Puppet::Util::Log.newdestination :console + # We have to register before loading actions, + # since the actions require the registration + # Use the full class name, so this works with + # subclasses. + Puppet::Interface.register_interface(name, self) - self.class.load_actions - end + Puppet::Interface.load_actions(name) + if block_given? + instance_eval(&block) + end + end end |
