Using RVM Gemsets & Bundler & RubyMine - ruby-on-rails

I use RVM to manage Ruby versions.
In my project I use Bundler to manage gems for the project.
RVM also have gemsets.
Gem in gemset don't have a connection with Bundler's gem. ← Is this correct?
I came to this conclusion because gem files stored in different locations:
RVM gemset: ~/.rvm/gems/ruby-2.0.0-p247#myApp
Bundler: [my_app_dir]/vendor/bundle/gems
So app uses Bundler gems, not RVM gemset gems.
But when I add gem to my Gemfile, RubyMine IDE shows me warning, that this gem is not in RVM gemset. So I add this gem to RVM gemset also (just to get rid of this warning).
So the questions are:
Is there any good reason to add gems in both places (RVM Gemset and Gemfile)?
If no, then why RubyMine warning me about this?

Is there any good reason to add gems in both places (RVM Gemset and Gemfile)?
The gemset is incidental, the Gemfile is absolutely the place to declare your dependencies. Where you store those gems is up to you.
It sounds like Bundler is configured to store them in a project-local path, but you're expecting them to be in a gemset. Bundler got that configuration by running bundle install --path vendor/bundle/gems at some point. It stores that configuration in its project configuration file at project_dir/.bundle/config:
BUNDLE_PATH: vendor/bundle/gems
I'm unfamiliar with Rubymine, but if you run the Rails server using Bundler (i.e. bundle exec rails server) you can ignore that warning. Bundler will correctly load the gems listed in the Gemfile.
If you want to use a gemset instead of the Bundler cache, you can just remove that line from the Bundler configuration file and reinstall your gems with bundle install.
If no, then why RubyMine warning me about this?
My guess is that Rubymine is not reading the Bundler project configuration (in project_path/.bundle/config) and does not understand where the gems are installed.

You (or if you are working in a team, somebody of your team) has once done a bundle install and specified a installation-folder. In your case vendor/bundle/gems. Bundle remembers this setting and all next invocations of the bundle command will use the same path.
There is a good reason to do it that way: your application-folder will contain all requirements and will be easier to redistribute (for instance).
Now if you want that bundle installs your gems in the normal locations, you can do the following:
run bundle install --system which will use the default location
alternatively: bundle stores it settings in a config file, I think .bundle/config and you can
check that one as well. Normally it is not needed, since bundle install --system will set that
correctly again.
then you can safely remove the vendor/bundle/gems folder

No, something's wrong, you shouldn't have anything under vendor/bundle, it should all be under ~/.rvm/gems/ruby-2.0.0-p247#myApp and perhaps ~/.rvm/gems/ruby-2.0.0-p247#global assuming your .rvmrc (or.ruby-version) is setup correctly.
What does "gem env" look like? Also "bundle env"?

So this just took me 3 days, since nothing else I was finding here was helping. I also run multiple projects through RubyMine at the same time (and different versions) so setting my GEM_PATH and launching from command-line doesn't work for me. I use IntelliJ with RM plugin, this should work on RM standalone.
Bundler seems to install custom gems, or gems from custom repos, in a different directory than gems from rubygems, or github.
/Users/YOURUSER/.rvm/environments/ruby-{version}\#yourgemset/bundler/gems
One thing I wasn't able to fix is in the GEMFILE, I have some custom git_sources, and rubymine highlights those and gives me the warning that it cannot find the gem in my bundle (you can ignore this warning; unless the gem doesn't install at all):
gem 'somegem', custom_git:'gituser/repo'
is highlighted and warning is "Gem x cannot be found... in SDK'
However Bundler installed it, and ruby is able to load it.
# TLDR: Steps to have RUBYMine find extra gems, and show up in external libs
vim ~/.rvm/environments/ruby-{your-verion-here}\#{your-gemset}
add the bundler gems path to GEM_PATH entry
export GEM_PATH='/Users/YOURUSER/.rvm/gems/ruby-{version}#yourgemset/bundler/gems:{the rest}'
save the file
Restart RubyMine/IntelliJ, reopen your project (if not open automatically)
Open the Project Structure dialog > Platform SDKs > Choose the GEMSET you're working with
add /Users/YOURUSER/.rvm/environments/ruby-{version}\#yourgemset/bundler/gems to your classpath
Hit OK, then REOPEN the Project Structure Dialog > Project Settings > Project
Your project will likely have no SDK So select the one you're using again and hit OKAY
RM/IJ will now reindex files
You're done, any broken/missing inspection links should now be fixed. And you should be able to introspect into your gems.
In the above instructions that when you run bundle install (from terminal or RM) it works successfully, and that you have RVM correctly setup, and gemset already created
I hope this helps! Let me know if I should clarify anything (happy NYE)

