Can't pass args through to rake task - has the syntax changed? - ruby

I'm using a rails 3.1.3 project which has rake (0.9.2.2). I want to do this in a rake task: call it like
rake tale:import_kml /path/to/file.txt
and then inside the rake task, get access to "/path/to/file.txt" as args.filename
I thought i would be able to do this like so (the puts is there for bit of debugging):
namespace :tale do
desc "Expects to get a file or folder name as the first argument, and passes that to Tale.import_kml"
task(:import_kml, [:filename] => :environment) do |t, args|
puts "args = #{args.inspect}"
if File.exists?(args.filename)
Tale.import_kml(filename)
end
end
end
But, i get this:
** Invoke tale:import_kml (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute tale:import_kml
args = {}
rake aborted!
can't convert nil into String
so, filename isn't making it into args. I can't work out what i'm doing wrong here...

Try such snippet:
namespace :tale do
desc "Expects to get a file or folder ..."
task(:import_kml, [:filename]) do |t, args|
args.with_default(:filename => :environment)
puts "args = #{args.inspect}"
end
end
rake tale:import_kml[foo] # => args = {:filename => "foo"}

WarHog helped me work it out: i had to change the 'task' line to
task :import_kml, [:filename] => [:environment] do |t, args|
and call it like
rake tale:import_kml[/path/to/file.txt]

Related

How to reference a function in a different rake file

I want to call a function that is in another rake file.
Rake File 1:
task :build => [:some_other_tasks] do
foo
end
def foo(type = :debug)
# ...
end
Rake File 2:
require_relative 'path_to_rake_file_1'
task :foo2 => [:some_other_tasks] do
foo
end
I am currently getting a no such file to load error despite confirming the path is absolutely correct.
Instead of defining methods inside rake files and sharing them among rake tasks, it is best practice to create a RakeHelper module and include it in your rake file. So, you could have something like:
rake_helper.rb
module RakeHelper
def self.foo
end
end
task1.rake
include RakeHelper
task :build => [:some_other_tasks] do
RakeHelper.foo
end
task2.rake
include RakeHelper
task :foo2 => [:some_other_tasks] do
RakeHelper.foo
end

Rake before task hook

Is there a straight forward way to modify a Rake task to run some bit of code before running the existing task? I'm looking for something equivalent to enhance, that runs at the beginning rather than the end of the task.
Rake::Task['lame'].enhance(['i_run_afterwards_ha_ha'])
You can use the dependency of Rake task to do that, and the fact that Rake allows you to redefine existing task.
Rakefile
task :your_task do
puts 'your_task'
end
task :before do
puts "before"
end
task :your_task => :before
As result
$ rake your_task
before
your_task
Or you could use the rake-hooks gem to do before and after hooks:
https://github.com/guillermo/rake-hooks
namespace :greetings do
task :hola do puts "Hola!" end ;
task :bonjour do puts "Bonjour!" end ;
task :gday do puts "G'day!" end ;
end
before "greetings:hola", "greetings:bonjour", "greetings:gday" do
puts "Hello!"
end
rake greetings:hola # => "Hello! Hola!"

rake pass parameters to dependent tasks

Here is the current way I run rak dependent tasks
task :test => [:prepare_testdir,:run_tests]
currently there is no parameters for these two dependent tasks. But I need to add parameters to one of tasks. It should be running like on command line
rake prepare_testdir[mydir]
How do I pass this new parameter to this
task :test => [:prepare_testdir,:run_tests]
I have tried
task :test => [:prepare_testdir[mydir],:run_tests]
and
task :test => [:prepare_testdir['mydir'],:run_tests]
both are not working.
Thanks in advance
Inside the rake file
task :test, [:dir] => [:prepare_testdir] do |t,args|
puts args.inspect # {:dir=>"foo"}
end
task :prepare_testdir, :dir do |t, args|
puts args.inspect # {:dir=>"foo"}
end
Invocation
rake test[foo]

Alias of task name in Rake

When I need to alias some task's name, how should I do it?
For example, how do I turn the task name:
rake db:table
rake db:create
rake db:schema
rake db:migration
to:
rake db:t
rake db:c
rake db:s
rake db:m
Editing after getting the answer:
def alias_task(tasks)
tasks.each do |new_name, old_name|
task new_name, [*Rake.application[old_name].arg_names] => [old_name]
end
end
alias_task [
[:ds, :db_schema],
[:dc, :db_create],
[:dr, :db_remove]
]
Why do you need an alias? You may introduce a new task without any code, but with a prerequisite to the original task.
namespace :db do
task :table do
puts "table"
end
#kind of alias
task :t => :table
end
This can be combined with parameters:
require 'rake'
desc 'My original task'
task :original_task, [:par1, :par2] do |t, args|
puts "#{t}: #{args.inspect}"
end
#Alias task.
#Parameters are send to prerequisites, if the keys are identic.
task :alias_task, [:par1, :par2] => :original_task
To avoid to search for the parameters names you may read the parameters with arg_names:
#You can get the parameters of the original
task :alias_task2, *Rake.application[:original_task].arg_names, :needs => :original_task
Combine it to a define_alias_task-method:
def define_alias_task(alias_task, original)
desc "Alias #{original}"
task alias_task, *Rake.application[original].arg_names, :needs => original
end
define_alias_task(:alias_task3, :original_task)
Tested with ruby 1.9.1 and rake-0.8.7.
Hmmm, well, I see that's more or less exactly the same solution RyanTM already posted some hours ago.
Here is some code someone wrote to do it: https://gist.github.com/232966
def alias_task(name, old_name)
t = Rake::Task[old_name]
desc t.full_comment if t.full_comment
task name, *t.arg_names do |_, args|
# values_at is broken on Rake::TaskArguments
args = t.arg_names.map { |a| args[a] }
t.invoke(args)
end
end

Passing arguments to an Rspec SpecTask

Rake allows for the following syntax:
task :my_task, :arg1, :arg2 do |t, args|
puts "Args were: #{args}"
end
I'd like to be able to do the same, but with RSpecs SpecTask.
The following unfortunately fails:
desc "Run example with argument"
SpecTask.new('my_task'), :datafile do |t, args|
t.spec_files = FileList['*_spec.rb -datafile=#{args}']
t.spec_opts = ["-c -f specdoc"]
end
Is it possible to achieve this with a SpecTask, or is there an alternative approach?
if rspec doesn't support the args variable, you could pass it in as a command line parameter and/or a variable from another location.
rake datafile=somevalue
#datafile = ENV["datafile"]
desc "Run example with argument"
SpecTask.new :my_task do |t|
t.spec_files = FileList["*._spec.rb -datafile=#{#datafile}"]
#... etc
end

Resources