summaryrefslogtreecommitdiffstats
path: root/lib/puppet/interface.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet/interface.rb')
-rw-r--r--lib/puppet/interface.rb103
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