Related

Does 'bundle install' install all the required gems on my computer permanently?

I am new to rails and am learning about bundler. I understand that bundle install installs all the gems specified in the gemfile but where does it install them to?
Does it install them on my computer permanently so that they can be used by any future project?
If so doesnt this mean my computer gets filled with random gem versions and gem installs that I needed for one example project but may never use again?
By default, bundle install is going to install at the root level so all users on a computer could have access to the gems. So 'yes' it is permanent (at least not tied to your application, you can remove them whenever you want).
Take a look at the man pages for bundler. In here, you'll notice that you can specify to install to a local directory.
Install your dependencies, even gems that are already installed to your system gems, to a location other than your system's gem
repository. In this case, install them to vendor/bundle.
$ bundle install --path vendor/bundle
Further bundle commands or calls to Bundler.setup or Bundler.require
will remember this location.
This will let you install the gems to a location inside your application. So when you delete the example app, you also delete the associated gems.
Also, if you would like to see where a specific gem is installed (say you want to look at its source code), type bundle show <gemname>. This will spit out the path to that gem.
The short answer is 'yes'. The longer answer is that there are some technologies which will reduce or eliminate the problems associated with this effect.
If you install 'RVM':
https://rvm.io/
this will allow you to install multiple versions of Ruby and create individual 'gemsets'. As you enter the directory that contains your project, the ruby version and gemset settings are automatically picked up and the active Ruby version will change. This way you can keep gems separate between projects - and use several Ruby versions at once, including JRuby and other esoteric versions.
To find out where gems are stored, type:
gem environment
into your command line and look for the INSTALLATION_DIRECTORY entry in the response.

Make rvm gemset mirror/reference Capistrano's bundle install

I'm currently deploying from my local machine to a development server using Capistrano. The dev server has a gemset for my project called 'vcc', but as is clear across the internet, Capistrano does its bundle install into shared/bundle rather than the rvm gemset.
It's easy enough to make a .rvmrc file and have that selecting the 'vcc' gemset when I cd into the project. However, this gemset doesn't get updated as part of a deploy. So I still generally run all my commands with 'bundle exec', which selects the 'shared/bundle' rather than the rvm gemset.
What I want to do is have the rvm gemset remain updated so that when I cd into the project I don't have to run bundle exec before everything. I'm not sure what the best way to do this is. My only idea was to create a symlink in the 'vcc' gemset directory that points to the 'shared/bundle' directory. I read somehwere that rvm should be self contained though and will not follow symlinks out of the /rvm directory?
I've seen that it's possible to make Capistrano deploy to your gemset, but it's not recommended. I'm fine with letting Capistrano handle gems and rvm handle ruby, I just want to get rid of "bundle exec." Maybe there's an easier way that doesn't have anything to do with configuring Capistrano or rvm?
Actually it is not recommended to use vendored gems, there are few issues with it and you will be safer using a gemset instead.
rvm-capistrano already suggests you disable the vendored gems here https://github.com/wayneeseguin/rvm-capistrano#disabling-bundle---deployment-when-using-gemsets :
set :bundle_dir, ''
set :bundle_flags, '--system --quiet'
This way gems will be installed in gemset and everything will work fine.

Rails 3 "bundle install" in Capistrano deploy -- but how to clean up?

After a long overdue reading of the bunder documents, I pretty much understand why it's a great thing compared to manual gem install.
But this came to me (and others) only recently, and now we have a hybrid environment. Our development machines are mostly fine. But when we deploy to production, Bundler tells capistrano to put the gems in shared/bundle/gems, which makes sense. But we still have manually installed gems in the normal .rvm location.
So now we know not to use "gem install" on production, but we're dealing with version mismatches when we run Rake tasks directly. We can use "bundle exec rake foo:bar" to force the correct behavior, I think. But for now we have a bunch of outdated gems:
Outdated gems installed by Bundler, and
Gems we manually installed using gem install
I would like to get things pristine. Is there any reason I shouldn't use gem cleanup?
Hope this isn't too convoluted :-)
Thanks in advance.
gem cleanup will keep the latest version of all gems, and remove older versions. What I think you want is this:
(Optional) create an RVM gemset for your project. (I like to do this; some people rely entirely on Bundler, which also works.)
Make sure all your top-level dependencies are specified in your Gemfile.
Remove all gems (rvm gemset empty may be helpful) except Bundler.
bundle install
Run everything with bundle exec from now on.

