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
task
must 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
Best Practice About Empty Belongs_To Association
How to Generate a Random Date in Ruby
Error When Starting Rails Server: Warning: Insecure World Writable Dir /Usr in Path, Mode 040777
Why Should I Use Rspec or Shoulda with Rails
Which Ruby Gems Support the Facebook API
How to Create a Rest API for a Ruby Application
How to Check If a Variable Is an Instance of a Class
"Rmagick" Gem Installation Issue
Rails Routing (Root :To => ...)
What Is Double Method in Rspec For
Find Records with Datetime That Match Today's Date - Ruby on Rails
What Alternatives to Irb Are There