Running Rake tasks can be awkward.
The commands tend to be really long.
For example...
$ bundle exec rake some_project:clear_expired_sessions
Also, I may not always remember the exact name of some task I only use occasionally.
So I have to discover task's name first like this and then copy and paste it into the command line...
$ bundle exec rake -T some_project
I'm using Zsh on OS X with oh-my-zsh and the Rake plugin.
It provides tab-completion of Rake tasks, but you still have to type "bund exec rake" the completions are really slow to load -- several seconds on my machine.
Is there a more efficient way?
You can always add an alias to your .bashrc or your .bash_profile to avoid bundle exec rake in the future.
alias rake='bundle exec rake'
Of course now bundle exec is implicated whenever you run rake, its up to you to decide if you want that.
or for project specific (lets say your project is rails_blog)
alias rkblog=railsblogtasks()
function railsblogtasks(){
cd /path/to/blog/;
bundle exec rake -T;
end
alias rkblogrun=runblogtask()
function runblogtask(){
cd /path/to/blog/;
bundle exec rake $1;
end
Now $ rkblog will show all your rails_blog tasks and $ rkblogrun <task> will run any task in your rails_blog project. This can of course be refactored and abstracted, but there is a general idea.
One quick simplication:
task :example_alias => :environment do
Rake::Task[some_project:clear_expired_sessions].invoke
end
Then you can simply do
$ rake example_alias
Related
I have and rails application and a rake task which I'm going to execute by cron around once in an hour. But the thing is that the task uses rails environment and some classes of my rails application. If I run it as ruby script, I'll have to include all the dependencies it uses and I think it's not possible to do it correctly and in a simple way. So I'll have to run it as a rake task because it'll preserve all the dependencies, right? Then how can I run a rake task from cron?
Note that I prefer not to use any third-party solution when there's no necessity, in this case I don't want to use the gem whenever or the like.
You can add to your crontab something like
0 * * * * /bin/bash -l -c 'cd /path/to/your/project && bundle exec rake foo:bar >> log/cron.log 2>&1'
This will run foo:bar task every hour and write stdout and stderr to log/cron.log.
Please notice bundle exec before rake command.
Using bundler ensure you that task will fetch correct environment.
To specify RAILS_ENV you can do
... && RAILS_ENV=production bundle exec rake foo:bar
Use whenever to simplify your life https://github.com/javan/whenever ;)
Here's an example of a rake task:
task :foo => :environment do
puts "Running rake task in environment: #{Rails.env}"
# can access Models here or whatever
end
Note that the => :environment part is optional, but it what makes your Rails environment to the task block.
You can put rake run_my_task in your cron job.
You may need to use something like cd /home/$USER/my_rails app && rake run_my_task to ensure that the cron runs the task from the Rails root directory.
What is the difference between using bin/rake and bundle exec rake.
And which is one preferred style?
bin/rake db:migrate
bundle exec rake db:migrate
bundle exec executes a command in the context of your application.
As each application can have different versions of gem used. Using bundle exec guarantees that you use the correct versions.
I use bundle exec always instead of rake because i have multiple applications running on my system.
Try to use bundle exec rake db:migrate always.
You can learn more about it here Official documentation
bin/rake is a kind of stub for the rake command from bundled Gems. It has exactly the same function as bundle exec rake. See http://bundler.io/v1.14/man/bundle-install.1.html and search for binstubs for more about stub. And also note that bin/rake and bin/rails are stubs generated by Rails, which are different in code from the stubs generated by bundler. However, they all serve the same purpose and have the same function.
You have 3 options on a typical system:
bin/rake db:migrate
rake db:migrate
bundle exec db:migrate
The first option is simply calling the path to the rake program, whose launcher can be found in the hidden /bin folder. This launcher is usually just a symlink to the program's content found in your /.rvm directory. You can find its original location by executing $ which rake, which will give you something like /home/ubuntu/.rvm/gems/ruby-2.2.3-p481#devonzuegel/bin/rake.
By default, the second option is essentially the same as the first on most systems. It's what is called an alias, which is basically just a shorthand command for some other program. This is defined somewhere in your shell settings as something like alias rake='/bin/rake'. It's possible that this alias is pointed to a different program on your machine though, so check that before taking my word for it.
When you use bundle exec you're telling bundler to ensure that only the gems and their specified versions from your Gemfile.lock are loaded. This will only work if you're in a directory that contains a Gemfile.lock or whose parent/grandparent directory contains one.
I am seeing many times the question about execution of bash files inside rake (task) files.
My question is, how to execute a rake command inside the bash file?
I have a migrate.sh file inside each rails app on my server and I'm using a general publish.sh. All of this runs ok.
Then, I have a command like rake tmp:clear assets:clean log:clear RAILS_ENV=production inside each migrate.sh that gives me a rake: command not found error.
Help?
Basically rake is not resolved as the PATH variable is not correct. You can try doing echo $PATH. Also you can create a bash script and provide some environment variables required by rake like this:
#!/bin/bash
GEM_HOME=/home/tuxdna/.gems
SHELL=/bin/bash
USER=tuxdna
PATH=/home/tuxdna/.gems/bin:/usr/lib/ruby/gems/1.8/bin/:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games
GEM_PATH=/home/tuxdna/.gems:/usr/lib/ruby/gems/1.8
cd ~/somesite
export RAILS_ENV=production
bundle exec rake mytask:task1
klashxx's supposition was correct. It was a permissions/profile issue. I had change my user to root to be able to do other previous tasks and found out that my root was not able to run rake tasks.
This will not be an issue on production server though.
Thanks klashxx
Is there a way to do a test run of a rake task? If so what is the command to do it? I don't want to actually touch the development database since my task manipulates the data.
Yes you can actually run bundle exec rake COMMAND -n
Having a look at rakes help we can see it here.
# rake --help
--dry-run Do a dry run without executing actions.
What is the difference between doing:
bundle exec rake
and
rake
I see people doing both, I never do bundle before my commands, curious what the reason for it is?
bundle exec executes a command in the context of the bundle.
This command executes the command, making all gems specified in the Gemfile available to require in Ruby programs.
Very useful when you have many applications with different versions of gems used
in them.
Please see docs for more information: http://gembundler.com/man/bundle-exec.1.html
bundle exec runs the command after it in the environment of Bundler. So say you had rake 0.9 in you Gemfile, but rake 10 installed in RubyGems.bundle exec rake will run rake 0.9 instead of rake 10.