How to call Rake tasks that are defined in the standard Rakefile from an other Ruby script?
You forgot to add your new rake
to the current Rake Application:
$LOAD_PATH.unshift File.dirname(__FILE__)
require 'rake'
require 'pp'
rake = Rake::Application.new
Rake.application = rake
rake.init
rake.load_rakefile
rake[:hello].invoke
or just
$LOAD_PATH.unshift File.dirname(__FILE__)
require 'rake'
require 'pp'
Rake.application.init
Rake.application.load_rakefile
Rake.application[:hello].invoke
How do I run Rake tasks within a Ruby script?
from timocracy.com:
require 'rake'
def capture_stdout
s = StringIO.new
oldstdout = $stdout
$stdout = s
yield
s.string
ensure
$stdout = oldstdout
end
Rake.application.rake_require 'metric_fetcher', ['../../lib/tasks']
results = capture_stdout {Rake.application['metric_fetcher'].invoke}
Remove duplication from rake tasks
Rake tasks can take arguments, so instead of relying on an instance variable you can pass the tags in:
TAGS = ['OPTIMIZE', 'TODO', 'FIXME']
task :find, [:tags] do |task, args|
# command lines can't pass an array, afaik; so if we pass the
# tags in, we'll need them as a space separated list
tags = if args[:tags]
args[:tags].split(' ')
else
TAGS
end
puts "finding all tags marked: #{tags.inspect}"
end
and then on the command line:
% rake find[TODO OPTIMIZE] # may need escaped: rake find\[TODO\ OPTIMIZE\]
finding all tags marked: ["TODO", "OPTIMIZE"]
% rake find
finding all tags marked: ["OPTIMIZE", "TODO", "FIXME"]
and then, if you still want named tasks as aliases, passing certain arguments, you can pass them in through invoke
:
TAGS.each do |tag|
task tag.downcase.to_sym do
Rake::Task["find"].invoke(tag)
end
end
and calling them:
% rake todo
finding all tags marked: ["TODO"]
% rake fixme
finding all tags marked: ["FIXME"]
% rake optimize
finding all tags marked: ["OPTIMIZE"]
Ruby: Accessing rake task from a gem without Rails
I found the body of the solution here. I've modified it to support specification of tasks with arguments and added support for cucumber
.
So..
Within your gem create bin/my_gem
Paste the script at bottom of this post into it. See comments for example usage.
Your rake
tasks must be in your Rakefile
.
Alternatively, add your tasks e.g. to lib/tasks/*.rake
then add the following into your Rakefile
:
Dir.glob('lib/tasks/*.rake').each {|r| import r}
Here's the secret sauce:
#!/usr/bin/env ruby
# Run rake tasks and cucumber features
# from my_gem once it's installed.
#
# Example:
#
# my_gem rake some-task
# my_gem rake some-task[args]
# my_gem cucumber feature1 feature2
#
# Note: cucumber features have '.feature' appended automatically,
# no need for you to do it ;)
#
# Author:: N David Brown
gem_dir = File.expand_path("..",File.dirname(__FILE__))
$LOAD_PATH.unshift gem_dir# Look in gem directory for resources first.
exec_type = ARGV[0]
if exec_type == 'rake' then
require 'rake'
require 'pp'
pwd=Dir.pwd
Dir.chdir(gem_dir) # We'll load rakefile from the gem's dir.
Rake.application.init
Rake.application.load_rakefile
Dir.chdir(pwd) # Revert to original pwd for any path args passed to task.
Rake.application.invoke_task(ARGV[1])
elsif exec_type == 'cucumber' then
require 'cucumber'
features = ARGV[1,].map{|feature| "#{gem_dir}/features/#{feature}.feature"}.join(' ')
runtime = Cucumber::Runtime.new
runtime.load_programming_language('rb')
pwd=Dir.pwd
Dir.chdir(gem_dir) # We'll load features from the gem's dir.
Cucumber::Cli::Main.new([features]).execute!(runtime)
Dir.chdir(pwd) # Revert to original pwd for convenience.
end
Bingo! :-)
ruby rake tasks in a namespace shared but not :all
You could express the dependencies directly on the depending tasks, like
namespace :build do
task :development => :delete do
puts "development!"
end
task :production => :delete do
puts "production!"
end
end
task :delete do
puts "delete!"
end
Execute bash commands from a Rakefile
I think the way rake wants this to happen is with: http://rubydoc.info/gems/rake/FileUtils#sh-instance_method
Example:
task :test do
sh "ls"
end
The built-in rake function sh takes care of the return value of the command (the task fails if the command has a return value other than 0) and in addition it also outputs the commands output.
How to pass command line arguments to a rake task
Options and dependencies need to be inside arrays:
namespace :thing do
desc "it does a thing"
task :work, [:option, :foo, :bar] do |task, args|
puts "work", args
end
task :another, [:option, :foo, :bar] do |task, args|
puts "another #{args}"
Rake::Task["thing:work"].invoke(args[:option], args[:foo], args[:bar])
# or splat the args
# Rake::Task["thing:work"].invoke(*args)
end
end
Then
rake thing:work[1,2,3]
=> work: {:option=>"1", :foo=>"2", :bar=>"3"}
rake thing:another[1,2,3]
=> another {:option=>"1", :foo=>"2", :bar=>"3"}
=> work: {:option=>"1", :foo=>"2", :bar=>"3"}
NOTE: variable
task
is the task object, not very helpful unless you know/care about Rake internals.
RAILS NOTE:
If running the task from Rails, it's best to preload the environment by adding
=> [:environment]
which is a way to setup dependent tasks.
task :work, [:option, :foo, :bar] => [:environment] do |task, args|
puts "work", args
end
Related Topics
How to Make Object Instance a Hash Key in Ruby
Ruby Merging Two Arrays into One
How to Read Lines from File into Array
Strange Activerecord::Associationtypemismatch
Ruby Easy Search for Key-Value Pair in an Array of Hashes
Rails 3 Initializes Extremely Slow on Ruby 1.9.2
Rubymine - No Ruby Interpreter Configured for the Project
Converting an Empty String into Nil in Ruby
How to Export a Ruby Array from My Heroku Console into CSV
Where/How to Include Helper Methods for Capybara Integration Tests
Ruby Request to Https - "In 'Read_Nonblock': Connection Reset by Peer (Errno::Econnreset)"
Asserting That a Particular Exception Is Thrown in Cucumber
Where Are the Gems When Ruby Compiled Manually in MAC Os X 10.6.8
Error About Nokogiri While Capistrano Deployment on Ubuntu Server
Using Question Mark Character in Rails/Activerecord Column Name