summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/puppetdoc197
-rw-r--r--lib/puppet/application/puppetdoc.rb198
-rwxr-xr-xspec/unit/application/puppetdoc.rb343
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