Jump To …

tasks.rb

Rocco Rake Tasks

To use the Rocco Rake tasks, require rocco/tasks in your Rakefile and define a Rake task with rocco_task. In its simplest form, rocco_task takes the path to a destination directory where HTML docs should be built:

require ‘rocco/tasks’

desc “Build Rocco Docs”
Rocco::make ‘docs/’

This creates a :rocco rake task, which can then be run with:

rake rocco

It’s a good idea to guard against Rocco not being available, since your Rakefile will fail to load otherwise. Consider doing something like this, so that your Rakefile will still work

begin
  require ‘rocco/tasks’
  Rocco::make ‘docs/’
rescue LoadError
  warn “#$! — rocco tasks not loaded.”
  task :rocco
end

It’s also possible to pass a glob pattern:

Rocco::make ‘html/’, ‘lib/thing/**/*.rb’

Or a list of glob patterns:

Rocco::make ‘html/’, [‘lib/thing.rb’, ‘lib/thing/*.rb’]

Finally, it is also possible to specify which Pygments language you would like to use to highlight the code, as well as the comment characters for the language in the options hash:

Rocco::make ‘html/’, ‘lib/thing/*/.rb’, { :language => ‘io’, :comment_chars => ‘#’ }

Might be nice to defer this until we actually need to build docs but this will have to do for now.

require 'rocco'

Reopen the Rocco class and add a make class method. This is a simple bit of sugar over Rocco::Task.new. If you want your Rake task to be named something other than :rocco, you can use Rocco::Task directly.

class Rocco
  def self.make(dest='docs/', source_files='lib/**/*.rb', options={})
    Task.new(:rocco, dest, source_files, options)
  end

Rocco::Task.new takes a task name, the destination directory docs should be built under, and a source file pattern or file list.

  class Task
    include Rake::DSL if defined?(Rake::DSL)

    def initialize(task_name, dest='docs/', sources='lib/**/*.rb', options={})
      @name = task_name
      @dest = dest[-1] == ?/ ? dest : "#{dest}/"
      @sources = FileList[sources]
      @options = options

Make sure there’s a directory task defined for our destination.

      define_directory_task @dest

Run over the source file list, constructing destination filenames and defining file tasks.

      @sources.each do |source_file|
        dest_file = source_file.sub(Regexp.new("#{File.extname(source_file)}$"), ".html")
        define_file_task source_file, "#{@dest}#{dest_file}"

If rake/clean was required, add the generated files to the list. That way all Rocco generated are removed when running rake clean.

        CLEAN.include "#{@dest}#{dest_file}" if defined? CLEAN
      end
    end

Define the destination directory task and make the :rocco task depend on it. This causes the destination directory to be created if it doesn’t already exist.

    def define_directory_task(path)
      directory path
      task @name => path
    end

Setup a file task for a single Rocco output file (dest_file). It depends on the source file, the destination directory, and all of Rocco’s internal source code, so that the destination file is rebuilt when any of those changes.

You can run these tasks directly with Rake:

rake docs/foo.html docs/bar.html

… would generate the foo.html and bar.html files but only if they don’t already exist or one of their dependencies was changed.

    def define_file_task(source_file, dest_file)
      prerequisites = [@dest, source_file] + rocco_source_files
      file dest_file => prerequisites do |f|
        verbose { puts "rocco: #{source_file} -> #{dest_file}" }
        rocco = Rocco.new(source_file, @sources.to_a, @options)
        FileUtils.mkdir_p(File.dirname(dest_file))
        File.open(dest_file, 'wb') { |fd| fd.write(rocco.to_html) }
      end
      task @name => dest_file
    end

Return a FileList that includes all of Roccos source files. This causes output files to be regenerated properly when someone upgrades the Rocco library.

    def rocco_source_files
      libdir = File.expand_path('../..', __FILE__)
      FileList["#{libdir}/rocco.rb", "#{libdir}/rocco/**"]
    end

  end
end