Signed-off-by: Brice Figureau <brice-pup...@daysofwonder.com>
---
 bin/puppet                       |  191 +------------------------
 lib/puppet/application/puppet.rb |  151 ++++++++++++++++++++
 spec/unit/application/puppet.rb  |  291 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 444 insertions(+), 189 deletions(-)
 create mode 100644 lib/puppet/application/puppet.rb
 create mode 100644 spec/unit/application/puppet.rb

diff --git a/bin/puppet b/bin/puppet
index e3a9c4f..ec609ce 100755
--- a/bin/puppet
+++ b/bin/puppet
@@ -64,192 +64,5 @@
 # Copyright (c) 2005 Reductive Labs, LLC
 # Licensed under the GNU Public License
 
-require 'puppet'
-require 'puppet/network/handler'
-require 'puppet/network/client'
-require 'getoptlong'
-
-options = [
-    [ "--debug",       "-d",                   GetoptLong::NO_ARGUMENT ],
-    [ "--help",                "-h",                   GetoptLong::NO_ARGUMENT 
],
-    [ "--logdest",     "-l",                   GetoptLong::REQUIRED_ARGUMENT ],
-    [ "--execute",     "-e",                   GetoptLong::REQUIRED_ARGUMENT ],
-    [ "--loadclasses", "-L",           GetoptLong::NO_ARGUMENT ],
-    [ "--verbose",  "-v",                      GetoptLong::NO_ARGUMENT ],
-    [ "--use-nodes",                           GetoptLong::NO_ARGUMENT ],
-    [ "--detailed-exitcodes",          GetoptLong::NO_ARGUMENT ],
-    [ "--version",  "-V",           GetoptLong::NO_ARGUMENT ]
-]
-
-# Add all of the config parameters as valid options.
-Puppet.settings.addargs(options)
-
-result = GetoptLong.new(*options)
-
-options = {
-    :debug => false,
-    :verbose => false,
-    :noop => false,
-    :logfile => false,
-    :loadclasses => false,
-    :logset => false,
-    :code => nil,
-    :detailed_exits => false,
-}
-
-
-master = {
-    :Local => true
-}
-
-begin
-    result.each { |opt,arg|
-        case opt
-            when "--version"
-                puts "%s" % Puppet.version
-                exit
-            when "--help"
-                if Puppet.features.usage?
-                    RDoc::usage && exit
-                else
-                    puts "No help available unless you have RDoc::usage 
installed"
-                    exit
-                end
-            when "--use-nodes"
-                options[:UseNodes] = true
-            when "--verbose"
-                options[:verbose] = true
-            when "--debug"
-                options[:debug] = true
-            when "--execute"
-                options[:code] = arg
-            when "--loadclasses"
-                options[:loadclasses] = true
-            when "--detailed-exitcodes"
-                options[:detailed_exits] = true
-            when "--logdest"
-                begin
-                    Puppet::Util::Log.newdestination(arg)
-                    options[:logset] = true
-                rescue => detail
-                    $stderr.puts detail.to_s
-                end
-            else
-                Puppet.settings.handlearg(opt, arg)
-        end
-    }
-rescue GetoptLong::InvalidOption => detail
-    $stderr.puts "Try '#{$0} --help'"
-    exit(1)
-end
-
-Puppet.parse_config
-
-# Now parse the config
-if Puppet[:config] and File.exists? Puppet[:config]
-    Puppet.settings.parse(Puppet[:config])
-end
-
-if Puppet.settings.print_configs?
-    exit(Puppet.settings.print_configs ? 0 : 1)
-end
-
-# If noop is set, then also enable diffs
-if Puppet[:noop]
-    Puppet[:show_diff] = true
-end
-
-unless options[:logset]
-    Puppet::Util::Log.newdestination(:console)
-end
-
-client = nil
-server = nil
-
-trap(:INT) do
-    $stderr.puts "Exiting"
-    exit(1)
-end
-
-if options[:debug]
-    Puppet::Util::Log.level = :debug
-elsif options[:verbose]
-    Puppet::Util::Log.level = :info
-end
-
-# Set our code or file to use.
-if options[:code] or ARGV.length == 0
-    Puppet[:code] = options[:code] || STDIN.read
-else
-    Puppet[:manifest] = ARGV.shift
-end
-
-if Puppet[:parseonly]
-    begin
-        Puppet::Parser::Interpreter.new.parser(Puppet[:environment])
-    rescue => detail
-        Puppet.err detail
-        exit 1
-    end
-    exit 0
-end
-
-# Collect our facts.
-facts = Puppet::Node::Facts.find(Puppet[:certname])
-
-# Find our Node
-unless node = Puppet::Node.find(Puppet[:certname])
-    raise "Could not find node %s" % Puppet[:certname]
-end
-
-# Merge in the facts.
-node.merge(facts.values)
-
-# Allow users to load the classes that puppetd creates.
-if options[:loadclasses]
-    file = Puppet[:classfile]
-    if FileTest.exists?(file)
-        unless FileTest.readable?(file)
-            $stderr.puts "%s is not readable" % file
-            exit(63)
-        end
-
-        node.classes = File.read(file).split(/[\s\n]+/)
-    end
-end
-
-begin
-    # Compile our catalog
-    starttime = Time.now
-    catalog = Puppet::Resource::Catalog.find(node.name, :use_node => node)
-
-    # Translate it to a RAL catalog
-    catalog = catalog.to_ral
-
-    catalog.host_config = true if Puppet[:graph] or Puppet[:report]
-
-    catalog.finalize
-
-    catalog.retrieval_duration = Time.now - starttime
-
-    # And apply it
-    transaction = catalog.apply
-
-    status = 0
-    if not Puppet[:noop] and options[:detailed_exits] then
-        transaction.generate_report
-       status |= 2 if transaction.report.metrics["changes"][:total] > 0
-        status |= 4 if transaction.report.metrics["resources"][:failed] > 0
-    end
-    exit(status)
-rescue => detail
-    if Puppet[:trace]
-        puts detail.backtrace
-    end
-    if detail.is_a?(XMLRPC::FaultException)
-        $stderr.puts detail.message
-    else
-        $stderr.puts detail
-    end
-    exit(1)
-end
+require 'puppet/application/puppet'
+Puppet::Application[:puppet].run
diff --git a/lib/puppet/application/puppet.rb b/lib/puppet/application/puppet.rb
new file mode 100644
index 0000000..cace097
--- /dev/null
+++ b/lib/puppet/application/puppet.rb
@@ -0,0 +1,151 @@
+require 'puppet'
+require 'puppet/application'
+require 'puppet/network/handler'
+require 'puppet/network/client'
+
+puppet_options = [
+    [ "--debug",       "-d",                   GetoptLong::NO_ARGUMENT ],
+    [ "--help",                "-h",                   GetoptLong::NO_ARGUMENT 
],
+    [ "--logdest",     "-l",                   GetoptLong::REQUIRED_ARGUMENT ],
+    [ "--execute",     "-e",                   GetoptLong::REQUIRED_ARGUMENT ],
+    [ "--loadclasses", "-L",           GetoptLong::NO_ARGUMENT ],
+    [ "--verbose",  "-v",                      GetoptLong::NO_ARGUMENT ],
+    [ "--use-nodes",                           GetoptLong::NO_ARGUMENT ],
+    [ "--detailed-exitcodes",          GetoptLong::NO_ARGUMENT ],
+    [ "--version",  "-V",           GetoptLong::NO_ARGUMENT ]
+]
+
+Puppet::Application.new(:puppet, puppet_options) do
+
+    should_parse_config
+
+    dispatch do
+        return Puppet[:parseonly] ? :parseonly : :main
+    end
+
+    command(:parseonly) do
+        begin
+            Puppet::Parser::Interpreter.new.parser(Puppet[:environment])
+        rescue => detail
+            Puppet.err detail
+            exit 1
+        end
+        exit 0
+    end
+
+    command(:main) do
+        # Collect our facts.
+        facts = Puppet::Node::Facts.find(Puppet[:certname])
+
+        # Find our Node
+        unless node = Puppet::Node.find(Puppet[:certname])
+            raise "Could not find node %s" % Puppet[:certname]
+        end
+
+        # Merge in the facts.
+        node.merge(facts.values)
+
+        # Allow users to load the classes that puppetd creates.
+        if options[:loadclasses]
+            file = Puppet[:classfile]
+            if FileTest.exists?(file)
+                unless FileTest.readable?(file)
+                    $stderr.puts "%s is not readable" % file
+                    exit(63)
+                end
+                node.classes = File.read(file).split(/[\s\n]+/)
+            end
+        end
+
+        begin
+            # Compile our catalog
+            starttime = Time.now
+            catalog = Puppet::Resource::Catalog.find(node.name, :use_node => 
node)
+
+            # Translate it to a RAL catalog
+            catalog = catalog.to_ral
+
+            catalog.host_config = true if Puppet[:graph] or Puppet[:report]
+
+            catalog.finalize
+
+            catalog.retrieval_duration = Time.now - starttime
+
+            # And apply it
+            transaction = catalog.apply
+
+            status = 0
+            if not Puppet[:noop] and options[:detailed_exits] then
+                transaction.generate_report
+                status |= 2 if transaction.report.metrics["changes"][:total] > 0
+                status |= 4 if 
transaction.report.metrics["resources"][:failed] > 0
+            end
+            exit(status)
+        rescue => detail
+            if Puppet[:trace]
+                puts detail.backtrace
+            end
+            if detail.is_a?(XMLRPC::FaultException)
+                $stderr.puts detail.message
+            else
+                $stderr.puts detail
+            end
+            exit(1)
+        end
+    end
+
+    setup do
+        # Now parse the config
+        if Puppet[:config] and File.exists? Puppet[:config]
+            Puppet.settings.parse(Puppet[:config])
+        end
+
+        if Puppet.settings.print_configs?
+            exit(Puppet.settings.print_configs ? 0 : 1)
+        end
+
+        # If noop is set, then also enable diffs
+        if Puppet[:noop]
+            Puppet[:show_diff] = true
+        end
+
+        unless options[:logset]
+            Puppet::Util::Log.newdestination(:console)
+        end
+        client = nil
+        server = nil
+
+        trap(:INT) do
+            $stderr.puts "Exiting"
+            exit(1)
+        end
+
+        if options[:debug]
+            Puppet::Util::Log.level = :debug
+        elsif options[:verbose]
+            Puppet::Util::Log.level = :info
+        end
+
+        # Set our code or file to use.
+        if options[:code] or ARGV.length == 0
+            Puppet[:code] = options[:code] || STDIN.read
+        else
+            Puppet[:manifest] = ARGV.shift
+        end
+    end
+
+
+    option(:logdest) do |arg|
+        begin
+            Puppet::Util::Log.newdestination(arg)
+            options[:logset] = true
+        rescue => detail
+            $stderr.puts detail.to_s
+        end
+    end
+
+    option(:version) do |arg|
+        puts "%s" % Puppet.version
+        exit
+    end
+end
\ No newline at end of file
diff --git a/spec/unit/application/puppet.rb b/spec/unit/application/puppet.rb
new file mode 100644
index 0000000..cc5017f
--- /dev/null
+++ b/spec/unit/application/puppet.rb
@@ -0,0 +1,291 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/application/puppet'
+
+describe "Puppet" do
+    before :each do
+        @puppet = Puppet::Application[:puppet]
+    end
+
+    it "should declare a version option" do
+        @puppet.should respond_to(:handle_version)
+    end
+
+    it "should ask Puppet::Application to parse Puppet configuration file" do
+        @puppet.should_parse_config?.should be_true
+    end
+
+    describe "when applying options" do
+        it "should exit after printing the version" do
+            @puppet.stubs(:puts)
+
+            lambda { @puppet.handle_version(nil) }.should 
raise_error(SystemExit)
+        end
+
+        it "should set the log destination with --logdest" do
+            Puppet::Log.expects(:newdestination).with("console")
+
+            @puppet.handle_logdest("console")
+        end
+
+        it "should put the logset options to true" do
+            @puppet.options.expects(:[]=).with(:logset,true)
+
+            @puppet.handle_logdest("console")
+        end
+    end
+
+    describe "during setup" do
+
+        before :each do
+            Puppet::Log.stubs(:newdestination)
+            Puppet.stubs(:trap)
+            Puppet::Log.stubs(:level=)
+            Puppet.stubs(:parse_config)
+            Puppet::Network::Client.dipper.stubs(:new)
+            STDIN.stubs(:read)
+
+            @puppet.options.stubs(:[]).with(any_parameters)
+        end
+
+        it "should parse additionnal Puppet config if set to" do
+            Puppet.stubs(:[]).with(:noop)
+            Puppet.stubs(:[]).with(:config).returns("file.conf")
+            File.stubs(:exists?).with("file.conf").returns(true)
+
+            Puppet.settings.expects(:parse).with("file.conf")
+
+            @puppet.run_setup
+        end
+
+        it "should set show_diff on --noop" do
+            Puppet.stubs(:[]=)
+            Puppet.stubs(:[]).with(:config)
+            Puppet.stubs(:[]).with(:noop).returns(true)
+
+            Puppet.expects(:[]=).with(:show_diff, true)
+
+            @puppet.run_setup
+        end
+
+        it "should set console as the log destination if logdest option wasn't 
provided" do
+            Puppet::Log.expects(:newdestination).with(:console)
+
+            @puppet.run_setup
+        end
+
+        it "should set INT trap" do
+            @puppet.expects(:trap).with(:INT)
+
+            @puppet.run_setup
+        end
+
+        it "should set log level to debug if --debug was passed" do
+            @puppet.options.stubs(:[]).with(:debug).returns(true)
+
+            Puppet::Log.expects(:level=).with(:debug)
+
+            @puppet.run_setup
+        end
+
+        it "should set log level to info if --verbose was passed" do
+            @puppet.options.stubs(:[]).with(:verbose).returns(true)
+
+            Puppet::Log.expects(:level=).with(:info)
+
+            @puppet.run_setup
+        end
+
+        it "should print puppet config if asked to in Puppet config" do
+            @puppet.stubs(:exit)
+            Puppet.settings.stubs(:print_configs?).returns(true)
+
+            Puppet.settings.expects(:print_configs)
+
+            @puppet.run_setup
+        end
+
+        it "should exit after printing puppet config if asked to in Puppet 
config" do
+            Puppet.settings.stubs(:print_configs?).returns(true)
+
+            lambda { @puppet.run_setup }.should raise_error(SystemExit)
+        end
+
+        it "should set the code to run from --code" do
+            @puppet.options.stubs(:[]).with(:code).returns("code to run")
+            Puppet.expects(:[]=).with(:code,"code to run")
+
+            @puppet.run_setup
+        end
+
+        it "should set the code to run from STDIN if no arguments" do
+            ARGV.stubs(:length).returns(0)
+            STDIN.stubs(:read).returns("code to run")
+
+            Puppet.expects(:[]=).with(:code,"code to run")
+
+            @puppet.run_setup
+        end
+
+        it "should set the manifest if some files are passed on command line" 
do
+            ARGV.stubs(:length).returns(1)
+            ARGV.stubs(:shift).returns("site.pp")
+
+            Puppet.expects(:[]=).with(:manifest,"site.pp")
+
+            @puppet.run_setup
+        end
+
+    end
+
+    describe "when executing" do
+
+        it "should dispatch to parseonly if parseonly is set" do
+            Puppet.stubs(:[]).with(:parseonly).returns(true)
+
+            @puppet.get_command.should == :parseonly
+        end
+
+        it "should dispatch to main if parseonly is not set" do
+            Puppet.stubs(:[]).with(:parseonly).returns(false)
+
+            @puppet.get_command.should == :main
+        end
+
+        describe "the parseonly command" do
+            before :each do
+                Puppet.stubs(:[]).with(:environment)
+                Puppet.stubs(:[]).with(:manifest).returns("site.pp")
+                @interpreter = stub_everything
+                Puppet.stubs(:err)
+                @puppet.stubs(:exit)
+                Puppet::Parser::Interpreter.stubs(:new).returns(@interpreter)
+            end
+
+            it "should delegate to the Puppet Parser" do
+
+                @interpreter.expects(:parser)
+
+                @puppet.parseonly
+            end
+
+            it "should exit with exit code 0 if no error" do
+                @puppet.expects(:exit).with(0)
+
+                @puppet.parseonly
+            end
+
+            it "should exit with exit code 1 if error" do
+                @interpreter.stubs(:parser).raises(Puppet::ParseError)
+
+                @puppet.expects(:exit).with(1)
+
+                @puppet.parseonly
+            end
+
+        end
+
+        describe "the main command" do
+            before :each do
+                Puppet.stubs(:[])
+                Puppet.stubs(:[]).with(:trace).returns(true)
+
+                @puppet.options.stubs(:[])
+
+                @facts = stub_everything 'facts'
+                Puppet::Node::Facts.stubs(:find).returns(@facts)
+
+                @node = stub_everything 'node'
+                Puppet::Node.stubs(:find).returns(@node)
+
+                @catalog = stub_everything 'catalog'
+                @catalog.stubs(:to_ral).returns(@catalog)
+                Puppet::Resource::Catalog.stubs(:find).returns(@catalog)
+
+                @transaction = stub_everything 'transaction'
+                @catalog.stubs(:apply).returns(@transaction)
+
+                @puppet.stubs(:exit)
+            end
+
+            it "should collect the node facts" do
+                Puppet::Node::Facts.expects(:find).returns(@facts)
+
+                @puppet.main
+            end
+
+            it "should find the node" do
+                Puppet::Node.expects(:find).returns(@node)
+
+                @puppet.main
+            end
+
+            it "should raise an error if we can't find the node" do
+                Puppet::Node.expects(:find).returns(nil)
+
+                lambda { @puppet.main }.should raise_error
+            end
+
+            it "should merge in our node the loaded facts" do
+                @facts.stubs(:values).returns("values")
+
+                @node.expects(:merge).with("values")
+
+                @puppet.main
+            end
+
+            it "should load custom classes if loadclasses" do
+                @puppet.options.stubs(:[]).with(:loadclasses).returns(true)
+                
Puppet.stubs(:[]).with(:classfile).returns("/etc/puppet/classes.txt")
+                
FileTest.stubs(:exists?).with("/etc/puppet/classes.txt").returns(true)
+                
FileTest.stubs(:readable?).with("/etc/puppet/classes.txt").returns(true)
+                
File.stubs(:read).with("/etc/puppet/classes.txt").returns("class")
+
+                @node.expects(:classes=)
+
+                @puppet.main
+            end
+
+            it "should compile the catalog" do
+                Puppet::Resource::Catalog.expects(:find).returns(@catalog)
+
+                @puppet.main
+            end
+
+            it "should transform the catalog to ral" do
+
+                @catalog.expects(:to_ral).returns(@catalog)
+
+                @puppet.main
+            end
+
+            it "should finalize the catalog" do
+                @catalog.expects(:finalize)
+
+                @puppet.main
+            end
+
+            it "should apply the catalog" do
+                @catalog.expects(:apply)
+
+                @puppet.main
+            end
+
+            it "should generate a report if not noop" do
+                Puppet.stubs(:[]).with(:noop).returns(false)
+                @puppet.options.stubs(:[]).with(:detailed_exits).returns(true)
+                metrics = stub 'metrics', :[] => { :total => 10, :failed => 0}
+                report = stub 'report', :metrics => metrics
+                @transaction.stubs(:report).returns(report)
+
+                @transaction.expects(:generate_report)
+
+                @puppet.main
+            end
+
+        end
+    end
+
+end
\ No newline at end of file
-- 
1.6.0.2


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to puppet-dev@googlegroups.com
To unsubscribe from this group, send email to 
puppet-dev+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to