Ruby: 'bundle exec' throws error for all shell commands - ruby

In my project, I have a Gem that contains a shell script in its bin folder, let's call the script do_something.sh.
do_something.sh actually executes a ruby script using Jruby command, the script is called ruby_script.rb.
I am trying to call do_something.sh from my project using:
bundle exec do_something.sh
it keeps throwing errors for all shell commands in the script. I erased all the contents of the script and added only one line "echo 'Hello'" and it is still throwing the following error
NoMethodError: undefined method echo' for main:Object
/usr/local/rvm/gems/ruby-2.1.1#projectName/gems/gemName/bin/do_something.sh:10:in'
/usr/local/rvm/gems/ruby-2.1.1#projectName/bin/do_something.sh:23:in load'
/usr/local/rvm/gems/ruby-2.1.1#projectName/bin/do_something.sh:23:in'
Edit#1
All the files has execute permission.
I also tried to put ruby_script.rb in the bin directory where are files are executables (according to a rule in the gemspec file) and tried calling
bundle exec ruby_script.rb
I get the error "bundler: command not found: ruby_script.rb"
bundle exec ruby ruby_script.rb
I get the error "ruby: No such file or directory -- ruby_script.rb (LoadError)"
Why am I getting this error and how can I solve it? I want to be able to either run do_something.sh or ruby_script.rb. Right now, ruby_script.rb is not recognised and do_something.sh does not recognise the commands.

Ok, finally after two days, I was able to make it work.
bundle install installs my GEM and creates a ruby wrapper by default to sh files in the 'bin' directory. So, when I call my script using bundle exec the ruby wrapper gets called first and it calls my script using a ruby 'load' function. This load function expects a ruby file and that is why all my shell script in the file threw errors, because they were expected to be in ruby.
A workaround to this is installing my gem before 'bundle install' using the following command:
gem install --no-wrapper my-gem
Apparently this command disabled creating the ruby wrapper and I was finally able to call the script using bundle execute do_something.sh

Try specifying sh when you run bundle exec. The NoMethodError is from the script being executed in ruby and not sh.
bundle exec sh do_something.sh

In order to make it work. Setting_up_permissions_on_a_script
First: you have to change the mode for the file using chomd +x file_path
Second: Now you can call either by bundle exec file_path or ./file_path
N.B
1: Don't forget to add #!/bin/sh on top of the file.
2: And do check with deploy-a-shell-script-with-ruby-gem-and-install-in-bin-directory will definitely help you.
Hope this help you!

According to Rubygems Specification Reference, executables included in the gem
... must be executable Ruby files. Files that use bash or other interpreters will not work.
In order to to add an executable to a gem please make sure to read the Adding an executable section on Rubygems Guide.
Eventually you'll be able to run the executable like this:
bundle exec do_something
where bundle exec part is optional.

Related

Cant run Ruby script via gem "ssh-net"

I am using gem net-ssh.
The connection is established. I am able to run some simple scripts(like "pwd", "ls", etc.) successfully, but when I run the "restart" script I get an error.
Here is a snippet:
output = ssh.exec!("cd /home/csrhub/git/csrhub-api; ./bin/restart")
puts "#{output}"
And the output:
./bin/restart:7:in exec': No such file or directory - bundle (Errno::ENOENT)
from ./bin/restart:7:in'
Environment determined as "development" based on the .environment file.
Loading application.yml
And here is the script where the error occurs.
#!/usr/bin/env ruby
require 'yaml'
require_relative '../app/models/environment.rb'
config = Environment.config('application')
exec "bundle exec pumactl --control-url tcp://127.0.0.1:#{config['control_port']} --control-token #{config['control_token']} phased-restart"
Connecting via Putty, when I run the same command it gets executed without any problems.
EDIT
The PATH variable is different when I Putty:
/home/csrhub/.rbenv/shims:/home/csrhub/.rbenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
And when I run with net-ssh PATH is:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
The problem is in your ssh.exec! call. Net::SSH does not use a login shell to run your commands. A login shell is required for Bash to execute .bash_profile.
Since your rbenv setup is in .bash_profile, your exec! call will be missing your full Ruby environment, and therefore running bundle later in you restart script will fail.
The solution should be to manually execute .bash_profile, so that rbenv gets loaded:
output = ssh.exec!("source ~/.bash_profile; ...rest of commands...")
More information and other proposals here:
net-ssh and remote environment

What is a proper way to execute ruby script from xcode build phase script?

I wrote some ruby script, that uses CocoaPods/Xcodeproj to edit xcode project file.
This script executes from xcode build phase script:
ruby script.rb someProj.xcodeproj
Inside ruby script, there is a 'require' for xcodeproj:
require 'xcodeproj'
When I invoke this script manually from terminal, everything is ok.
But when it invokes from xcode build phase, ruby throws exception:
cannot load such a file xcodeproj (something like that)
What am I missing?
Build phase -> Shell: change /bin/sh to /bin/bash -l
Bash login is required, in order to load ruby variables/paths/etc.

Run `bundle` system command in subfolder

I am attempting to run bundle in a subfolder of my ruby project, but it appears to be running in the context of my initial directory even though I have changed the current working dir to the subfolder.
# change directories and run bundle in a sub directory:
# ruby script.rb
system('bundle')
system('cd sub_folder')
system('bundle')
The bundle command runs successfully but only for the parent folder. Changing directories via system commands does not properly switch the context for bundler, and runs for the parent folders gemfile twice. What am I missing?
Just figured it out:
Dir.chdir('sub_folder') do
Bundler.with_clean_env do
system('bundle')
end
end
Shelling out - Any Ruby code that opens a subshell (like system,
backticks, or %x{}) will automatically use the current Bundler
environment. If you need to shell out to a Ruby command that is not
part of your current bundle, use the with_clean_env method with a
block. Any subshells created inside the block will be given the
environment present before Bundler was activated. For example,
Homebrew commands run Ruby, but don't work inside a bundle:
http://bundler.io/man/bundle-exec.1.html#ENVIRONMENT-MODIFICATIONS
You could try:
# ruby script.rb
Dir.chdir('sub_folder') do
system('bundle')
end

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.

Difficulty installing RSpec on Windows

I'm trying to get started with RSpec. I already had Ruby 1.8.7 installed on my Windows 7 machine.
So I typed gem install rspec and that seemed to work. But if I type spec in the command line, the command is not found. My path currently includes the bin folder in my RUBY_HOME.
If I look into the C:\Users\Eric\.gem\specs\rubygems.org%80\quick\Marshal.4.8 directory, I do see four RSpec files such as rspec-core-2.5.0.gemspec. Nevertheless, the spec command fails even in this directory.
What needs to be done to install RSpec correctly? It would seem like a path issue, but I have been unable to find a directory where the spec command works, so I can't figure what to add to my path.
On Windows, try this bundle exec rspec spec
There's no spec command in RSpec 2. Try rake spec or rspec spec.

Resources