summaryrefslogtreecommitdiffstats
path: root/lib/puppet/interface
diff options
context:
space:
mode:
authorDaniel Pittman <daniel@puppetlabs.com>2011-04-15 15:34:24 -0700
committerDaniel Pittman <daniel@puppetlabs.com>2011-04-15 15:34:24 -0700
commit0d0318f9f0eadff7f9934d3d02a7081bba05164c (patch)
treedfc6b3d976ac5acf822846c272bdb4451b10aeba /lib/puppet/interface
parent3fe01a34e8397c30a00e7d47b4ac0b93198e1fcf (diff)
parentd80500f42367fa30a00dc12ef4b32b55b350b1ca (diff)
downloadpuppet-0d0318f9f0eadff7f9934d3d02a7081bba05164c.tar.gz
puppet-0d0318f9f0eadff7f9934d3d02a7081bba05164c.tar.xz
puppet-0d0318f9f0eadff7f9934d3d02a7081bba05164c.zip
Merge branch 'feature/2.7.x/6978-face-and-action-options-should-have-hooks-for-various-actions' into 2.7.x
Diffstat (limited to 'lib/puppet/interface')
-rw-r--r--lib/puppet/interface/action.rb39
-rw-r--r--lib/puppet/interface/option.rb47
-rw-r--r--lib/puppet/interface/option_builder.rb31
-rw-r--r--lib/puppet/interface/option_manager.rb4
4 files changed, 95 insertions, 26 deletions
diff --git a/lib/puppet/interface/action.rb b/lib/puppet/interface/action.rb
index 3c18c2aaf..b94298963 100644
--- a/lib/puppet/interface/action.rb
+++ b/lib/puppet/interface/action.rb
@@ -7,8 +7,9 @@ class Puppet::Interface::Action
raise "#{name.inspect} is an invalid action name" unless name.to_s =~ /^[a-z]\w*$/
@face = face
@name = name.to_sym
- @options = {}
attrs.each do |k, v| send("#{k}=", v) end
+
+ @options = {}
end
# This is not nice, but it is the easiest way to make us behave like the
@@ -84,11 +85,21 @@ class Puppet::Interface::Action
internal_name = "#{@name} implementation, required on Ruby 1.8".to_sym
file = __FILE__ + "+eval"
line = __LINE__ + 1
- wrapper = "def #{@name}(*args, &block)
- args << {} unless args.last.is_a? Hash
- args << block if block_given?
- self.__send__(#{internal_name.inspect}, *args)
- end"
+ wrapper = <<WRAPPER
+def #{@name}(*args, &block)
+ if args.last.is_a? Hash then
+ options = args.last
+ else
+ args << (options = {})
+ end
+
+ action = get_action(#{name.inspect})
+ __invoke_decorations(:before, action, args, options)
+ rval = self.__send__(#{internal_name.inspect}, *args)
+ __invoke_decorations(:after, action, args, options)
+ return rval
+end
+WRAPPER
if @face.is_a?(Class)
@face.class_eval do eval wrapper, nil, file, line end
@@ -123,7 +134,19 @@ class Puppet::Interface::Action
(@options.keys + @face.options).sort
end
- def get_option(name)
- @options[name.to_sym] || @face.get_option(name)
+ def get_option(name, with_inherited_options = true)
+ option = @options[name.to_sym]
+ if option.nil? and with_inherited_options
+ option = @face.get_option(name)
+ end
+ option
+ end
+
+ ########################################################################
+ # Support code for action decoration; see puppet/interface.rb for the gory
+ # details of why this is hidden away behind private. --daniel 2011-04-15
+ private
+ def __decorate(type, name, proc)
+ @face.__send__ :__decorate, type, name, proc
end
end
diff --git a/lib/puppet/interface/option.rb b/lib/puppet/interface/option.rb
index ccc2fbba7..2abcd4033 100644
--- a/lib/puppet/interface/option.rb
+++ b/lib/puppet/interface/option.rb
@@ -1,19 +1,6 @@
require 'puppet/interface'
class Puppet::Interface::Option
- attr_reader :parent
- attr_reader :name
- attr_reader :aliases
- attr_reader :optparse
- attr_accessor :desc
-
- def takes_argument?
- !!@argument
- end
- def optional_argument?
- !!@optional_argument
- end
-
def initialize(parent, *declaration, &block)
@parent = parent
@optparse = []
@@ -79,4 +66,38 @@ class Puppet::Interface::Option
raise "#{name.inspect} is an invalid option name" unless name.to_s =~ /^[a-z]\w*$/
name.to_sym
end
+
+
+ def takes_argument?
+ !!@argument
+ end
+ def optional_argument?
+ !!@optional_argument
+ end
+
+
+ attr_reader :parent, :name, :aliases, :optparse
+ attr_accessor :desc
+
+ attr_accessor :before_action
+ def before_action=(proc)
+ proc.is_a? Proc or raise ArgumentError, "before action hook for #{self} is a #{proc.class.name.inspect}, not a proc"
+ @before_action =
+ @parent.__send__(:__decorate, :before, __decoration_name(:before), proc)
+ end
+
+ attr_accessor :after_action
+ def after_action=(proc)
+ proc.is_a? Proc or raise ArgumentError, "after action hook for #{self} is a #{proc.class.name.inspect}, not a proc"
+ @after_action =
+ @parent.__send__(:__decorate, :after, __decoration_name(:after), proc)
+ end
+
+ def __decoration_name(type)
+ if @parent.is_a? Puppet::Interface::Action then
+ :"option #{name} from #{parent.name} #{type} decoration"
+ else
+ :"option #{name} #{type} decoration"
+ end
+ end
end
diff --git a/lib/puppet/interface/option_builder.rb b/lib/puppet/interface/option_builder.rb
index 2240b3e4a..d4e59a4df 100644
--- a/lib/puppet/interface/option_builder.rb
+++ b/lib/puppet/interface/option_builder.rb
@@ -17,9 +17,34 @@ class Puppet::Interface::OptionBuilder
# Metaprogram the simple DSL from the option class.
Puppet::Interface::Option.instance_methods.grep(/=$/).each do |setter|
- next if setter =~ /^=/ # special case, darn it...
+ next if setter =~ /^=/
+ dsl = setter.sub(/=$/, '')
- dsl = setter.to_s.sub(/=$/, '')
- define_method(dsl) do |value| @option.send(setter, value) end
+ unless self.class.methods.include?(dsl)
+ define_method(dsl) do |value| @option.send(setter, value) end
+ end
+ end
+
+ # Override some methods that deal in blocks, not objects.
+ def before_action(&block)
+ block or raise ArgumentError, "#{@option} before_action requires a block"
+ if @option.before_action
+ raise ArgumentError, "#{@option} already has a before_action set"
+ end
+ unless block.arity == 3 then
+ raise ArgumentError, "before_action takes three arguments, action, args, and options"
+ end
+ @option.before_action = block
+ end
+
+ def after_action(&block)
+ block or raise ArgumentError, "#{@option} after_action requires a block"
+ if @option.after_action
+ raise ArgumentError, "#{@option} already has a after_action set"
+ end
+ unless block.arity == 3 then
+ raise ArgumentError, "after_action takes three arguments, action, args, and options"
+ end
+ @option.after_action = block
end
end
diff --git a/lib/puppet/interface/option_manager.rb b/lib/puppet/interface/option_manager.rb
index 56df9760f..d42359c07 100644
--- a/lib/puppet/interface/option_manager.rb
+++ b/lib/puppet/interface/option_manager.rb
@@ -37,10 +37,10 @@ module Puppet::Interface::OptionManager
result.sort
end
- def get_option(name)
+ def get_option(name, with_inherited_options = true)
@options ||= {}
result = @options[name.to_sym]
- unless result then
+ if result.nil? and with_inherited_options then
if self.is_a?(Class) and superclass.respond_to?(:get_option)
result = superclass.get_option(name)
elsif self.class.respond_to?(:get_option)