task in Capistrano 3 cannot find RVM - ruby

I have been using Capistrano 3 to deploy a PHP app for several months and it works great. Recently, we decided to start using Sass for stylesheets and I am now trying to deploy these changes.
I am trying to write a task that runs after the rest of the deploy stuff is finished that converts a scss file to css using the Sass gem.
namespace :deploy do
after :finished, :assets do
on roles(:app), in: :sequence, wait: 5 do
within release_path do
# process sass files to css
execute "sass #{release_path}/styles/test.scss #{release_path}/styles/test.css"
end
end
end
end
I am using RVM on the server and have the sass gem installed in a specific gemset. There is also an .rvmrc file in the project root that loads the correct gemset when you cd into the 'current' directory that capistrano creates.
When I deploy, it fails on my new task saying that it cannot find sass.
stderr: bash: sass: command not found
I can log into the server as the same user that is used to deploy with Capistrano and cd into the 'current' directory and run the same command in the task (substituting the #{release_path} with actual path) and it works fine.
Things I have tried:
rewriting the execute command with the following:
rvm use 2.1.5#deployer && sass #{release_path}/styles/test.scss #{release_path}/styles/test.css
writing a bash script accessible by the deployer user that loads the gemset then runs the sass command (works when I run the new script while logged into the sever in any directory, does not work when called from the capistrano task)
using the capistrano-rvm plugin (adding to Gemfile, requiring in Capfile) to set the RVM gemset - hoping that it would load the gemset before running any commands.
I have used Capistrano many times for deploying Rails apps and always use the asset plugin that handles precompiling and whatnot... This is the first project that I have used for deploying a PHP app and maybe the first time I have tried to manually run a capistrano task that uses a rubygem installed on the server with RVM.
Is it possible to run a task that depends on a specific gem/gemset... without using the default rails plugins?
Any help is appreciated.
Thanks,
JD

figured this one out by requiring the capistrano/bundler command, just to see how capistrano runs bundle by default... copied the bundler command that was logged during a deploy, then modified it to work for what I was trying to do and finally removed the bundler plugin as I do not actually need the deploy to bundle anything.
without using any capistrano plugins, you can preface the capistrano task execute command with the location of the gemset like so:
after :finished, :assets do
on roles(:app), in: :sequence, wait: 5 do
within release_path do
execute "~/.rvm/bin/rvm ruby-2.1.5#deployer do sass #{release_path}/styles/sass/screen.scss #{release_path}/styles/screen.css"
end
end
end
The key difference is the following snippet prefaces the actual command I was trying initially:
~/.rvm/bin/rvm ruby-2.1.5#deployer do ....
Obviously, you could use whatever command requiring the gemset specified that you want (instead of the sass command I am using).

Related

Rails console not working on server

When I run bundle exec rails console production or rails console production via SSH on the server in the Current folder of the Capistrano deploy I get:
Usage:
rails new APP_PATH [options]
Options:
(...)
with an explanation to start a new app. Locally it works. Why can't I start a console remotely?
I'm assuming that you updated to rails 4 from version 3 and your app can't find the executables in the bin directory. Run this to see your rails version:
$ rails -v
If your rails version is 4 or above, try running this:
$ rake rails:update:bin
Source: Rails 4 Release Notes
6.1 Notable changes
Your app's executables now live in the bin/ dir. Run rake rails:update:bin to get bin/bundle, bin/rails, and bin/rake.
I am using capistrano to deploy, including the capistrano/bundler gem. Since the ./bin directory is version controlled in Rails 4, we need to prevent Capistrano from linking it on deployments by removing bin from set :linked_dirs.
Now in order to prevent bundler from overwriting the version controlled binstubs, we can add the line set :bundle_binstubs, nil which will prevent capistrano-bundler from setting the --binstubs option when running bundle install.
My config/deploy.rb file now has these lines:
# Default value for linked_dirs is []
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system')
set :bundle_binstubs, nil
Note the lack of the bin directory in the :linked_dirs line.
I have the same problem, and turns out when you deploy through cap shared/bin is symlink to current/bin.
Here's what works for me:
rm current/bin
mkdir current/bin
rake rails:update:bin
This should help, but it is somewhat a temporary solution, I'm trying to find out how to make cap not auto symlink-ing current/bin.
In case of Rails 5.2
I had to remove bin directory by running below command in project root directory.
rm -rf bin
and then I ran another command in project root directory:
rake app:update:bin
It will show you output like below:
create bin
create bin/bundle
create bin/rails
create bin/rake
create bin/setup
create bin/update
create bin/yarn
That's it.
It's been a little while since this was answered.
In my case I needed to run:
rake app:update:bin
Note- app rather than rails.
I was missing the bin directory all-together in my Rails 5.1 App
I faced this issue on my production server when I updated my application from Rails 5.2 to 6.0.4. Simply follow these steps:
cd to_your_project_dir
rm -r bin
rake app:update:bin

Installing the correct environment for Angular with Compass and all other Node dependencies

I am just trying to make a local development environment that isn't on my work computer, and I keep getting an error:
Warning: Errno::ENOENT on line 441 of /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/pathname.rb: No such file or directory - /Users/johnpett/Desktop/Node/app/bower_components
Run with --trace to see the full backtrace Use --force to continue.
I have installed all the Ruby parts and Yeoman to build the app scaffold, but I can't seem to run the 'grunt server' command without throwing up this error.
The error is quite clear, a grunt-plugin require that file...
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/pathname.rb
Anyway ruby components are needed usually if you plan to use compass, if not, you can comment the "compass" sub-task in the "server" task in Gruntfile.js
Your folder was surely not called bower_components at that time. I guess you used yeoman.
In your compass task config you should have modified bower_components.

How to develop a Ruby GEM without having to install it first?

I'm developing a GEM that I've forked and I'm trying to modify it slightly for my app.
I'm finding it difficult and time consuming because for every change I make I have to
uninstall
build
re-install
run the app
Is there an easier way of which doesn't require repeating all steps above?
To use it in some app using bundler
If what you mean is for using it in a app to test it / use it, you can just specify a path for your gem or even point to a git repo in the Gemfile http://gembundler.com/gemfile.html
Like
gem "mygem", :path => "~/code/gems/mygem"
To use it as a standalone gem. i.e: like rspec or rake that can run outside of an app.
Just specify the path to your gem binary when running the gem command, like:
$ ~/path_to_my_gem/bin/mygem some args
If you can execute inside your gem directory (i.e: the command does not create files in the current directory, or needs any specific files from the current directory), just do this:
$ ./bin/mygem some args
Note that this last one is just for future reference, I think it's not applicable in the OP context.
use require_relative to include your files:
require_relative 'yourgem/yourclass'
This is the documentation for the function.

How to build and run a Ruby command-line tool found on github?

Hi cloned a simple app ( https://github.com/cfx/twix) on github that allows me to send Twitter messages from the console, but I'm not sure how to run it.
I now have a folder in my users/name director called Twix. Inside twix, I have these folders created by the app.
README Rakefile bin lib test
The readme doesn't provide a lot of instruction to get things started. It just tells you what to do after the program's running (see below).
Questions: What command do I use to get this started? What folder do I need to be in?
The README
Twix 0.0.1
Simple twitter client for console
Keys:
q - quit
t - write new message
If you want to post your twit, finish you message with !SEND
If you want abort and back to your feed, finish your message with !EXIT
new features soon
This program is packaged as a gem. The following command will install the gem (run it in the Twix directory):
rake package && gem install pkg/twix-0.0.1.gem
You can now run the program from anywhere with the twix command.
Edit
The first thing I saw in the repository was the Rakefile, meaning there were some rake tasks defined. When you find yourself in this case, running rake -T is your best bet as it will show you the rake tasks available. Its output was the following:
(in /home/benoit/code/clones/twix)
rake clobber_package # Remove package products
rake gem # Build the gem file twix-0.0.1.gem
rake package # Build all the packages
rake repackage # Force a rebuild of the package files
I picked the command that would be the most likely to build the gem: the package one. I guess the gem task would have worked as well.
Running rake package gave me the following output:
(in /home/benoit/code/clones/twix)
mkdir -p pkg
WARNING: no homepage specified
Successfully built RubyGem
Name: twix
Version: 0.0.1
File: twix-0.0.1.gem
mv twix-0.0.1.gem pkg/twix-0.0.1.gem
All that was left was to install the pkg/twix-0.0.1.gem created by the previous command:
gem install pkg/twix-0.0.1.gem
There's another case you could have encountered: the presence of a twix.gemspec in the root directory of the application. In this case, running:
gem build twix.gemspec
would have built the gem, the installation step remains the same.
ruby ./bin/twix
or
ruby -I lib ./bin/twix

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