How do I use frozen Capistrano part 2? - ruby-on-rails

Following on from my question on using frozen Capistrano a couple of days back I'm still having issues running Capistrano frozen in my vendor folder.
When I try and run my frozen version of cap
ruby -r rubygems ./vendor/gems/capistrano-2.5.2/bin/cap deploy-with-migrations
I get an error
... RubyGem version error: net-ssh(1.0.8 not >= 2.0.0) (Gem::LoadError) ...
I have net-ssh-2.0.4 frozen in my vendor folder as I knew it was a dependency so how do I make use of it?
I'd hoped adding my vendor folder to my .gemrc file under the gempath: would have done the trick, but it hasn't. 'gem environment' shows the vendor path, but 'gem list' doesn't show the gems in the vendor folder.
Any ideas?

In the end I decided not to freeze Capistrano and dependancies to my vendor gems directory as they weren't gems used by my application - they were used to deploy my application.
Instead I locally installed them on my hosting account and all worked fine.

If you want to completely avoid the system-installed gems (which isn't a bad idea if you don't have control over them), I'd install a copy of rubygems to vendor directory.
Set GEM_PATH and GEM_HOME environment variables to /path/to/your/vendor/gems directory, and then install rubygems and go from there.

Related

Does Rails need to be installed as a system gem?

In every setup describing a configuring an environment with rbenv and Bundler, the instructions are always to install bundle as a system gem, using gem install bundler. Often, they'll also recommend rbenv-bundler rbenv plugin, but the maintainers of rbenv discourage this.
What's not described is how to install Rails. Initializing a new Rails project creates a basic Gemfile for bundler. However, in order to initialize a Rails project, one needs to have Rails installed. It seems weird and even wrong to make a directory, write a basic Gemfile that includes Rails, run bundle install, and then initialize Rails to the current directory. In fact, I doubt that would even work well, if it worked at all.
So, does Rails need to be installed as a system gem with gem install rails? If so, how does one manage multiple versions of Rails, particularly with rbenv?
It totally makes sense to NOT install rails as system gem.
Without messing up rbenv or other ruby version manager you use, below are brief steps to create (initialize) a new Rails app from a directory with a Gemfile:
mkdir rails_app
cd rails_app
vi Gemfile # Edit it to include a rails version you need
bundle --path vendor # Wait for bundler to finish
bundle exec rails new ./
The last step would ask: Overwrite /path/to/rails_app/Gemfile? (enter "h" for help) [Ynaqdh]. Input y to get the default Rails Gemfile content.
Note: the above steps specify the local vendor directory (inside the rails app folder) to avoid installing gems to system global scope.
Answer is no, you don't install rails as system gem. Create a project folder, add .ruby-version file and add the ruby version you would like in this file i.e. 2.3.0. rbenv uses the version specified in this file and it won't be system's ruby.
Now you can do gem install bundler from this directory and create Gemfile and add your rails version. Now run bundle install and roll it on the tracks of RAILS.....
Force rails to vendor gems.
$ mkdir foo
$ cd foo
$ bundle config --local path vendor
$ rails new .

Should I install ruby gems in system repository (globally) or the project vendor/bundle (locally)?