What are the benefits & drawbacks of installing things into the #global gemset in RVM?

What are the benefits & drawbacks of installing things into the #global gemset in RVM?
Let's say I want to install different versions of rails on the same server. I then want the ability to install multiple ruby apps on the same server, with the least duplication of files to save on disk space. However, I still want to avoid dependency problems, gem conflict issues and other problems.
Let's also assume that each app has extra gems it needs that I only want in it's local project gemset.
Would I be better off:
Installing both Rails 3 and Rails 2 gems into the #global gemset
...And use project-local gemsets for their gems...
Installing Rails 3 into a #rails3 gemset, and Rails 2 into a #rails2 set... then cloning for each project I need?
For example:
rvm use ree#rails3 && rvm gemset export rails3.gems
rvm use ree#rails2 && rvm gemset export rails2.gems
rvm use --create ree#project1-on-rails3 && rvm gemset import rails3.gems
Install more project-local gems here...
rvm use --create ree#project2-on-rails2 && rvm gemset import rails2.gems
Install more project-local gems here...
Something else entirely...
NOTE: I wrote this whole response assuming that you are using Bundler to manage your gem dependencies. I realize that some people don't, and you didn't mention Bundler in your question. If you aren't using Bundler, I would point out that it probably is the best way to conserve disk space (only if you bundle install --system, though!). If you are using exported gemsets to manage dependencies, I think your scheme sounds reasonable, but I have no experience with it.
Both Rails 3, and Rails 2 with Bundler will set their load path appropriately such that they will not load any gems (or any versions of any gems) that are not in the Gemfile.lock. There's not really any way that I've experienced to have a "gem dependency problem" on the server. It is important that you run bundle install on your development machine whenever you modify the Gemfile, and that you check your Gemfile.lock into source control, as described on the Bundler homepage.
I spent some time digging into the use-cases of gemsets back in January. The reasons I found to use separate gemsets for each project were:
Your shell environment is the same as your application environment (scripts run correctly without bundle exec).
You can easily browse and grep through the source code of all your dependencies, by navigating to the gemset install directory.
It prevents some reported ‘heisenbugs’, according to the author of RVM. I have experienced something like this where a gem executable wasn't available and bundle exec didn't seem to help.
I don't think any of these benefits are very compelling on the server, so if you are aiming to conserve disk space, I'm not sure why you would use gemsets at all.
Actually, the only reason I've used rvm at all on the server was because it was a convenient way to build ruby from source (we needed a version that wasn't available in the native package manager).

Bundler puts my gems in my project directory

I have a Rails 3rc app on Ruby 1.9.2 that works fine, but Bundler keeps making a folder named "bandsintown" (bandsintown is a gem I use) in my project directory. From what I can tell, the folder has all my gems in it. I'm pretty sure that this never happened before. Is it normal behavior?
I think this might be interfering with running tests. I get a "Command failed with status (1)" error and then it mentions the "bandsintown" folder a few times.
I find it odd that Bundler names the folder "bandsintown" even when I comment out that gem in the gemfile. There's a "ruby" folder in that one, and a "1.9.1" folder inside the "ruby" folder. I don't understand why it says 1.9.1 when I'm using 1.9.2. The 1.9.1 folder has a bin, bundler, cache, doc, gems and specification folder inside of it.
I made a testapp with all the same gems and did a bundle install. It doesn't make a new folder with all my gems in it.
Anyway, my app works fine, but I'd appreciate it if anyone could help me out here. If I left out any need-to-know information, let me know. Thanks.
You are probably running the following command: bundle install bandsintown. That command tells bundler to install gems into the bandsintown subdirectory of your application. In order to install gems, all you need to do is modify your Gemfile and run bundle install.
Bundler will remember the location that you last specified in the .bundle/config file. So, in order to "reset" bundler's memory. In your application's directory, run rm -r .bundle/config.
Then, after updating your Gemfile, simply run bundle install

Resources