Capistrano: run_locally in separate project - ruby

I'm using capistrano for deployment. I'm trying to define a task which will:
cd other-rails-app && bundle exec rake sometask
But it's complaining about Rake not being part of the bundle (which is obviously not true in the project where I am trying to run this task). I think it must be altering the environment somehow before executing the command and assuming bundler is already loaded (which is true in the capistrano task, but it's the wrong Gemfile).
How do I run a command locally with capistrano with a clean environment?

I figured out the problem. When you run capistrano, the BUNDLE_GEMFILE environment variable gets set to the Gemfile of the current project. So when you run bundle exec rake, Bundler looks first to the Gemfile set in the environment. The solution is to "reset" this Gemfile variable. I created a script for running my rake task in the root of my other project.
So instead of doing:
run_locally "cd other-rails-app && bundle exec rake mytask"
I do this:
run_locally "cd other-rails-app && ./mytask.rb"
In the mytask.rb file I do this:
#!/usr/bin/env ruby
ENV['BUNDLE_GEMFILE'] = File.expand_path('Gemfile', File.dirname(__FILE__))
require 'bundler/setup'
%x{rake mytask}

Related

Jenkins and running rake tasks

I'm having some issues running a rake task from within Jenkins (within a docker container) as part of a build process (I have the Rake plugin installed). I am getting the error
java.io.IOException: Cannot run program "rake" (in directory "/var/jenkins/workspace/HendricksFeaturesCopy"): error=2, No such file or directory
Which i don't understand as when i pwd $ECHO before the rake task is invoked i get.
/var/jenkins/workspace/HendricksFeaturesCopy
So i'm in the correct place and rake is installed as its located here
/usr/local/rvm/rubies/ruby-2.3.0/bin/rake
My Rakefile looks like
import 'lib/tasks/yard-docs.rake'
lib/tasks/yard-docs.rake
require 'yard'
namespace :yard_docs do
desc 'Generate Yard Documentation'
task :generate do
# Generate Yard Documentation
end
end
Does anyone know how to rectify this or what I am missing?
UPDATE
After doing echo $PATH
/usr/local/rvm/gems/ruby-2.3.0/bin:/usr/local/rvm/gems/ruby-2.3.0#global/bin:/usr/local/rvm/rubies/ruby-2.3.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/rvm/bin
So this means the correct gemset is being used and when I have done rvm #global do gem list
rake (10.4.2)
So, rake is available right ?
Make sure /usr/local/rvm/rubies/ruby-2.3.0/bin/ is in your $PATH.
PATH=/usr/local/rvm/rubies/ruby-2.3.0/bin/:$PATH
Alternatively, symlink /usr/local/rvm/rubies/ruby-2.3.0/bin/rake to /usr/local/bin/
ln -s /usr/local/rvm/rubies/ruby-2.3.0/bin/rake /usr/local/bin/

How to run a ruby script within bundler context?

I have a Ruby script called foo.rb, and I want to run it within the context of the bundler environment. How?
bundle exec foo.rb doesn't work, because exec expects a shell script.
Pass the script name to the ruby command:
bundle exec ruby script_name
If you also want the Rails environment:
bundle exec rails runner script_name
For instance, I wanted to use the same version of Rubocop as my Rails app and not the latest system one, so doing this in a script:
require 'bundler'
Bundler.require
# ...
Allowed me to use my app's version of rubocop.
You can just make it a script - add
#!/usr/bin/env ruby
to the start of the file, and make it executable. Then bundle exec foo.rb will work as expected.
(This is on unix or OSX - not sure about Windows)
See http://bundler.io/v1.15/man/bundle-exec.1.html#Loading
Also see https://coderwall.com/p/kfyzcw/execute-ruby-scripts-directly-without-bundler-exec for how to run ruby scripts with bundled dependencies, without needing bundle exec
If you want to create a script that you can run in bundle context within a project, you can invoke Bundler programmatically. E.g., given a project:
foo
├── Gemfile
└── bar
└── baz.rb
you can put the following at the top of baz.rb to give it access to the gems in the Gemfile:
#!/usr/bin/env ruby
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
require 'bundler/setup'
# ...etc.
With that, you can invoke the script directly without using bundle exec, and you also don't have to invoke it from within the project directory.

How can I run rake with --trace within capistrano?

I want capistrano to invoke rake with --trace so I can figure out why it's failing. How do I do this? set :rake 'rake --trace' doesn't work.
The best way I found is:
set :rake, "#{rake} --trace"
This way you don't overwrite the rake variable.
For example if you use bundler this is set before to:
"bundle exec rake"
and after to:
"bundle exec rake --trace"
The chances are your custom tasks aren't using the rake variables, but instead hard-coding rake, here's an example:
run("rake sass:compile")
This is hard-coded, and won't care about your setting set :rake, 'rake --trace', here's the correct way:
run("#{fetch(:rake)} sass:compile")
Or, shorthand:
run("#{rake} sass:compile")
You can see this in practice in the Capistrano source code, in the one place that the default recipes actually invoke rake, in the migrations task: https://github.com/capistrano/capistrano/blob/master/lib/capistrano/recipes/deploy.rb#L387

Capistrano + RVM + Rake task

I have a project which
uses rvm ruby 1.9.2 (set in .rvmrc in project dir).
deploying with capistrano.
has a rake task I want to run remotely from my local machine by capistrano.
I've created a .sh file to run my task:
cd /var/www/pluslook/current
/home/kirill/.rvm/scripts/rvm use 1.9.2#pluslook
/home/kirill/.rvm/gems/ruby-1.9.2-p180#pluslook/bin/rake parse:feed RAILS_ENV="production" --trace
But when I'm trying to run this task i have an error:
Using /home/kirill/.rvm/gems/ruby-1.9.2-p180 with gemset pluslook
Could not find linecache19-0.5.12 in any of the sources
Run `bundle install` to install missing gems.
I've installed all my gems in project's current directory so it looks like rake task is running from another directory. When I'm trying to run task from capistrano, It shows me the same error.
Thank you and sorry for my English:)
do you have 'require "bundler/capistrano"' in config/deploy.rb
did you run "bundle install" before commit latest code changes?

rake command looks for Rakefile up the directory chain?

I am using Rails3 and accidentally I ran rake command from within lib directory. rake command successfully ran. I think rake command looks for Rakefile all the up the chain. Is that true?
Yes. According to http://docs.rubyrake.org/user_guide/chapter02.html you can avoid that by:
rake -N

Resources