Can I get Bundler to share Git-based gems across projects? - ruby

Without the gemsets provide by a tool like RVM, all gem installations are global. So if two projects use the same version of Ruby, and both have identical gemfiles, I would expect that running bundle install for the first one would install the gems, then running bundle install for the second would be able to use the already-downloaded gems to satisfy its requirements.
However, this doesn't appear the be the case with gems that are located in Github repos. For example, I have several projects with identical gem references, similar to this:
gem 'some_gem', git: 'git#github.com/me/some_gem.git', ref: 'a293bkd9d23'
Yet, although bundle install in one project clearly has to download this particular commit, it seems that bundle install in the next project repeats that process.
Bundler does not appear to store these Git-based gems in ~/.gem with my normal gems.
Where does it put them, and can I make it check for the specified commit locally before fetching from the repo again?

Related

Is it recomment to install ruby dependencies into local folder?

I'm learning ruby recently and I'm a front-end developer, I found the dependecies are installed to C:/Ruby31-x64/lib/ruby/gems/3.1.0 folder when I use bundle install. it seems dependencies are installed globally by default like the npm install -g. I know that Bundler also have a way to install the gems to the local folder, so I wonder is
it recommend to install the dependencies to the local folder like npm does?
Similar to Composer, Bundler takes care of maintaining your dependencies, but rather than installing everything in the project folder, it distributes your gems system-wide, which are then shared by all of your projects. Using the Gemfile in your project folder, it keeps track of which libraries each project needs. Bundler is the default package manager for Rails, so you should simply let it do its thing. It does it quite well.
Hope this helps.
Use a Version Manager for Ruby, and Bundler for Gem Version Management
There are occasionally reasons to install gems in from one another isolation, but most often you should use a Ruby version manager to manage your non-system Rubies and Bundler to handle multiple gem versions and locations. Avoid modifying your system Ruby or its gems whenever possible. Also, be aware that even using RVM gemsets (or similar features in other version managers) without tweaking some poorly documented features like rvm gemset globalcache enable can create a level of isolation that is likely unnecessary and can bloat disk usage dramatically.
If You Need Gem Isolation...
That said, if you want to ensure you are isolating your gems or localizing them to your application and aren't using direnv's Ruby layout to manage all the various environment variables involved, you can use Bundler's BUNDLE_PATH environment variable to "vendor" your gems into the local application directory (these days usually under vendor/bundle). For deployments or containerization, you can also invoke bundle-install with the --deployment or --standalone flags and a list of gem groups to install if you don't want to rely on the availability of Bundler itself after installing the gems.
This sort of thing might be useful for building containers or tarballs, but isn't really very useful for development. Don't do it unless you have a really strong reason.

Bundler: ensure production gems installed system-wide?

I have a ruby program in my git repo, used by a team. It's executed directly out of the git repo. I don't want all the team members to have to deal with gems, so I want the production-level gems to be installed system-wide (on shared disk). Bundler will use the git-controlled Gemfile.lock to decide which gems to pick up.
For development, I often install gems using --user-install.
Problem: I might accidentally push changes that use gems which are only user-installed, which will break other team members when they pull and try to run.
How can I ensure that all non-development gems are installed system-wide?
Is there a bundle command I can run that will detect this and throw an error? Or can I somehow get my cucumber tests to run using only system gems?
There is no way to get Bundler to use System gems, though I think there should be: https://github.com/bundler/bundler/issues/1964
The most straightforward solution for you would be to package the gems into your Git repo: http://bundler.io/v1.12/bundle_package.html.
This is really how the bundler team recommend that it should be run in a case where you want a user to be able to run your app without having to install gems locally.
A second option would be for you to use the --path option to bundle install and point that to a shared location visible to all your users. This option is remembered, so check .bundle into your Git repo and then your users would use the same configuration and reference the same location when they run bundle. Since all of the gems would already be installed there by you, they would have no problems.

How to Install Ruby gems on all agents using TeamCity?

I am working on Teamcity 6.5.6, and looking for a way to automatically install required ruby GEMS on build agents.
For Ex: Suppose I have two gems that are required on each agent/remote (build) machine. Ex: Watir and Selenium gems. Then am I suppose to install them manually by logging on to those machines, or can I do keep them in a common library folder in SVN, and perform some tasks in Teamcity to install them if not present on machine.
If so, then What would be that task in Teamcity?
Thanks
Take a look at Bundler.
You could maintain a list of your required gems in a Gemfile, then run bundle install on each machine before the build starts. This would install all of the gems in the Gemfile (and you could lock gems to a particular version by also including the Gemfile.lock file).

Bundler: do I have to use the same commandline options each time?

I had some problems with Bundler and stopped using it for a while. Now, I'm getting back to using it, and read up on it more this time and decided these are the first commands I should run:
bundle install --binstubs --path vendor
bundle package
I know that future calls to bundle will remember the path, but now I've updated my Gemfile with a new gem, should I run...?
bundle install - Bundler will work out that I already have the other gems cached, and I want executables to bin/.
bundle install --local - Bundler needs to know I want to use the cached gems but remembers the other stuff. This doesn't work (or, more precisely, isn't for this situation), just use bundle install and it won't reinstall current gems (although I've seen it do that which is why I asked)
bundle install --local --binstubs - Bundler isn't going to remember anything and I need to provide it.
Any other combination/commands I'm not aware of.
And then, do I need to re-run bundle package again after this? My experiments show me that re-running bundle package is not required, the cache is updated with new gems.
I did read the docs, (and a couple of blogs, though finding up-to-date ones is quite difficult) but this isn't clear to me.
Any help is much appreciated.
Certain options are what bundler calls remembered options and are stored in .bundle/config. These remembered options don't need to be typed again and again.
According to the http://gembundler.com/man/bundle-install.1.html#REMEMBERED-OPTIONS, the remembered options are --deployment, --path, --binstubs, --without

Is there a way to use Bundler for production gems?

I tried searching for this several times, but if this question has been answered already I didn't find it.
So, let's say I've developed a plain old gem (not a Rails app). I already know how to use Bundler for development, so I have a Gemfile and everything in my repository. However, I want this gem to use Bundler for dependency resolution when I install it, not just when I work on it.
Is there a way to do so, or would I have to resort to running its commands from a git checkout with bundle exec?
Bundler resolves dependencies not only for development. Just run bundle install on production server after deployment and it will install all needed gems there too.
If you need to install gems from several repositories, add row in you Gemfile:
source 'http://you_repository.com

Resources