diff options
author | Jesse Wolfe <jes5199@gmail.com> | 2010-04-30 16:05:43 -0700 |
---|---|---|
committer | test branch <puppet-dev@googlegroups.com> | 2010-02-17 06:50:53 -0800 |
commit | d038a1d3ddffdf1366c78fe31118e9f15c1c6ed1 (patch) | |
tree | 6ff89deef467aa58b8b50ea06200b5d2f2dc97ac /lib/puppet/application.rb | |
parent | 7656ba73ddfd883b36a01c81147ae69e80773bce (diff) | |
download | puppet-d038a1d3ddffdf1366c78fe31118e9f15c1c6ed1.tar.gz puppet-d038a1d3ddffdf1366c78fe31118e9f15c1c6ed1.tar.xz puppet-d038a1d3ddffdf1366c78fe31118e9f15c1c6ed1.zip |
Refactor #3706 Reify eigenclasses of Applications
The Puppet::Application DSL is complicated by the fact that it operates
on eigenclasses of instances of Puppet::Application, rather than
subclassing it.
This patch reifies the eigenclasses as subclasses of
Puppet::Application.
Signed-off-by: Jesse Wolfe <jes5199@gmail.com>
Diffstat (limited to 'lib/puppet/application.rb')
-rw-r--r-- | lib/puppet/application.rb | 196 |
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 |