A rake task by .rake file - ruby

I have the following Rakefile in a Ruby 1.9.3 project:
require 'rake/testtask'
require 'json'
Rake::TestTask.new do |t|
t.pattern = "spec/**/*_spec.rb"
t.verbose = true
end
task :default => :test
namespace :omglol do
namespace :file_a do
task :foo do
# do some stuff
end
end
namespace :file_b do
task :bar do
# do some stuff
end
end
end
As you can see, the first part of this file allow to run tests, just using rake command. And the second part contains some tasks.
Actually, I have a lot of tasks inside omglol:file_a and omglol:file_b namespaces. That's why I would like to move each of them inside a file, for instance tasks/omglol/file_a.rake and tasks/omglol/file_b.rake.
Is there a best way to do so? Thanks.

Yes. Simply move the logic into the appropriate files and then require them.
Example Rakefile:
require 'rake/testtask'
require 'json'
require 'lib/tasks/omglol/file_a.rake' # <= contains your subtasks
Rake::TestTask.new do |t|
t.pattern = "spec/**/*_spec.rb"
t.verbose = true
end
task :default => :test
Then in lib/tasks/omglol/file_a.rake simply define your tasks as normal:
namespace :omglol do
namespace :file_a do
task :foo do
# do some stuff
end
end
end
The pattern would be the same for file_b.rake.

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 not running any tests with minitest

I have a file containing a class of multiple tests (using minitest). I have require 'minitest/autorun' at the top of the file and all tests run correctly when I call the file directly (ruby my_tests.rb).
So far, so good. However, now I'm trying to run my tests via rake.
require "rake/testtask"
task :default => [:test]
Rake::TestTask.new do |t|
t.libs << Dir.pwd + "/lib/examples"
t.test_files = FileList['test/test*.rb']
end
Calling rake shows test/my_test.rb getting called but no tests within the class get run (0 tests, 0 assertions, etc.). I do get these warnings:
...gems/minitest-5.8.0/lib/minitest/assertions.rb:17: warning: already initialized constant MiniTest::Assertions::UNDEFINED
...ruby/2.1.0/lib/ruby/2.1.0/minitest/unit.rb:80: warning: previous definition of UNDEFINED was here
How can I run my tests within rake successfully? I am not using rails.
EDIT: Here is the top of my test file:
require 'minitest/spec'
require 'minitest/autorun'
require 'minitest/reporters'
reporter_options = { color: true }
Minitest::Reporters.use![Minitest::Reporters::DefaultReporter.new(reporter_options)]
class Test_PowerSpecInputs < Minitest::Test
def setup
#mc = TestClass.new()
end
def test_does_lib_have_constant
# my test code
end
end
Try changing your Rakefile to this.
require "bundler/gem_tasks"
require "rake/testtask"
Rake::TestTask.new(:test) do |t|
t.libs << "test"
t.libs << "lib"
t.test_files = FileList['test/**/*_test.rb']
end
task :default => :test
jphager2 got me thinking about tool versions and it turned out that my version of rake was fairly old. Updating to 11.x did the trick.

ActiveSupport TestCase not running in Sinatra

I'm setting up a new Sinatra app and am having issues getting my tests to run via a rake task. When I run rake:test, the task runs, shows me which files it will be running, but nothing happens. I know it's loading the class because it has failed due to syntax errors, but I never see my tests running. What am I missing? Below is my configuration and example test:
rakefile.rb
require "rake/testtask"
require "sinatra/activerecord/rake"
require "./app"
task :default => :test
TEST_FILES = FileList["test/**/test*.rb"]
desc "Run all of the tests for redFish"
Rake::TestTask.new do |t|
t.libs << "test"
t.test_files = TEST_FILES
t.verbose = true
end
task :default => "test"
test/test_helper.rb
ENV["RACK_ENV"] = "test"
require "rack/test"
require "awesome_print"
require "active_support"
require "active_support/core_ext"
/test/unit/test_organization.rb
require File.expand_path '../../test_helper.rb',__FILE__
class TestOrganization < ActiveSupport::TestCase
def setup
puts "setup for tests"
end
test "validates_required_fields" do
puts "RUNNING TESTS"
assert true
refute false
end
end
When I run rake:test, I can see that test_helper and test_organization.rb are being found by the TestTask, but I don't see any tests pass/fail.
Am I missing something obvious?
Looks like the issue was caused by not requiring minitest/autorun in my test helper. I added that line, and the tests ran fine.

