summaryrefslogtreecommitdiffstats
path: root/lib/puppet/application/doc.rb
blob: a28cac21beb28102d2d196387b54339bbf6965e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
require 'puppet/application'

class Puppet::Application::Doc < Puppet::Application

    should_not_parse_config
    run_mode :master

    attr_accessor :unknown_args, :manifest

    def preinit
        {: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("--charset CHARSET")

    option("--format FORMAT", "-f") do |arg|
        method = "to_%s" % arg
        require 'puppet/util/reference'
        if Puppet::Util::Reference.method_defined?(method)
            options[:format] = method
        else
            raise "Invalid output format %s" % arg
        end
    end

    option("--mode MODE", "-m") do |arg|
        require 'puppet/util/reference'
        if Puppet::Util::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|
        require 'puppet/util/reference'
        puts Puppet::Util::Reference.references.collect { |r| Puppet::Util::Reference.reference(r).doc }.join("\n")
        exit(0)
    end

    option("--reference REFERENCE", "-r") do |arg|
        options[:references] << arg.intern
    end

    def handle_unknown( opt, arg )
        @unknown_args << {:opt => opt, :arg => arg }
        true
    end

    def run_command
        return send(options[:mode]) if [:rdoc, :trac, :markdown].include?(options[:mode])
        return other
    end

    def rdoc
        exit_code = 0
        files = []
        unless @manifest
            env = Puppet::Node::Environment.new
            files += env.modulepath
            files << File.dirname(env[:manifest])
        end
        files += command_line.args
        Puppet.info "scanning: %s" % files.inspect
        Puppet.settings.setdefaults("puppetdoc",
            "document_all" => [false, "Document all resources"]
        )
        Puppet.settings[:document_all] = options[:all] || false
        begin
            require 'puppet/util/rdoc'
            if @manifest
                Puppet::Util::RDoc.manifestdoc(files)
            else
                options[:outputdir] = "doc" unless options[:outputdir]
                Puppet::Util::RDoc.rdoc(options[:outputdir], files, options[:charset])
            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

    def trac
        require 'puppet/util/reference'
        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

    def markdown
        text = ""
        with_contents = false
        exit_code = 0
        require 'puppet/util/reference'
        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)
                text += Puppet::Util::Reference.footer
                text.gsub!(/`\w+\s+([^`]+)`:trac:/) { |m| $1 }
                Puppet::Util::Reference.markdown(name, text)
                text = ""
            rescue => detail
                puts detail.backtrace
                $stderr.puts "Could not generate reference %s: %s" % [name, detail]
                exit_code = 1
                next
            end
        end

        exit exit_code
    end

    def other
        text = ""
        if options[:references].length > 1
            with_contents = false
        else
            with_contents = true
        end
        exit_code = 0
        require 'puppet/util/reference'
        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

    def setup
        # sole manifest documentation
        if command_line.args.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.
            require 'puppet/util/reference'
            options[:references] = Puppet::Util::Reference.references.reject do |ref|
                Puppet::Util::Reference.reference(ref).dynamic?
            end
        end

        if options[:references].empty?
            options[:references] << :type
        end
    end

    def setup_rdoc(dummy_argument=:work_arround_for_ruby_GC_bug)
        # 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

        # 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