Run `bundle` system command in subfolder - ruby

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

Related

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

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.

Gemsets file isn't working

I have a folder which contains a file named gemsets.rvmrc. The file contains this:
rvm use #pa
Running this code in the terminal successfully switches over to the correct gemset. I'd heard that putting this file in the folder would do that automatically when I CD to that folder, but this isn't the case. Running a ruby file in the same folder, test.rb, gives errors until I run that code in the terminal to switch to the correct gemset.
gemsets.rvmrc is not a supported file, it should be just .rvmrc, but using just gemset not always works - check this bug: https://github.com/wayneeseguin/rvm/issues/2078

Automatically run RSPec when plain-old Ruby (not Rails) files change

I am writing a Ruby script designed to run from the command line. The script has a corresponding RSpec file that verifies its functionality. The folder structure is:
./main_script.rb
./spec/main_script_spec.rb
Running rspec spec in the top level directory works as expected. Test results from the ./spec/main_script_spec.rb file are shown. I'd like to avoid running this manually every time I change either the main script file or the spec file. All my search results turn up things like guard which (as far as I can tell) are all designed for Rails apps.
How do I setup RSpec to watch for script or spec changes and run automatically with non-Rails Ruby code?
Like David said, Guard can be used to watch a wide variety of files and perform actions when those files are modified. It does not have to be used with a Rails app. I have set up something similar in the past using guard. Here is what I did:
Place the following in your Gemfile:
source 'https://rubygems.org'
gem 'guard'
gem 'guard-shell'
gem 'rspec'
gem 'rb-fsevent', '~> 0.9'
Then run:
$ bundle install
Create a Guardfile in your home directory with:
$ guard init
In the Guardfile, comment out the examples and add this:
guard :shell do
watch(%r{^*\.rb}) { `bundle exec rspec spec/` }
end
This tells guard to watch for modifications to any ruby files in the directory and execute the command bundle exec rspec spec/ when they change (the backticks are used to execute the command in the shell).
Then open up a new terminal window in your current directory and start a guard server to start watching the files:
$ bundle exec guard
Now your Rspec test suite should automatically run when you modify ruby files in the directory.
I used guard at the past, but now I'm using a combination of rspec focus feature and watch command.
It's very simple, just add an f before a describe of it block you want to run the test. So it would becomes fdescribe or fit block. This is the same as adding a tag :focus => true to your block.
We can then filter specs with the focus tag: rspec -t focus
Now, to keeping running theses specs (every 0.5 seconds) with focus tag we call it with watch command:
watch -n 0.5 rspec -t focus
But with that the output won't show colors. So, we need to use with unbuffer.
sudo apt-get install expect
With a little customization:
watch -n 0.5 --color 'unbuffer bundle exec rspec -t focus'
Since it's annoying to type this all, I made two alias at my ~/.bash_aliases file (your can use .bashrc as well):
alias focus="watch -n 0.5 --color 'unbuffer bundle exec rspec -t focus'"
alias focuss="bundle exec rspec -t focus"
Now I can type focus to keep running it, or for a single focus execution I type focuss
Guard can be used for plain old ruby. I generally have trouble with guard so I like to use watchr, another gem. With a few lines of code you can tell watchr to watch for changes to your files and run a command when they change.
For an example of guard with plain ruby, see the shuhari gem.
update on watchr gem: There appears to be an issue with this gem, perhaps with versions of ruby >= 2.0. The observr gem addresses this issue and works as expected in ruby 2.3.
I have used guard and the guard-rspec addition with great results, and I don't believe it to be Rails-specific. Other Ruby/RSpec projects should work equally well.
The guard documentation recommends the use of Bundler and to "always run Guard through Bundler to avoid errors". I.e. you install it through your Gemfile and always run it with bundle exec guard (or use rubygems-bundler to avoid the bundle exec part).

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 execute a self contained rake build?

We have an application which is compiled using Rake (on windows). We have a new requirement that one of our clients needs to compile the source code in their own environment using a bat file.
So I need to find a way to execute a rake build without installing anything on the host environment (i.e. everything required to do the build needs to be in the source directory, ruby, gems, etc...) from a batch file.
Anyone have any clues how I could get started with this?
Download and install ruby to a folder inside your project (do not add it to your PATH). After go to this folder and delete any "uninstall" file. Go to the folder again with the console (cmd and then use cd path\to\ruby\folder) and run gem install ... to install everything you need. After add a .bat file to run your app. Something like:
#echo off
rubyfolder\bin\ruby.exe myscript.rb
This is a fully portable ruby installation, you can put it in any computer and it will work as well. (I use it as a portable ruby in my pendrive to let me play everywhere with ruby!)
PS.: rake is a script from bin, you can open it with:
rubyfolder\bin\ruby.exe rubyfolder\bin\rake

Resources