How do I create a global rakefile on Windows 7? - ruby

I want to be able to create a rakefile on Windows 7 that I can call with the rake -g <taskname> or rake --system <taskname> command. Where do I save the rakefile? I've tried creating a Rake directory under my user directory (c:\users\me\rake), but when I call rake -g hello_world, rake errors out saying it doesn't know how to build the :hello_world task, which makes me think it just can't see the rakefile. Here's what my global rakefile looks like:
require 'rake'
desc "a hello world task"
task :hello_world do
puts "hello from your global rakefile"
end

Figured it out - turns out Rake expects global rakefiles to end in a ".rake" extension. I changed the example above to this:
require 'rake'
desc "a hello world task"
task :hello_world do
puts "hello from {__FILE__}"
end
And saved it as "testing.rake" in my c:\users\me\rake\ directory. I opened up a command prompt to a random directory and ran "rake -g hello_world" and got this output:
C:\Windows\system32>rake -g hello_world
(in C:/Windows/system32)
hello from C:/Users/me/Rake/testing.rake

Rake looks for Rakefile in the current directory unless specified explicitly as in:
rake --rakefile C:\users\me\rake\[rakefile]

Rake on Windows looks for $HOME/Rake/*.rake if the target cannot be found locally. If HOME is not set, then it will use c:\Users\me\Rake as the other responders have indicated.
But, if you happen to have HOME set (as I do, operating in a mixed Cygwin/Windows 7 world), now you know where rake will be expecting to find your global rake files.
Btw, I don't find it necessary to pass the -g flag; Rake seems happy to find the global definitions on its own. I think the only case in which -g is warranted is if you need to be absolutely sure there is no rake task of the same name locally.

Related

Ruby: run rake task to execute ruby scripts

I have a bunch of Ruby scripts and I'd like to start them with a Rake task.
A simplified version to illustrate my issue:
export_stats.rake:
desc 'Export statistics'
task :export_stats do
puts "executing: export_stats.rb #{START_MONTH} #{END_MONTH} #{OUTPUT} #{ENVIRONMENT}"
ruby "export_stats.rb #{START_MONTH} #{END_MONTH} #{OUTPUT} #{ENVIRONMENT}"
end
rake aborted! elk-stack/export_stats.rake Don't know how to build task
'export_stats'
the export_stats.rb file is in same directory with export_stats.rake
the rake gem is installed and if I run
rake export_stats
I get an error:
rake aborted!
Don't know how to build task 'export_stats'
What am I missing?
If I understand you correctly you have a folder with some ruby scripts and you are trying to run a rake task that is located in the same folder. I assume you are not using any application framework like Rails (because you did tag the question only with "Ruby").
Do you have a Rakefile in same directory? If so does it contain a statement to load the specific files to run?
# Rakefile
#!/usr/bin/env rake
load 'export_stats.rake'
You have a typo.
The code says export_stats, and the error says exports_stats.
There's an extra s.
Read the error message carefully! ;)

How do I run Rails/Rake from another directory?

Without cd-ing into the root directory of my Rails application, how can I execute a Rails or Rake command for that application.
I tried:
bundle exec rake my_tasks:do_stuff BUNDLE_GEMFILE=/PATH/TO/RAILS_APP/Gemfile
among other combinations, to no avail.
[Update]
The issue is actually two-fold, bundle doesn't know where the gemfile is and rake doesn't know what to run.
To use Bundler:
BUNDLE_GEMFILE=/PATH/TO/RAILS_APP/Gemfile bundle exec ...
Note that BUNDLE_GEMFILE has to go before 'bundle exec'.
To use Rake:
rake -f /PATH/TO/RAILS_APP/Rakefile my_task:do_stuff
To use Rails console:
????
Have yet to figure out how to enter the Rails console from another directory. Looking at the source, I think it may not be possible, because it eventually does File.join('script','rails') to kick off the rails process.
Without you showing the error message you are getting, I'm assuming it has less to do with Bundler than it does Rake. When the rake command is run, it searches for a Rakefile starting in the current directory and traversing up the tree until it finds one. You can override this behavior by explicitly specifying a Rakefile in the options to the rake command. This is done using the -f <RAKEFILE> option.
eg.
bundle exec rake -f /PATH/TO/RAILS_APP/Rakefile my_task:do_stuff
Bear in mind that your Rake tasks have to be "CWD agnostic". Most tasks and scripts are as they tend to get the project directory based on a path relative to a known file in the directory tree. You probably already understand that, but it's worth mentioning in case the tasks are expecting the current working directory to actually be the rails root. That would be a case where running them from outside the project could potentially be dangerous.

How to setup Whenever gem in production (RVM)

I've one rake task which i want to execute once every day:
in production installed rvm
in schedule.rb i have
set :output, "/home/username/data/public_html/log/cron_log.log"
every 24.hours do
rake "fetch:smth"
end
crontab -l shows me:
MAILTO="my.mail#gmail.com"
PATH="/usr/local/rvm/rubies/ruby-1.9.3-p125/bin/ruby "
#daily cd /home/username/data/www/nameofsite.com && RAILS_ENV=production bundle exec rake fetch:smth
truly, i'm a little bit confused, coz previously i didn't have experience with cron, so plz help.
EDIT #1
i've run rvm env -- path 1.9.3#global
and it gave me:
PATH="/usr/local/rvm/gems/ruby-1.9.3-p125/bin:/usr/local/rvm/gems/ruby-1.9.3-p125#global/bin:/usr/local/rvm/rubies/ruby-1.9.3-p125/bin:/usr/local/rvm/bin:$PATH"
and then i've
MAILTO="said.kaldybaev#gmail.com"
PATH="/usr/local/rvm/gems/ruby-1.9.3-p125/bin:/usr/local/rvm/gems/ruby-1.9.3-p125#global/bin:/usr/local/rvm/rubies/ruby-1.9.3-p125/bin:/usr/local/rvm/bin:$PATH"
#daily RAILS_ENV=production rake rate:fetch
and when i run execute, from ISPmanager, it gave me: Exited with return code = 1
the link below says that if the exit error is 1, then there is already a /var/run/cron.pid file. and it's true, but i don't have root privileges
You don't need schedule.rb if you're calling the task from cron. That's handled by the #daily entry in crontab. Just set the logfile name as an environment variable and have the rake task refer to that. You'll probably also need more in your $PATH than just the path to the ruby binary, otherwise bundle isn't going to be found. While you're giving the path to a ruby, you're not actually selecting it for RVM to know what you mean, so it's not going to be able to find the right gemset. RVM provides wrappers which Do The Right Thing for this sort of task - replace bundle exec with /usr/local/rvm/wrappers/ruby-1.9.3-p125 -S bundle exec and it should work.
Hope that gives you some ideas. There's more here.
UPDATE #1
With Edit #1, you've fixed one problem and created another. You still need to cd to the app directory, otherwise rake won't find the Rakefile.

How can I speed up Ruby/Rake task

rake --tasks takes about 18s to run. This is just the time it takes to load all the tasks, as a result any task I define will take at least this amount of time to run :
$time rake --tasks
rake db:clean # Cleaning up database
rake passenger:restart # Restart Application
rake spec # Run specs
real 0m18.816s
user 0m7.306s
sys 0m5.665s
My Rakefile :
$: << "."
require "rubygems"
require "rspec/core/rake_task"
desc "Run those specs"
task :spec do
RSpec::Core::RakeTask.new(:spec) do |t|
t.rspec_opts = %w{--colour --format progress}
t.pattern = 'spec/*_spec.rb'
end
end
task :default => :spec
Any idea why rake takes to much times ?
Thanks
Try spring
Command line will look like:
spring rake -T
It will take more time running the first time, but subsequent runs will be very fast.
This solution worked for me: Faster rake tasks in Rails.
I had to do a little variation where I created a lib/tasks/no_rails directory and put all the Rake files which do not need Rails in there and loaded only those using the above method.
I like the solution Pratik mentions for the general case of loading rails for tasks that need it and not for those that don't, for any rake task without having to remember beforehand.
A less-invasive method to run a rake task that doesn't need rails is to use the -f rake option to tell rake to use a particular Rakefile. This way, rake won't go looking for rake tasks in all of rails.
For example, assuming your task above is in a file called Rakefile at the top level of your project and your Rakefile doesn't do anything that loads Rails like require File.expand_path('../config/application', __FILE__), you can do:
$ rake -f Rakefile spec
and it should run your spec task much faster. Try $ time rake -f Rakefile -T; I did this with a rails-independent Rakefile of mine and got:
real 0m1.543s
user 0m1.308s
sys 0m0.201s
The downside is you have to remember to specify this option every time, and not to specify it if you want to run a rake task from rails like rake db:migrate.
The entire rails environment has to be loaded, therefore even simple rake tasks such as rake --tasks take a while. Opening a console with rails console or script/console takes a similar time. You may try to hack Ruby or Rails to speed up rake, but too much optimization can be bad if you want to switch to a newer version later. Since the rails environment must be loaded, cleaning up routes may also help.

Execute tests for another app from a rake file

I'm trying to execute cucumber tests for a project within a rake file in another project.
Currently I am trying this:
system "cd /path/to/project;rvm use --create 1.9.2-p290#test; cucumber features/test.feature"
This works for the cd, and the rvm seems to work if I run which ruby after the rvm use... but the problem is that the cucumber gem seems to be called from the current folder (not the app to test folder).
The error I get is:
cucumber is not part of the bundle. Add it to Gemfile. (Gem::LoadError)
It seems to be using the local gemset version of cucumber rather than the #test gemset.
Any thoughts on this?
Or is there a better way to run cucumber tests for another project that relies on rvm & a different bundle?
I've also been trying to do exactly the same thing; run an application's tests (or any rake task) from inside another 'control' application.
Reason: (just so I don't get served with a "why on earth?")
I am trying to build an application (rather like cruisecontrol.rb ) which can monitor, schedule and review the specs for a set of apps.
After some digging around in cruisecontrol's source I found that Bundler provides a solution;
Bundler.with_clean_env do
system "rake spec"
end
see line56 of https://github.com/thoughtworks/cruisecontrol.rb/blob/master/lib/platform.rb
That steps out of the bundle and the command is run without the control app's gems.
BUT as is most likely, the command uses bundle exec then this stops working.
Bundler.with_clean_env { system "bundle exec rake spec" }
And you are right back to the exact same problem. This is caused by some bundler variables still existing and being inherited by the sub-shell. Full (very good) explanation here.
The solution is to change the with_clean_env method on bundler like this;
BUNDLER_VARS = %w(BUNDLE_GEMFILE RUBYOPT BUNDLE_BIN_PATH)
module Bundler
def self.with_clean_env &blk
bundled_env = ENV.to_hash
BUNDLER_VARS.each{ |var| ENV.delete(var) }
yield
ensure
ENV.replace(bundled_env.to_hash)
end
end
above code from here
I put that in the environment.rb of my control application (it should probably be in a initializer?) and now I can run the specs of another app from within the control app.
#in control app
result = nil
Dir.chdir(test_app_path) #move into test app
Bundler.with_clean_env { result = `bundle exec rake spec` } #run test apps specs
puts result #display result inside control app
Changing the ; in your script to && seems to work.

Resources