1# rake/rdoctask is deprecated in favor of rdoc/task
2
3if Rake.application
4  Rake.application.deprecate('require \'rake/rdoctask\'', 'require \'rdoc/task\' (in RDoc 2.4.2+)', caller.first)
5end
6
7require 'rubygems'
8
9begin
10  gem 'rdoc'
11  require 'rdoc'
12  require 'rdoc/task'
13rescue LoadError, Gem::LoadError
14end
15
16# :stopdoc:
17
18if defined?(RDoc::Task) then
19  module Rake
20    RDocTask = RDoc::Task unless const_defined? :RDocTask
21  end
22else
23  require 'rake'
24  require 'rake/tasklib'
25
26  module Rake
27
28    # NOTE: Rake::RDocTask is deprecated in favor of RDoc:Task which is included
29    # in RDoc 2.4.2+.  Use require 'rdoc/task' to require it.
30    #
31    # Create a documentation task that will generate the RDoc files for
32    # a project.
33    #
34    # The RDocTask will create the following targets:
35    #
36    # [<b><em>rdoc</em></b>]
37    #   Main task for this RDOC task.
38    #
39    # [<b>:clobber_<em>rdoc</em></b>]
40    #   Delete all the rdoc files.  This target is automatically
41    #   added to the main clobber target.
42    #
43    # [<b>:re<em>rdoc</em></b>]
44    #   Rebuild the rdoc files from scratch, even if they are not out
45    #   of date.
46    #
47    # Simple Example:
48    #
49    #   Rake::RDocTask.new do |rd|
50    #     rd.main = "README.rdoc"
51    #     rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
52    #   end
53    #
54    # The +rd+ object passed to the block is an RDocTask object. See the
55    # attributes list for the RDocTask class for available customization options.
56    #
57    # == Specifying different task names
58    #
59    # You may wish to give the task a different name, such as if you are
60    # generating two sets of documentation.  For instance, if you want to have a
61    # development set of documentation including private methods:
62    #
63    #   Rake::RDocTask.new(:rdoc_dev) do |rd|
64    #     rd.main = "README.doc"
65    #     rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
66    #     rd.options << "--all"
67    #   end
68    #
69    # The tasks would then be named :<em>rdoc_dev</em>, :clobber_<em>rdoc_dev</em>, and
70    # :re<em>rdoc_dev</em>.
71    #
72    # If you wish to have completely different task names, then pass a Hash as
73    # first argument. With the <tt>:rdoc</tt>, <tt>:clobber_rdoc</tt> and
74    # <tt>:rerdoc</tt> options, you can customize the task names to your liking.
75    # For example:
76    #
77    #   Rake::RDocTask.new(:rdoc => "rdoc", :clobber_rdoc => "rdoc:clean", :rerdoc => "rdoc:force")
78    #
79    # This will create the tasks <tt>:rdoc</tt>, <tt>:rdoc_clean</tt> and
80    # <tt>:rdoc:force</tt>.
81    #
82    class RDocTask < TaskLib
83      # Name of the main, top level task.  (default is :rdoc)
84      attr_accessor :name
85
86      # Name of directory to receive the html output files. (default is "html")
87      attr_accessor :rdoc_dir
88
89      # Title of RDoc documentation. (defaults to rdoc's default)
90      attr_accessor :title
91
92      # Name of file to be used as the main, top level file of the
93      # RDoc. (default is none)
94      attr_accessor :main
95
96      # Name of template to be used by rdoc. (defaults to rdoc's default)
97      attr_accessor :template
98
99      # List of files to be included in the rdoc generation. (default is [])
100      attr_accessor :rdoc_files
101
102      # Additional list of options to be passed rdoc.  (default is [])
103      attr_accessor :options
104
105      # Whether to run the rdoc process as an external shell (default is false)
106      attr_accessor :external
107
108      attr_accessor :inline_source
109
110      # Create an RDoc task with the given name. See the RDocTask class overview
111      # for documentation.
112      def initialize(name = :rdoc)  # :yield: self
113        if name.is_a?(Hash)
114          invalid_options = name.keys.map { |k| k.to_sym } - [:rdoc, :clobber_rdoc, :rerdoc]
115          if !invalid_options.empty?
116            raise ArgumentError, "Invalid option(s) passed to RDocTask.new: #{invalid_options.join(", ")}"
117          end
118        end
119
120        @name = name
121        @rdoc_files = Rake::FileList.new
122        @rdoc_dir = 'html'
123        @main = nil
124        @title = nil
125        @template = nil
126        @external = false
127        @inline_source = true
128        @options = []
129        yield self if block_given?
130        define
131      end
132
133      # Create the tasks defined by this task lib.
134      def define
135        if rdoc_task_name != "rdoc"
136          desc "Build the RDOC HTML Files"
137        else
138          desc "Build the #{rdoc_task_name} HTML Files"
139        end
140        task rdoc_task_name
141
142        desc "Force a rebuild of the RDOC files"
143        task rerdoc_task_name => [clobber_task_name, rdoc_task_name]
144
145        desc "Remove rdoc products"
146        task clobber_task_name do
147          rm_r rdoc_dir rescue nil
148        end
149
150        task :clobber => [clobber_task_name]
151
152        directory @rdoc_dir
153        task rdoc_task_name => [rdoc_target]
154        file rdoc_target => @rdoc_files + [Rake.application.rakefile] do
155          rm_r @rdoc_dir rescue nil
156          @before_running_rdoc.call if @before_running_rdoc
157          args = option_list + @rdoc_files
158          if @external
159            argstring = args.join(' ')
160            sh %{ruby -Ivendor vendor/rd #{argstring}}
161          else
162            require 'rdoc/rdoc'
163            RDoc::RDoc.new.document(args)
164          end
165        end
166        self
167      end
168
169      def option_list
170        result = @options.dup
171        result << "-o" << @rdoc_dir
172        result << "--main" << quote(main) if main
173        result << "--title" << quote(title) if title
174        result << "-T" << quote(template) if template
175        result << "--inline-source" if inline_source && !@options.include?("--inline-source") && !@options.include?("-S")
176        result
177      end
178
179      def quote(str)
180        if @external
181          "'#{str}'"
182        else
183          str
184        end
185      end
186
187      def option_string
188        option_list.join(' ')
189      end
190
191      # The block passed to this method will be called just before running the
192      # RDoc generator. It is allowed to modify RDocTask attributes inside the
193      # block.
194      def before_running_rdoc(&block)
195        @before_running_rdoc = block
196      end
197
198      private
199
200      def rdoc_target
201        "#{rdoc_dir}/index.html"
202      end
203
204      def rdoc_task_name
205        case name
206        when Hash
207          (name[:rdoc] || "rdoc").to_s
208        else
209          name.to_s
210        end
211      end
212
213      def clobber_task_name
214        case name
215        when Hash
216          (name[:clobber_rdoc] || "clobber_rdoc").to_s
217        else
218          "clobber_#{name}"
219        end
220      end
221
222      def rerdoc_task_name
223        case name
224        when Hash
225          (name[:rerdoc] || "rerdoc").to_s
226        else
227          "re#{name}"
228        end
229      end
230
231    end
232  end
233end
234
235