I'm using Ruby 2.1 and Rails 4.1 on Windows 7. Whenever I run bundle install, all gems are installed in the system path c:/Ruby21/lib/ruby/gems/2.1.0/gems/. I also found the vendor directory in my project.
Coming from PHP composer and node.js npm background, all dependencies should be locally installed in the project vendor folder or node_modules folder. So, my questions are:
Should I install gems in the system path or vendor/bundle?
If all gems or some gems should be installed in the system path, how could it affect the production environment where I may not have shell access?
Should all gems or specific gems be installed in vendor/bundle?
How can I install gems in vendor/bundle?
When you run bundle install, you are using a tool called Bundler.
Bundler takes care of managing your dependencies in a similar way as Composer, but instead of installing everything in the project folder, it installs your gems system-wide, that are shared among all your projects. It keeps track of what project requires which libraries by using the Gemfile in your project folder. So, you should just let Bundler do its thing, it does it very well and is the standard package manager for Rails.
If your host supports Ruby and Rails applications (for example, a PaaS like Heroku), it definitely will support Bundler and all the necessary gems will be installed. If you're talking about a cheap shared hosting without shell access, you won't be able to deploy a Ruby application there anyway because you will need to install the actual Ruby interpreter and other things, which would require shell access.
No.
You shouldn't. There's this article describing how to do it, but it seems to me that
countless times where installing gems globally leaked into other projects on the same machine and led to weird behavior that was annoying to debug
has only ever happened to the author of this article, and I don't think Bundler is at fault. In any case, you should always prepend gem commands with bundle exec (as in bundle exec rspec) and you will never have the mentioned problem. bundle exec makes sure that when you execute a command from a gem, the correct version defined in your Gemfile is called, it is important if you have several version of the same gem installed in your system.
A few years ago when RVM was popular, gemsets achieved a similar goal but got mostly deprecated by rbenv and Bundler.

Bundler unable to find custom gem

I have a custom gem built as a .gem file that I am trying to reference from my Gemfile. I have placed the .gem file, along with the .gemspec, in the vendor/gems folder. My Gemfile has the following line:
gem 'umlgrader', '1.0.0', :path=>'vendor/gems'
When I run bundle install, it claims to have found the gem but it says it is "using" the gem, rather than "installing" it, even though the gem was not previously installed on my machine. When I try to run my app, I then get a NoMethodError when it tries to call any of the methods in the gem. Why isn't Bundler installing the gem?
I have gotten it to work by unpacking the gem in that directory and then editing the Gemfile as follows:
gem 'umlgrader', '1.0.0', :path=>'vendor/gems/umlgrader-1.0.0'
This solution is less than desirable. I would prefer to be able to install the gem using Bundler since I am trying to deploy the app to Heroku. I have already tried a lot of the solutions I have found online, but I am open to any suggestions.
EDIT:
Some of the other pages I have already gone through and tried:
Bundler: installing a specific .gem file
How to use Bundler with offline .gem file?
How do I specify local .gem files in my Gemfile?
I also noticed a lot of people suggest pointing to a Git repository containing the gem. I would rather not do this if I don't have to.
The Bundler documentation is somewhat cryptic on that topic, but that is the intended behaviour of Bundler. In order to use the path option you must unpack the gem at the desired location.
But that should be no problem for Heroku. After all, you are still using Bundler, even if the gem is already unpacked. It's just a step less in the gem installing process...
Without Docker
You need to clone the repository from github (or other source) to your custom folder. In example below the steps to reproduce how I use custom path to edit gems in a separeted folder:
In this case I use a custom_gems folder inside /bundle: mkdir /bundle/custom_gems.
cd /bundle/custom_gems.
git clone <gem-repository-source>. Is necessary to clone because if you copy from other folder in your computer probably some files are missed.
Set in your Gemfile: gem '<gem-name>', path: '/bundle/custom_gems/<gem-name>'.
Restart you application.
In docker-compose (or Docker)
With docker is little different, in this case I use a /gems folder inside my rails application folder: mkdir <my-app>/gems.
cd <my-app>/gems.
git clone <gem-repository-source>. Is necessary to clone because if you copy from other folder in your computer probably some files are missed.
Set in your Gemfile: gem '<gem-name>', path: '/bundle/custom_gems/<gem-name>'.
If you use docker-compose, you need to bind folders with volumes config, like below:
volumes:
- ./app/gems:/bundle/custom_gems
With this, your local folder (your machine) copy files inside ./app/gems to /bundle/custom_gems in Docker container.
Restart service.
If you NOT use docker-compose, you need add in Dockerfile some like:
ADD ./app/gems /bundle/custom_gems

Using RVM Gemsets & Bundler & RubyMine

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)

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