The file now:
require 'writer'Clearly, this file is not near as DRY as it could be.
require 'html_writer'
require 'doc_writer'
directory "built_docs"
directory "built_html"
task :doc => [:built_docs, :clean_doc] do
Dir['chapters/*.txt'].each do |chapter|
output = "built_docs/#{File.basename(chapter,'txt')}doc"
File.open(output, 'w') { |file| DocWriter.new(file).write(chapter) }
puts "generated #{output}"
system "chmod 444 #{output}"
end
end
task :html => [:built_html, :clean_html] do
Dir['chapters/*.txt'].each do |chapter|
output = "built_html/#{File.basename(chapter,'txt')}html"
File.open(output, 'w') { |file| HtmlWriter.new(file).write(chapter) }
puts "generated #{output}"
system "chmod 444 #{output}"
end
end
task :clean_doc do
Dir['built_docs/*'].each do |output|
rm output
end
end
task :clean_html do
Dir['built_html/*'].each do |output|
rm output
end
end
The first step is to create a new task that will generate output and accept the format as an argument.
task :default doThe above code verifies that a valid format is specified. It also removes the need for both the directory and clean tasks. The only work left to do is combine the output generation tasks.
unless ENV.include?("output") && (ENV['output']=='doc' || ENV['output']=='html')
raise "usage: rake output=# valid formats are [html] or [doc]"
end
format = ENV['output']
puts format
rm_rf format
mkdir format
end
task :default doThe resulting task is cleaner and easier to maintain.
unless ENV.include?("output") && (ENV['output']=='doc' || ENV['output']=='html')
raise "usage: rake output=# valid formats are [html] or [doc]"
end
format = ENV['output']
puts format
rm_rf format
mkdir format
Dir['chapters/*.txt'].each do |chapter|
output = "#{format}/#{File.basename(chapter,'txt')}#{format}"
writer = (format=='doc' ? DocWriter : HtmlWriter)
File.open(output, 'w') { |file| writer.new(file).write(chapter) }
puts "generated #{output}"
system "chmod 444 #{output}"
end
end
Running the new task from the command line:
focus:~ jay$ rake output=html
So how do you use it then? I can see 'rake html' and 'rake doc' from the old version, I'm presuming 'rake output=html' for the second, or do you need to set an environment variable from the shell?
ReplyDeleteThanks, I updated the entry.
ReplyDeleteAnd, you are correct 'rake output=html' is the correct way to use parameters.
While parameters are often very useful, in this case I'd remove the code duplication using the fact that Rakefiles are just Ruby scripts:
ReplyDeleteFORMATS = {
'html' => HtmlWriter,
'doc' => DocWriter
}
FORMATS.each_pair do |format, writer|
desc "Build documentation in #{format} format"
task format do
# whatever
end
end
As a bonus, 'rake -T' stays usable without extra work (and 'rake html' is easier to type than 'rake output=html' ;))
@ville, very good point. I guess this proves the point that pairing is much better than working on your own. ;)
ReplyDeleteThanks for the feedback.
Jay, I would suggest the following variation...
ReplyDeletedef generate(writer_class, pathmapping)
Dir['chapters/*.txt'].each do |chapter|
output = chapter.pathmap(pathmapping)
File.open(output, 'w') { |file| writer_class.new(file).write(chapter) }
puts "generated #{output}"
system "chmod 444 #{output}"
end
end
task :doc => [:built_docs, :clean_doc] do
generate(DocWriter, "built_docs/%n.doc")
end
task :html => [:built_html, :clean_html] do
generate(DocWriter, "built_html/%n.html")
end
Since indentation is messed up, you might find http://rafb.net/paste/results/wNWexm13.html more readable.
The next thing I would consider doing is replacing the explicit loop over Dir[...] with a rule.