Skip to content

Instantly share code, notes, and snippets.

@trcook
Last active February 18, 2018 10:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trcook/185ca6faf33cd69db2b9 to your computer and use it in GitHub Desktop.
Save trcook/185ca6faf33cd69db2b9 to your computer and use it in GitHub Desktop.
Advanced Rake Rules and Conditional Rake Rules

rules matching by regex

Occassionally we want to make a rule that matches on something more complex than file extensions. If, for example files that will be prefixed with pandoc_ depend on files that do not contain the prefix.

Ex: pandoc_slides=>slides.rmd. we can make a rule that will capture this, but we need to use a lambda function to do so:

rule (%r{pandoc_.*\.md}) => lambda{|objfile| potential_source_files.find{objfile.pathmap("%{pandoc_,}n")}} do |t|
	puts "This rule gets #{t.name} from #{t.source}"
end

This rule matches on any markdown with the prefix pandocc and the ext: .md. It then searches a file list of potential source files as prereqs potential_source_files. The trick to this is that it needs to be snuggled in an anonymous function (i.e. a lambda function). objfile is a name(iterator?) that references the function that corresponds to the match from (%r{pandoc_.*\.md})on the left hand of the dependency operator (=>).

Note that, as constructed we still need to know precisely how the target file is prefixed and unwind that prefix when searching potential source files.

rules conditioned on invocation chain

Then there are times when we want to have different rules based on what argument we've passed to rake

If we have a rakefile with 2 tasks :one_task and :the_other_task, we can generate different rules based on which has been called. This is useful if you have the same sources and you are building to multiple, different targets (maybe in different directories). The key here is to make good use of namespace

namespace :one_task do
rule ".md" =>".rmd" do |t|
	puts "Running task :one_task, building #{t.name} from #{t.source}"
end
end

namespace :the_other_task do
rule ".md" =>".rmd" do |t|
	some_additional_function(t.source)
	puts "Running  :the_other_task, building #{t.name} from #{t.source} using some_additional_function"
end
end


rule (%r{pandoc_.*\.md}) => lambda{|objfile| potential_source_files.find{objfile.pathmap("%{pandoc_,}n")}} do |t|
puts "This rule gets #{t.name} from #{t.source}"
end
namespace :one_task do
rule ".md" =>".rmd" do |t|
puts "Running task :one_task, building #{t.name} from #{t.source}"
end
end
namespace :the_other_task do
rule ".md" =>".rmd" do |t|
some_additional_function(t.source)
puts "Running :the_other_task, building #{t.name} from #{t.source} using some_additional_function"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment