summaryrefslogtreecommitdiffstats
path: root/lib/puppet/util/reference.rb
blob: 62bab643eefd5a0d1bc07eac8b081ddc539d4f33 (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
require 'puppet/util/instance_loader'
require 'fileutils'

# Manage Reference Documentation.
class Puppet::Util::Reference
  include Puppet::Util
  include Puppet::Util::Docs

  extend Puppet::Util::InstanceLoader

  instance_load(:reference, 'puppet/reference')

  def self.footer
    "\n\n----------------\n\n*This page autogenerated on #{Time.now}*\n"
  end

  def self.modes
    %w{pdf trac text markdown}
  end

  def self.newreference(name, options = {}, &block)
    ref = self.new(name, options, &block)
    instance_hash(:reference)[symbolize(name)] = ref

    ref
  end

  def self.page(*sections)
    depth = 4
    # Use the minimum depth
    sections.each do |name|
      section = reference(name) or raise "Could not find section #{name}"
      depth = section.depth if section.depth < depth
    end
    text = ".. contents:: :depth: 2\n\n"
  end

  def self.pdf(text)
    puts "creating pdf"
    Puppet::Util.secure_open("/tmp/puppetdoc.txt", "w") do |f|
      f.puts text
    end
    rst2latex = %x{which rst2latex}
    if $CHILD_STATUS != 0 or rst2latex =~ /no /
      rst2latex = %x{which rst2latex.py}
    end
    if $CHILD_STATUS != 0 or rst2latex =~ /no /
      raise "Could not find rst2latex"
    end
    rst2latex.chomp!
    cmd = %{#{rst2latex} /tmp/puppetdoc.txt > /tmp/puppetdoc.tex}
    Puppet::Util.secure_open("/tmp/puppetdoc.tex","w") do |f|
      # If we get here without an error, /tmp/puppetdoc.tex isn't a tricky cracker's symlink
    end
    output = %x{#{cmd}}
    unless $CHILD_STATUS == 0
      $stderr.puts "rst2latex failed"
      $stderr.puts output
      exit(1)
    end
    $stderr.puts output

    # Now convert to pdf
    Dir.chdir("/tmp") do
      %x{texi2pdf puppetdoc.tex >/dev/null 2>/dev/null}
    end

  end

  def self.markdown(name, text)
    puts "Creating markdown for #{name} reference."
    dir = "/tmp/#{Puppet::PUPPETVERSION}"
    FileUtils.mkdir(dir) unless File.directory?(dir)
    Puppet::Util.secure_open(dir + "/#{name}.rst", "w") do |f|
      f.puts text
    end
    pandoc = %x{which pandoc}
    if $CHILD_STATUS != 0 or pandoc =~ /no /
      pandoc = %x{which pandoc}
    end
    if $CHILD_STATUS != 0 or pandoc =~ /no /
      raise "Could not find pandoc"
    end
    pandoc.chomp!
    cmd = %{#{pandoc} -s -r rst -w markdown #{dir}/#{name}.rst -o #{dir}/#{name}.mdwn}
    output = %x{#{cmd}}
    unless $CHILD_STATUS == 0
      $stderr.puts "Pandoc failed to create #{name} reference."
      $stderr.puts output
      exit(1)
    end

    File.unlink(dir + "/#{name}.rst")
  end

  def self.references
    instance_loader(:reference).loadall
    loaded_instances(:reference).sort { |a,b| a.to_s <=> b.to_s }
  end

  HEADER_LEVELS = [nil, "=", "-", "+", "'", "~"]

  attr_accessor :page, :depth, :header, :title, :dynamic
  attr_writer :doc

  def doc
    if defined?(@doc)
      return "#{@name} - #{@doc}"
    else
      return @title
    end
  end

  def dynamic?
    self.dynamic
  end

  def h(name, level)
    "#{name}\n#{HEADER_LEVELS[level] * name.to_s.length}\n\n"
  end

  def initialize(name, options = {}, &block)
    @name = name
    options.each do |option, value|
      send(option.to_s + "=", value)
    end

    meta_def(:generate, &block)

    # Now handle the defaults
    @title ||= "#{@name.to_s.capitalize} Reference"
    @page ||= @title.gsub(/\s+/, '')
    @depth ||= 2
    @header ||= ""
  end

  # Indent every line in the chunk except those which begin with '..'.
  def indent(text, tab)
    text.gsub(/(^|\A)/, tab).gsub(/^ +\.\./, "..")
  end

  def option(name, value)
    ":#{name.to_s.capitalize}: #{value}\n"
  end

  def paramwrap(name, text, options = {})
    options[:level] ||= 5
    #str = "#{name} : "
    str = h(name, options[:level])
    str += "- **namevar**\n\n" if options[:namevar]
    str += text
    #str += text.gsub(/\n/, "\n    ")

    str += "\n\n"
  end

  # Remove all trac links.
  def strip_trac(text)
    text.gsub(/`\w+\s+([^`]+)`:trac:/) { |m| $1 }
  end

  def text
    puts output
  end

  def to_rest(withcontents = true)
    # First the header
    text = h(@title, 1)
    text += "\n\n**This page is autogenerated; any changes will get overwritten** *(last generated on #{Time.now.to_s})*\n\n"
    text +=  ".. contents:: :depth: #{@depth}\n\n" if withcontents

    text += @header

    text += generate

    text += self.class.footer if withcontents

    text
  end

  def to_text(withcontents = true)
    strip_trac(to_rest(withcontents))
  end

  def to_trac(with_contents = true)
    "{{{\n#!rst\n#{self.to_rest(with_contents)}\n}}}"
  end

  def trac
    Puppet::Util.secure_open("/tmp/puppetdoc.txt", "w") do |f|
      f.puts self.to_trac
    end

    puts "Writing #{@name} reference to trac as #{@page}"
    cmd = %{sudo trac-admin /opt/rl/trac/puppet wiki import %s /tmp/puppetdoc.txt} % self.page
    output = %x{#{cmd}}
    unless $CHILD_STATUS == 0
      $stderr.puts "trac-admin failed"
      $stderr.puts output
      exit(1)
    end
    unless output =~ /^\s+/
      $stderr.puts output
    end
  end
end