If I have one rake which invokes multiple other rakes.
Once I initiate the parent rake
rake myapp:main
Then invokes done within the rake would load environment for each task or its just one time activity done while running rake myapp:main
?
namespace :myapp do
desc "Main Run"
task :main => :environment do
Rake::Task['myapp:task1'].invoke
Rake::Task['myapp:task2'].invoke
end
task :task1 => :environment do
# Does the first task
end
task :task2 => :environment do
# Does the second task
end
end
Adding details to @Shadwell's answer..
The => :environment
is specifying that the :environment
task (defined by rails) is a dependency of your tasks and must be invoked before your tasks are.
You can see :environment
task's definition here
https://github.com/rails/rails/blob/d70ba48c4dd6b57d8f38612ea95a3842337c1419/railties/lib/rails/application.rb#L428-432
Rake keeps track of which tasks have invoked though and when it reaches a dependency that has already been invoked it knows it can skip it.
https://github.com/jimweirich/rake/blob/5e59bccecaf480d1de565ab34fd15e54ff667660/lib/rake/task.rb#L195-204
# Invoke all the prerequisites of a task.
def invoke_prerequisites(task_args, invocation_chain) # :nodoc:
if application.options.always_multitask
invoke_prerequisites_concurrently(task_args, invocation_chain)
else
prerequisite_tasks.each { |p|
prereq_args = task_args.new_scope(p.arg_names)
p.invoke_with_call_chain(prereq_args, invocation_chain)
}
end
end
Rake maintains an intance variable @already_invoked
to know if a task has already been called. The same can be seen in the below method
https://github.com/jimweirich/rake/blob/5e59bccecaf480d1de565ab34fd15e54ff667660/lib/rake/task.rb#L170-184
def invoke_with_call_chain(task_args, invocation_chain) # :nodoc:
new_chain = InvocationChain.append(self, invocation_chain)
@lock.synchronize do
if application.options.trace
application.trace "** Invoke #{name} #{format_trace_flags}"
end
return if @already_invoked
@already_invoked = true
invoke_prerequisites(task_args, new_chain)
execute(task_args) if needed?
end
rescue Exception => ex
add_chain_to(ex, new_chain)
raise ex
end
The environment would only be set up once.
The => :environment
is specifying that the :environment
task (defined by rails) is a dependency of your tasks and must be invoked before your tasks are. Rake keeps track of which tasks have invoked though and when it reaches a dependency that has already been invoked it knows it can skip it.
(Aside: this can cause problems if you actually want the dependency to be invoked multiple times)
You could also define your main
task using dependencies:
task :main => [:task1, :task2] do
# Blank
end
When you run rake myapp:main
it will look at the dependencies and invoke task1
and then task2
. Because task1
has a dependency environment
it will invoke that first too. It'll skip the environment
dependency on task2
though.
Answer is NO, Environment is not loaded when executing another Rake task from the parent Task. Simple explanation for this is the code below :
namespace :myapp do
desc "Main Run"
task :main => :environment do
puts "Start Time : #{Time.now.to_i}"
Rake::Task['myapp:task1'].invoke
puts "End Time1 : #{Time.now.to_i}"
Rake::Task['myapp:task2'].invoke
puts "End Time2 : #{Time.now.to_i}"
end
task :task1 => :environment do
# Does the first task
puts "Executing..1"
end
task :task2 => :environment do
# Does the second task
puts "Executing..2"
end
end
But it is not a good practice to do the two or multiple rake tasks. If you want to achieve the same thing, you can modularize the code, and create two functions and call the function to achieve the same result.