How to create an RSpec Rake task using RSpec::Core::RakeTask?

How do I initialize an RSpec Rake task using RSpec::Core::RakeTask?
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new do |t|
# what do I put in here?
end
The Initialize function documented at
http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method isn't very well-documented; it just says:
- (RakeTask) initialize(*args, &task_block)
A new instance of RakeTask
What should I put for *args and &task_block?
I'm following in the footsteps of someone who had already started to build some ruby automation for a PHP project using RSpec in combination with Rake. I'm used to using RSpec without Rake, so I'm unfamiliar with the syntax.
Thanks,
-Kevin
Here is an example of my Rakefile:
require 'rspec/core/rake_task'
task :default => [:spec]
desc "Run the specs."
RSpec::Core::RakeTask.new do |t|
t.pattern = "spec.rb"
end
desc "Run the specs whenever a relevant file changes."
task :watch do
system "watchr watch.rb"
end
This allows to run specs defined in the spec.rb file from Rake
This is what my rakefile looks like
gem 'rspec', '~>3'
require 'rspec/core/rake_task'
task :default => :spec
desc "run tests for this app"
RSpec::Core::RakeTask.new do |task|
test_dir = Rake.application.original_dir
task.pattern = "#{test_dir}/*_spec.rb"
task.rspec_opts = [ "-I#{test_dir}", "-I#{test_dir}/source", '-f documentation', '-r ./rspec_config']
task.verbose = false
end
You can 'rake' from your tests directory and it will run all tests with a name [something]_spec.rb - and it should work across different test directories (e.g. different projects); if you have source in a separate directory (e.g. in the code above, a subdirectory called '/source' it will pick them up. Obviously, you can change that source directory to what you want.
Here's the rspec_config file I use - you can add your own settings in here:
RSpec.configure do |c|
c.fail_fast = true
c.color = true
end

Default task for namespace in Rake

Given something like:
namespace :my_tasks do
task :foo do
do_something
end
task :bar do
do_something_else
end
task :all => [:foo, :bar]
end
How do I make :all be the default task, so that running rake my_tasks will call it (instead of having to call rake my_tasks:all)?
Place it outside the namespace like this:
namespace :my_tasks do
task :foo do
do_something
end
task :bar do
do_something_else
end
end
task :all => ["my_tasks:foo", "my_tasks:bar"]
Also... if your tasks require arguments then:
namespace :my_tasks do
task :foo, :arg1, :arg2 do |t, args|
do_something
end
task :bar, :arg1, :arg2 do |t, args|
do_something_else
end
end
task :my_tasks, :arg1, :arg2 do |t, args|
Rake::Task["my_tasks:foo"].invoke( args.arg1, args.arg2 )
Rake::Task["my_tasks:bar"].invoke( args.arg1, args.arg2 )
end
Notice how in the 2nd example you can call the task the same name as the namespace, ie 'my_tasks'
Not very intuitive, but you can have a namespace and a task that have the same name, and that effectively gives you what you want. For instance
namespace :my_task do
task :foo do
do_foo
end
task :bar do
do_bar
end
end
task :my_task do
Rake::Task['my_task:foo'].invoke
Rake::Task['my_task:bar'].invoke
end
Now you can run commands like,
rake my_task:foo
and
rake my_task
I suggest you to use this if you have lots of tasks in the namespace.
task :my_tasks do
Rake.application.in_namespace(:my_tasks){|namespace| namespace.tasks.each(&:invoke)}
end
And then you can run all tasks in the namespace by:
rake my_tasks
With this, you don't need to worry to change your :all task when you add new tasks into that namespace.
I use this Rakefile for cucumber:
require 'cucumber'
require 'cucumber/rake/task'
namespace :features do
Cucumber::Rake::Task.new(:fast) do |t|
t.profile = 'fast'
end
Cucumber::Rake::Task.new(:slow) do |t|
t.profile = 'slow'
end
task :ci => [:fast, :slow]
end
task :default => "features:ci"
Then if I type just:
rake
It runs the default task, which runs both fast and slow tests.
I learned this from Cheezy's blog.
The way I'm reading obvio171's question is that he is asking1) for a systematic way to invoke a certain task in a namespace by invoking the namespace as a task.
I've frequently encountered the same need. I like to logically group tasks into namespaces. Often that grouping resembles a hierarchy. Hence the desire to invoke the group makes very much sense to me.
Here's my take:
module Rake::DSL
def group(name, &block)
ns = namespace name, &block
default = ns[:default]
task name => "#{name}:default" if default
ns
end
end
group :foo do
task :foo1 do |t| puts t.name end
task :foo2 do |t| puts t.name end
task :default => [:foo1, :foo2]
end
task :default => :foo
1)...or was asking, years ago. Nonetheless a still interesting question.
Add the following task outside of the namespace:
desc "Run all my tasks"
task :my_tasks => ["my_tasks:all"]
Keep in mind, that you can have a task with the same name as the namespace.
And hier a bigger example, that shows, how you can make use of tasks, which have the same name as the namespace, even when nesting namespaces:
namespace :job1 do
task :do_something1 do
puts "job1:do_something1"
end
task :do_something2 do
puts "job1:do_something2"
end
task :all => [:do_something1, :do_something2]
end
desc "Job 1"
task :job1 => ["job1:all"]
# You do not need the "all"-task, but it might be handier to have one.
namespace :job2 do
task :do_something1 do
puts "job2:do_something1"
end
task :do_something2 do
puts "job2:do_something2"
end
end
desc "Job 2"
task :job2 => ["job2:do_something1", "job2:do_something2"]
namespace :superjob do
namespace :job1 do
task :do_something1 do
puts "superjob:job1:do_something1"
end
task :do_something2 do
puts "superjob:job1:do_something2"
end
end
desc "Job 1 in Superjob"
task :job1 => ["job1:do_something1", "job1:do_something2"]
namespace :job2 do
task :do_something1 do
puts "superjob:job2:do_something1"
end
task :do_something2 do
puts "superjob:job2:do_something2"
end
end
desc "Job 2 in Superjob"
task :job2 => ["job2:do_something1", "job2:do_something2"]
end
desc "My Super Job"
task :superjob => ["superjob:job1", "superjob:job2"]
# Do them all just by calling "$ rake"
task :default => [:job1, :job2, :superjob]
Just copy it and try it out.
Based on Rocky's solution Default task for namespace in Rake
And this dexter's answer Is there a way to know the current rake task?
namespace :root do
namespace :foo do
end
namespace :target do
task :all do |task_all|
Rake.application.in_namespace(task_all.scope.path) do |ns|
ns.tasks.each { |task| task.invoke unless task.name == task_all.name }
end
end
task :one do
end
task :another do
end
end
end
Combining Szymon LipiƄski's and Shyam Habarakada's answers, here is what I think is the most idiomatic and consise answer:
namespace :my_tasks do
task :foo do
do_something
end
task :bar do
do_something_else
end
end
task :my_tasks => ["my_tasks:foo", "my_tasks:bar"]
allows you to do rake my_tasks while avoiding cumbersome invocation of the subtasks.

Resources