2

I have a custom rake task, implemented as a method, which sits "above" the task method. It works with a custom configuration object to give the whole thing a more declarative feel. Here it is.

def robocopy(*args, &block)
  config = RobocopyConfiguration.new
  block.call config

  body = proc { 
    system "robocopy #{config.make_parameters.join ' '}"
  }

  Rake::Task.define_task *args, &body
end

class RobocopyConfiguration
  attr_accessor :source, :destination, :files
  attr_reader :mirror

  def mirror
    @mirror = true
  end

  def make_parameters
    parameters = [ @source, @destination ]
    parameters << @files.flatten if @files
    parameters << '/MIR' if @mirror
    parameters
  end
end

And you can declare it like a normal-ish rake task with a name and dependencies.

robocopy :copy => [ :build ] do |cmd|
  cmd.source = File.expand_path File.dirname __FILE__
  cmd.destination = '//some/default/network/share'
  cmd.mirror
end

However, as soon as you add arguments, things start to blow up.

robocopy :copy, [ :destination ] => [ :build ] do |cmd, args|
  args.with_defaults(:destination => '//some/default/network/share')

  cmd.source = File.expand_path File.dirname __FILE__
  cmd.destination = args[:destination]
  cmd.mirror
end

cmd> rake copy['//some/network/share']
rake aborted!
undefined method `with_defaults' for nil:NilClass

I suspect the *args aren't getting turned into TaskArguments, with all the special methods, they're are being used immediately in the custom block.call. And I can't quite figure out what call to make to turn them into the right kind of arguments.

Anthony Mastrean
  • 21,850
  • 21
  • 110
  • 188

0 Answers0