summaryrefslogtreecommitdiffstats
path: root/lib/puppet/application.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet/application.rb')
-rw-r--r--lib/puppet/application.rb196
1 files changed, 82 insertions, 114 deletions
diff --git a/lib/puppet/application.rb b/lib/puppet/application.rb
index 7b404a906..49a146ffe 100644
--- a/lib/puppet/application.rb
+++ b/lib/puppet/application.rb
@@ -8,26 +8,28 @@ require 'optparse'
# * representing execution status
#
# === Usage
-# The application is a Puppet::Application object that register itself in the list
-# of available application. Each application needs a +name+ and a getopt +options+
-# description array.
+# An application is a subclass of Puppet::Application.
#
-# The executable uses the application object like this:
+# For legacy compatibility,
# Puppet::Application[:example].run
+# is equivalent to
+# Puppet::Application::Example.new.run
#
#
-# Puppet::Application.new(:example) do
+# class Puppet::Application::Example << Puppet::Application
#
-# preinit do
+# def preinit
# # perform some pre initialization
# @all = false
# end
#
-# # dispatch is called to know to what command to call
-# dispatch do
-# Puppet::Util::CommandLine.args.shift
+# # run_command is called to actually run the specified command
+# def run_command
+# send Puppet::Util::CommandLine.args.shift
# end
#
+# # option uses metaprogramming to create a method
+# # and also tells the option parser how to invoke that method
# option("--arg ARGUMENT") do |v|
# @args << v
# end
@@ -40,18 +42,18 @@ require 'optparse'
# @all = v
# end
#
-# unknown do |opt,arg|
+# def handle_unknown(opt,arg)
# # last chance to manage an option
# ...
# # let's say to the framework we finally handle this option
# true
# end
#
-# command(:read) do
+# def read
# # read action
# end
#
-# command(:write) do
+# def write
# # writeaction
# end
#
@@ -117,9 +119,6 @@ class Puppet::Application
BINDIRS = %w{sbin bin}.map{|dir| File.expand_path(File.dirname(__FILE__)) + "/../../#{dir}/*"}.join(" ")
- @@applications = {}
- def self.applications; @@applications end
-
class << self
include Puppet::Util
@@ -172,128 +171,97 @@ class Puppet::Application
Process.kill(:HUP, $$) if restart_requested?
result
end
- end
- attr_reader :options, :opt_parser
+ def should_parse_config
+ @parse_config = true
+ end
- def self.[](name)
- name = symbolize(name)
- @@applications[name]
- end
+ def should_not_parse_config
+ @parse_config = false
+ end
- def should_parse_config
- @parse_config = true
- end
+ def should_parse_config?
+ if ! defined? @parse_config
+ @parse_config = true
+ end
+ return @parse_config
+ end
- def should_not_parse_config
- @parse_config = false
- end
+ # used to declare code that handle an option
+ def option(*options, &block)
+ long = options.find { |opt| opt =~ /^--/ }.gsub(/^--(?:\[no-\])?([^ =]+).*$/, '\1' ).gsub('-','_')
+ fname = symbolize("handle_#{long}")
+ if (block_given?)
+ define_method(fname, &block)
+ else
+ define_method(fname) do |value|
+ self.options["#{long}".to_sym] = value
+ end
+ end
+ @opt_parser_commands ||= []
+ @opt_parser_commands << [options, fname]
+ end
- def should_parse_config?
- unless @parse_config.nil?
- return @parse_config
+ def banner(banner = nil)
+ @banner = banner unless banner.nil?
end
- @parse_config = true
- end
- # used to declare a new command
- def command(name, &block)
- meta_def(symbolize(name), &block)
- end
+ def new_option_parser( target )
+ @banner ||= nil
- # used as a catch-all for unknown option
- def unknown(&block)
- meta_def(:handle_unknown, &block)
- end
+ opt_parser = OptionParser.new(@banner)
- # used to declare code that handle an option
- def option(*options, &block)
- long = options.find { |opt| opt =~ /^--/ }.gsub(/^--(?:\[no-\])?([^ =]+).*$/, '\1' ).gsub('-','_')
- fname = "handle_#{long}"
- if (block_given?)
- meta_def(symbolize(fname), &block)
- else
- meta_def(symbolize(fname)) do |value|
- self.options["#{long}".to_sym] = value
+ @opt_parser_commands ||= []
+ @opt_parser_commands.each do |options, fname|
+ opt_parser.on(*options) do |value|
+ target.send(fname, value)
+ end
end
+ opt_parser
end
- @opt_parser.on(*options) do |value|
- self.send(symbolize(fname), value)
+
+ def find(name)
+ self.const_get(name.to_s.capitalize)
end
- end
- # used to declare accessor in a more natural way in the
- # various applications
- def attr_accessor(*args)
- args.each do |arg|
- meta_def(arg) do
- instance_variable_get("@#{arg}".to_sym)
- end
- meta_def("#{arg}=") do |value|
- instance_variable_set("@#{arg}".to_sym, value)
- end
+ def [](name)
+ find(name).new
end
end
- # used to declare code run instead the default setup
- def setup(&block)
- meta_def(:run_setup, &block)
- end
+ attr_reader :options, :opt_parser
- # used to declare code to choose which command to run
- def dispatch(&block)
- meta_def(:get_command, &block)
+ # Every app responds to --version
+ option("--version", "-V") do |arg|
+ puts "%s" % Puppet.version
+ exit
end
- # used to execute code before running anything else
- def preinit(&block)
- meta_def(:run_preinit, &block)
+ # Every app responds to --help
+ option("--help", "-h") do |v|
+ help
end
- def initialize(name, banner = nil, &block)
- @opt_parser = OptionParser.new(banner)
-
- @name = symbolize(name)
-
- init_default
-
- @options = {}
-
- instance_eval(&block) if block_given?
-
- @@applications[@name] = self
+ def should_parse_config?
+ self.class.should_parse_config?
end
- # initialize default application behaviour
- def init_default
- setup do
- default_setup
- end
-
- dispatch do
- :main
- end
-
- # empty by default
- preinit do
- end
+ # override to execute code before running anything else
+ def preinit
+ end
- option("--version", "-V") do |arg|
- puts "%s" % Puppet.version
- exit
- end
+ def initialize
+ @opt_parser = self.class.new_option_parser( self )
- option("--help", "-h") do |v|
- help
- end
+ @options = {}
end
# This is the main application entry point
def run
- exit_on_fail("initialize") { run_preinit }
+ exit_on_fail("initialize") { preinit }
exit_on_fail("parse options") { parse_options }
exit_on_fail("parse configuration file") { Puppet.settings.parse } if should_parse_config?
- exit_on_fail("prepare for execution") { run_setup }
+ exit_on_fail("prepare for execution") { setup }
exit_on_fail("run") { run_command }
end
@@ -302,14 +270,10 @@ class Puppet::Application
end
def run_command
- if command = get_command() and respond_to?(command)
- send(command)
- else
- main
- end
+ main
end
- def default_setup
+ def setup
# Handle the logging settings
if options[:debug] or options[:verbose]
Puppet::Util::Log.newdestination(:console)
@@ -370,10 +334,14 @@ class Puppet::Application
exit(code)
end
+ def name
+ self.class.to_s.sub(/.*::/,"").downcase.to_sym
+ end
+
def help
if Puppet.features.usage?
# RH:FIXME: My goodness, this is ugly.
- ::RDoc.const_set("PuppetSourceFile", @name)
+ ::RDoc.const_set("PuppetSourceFile", name)
def (::RDoc).caller
docfile = `grep -l 'Puppet::Application\\[:#{::RDoc::PuppetSourceFile}\\]' #{BINDIRS}`.chomp
super << "#{docfile}:0"
@@ -384,7 +352,7 @@ class Puppet::Application
exit
end
rescue Errno::ENOENT
- puts "No help available for puppet #@name"
+ puts "No help available for puppet #{name}"
exit
end