Def Block in Rake Task

def block in rake task

Update: Gotcha

This potentially adds the method to global scope and will conflict with any other method with the same name. Look at @Hula_Zell's answer https://stackoverflow.com/a/44294243/584440 for a better way.

Original answer

You are defining the method inside the rake task. For getting the function, you should define outside the rake task (outside the task block). Try this:

include Geokit::Geocoders

namespace :geocode do
desc "Geocode to get latitude, longitude and address"
task :all => :environment do
@spot = Spot.find(:first)
if @spot.latitude.blank? && !@spot.address.blank?
puts address_geo
end
end

def address_geo
arr = []
arr << address if @spot.address
arr << city if @spot.city
arr << country if @spot.country
arr.reject{|y|y==""}.join(", ")
end
end

How to catch raised exception in rake task

I solved this issue by just commenting out the line that is raising an exception because it seems like it the quickest fix for now.

# raise Exception.new('...')

I'm still open to other suggestions if there are any better ways to do it.

Is it possible to include a module in rake tasks without polluting the global scope?

Here's what worked for me:

module MyRakeHelpers
def helper
puts 'foo'
end
end

module MyRakeTasks
extend Rake::DSL
extend MyRakeHelpers

task :some_task do
helper
end
end

In short, you can use the Rake DSL in a different scope by including (or extending) Rake::DSL. From the source:

DSL is a module that provides #task, #desc, #namespace, etc. Use this when you'd like to use rake outside the top level scope. For a Rakefile you run from the command line this module is automatically included.

task uses Rake::Task#define_task under the hood, which you could also use to write your own DSL.

Thanks to How To Build Custom Rake Tasks; The Right Way for the tip about define_task.

Access Rake Task Description from within Task

taskmust be defined as a parameter for the task-block.

desc "Populate DB"
task :populate do |task|
puts task.comment # "Populate DB"
puts task.full_comment # "Populate DB"
puts task.name # "populate "
end

Edit:
This solution works with rake 0.8.7. At least rake 0.9.2.2 need an additional Rake::TaskManager.record_task_metadata = true (I checked only this two versions).

A stand alone ruby-script with adaption:

gem 'rake'    #'= 0.9.2.2'
require 'rake'

#Needed for rake/gem '= 0.9.2.2'
Rake::TaskManager.record_task_metadata = true

desc "Populate DB"
task :populate do |task|
p task.comment # "Populate DB"
p task.full_comment # "Populate DB"
p task.name # "populate "
end

if $0 == __FILE__
Rake.application['populate'].invoke() #all tasks
end

Reason: in rake/task_manager.rb line 30 (rake 0.9.2.2) is a check

  if Rake::TaskManager.record_task_metadata
add_location(task)
task.add_description(get_description(task))
end

The default false is set in line 305.

How do I return early from a rake task?

A Rake task is basically a block. A block, except lambdas, doesn't support return but you can skip to the next statement using next which in a rake task has the same effect of using return in a method.

task :foo do
puts "printed"
next
puts "never printed"
end

Or you can move the code in a method and use return in the method.

task :foo do
do_something
end

def do_something
puts "startd"
return
puts "end"
end

I prefer the second choice.

Real-time output of a rake task with popen3

Adding $stdout.sync = true at the beginning of the rake task solved it.

Rake task variable under namespace

This is not specific to Rake, it is just a consequence of lexical scope and the way Ruby handles local variables, declaring them on first use.

First you assign a value to path:

path = "/home/tomcat/tomcat"

Then you create the stage namespace and reassign the variable:

path = "/home/tomcat/stage-tomcat"

Note that this line is executed whatever task you specify, as it is not in any tasks.

Next you create the java_deploy task, but it doesn’t get run yet. This task refers to the path variable, but when the task is called the value of it might have changed.

Later, when defining the production namespace this variable gets reassigned again. Importantly this is still the same variable:

path = "/home/tomcat/production-tomcat"

When the task is actually run, it refers to the path variable and the value of this variable is the latest value assigned to it, which is /home/tomcat/production-tomcat.

When you remove the first assignment to path, then the variable doesn’t exist in the top level. This means that when you assign to path in each namespace definition you are declaring a new (and separate) local variable in each case.



Related Topics



Leave a reply



Submit