diff options
author | Brice Figureau <brice-puppet@daysofwonder.com> | 2009-02-14 17:16:09 +0100 |
---|---|---|
committer | Brice Figureau <brice-puppet@daysofwonder.com> | 2009-02-16 20:12:11 +0100 |
commit | 0c71c5cde211808ef6fd744ccbcc82b6cfc38bb5 (patch) | |
tree | 5328d85be48271fd2d34ff78a98f2e4250e3cad4 | |
parent | e317fa9717e648435dbbc62497d73f803b7b2760 (diff) | |
download | puppet-0c71c5cde211808ef6fd744ccbcc82b6cfc38bb5.tar.gz puppet-0c71c5cde211808ef6fd744ccbcc82b6cfc38bb5.tar.xz puppet-0c71c5cde211808ef6fd744ccbcc82b6cfc38bb5.zip |
Move puppetdoc to the Application Controller paradigm
Signed-off-by: Brice Figureau <brice-puppet@daysofwonder.com>
-rwxr-xr-x | bin/puppetdoc | 197 | ||||
-rw-r--r-- | lib/puppet/application/puppetdoc.rb | 198 | ||||
-rwxr-xr-x | spec/unit/application/puppetdoc.rb | 343 |
3 files changed, 543 insertions, 195 deletions
diff --git a/bin/puppetdoc b/bin/puppetdoc index 7c90785cd..87e711056 100755 --- a/bin/puppetdoc +++ b/bin/puppetdoc @@ -59,198 +59,5 @@ # Copyright (c) 2005-2007 Reductive Labs, LLC # Licensed under the GNU Public License -require 'puppet' -require 'puppet/util/reference' -require 'puppet/network/handler' -require 'puppet/util/rdoc' -require 'getoptlong' - -options = [ - [ "--all", "-a", GetoptLong::NO_ARGUMENT ], - [ "--list", "-l", GetoptLong::NO_ARGUMENT ], - [ "--format", "-f", GetoptLong::REQUIRED_ARGUMENT ], - [ "--mode", "-m", GetoptLong::REQUIRED_ARGUMENT ], - [ "--reference", "-r", GetoptLong::REQUIRED_ARGUMENT ], - [ "--help", "-h", GetoptLong::NO_ARGUMENT ], - [ "--outputdir", "-o", GetoptLong::REQUIRED_ARGUMENT ], - [ "--verbose", "-v", GetoptLong::NO_ARGUMENT ], - [ "--debug", "-d", GetoptLong::NO_ARGUMENT ] -] - -# Add all of the config parameters as valid options. -Puppet.settings.addargs(options) -result = GetoptLong.new(*options) - -debug = false - -$tab = " " -options = {:references => [], :mode => :text, :format => :to_rest} - -Reference = Puppet::Util::Reference - -begin - unknown_args = [] - result.each { |opt,arg| - case opt - when "--outputdir" - options[:outputdir] = arg - when "--all" - options[:all] = true - when "--format" - method = "to_%s" % arg - if Reference.method_defined?(method) - options[:format] = method - else - raise "Invalid output format %s" % arg - end - when "--mode" - if Reference.modes.include?(arg) or arg.intern==:rdoc - options[:mode] = arg.intern - else - raise "Invalid output mode %s" % arg - end - when "--list" - puts Reference.references.collect { |r| Reference.reference(r).doc }.join("\n") - exit(0) - when "--reference" - options[:references] << arg.intern - when "--verbose" - options[:verbose] = true - when "--debug" - options[:debug] = true - when "--help" - if Puppet.features.usage? - RDoc::usage && exit - else - puts "No help available unless you have RDoc::usage installed" - exit - end - else - unknown_args << {:opt => opt, :arg => arg } - end - } - - # sole manifest documentation - if ARGV.size > 0 - options[:mode] = :rdoc - manifest = true - end - - # consume the remaining unknown options - # and feed them as settings, but only for rdoc mode - if options[:mode] == :rdoc and unknown_args.size > 0 - unknown_args.each do |option| - # force absolute path for modulepath when passed on commandline - if option[:opt]=="--modulepath" or option[:opt] == "--manifestdir" - option[:arg] = option[:arg].split(':').collect { |p| File.expand_path(p) }.join(':') - end - Puppet.settings.handlearg(option[:opt], option[:arg]) - end - end -rescue GetoptLong::InvalidOption => detail - $stderr.puts "Try '#{$0} --help'" - exit(1) -end - -if options[:mode] == :rdoc # rdoc mode - # hack to get access to puppetmasterd modulepath and manifestdir - Puppet[:name] = "puppetmasterd" - # Now parse the config - Puppet.parse_config - - # Handle the logging settings. - if options[:debug] or options[:verbose] - if options[:debug] - Puppet::Util::Log.level = :debug - else - Puppet::Util::Log.level = :info - end - - Puppet::Util::Log.newdestination(:console) - end -end - -if options[:all] and options[:mode] != :rdoc - # Don't add dynamic references to the "all" list. - options[:references] = Reference.references.reject do |ref| - Reference.reference(ref).dynamic? - end -end - -if options[:references].empty? - options[:references] << :type -end - -case options[:mode] -when :rdoc # rdoc or sole manifest mode - exit_code = 0 - files = [] - unless manifest - files += Puppet[:modulepath].split(':').collect { |p| File.expand_path(p) } - files += Puppet[:manifestdir].split(':').collect { |p| File.expand_path(p) } - end - files += ARGV - Puppet.info "scanning: %s" % files.inspect - Puppet.settings.setdefaults("puppetdoc", - "document_all" => [false, "Document all resources"] - ) - Puppet.settings[:document_all] = options[:all] || false - begin - if manifest - Puppet::Util::RDoc.manifestdoc(files) - else - Puppet::Util::RDoc.rdoc(options[:outputdir], files) - end - rescue => detail - if Puppet[:trace] - puts detail.backtrace - end - $stderr.puts "Could not generate documentation: %s" % detail - exit_code = 1 - end - exit exit_code -when :trac - options[:references].each do |name| - section = Puppet::Util::Reference.reference(name) or raise "Could not find section %s" % name - unless options[:mode] == :pdf - section.trac - end - end -else - text = "" - if options[:references].length > 1 - with_contents = false - else - with_contents = true - end - exit_code = 0 - options[:references].sort { |a,b| a.to_s <=> b.to_s }.each do |name| - raise "Could not find reference %s" % name unless section = Puppet::Util::Reference.reference(name) - - begin - # Add the per-section text, but with no ToC - text += section.send(options[:format], with_contents) - rescue => detail - puts detail.backtrace - $stderr.puts "Could not generate reference %s: %s" % [name, detail] - exit_code = 1 - next - end - end - - unless with_contents # We've only got one reference - text += Puppet::Util::Reference.footer - end - - # Replace the trac links, since they're invalid everywhere else - text.gsub!(/`\w+\s+([^`]+)`:trac:/) { |m| $1 } - - if options[:mode] == :pdf - Puppet::Util::Reference.pdf(text) - else - puts text - end - - exit exit_code -end - +require 'puppet/application/puppetdoc' +Puppet::Application[:puppetdoc].run diff --git a/lib/puppet/application/puppetdoc.rb b/lib/puppet/application/puppetdoc.rb new file mode 100644 index 000000000..99e46cfd1 --- /dev/null +++ b/lib/puppet/application/puppetdoc.rb @@ -0,0 +1,198 @@ +require 'puppet' +require 'puppet/application' +require 'puppet/util/reference' +require 'puppet/network/handler' +require 'puppet/util/rdoc' + +$tab = " " +Reference = Puppet::Util::Reference + +Puppet::Application.new(:puppetdoc) do + + should_not_parse_config + + attr_accessor :unknown_args, :manifest + + preinit do + {:references => [], :mode => :text, :format => :to_rest }.each do |name,value| + options[name] = value + end + @unknown_args = [] + @manifest = false + end + + option("--all","-a") + option("--outputdir OUTPUTDIR","-o") + option("--verbose","-v") + option("--debug","-d") + + option("--format FORMAT", "-f") do |arg| + method = "to_%s" % arg + if Reference.method_defined?(method) + options[:format] = method + else + raise "Invalid output format %s" % arg + end + end + + option("--mode MODE", "-m") do |arg| + if Reference.modes.include?(arg) or arg.intern==:rdoc + options[:mode] = arg.intern + else + raise "Invalid output mode %s" % arg + end + end + + option("--list", "-l") do |arg| + puts Reference.references.collect { |r| Reference.reference(r).doc }.join("\n") + exit(0) + end + + option("--reference REFERENCE", "-r") do |arg| + options[:references] << arg.intern + end + + unknown do |opt, arg| + @unknown_args << {:opt => opt, :arg => arg } + true + end + + dispatch do + return :rdoc if options[:mode] == :rdoc + return :trac if options[:mode] == :trac + return :other + end + + command(:rdoc) do + exit_code = 0 + files = [] + unless @manifest + files += Puppet[:modulepath].split(':').collect { |p| File.expand_path(p) } + files += Puppet[:manifestdir].split(':').collect { |p| File.expand_path(p) } + end + files += ARGV + Puppet.info "scanning: %s" % files.inspect + Puppet.settings.setdefaults("puppetdoc", + "document_all" => [false, "Document all resources"] + ) + Puppet.settings[:document_all] = options[:all] || false + begin + if @manifest + Puppet::Util::RDoc.manifestdoc(files) + else + Puppet::Util::RDoc.rdoc(options[:outputdir], files) + end + rescue => detail + if Puppet[:trace] + puts detail.backtrace + end + $stderr.puts "Could not generate documentation: %s" % detail + exit_code = 1 + end + exit exit_code + end + + command(:trac) do + options[:references].each do |name| + section = Puppet::Util::Reference.reference(name) or raise "Could not find section %s" % name + unless options[:mode] == :pdf + section.trac + end + end + end + + command(:other) do + text = "" + if options[:references].length > 1 + with_contents = false + else + with_contents = true + end + exit_code = 0 + options[:references].sort { |a,b| a.to_s <=> b.to_s }.each do |name| + raise "Could not find reference %s" % name unless section = Puppet::Util::Reference.reference(name) + + begin + # Add the per-section text, but with no ToC + text += section.send(options[:format], with_contents) + rescue => detail + puts detail.backtrace + $stderr.puts "Could not generate reference %s: %s" % [name, detail] + exit_code = 1 + next + end + end + + unless with_contents # We've only got one reference + text += Puppet::Util::Reference.footer + end + + # Replace the trac links, since they're invalid everywhere else + text.gsub!(/`\w+\s+([^`]+)`:trac:/) { |m| $1 } + + if options[:mode] == :pdf + Puppet::Util::Reference.pdf(text) + else + puts text + end + + exit exit_code + end + + setup do + # sole manifest documentation + if ARGV.size > 0 + options[:mode] = :rdoc + @manifest = true + end + + if options[:mode] == :rdoc + setup_rdoc + else + setup_reference + end + end + + def setup_reference + if options[:all] + # Don't add dynamic references to the "all" list. + options[:references] = Reference.references.reject do |ref| + Reference.reference(ref).dynamic? + end + end + + if options[:references].empty? + options[:references] << :type + end + end + + def setup_rdoc + # consume the unknown options + # and feed them as settings + if @unknown_args.size > 0 + @unknown_args.each do |option| + # force absolute path for modulepath when passed on commandline + if option[:opt]=="--modulepath" or option[:opt] == "--manifestdir" + option[:arg] = option[:arg].split(':').collect { |p| File.expand_path(p) }.join(':') + end + Puppet.settings.handlearg(option[:opt], option[:arg]) + end + end + + # hack to get access to puppetmasterd modulepath and manifestdir + Puppet[:name] = "puppetmasterd" + # Now parse the config + Puppet.parse_config + + # Handle the logging settings. + if options[:debug] or options[:verbose] + if options[:debug] + Puppet::Util::Log.level = :debug + else + Puppet::Util::Log.level = :info + end + + Puppet::Util::Log.newdestination(:console) + end + end +end diff --git a/spec/unit/application/puppetdoc.rb b/spec/unit/application/puppetdoc.rb new file mode 100755 index 000000000..fcb000e0a --- /dev/null +++ b/spec/unit/application/puppetdoc.rb @@ -0,0 +1,343 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../spec_helper' + +require 'puppet/application/puppetdoc' + +describe "puppetdoc" do + before :each do + @puppetdoc = Puppet::Application[:puppetdoc] + @puppetdoc.stubs(:puts) + @puppetdoc.run_preinit + end + + it "should ask Puppet::Application to not parse Puppet configuration file" do + @puppetdoc.should_parse_config?.should be_false + end + + it "should declare a other command" do + @puppetdoc.should respond_to(:other) + end + + it "should declare a rdoc command" do + @puppetdoc.should respond_to(:rdoc) + end + + it "should declare a trac command" do + @puppetdoc.should respond_to(:trac) + end + + it "should declare a fallback for unknown options" do + @puppetdoc.should respond_to(:handle_unknown) + end + + it "should declare a preinit block" do + @puppetdoc.should respond_to(:run_preinit) + end + + describe "in preinit" do + it "should set references to []" do + @puppetdoc.run_preinit + + @puppetdoc.options[:references].should == [] + end + + it "should init mode to text" do + @puppetdoc.run_preinit + + @puppetdoc.options[:mode].should == :text + end + + it "should init format to to_rest" do + @puppetdoc.run_preinit + + @puppetdoc.options[:format].should == :to_rest + end + end + + describe "when handling options" do + [:all, :outputdir, :verbose, :debug].each do |option| + it "should declare handle_#{option} method" do + @puppetdoc.should respond_to("handle_#{option}".to_sym) + end + + it "should store argument value when calling handle_#{option}" do + @puppetdoc.options.expects(:[]=).with(option, 'arg') + @puppetdoc.send("handle_#{option}".to_sym, 'arg') + end + end + + it "should store the format if valid" do + Puppet::Util::Reference.stubs(:method_defined?).with('to_format').returns(true) + + @puppetdoc.options.expects(:[]=).with(:format, 'to_format') + + @puppetdoc.handle_format('format') + end + + it "should raise an error if the format is not valid" do + Puppet::Util::Reference.stubs(:method_defined?).with('to_format').returns(false) + lambda { @puppetdoc.handle_format('format') } + end + + it "should store the mode if valid" do + Puppet::Util::Reference.stubs(:modes).returns(stub 'mode', :include? => true) + + @puppetdoc.options.expects(:[]=).with(:mode, :mode) + + @puppetdoc.handle_mode('mode') + end + + it "should store the mode if :rdoc" do + Puppet::Util::Reference.modes.stubs(:include?).with('rdoc').returns(false) + + @puppetdoc.options.expects(:[]=).with(:mode, :rdoc) + + @puppetdoc.handle_mode('rdoc') + end + + it "should raise an error if the mode is not valid" do + Puppet::Util::Reference.modes.stubs(:include?).with('unknown').returns(false) + lambda { @puppetdoc.handle_mode('unknown') } + end + + it "should list all references on list and exit" do + reference = stubs 'reference' + ref = stubs 'ref' + Puppet::Util::Reference.stubs(:references).returns([reference]) + + Puppet::Util::Reference.expects(:reference).with(reference).returns(ref) + ref.expects(:doc) + @puppetdoc.expects(:exit) + + @puppetdoc.handle_list(nil) + end + + it "should add reference to references list with --reference" do + @puppetdoc.options[:references] = [:ref1] + + @puppetdoc.handle_reference('ref2') + + @puppetdoc.options[:references].should == [:ref1,:ref2] + end + end + + describe "during setup" do + + before :each do + Puppet::Log.stubs(:newdestination) + ARGV.stubs(:size).returns(0) + end + + it "should default to rdoc mode if there are command line arguments" do + ARGV.stubs(:size).returns(1) + @puppetdoc.stubs(:setup_rdoc) + + @puppetdoc.options.expects(:[]=).with(:mode,:rdoc) + + @puppetdoc.run_setup + end + + it "should call setup_rdoc in rdoc mode" do + @puppetdoc.options.stubs(:[]).with(:mode).returns(:rdoc) + + @puppetdoc.expects(:setup_rdoc) + + @puppetdoc.run_setup + end + + it "should call setup_reference if not rdoc" do + @puppetdoc.options.stubs(:[]).with(:mode).returns(:test) + + @puppetdoc.expects(:setup_reference) + + @puppetdoc.run_setup + end + + describe "in non-rdoc mode" do + + it "should get all non-dynamic reference if --all" do + @puppetdoc.options.stubs(:[]).with(:all).returns(true) + @puppetdoc.options.stubs(:[]).with(:references).returns([]) + static = stub 'static', :dynamic? => false + dynamic = stub 'dynamic', :dynamic? => true + Reference.stubs(:reference).with(:static).returns(static) + Reference.stubs(:reference).with(:dynamic).returns(dynamic) + Reference.stubs(:references).returns([:static,:dynamic]) + + @puppetdoc.options.stubs(:[]=).with(:references, [:static]) + + @puppetdoc.setup_reference + end + + it "should default to :type if no references" do + @puppetdoc.options.stubs(:[]).with(:all).returns(false) + array = stub 'array', :empty? => true + @puppetdoc.options.stubs(:[]).with(:references).returns(array) + + array.expects(:<<).with(:type) + + @puppetdoc.setup_reference + end + + end + + describe "in rdoc mode" do + + before :each do + @puppetdoc.options.stubs(:[]).returns(false) + Puppet.stubs(:[]=).with(:name, "puppetmasterd") + Puppet.stubs(:parse_config) + Puppet::Util::Log.stubs(:level=) + Puppet::Util::Log.stubs(:newdestination) + end + + describe "when there are unknown args" do + + it "should expand --modulepath if any" do + @puppetdoc.unknown_args = [ { :opt => "--modulepath", :arg => "path" } ] + Puppet.settings.stubs(:handlearg) + + File.expects(:expand_path).with("path") + + @puppetdoc.setup_rdoc + end + + it "should expand --manifestdir if any" do + @puppetdoc.unknown_args = [ { :opt => "--manifestdir", :arg => "path" } ] + Puppet.settings.stubs(:handlearg) + + File.expects(:expand_path).with("path") + + @puppetdoc.setup_rdoc + end + + it "should give them to Puppet.settings" do + @puppetdoc.unknown_args = [ { :opt => :option, :arg => :argument } ] + Puppet.settings.expects(:handlearg).with(:option,:argument) + + @puppetdoc.setup_rdoc + end + end + + it "should pretend to be puppetmasterd" do + Puppet.expects(:[]=).with(:name, "puppetmasterd") + + @puppetdoc.setup_rdoc + end + + it "should parse puppet configuration" do + Puppet.expects(:parse_config) + + @puppetdoc.setup_rdoc + end + + it "should set log level to debug if --debug" do + @puppetdoc.options.stubs(:[]).with(:debug).returns(true) + Puppet::Util::Log.expects(:level=).with(:debug) + + @puppetdoc.setup_rdoc + end + + it "should set log level to info if --verbose" do + @puppetdoc.options.stubs(:[]).with(:verbose).returns(true) + Puppet::Util::Log.expects(:level=).with(:info) + + @puppetdoc.setup_rdoc + end + + it "should set log destination to console if --verbose" do + @puppetdoc.options.stubs(:[]).with(:verbose).returns(true) + + Puppet::Util::Log.expects(:newdestination).with(:console) + + @puppetdoc.setup_rdoc + end + + it "should set log destination to console if --debug" do + @puppetdoc.options.stubs(:[]).with(:debug).returns(true) + + Puppet::Util::Log.expects(:newdestination).with(:console) + + @puppetdoc.setup_rdoc + end + + end + + end + + describe "when running" do + before :each do + end + + describe "in trac mode" do + it "should call trac for each reference" do + ref = stub 'ref' + Puppet::Util::Reference.stubs(:reference).with(:ref).returns(ref) + @puppetdoc.options.stubs(:[]).with(:references).returns([:ref]) + @puppetdoc.options.stubs(:[]).with(:mode).returns(:trac) + + ref.expects(:trac) + + @puppetdoc.trac + end + end + + describe "in rdoc mode" do + before :each do + @puppetdoc.manifest = false + Puppet.stubs(:info) + Puppet.stubs(:[]).with(:trace).returns(false) + Puppet.stubs(:[]).with(:modulepath).returns('modules') + Puppet.stubs(:[]).with(:manifestdir).returns('manifests') + @puppetdoc.options.stubs(:[]).with(:all).returns(false) + @puppetdoc.options.stubs(:[]).with(:outputdir).returns('doc') + Puppet.settings.stubs(:[]=).with(:document_all, false) + Puppet.settings.stubs(:setdefaults) + Puppet::Util::RDoc.stubs(:rdoc) + @puppetdoc.stubs(:exit) + File.stubs(:expand_path).with('modules').returns('modules') + File.stubs(:expand_path).with('manifests').returns('manifests') + @old = ARGV.dup + ARGV.clear + end + + after :each do + ARGV << @old + end + + it "should set document_all on --all" do + @puppetdoc.options.expects(:[]).with(:all).returns(true) + Puppet.settings.expects(:[]=).with(:document_all, true) + + @puppetdoc.rdoc + end + + it "should call Puppet::Util::RDoc.rdoc in full mode" do + Puppet::Util::RDoc.expects(:rdoc).with('doc', ['modules','manifests']) + @puppetdoc.rdoc + end + + it "should call Puppet::Util::RDoc.manifestdoc in manifest mode" do + @puppetdoc.manifest = true + Puppet::Util::RDoc.expects(:manifestdoc) + @puppetdoc.rdoc + end + end + + describe "in the other modes" do + it "should get reference in given format" do + reference = stub 'reference' + @puppetdoc.options.stubs(:[]).with(:mode).returns(:none) + @puppetdoc.options.stubs(:[]).with(:references).returns([:ref]) + Puppet::Util::Reference.expects(:reference).with(:ref).returns(reference) + @puppetdoc.options.stubs(:[]).with(:format).returns(:format) + @puppetdoc.stubs(:exit) + + reference.expects(:send).with { |format,contents| format == :format }.returns('doc') + @puppetdoc.other + end + end + + end +end
\ No newline at end of file |